Example #1
0
def start_ip6bound_httpservice(device, ip="::", port="9001"):
    '''
    Starts a simple web service on a specified port,
    bound to a specified interface. (e.g. tun0)
    Send ctrl-c to stop (twice? needs better signal handling)
    '''
    device.sendline('''cat > /root/SimpleHTTPServer6.py<<EOF
import socket
import BaseHTTPServer as bhs
import SimpleHTTPServer as shs

class HTTPServerV6(bhs.HTTPServer):
    address_family = socket.AF_INET6
HTTPServerV6((\"%s\", %s),shs.SimpleHTTPRequestHandler).serve_forever()
EOF''' % (ip, port))

    device.expect(device.prompt)
    device.sendline("python -m /root/SimpleHTTPServer6")
    if 0 == device.expect(['Traceback', pexpect.TIMEOUT], timeout=10):
        if "BFT_DEBUG" in os.environ:
            print_bold('Faield to start service on [' + ip + ']:' + port)
        return False
    else:
        if "BFT_DEBUG" in os.environ:
            print_bold("Service started on [" + ip + "]:" + port)
        return True
Example #2
0
def retry_on_exception(method, args, retries=10, tout=5):
    """
    Retries a method if an exception occurs
    NOTE: args must be a tuple, hence a 1 arg tuple is (<arg>,)
    """
    output = None
    for not_used in range(retries):
        try:
            output = method(*args)
            break
        except Exception as e:
            print_bold("method failed %d time (%s)" % ((not_used + 1), e))
            time.sleep(tout)
            pass

    return output
Example #3
0
def start_ipbound_httpservice(device, ip="0.0.0.0", port="9000"):
    '''
    Starts a simple web service on a specified port,
    bound to a specified interface. (e.g. tun0)
    Send ctrl-c to stop
    '''
    device.sendline(
        "python -c 'import BaseHTTPServer as bhs, SimpleHTTPServer as shs; bhs.HTTPServer((\"%s\", %s), shs.SimpleHTTPRequestHandler).serve_forever()'"
        % (ip, port))
    if 0 == device.expect(['Traceback', pexpect.TIMEOUT], timeout=10):
        if "BFT_DEBUG" in os.environ:
            print_bold("Faield to start service on " + ip + ":" + port)
        return False
    else:
        if "BFT_DEBUG" in os.environ:
            print_bold("Service started on " + ip + ":" + port)
        return True
Example #4
0
def start_ipbound_httpsservice(device,
                               ip="0.0.0.0",
                               port="443",
                               cert="/root/server.pem"):
    '''
    Starts a simple HTTPS web service on a specified port,
    bound to a specified interface. (e.g. tun0)
    Send ctrl-c to stop (twice? needs better signal handling)
    '''
    import re
    # the https server needs a certificate, lets create a bogus one
    device.sendline(
        "openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes"
    )
    for i in range(10):
        if device.expect([re.escape("]:"),
                          re.escape("Email Address []:")]) > 0:
            device.sendline()
            break
        device.sendline()
    device.expect(device.prompt)
    device.sendline("python -c 'import os; print os.path.exists(\"%s\")'" %
                    cert)
    if 1 == device.expect(["True", "False"]):
        # no point in carrying on
        print_bold("Failed to create certificate for HTTPs service")
        return False
    device.expect(device.prompt)
    # create and run the "secure" server
    device.sendline('''cat > /root/SimpleHTTPsServer.py<< EOF
# taken from http://www.piware.de/2011/01/creating-an-https-server-in-python/
# generate server.xml with the following command:
#    openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
# run as follows:
#    python simple-https-server.py
# then in your browser, visit:
#    https://<ip>:<port>

import BaseHTTPServer, SimpleHTTPServer
import ssl

httpd = BaseHTTPServer.HTTPServer((\"%s\", %s), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket, certfile=\"%s\", server_side=True)
httpd.serve_forever()
EOF''' % (ip, port, cert))

    device.expect(device.prompt)
    device.sendline("python -m /root/SimpleHTTPsServer")
    if 0 == device.expect(['Traceback', pexpect.TIMEOUT], timeout=10):
        print_bold("Failed to start service on [" + ip + "]:" + port)
        return False
    else:
        if "BFT_DEBUG" in os.environ:
            print_bold("Service started on [" + ip + "]:" + port)
        return True
Example #5
0
def start_ip6bound_httpsservice(device,
                                ip="::",
                                port="4443",
                                cert="/root/server.pem"):
    '''
    Starts a simple HTTPS web service on a specified port,
    bound to a specified interface. (e.g. tun0)
    Send ctrl-c to stop (twice? needs better signal handling)
    '''
    import re
    # the https server needs a certificate, lets create a bogus one
    device.sendline(
        "openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes"
    )
    for i in range(10):
        if device.expect([re.escape("]:"),
                          re.escape("Email Address []:")]) > 0:
            device.sendline()
            break
        device.sendline()
    device.expect(device.prompt)
    device.sendline("python -c 'import os; print os.path.exists(\"%s\")'" %
                    cert)
    if 1 == device.expect(["True", "False"]):
        # no point in carrying on
        print_bold("Failed to create certificate for HTTPs service")
        return False
    device.expect(device.prompt)
    # create and run the "secure" server
    device.sendline('''cat > /root/SimpleHTTPsServer.py<< EOF
import socket
import BaseHTTPServer as bhs
import SimpleHTTPServer as shs
import ssl

class HTTPServerV6(bhs.HTTPServer):
    address_family = socket.AF_INET6
https=HTTPServerV6((\"%s\", %s),shs.SimpleHTTPRequestHandler)
https.socket = ssl.wrap_socket (https.socket, certfile=\"%s\", server_side=True)
https.serve_forever()
EOF''' % (ip, port, cert))

    device.expect(device.prompt)
    device.sendline("python -m /root/SimpleHTTPsServer")
    if 0 == device.expect(['Traceback', pexpect.TIMEOUT], timeout=10):
        print_bold("Failed to start service on [" + ip + "]:" + port)
        return False
    else:
        if "BFT_DEBUG" in os.environ:
            print_bold("Service started on [" + ip + "]:" + port)
        return True
Example #6
0
def parse():
    '''
    Read command-line arguments, return a simple configuration for running tests.
    '''
    parser = argparse.ArgumentParser(
        description=
        'Connect to an available board, flash image(s), and run tests.',
        usage='bft [options...]',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=HELP_EPILOG)
    parser.add_argument('-l',
                        '--list_tests',
                        action='store_true',
                        help='List available tests and exit')
    parser.add_argument('-i',
                        '--inventory',
                        action='store_true',
                        help='List available boards and exit')
    parser.add_argument(
        '-y',
        '--batch',
        action='store_true',
        help='Run in unattended mode - do not spawn console on failed test')
    parser.add_argument('-t',
                        '--retry',
                        type=int,
                        default=0,
                        help='How many times to retry every test if it fails')
    parser.add_argument('-k',
                        '--kernel',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH of Kernel image to flash')
    parser.add_argument('-r',
                        '--rootfs',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH of Rootfs image to flash')
    parser.add_argument('--nfsroot',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH of Rootfs image to flash')
    parser.add_argument('-m',
                        '--meta_img_loc',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH to meta image to flash')
    parser.add_argument('-p',
                        '--package',
                        metavar='',
                        type=str,
                        action="append",
                        default=None,
                        help='URL or file PATH of ipk install after boot')
    parser.add_argument('-u',
                        '--uboot',
                        metavar='',
                        type=str,
                        default=None,
                        help=argparse.SUPPRESS)
    parser.add_argument('-s',
                        '--sysupgrade',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH to Sysupgrade image')
    parser.add_argument('-x',
                        '--testsuite',
                        metavar='',
                        type=str,
                        default=None,
                        help='NAME of test suite to run')
    parser.add_argument('-e',
                        '--extend',
                        metavar='',
                        type=str,
                        default=None,
                        action="append",
                        help='NAME of extra test to run')
    parser.add_argument('-n',
                        '--board_names',
                        metavar='',
                        type=str,
                        nargs='+',
                        default=[],
                        help='NAME(s) of boards to run on')
    parser.add_argument('-b',
                        '--board_type',
                        metavar='',
                        type=str,
                        nargs='+',
                        default=None,
                        help='MODEL(s) of board to connect to')
    parser.add_argument('-w',
                        '--wan',
                        metavar='',
                        type=str,
                        default='dhcp',
                        help='WAN protocol, dhcp (default) or pppoe')
    parser.add_argument('-v',
                        '--reboot-vms',
                        action="store_true",
                        help='Reboot VMs before starting tests')
    parser.add_argument('-f',
                        '--filter',
                        metavar='',
                        type=str,
                        default=None,
                        action="append",
                        help='Regex filter off arbitrary board parameters')
    parser.add_argument('-a',
                        '--analysis',
                        metavar='',
                        type=str,
                        default=None,
                        help='Only run post processing analysis on logs')
    owrt_tests_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                  "results", '')
    parser.add_argument('-o',
                        '--output_dir',
                        metavar='',
                        type=str,
                        default=owrt_tests_dir,
                        help='Directory to output results files too')
    parser.add_argument('-z',
                        '--no-network',
                        action='store_true',
                        help='Skip basic network tests when booting')
    parser.add_argument('-c',
                        '--config_file',
                        metavar='',
                        type=str,
                        default=boardfarm_config_location,
                        help='JSON config file for boardfarm')
    parser.add_argument(
        '--bootargs',
        metavar='',
        type=str,
        default=None,
        help='bootargs to set or append to default args (board dependant)')
    parser.add_argument(
        '-g',
        '--golden',
        metavar='',
        type=str,
        default=[],
        nargs='+',
        help='Path to JSON results to compare against (golden master)')
    parser.add_argument('-q',
                        '--feature',
                        metavar='',
                        type=str,
                        default=[],
                        nargs='+',
                        help='Features required for this test run')

    args = parser.parse_args()

    if args.list_tests:
        import tests
        tests.init(config)
        # Print all classes that are a subclass of TestCase
        for e in dir(tests):
            thing = getattr(tests, e)
            if inspect.isclass(thing) and \
               issubclass(thing, unittest2.TestCase):
                try:
                    print("%20s - %s" % (e, thing.__doc__.split('\n')[0]))
                except:
                    print("%20s -" % e)
        sys.exit(0)

    try:
        if args.config_file.startswith("http"):
            data = urlopen(args.config_file).read().decode()
        else:
            data = open(args.config_file, 'r').read()
        config.boardfarm_config = json.loads(data)

        if 'locations' in config.boardfarm_config:
            location = config.boardfarm_config['locations']
            del config.boardfarm_config['locations']

            for board in config.boardfarm_config:
                if 'location' in config.boardfarm_config[board]:
                    board_location = config.boardfarm_config[board]['location']
                    if board_location in location:
                        for key, value in location[board_location].iteritems():
                            if type(value) == list:
                                config.boardfarm_config[board][key].extend(
                                    value)
                            else:
                                config.boardfarm_config[board][key] = value

    except Exception as e:
        print(e)
        print('Unable to access/read Board Farm configuration\n%s' %
              boardfarm_config_location)
        sys.exit(1)

    config.batch = args.batch

    if args.inventory:
        print("%11s  %15s  %5s  %25s  %25s  %s" %
              ('Name', 'Model', 'Auto', 'LAN', 'WAN', 'Notes'))
        bf = config.boardfarm_config
        for i, b in enumerate(sorted(bf)):
            if args.board_type is None or bf[b].get(
                    'board_type') in args.board_type:
                if not args.board_names or b in args.board_names:
                    info = {
                        'name': b,
                        'type': bf[b].get('board_type'),
                        'wlan': bf[b].get('wlan_device') != None,
                        'auto': bf[b].get('available_for_autotests', True),
                        'conn_cmd': bf[b].get('conn_cmd'),
                        'lan_device': bf[b].get('lan_device', ''),
                        'wan_device': bf[b].get('wan_device', ''),
                        'notes': bf[b].get('notes', "")
                    }
                    if not args.filter or (args.filter and filter_boards(
                            bf[b], args.filter)):
                        print(
                            "%(name)11s  %(type)15s  %(auto)5s  %(lan_device)25s  %(wan_device)25s  %(notes)s"
                            % info)
        print("To connect to a board by name:\n  ./bft -x connect -n NAME")
        print(
            "To connect to any board of a given model:\n  ./bft -x connect -b MODEL"
        )
        sys.exit(0)

    if hasattr(config, 'INSTALL_PKGS') is False:
        config.INSTALL_PKGS = ""

    config.retry = args.retry

    if args.package:
        for pkg in args.package:
            config.INSTALL_PKGS += " %s" % pkg

    config.UBOOT = args.uboot
    config.KERNEL = args.kernel
    config.ROOTFS = args.rootfs
    config.NFSROOT = args.nfsroot
    config.META_BUILD = args.meta_img_loc
    # Quick check to make sure file url/path arguments are reasonable
    for x in (config.UBOOT, config.KERNEL, config.ROOTFS, config.META_BUILD):
        if x is None:
            continue
        if x.startswith('http://') or x.startswith('https://'):
            try:

                def add_basic_auth(login_str, request):
                    '''Adds Basic auth to http request, pass in login:password as string'''
                    import base64
                    encodeuser = base64.b64encode(
                        login_str.encode('utf-8')).decode("utf-8")
                    authheader = "Basic %s" % encodeuser
                    request.add_header("Authorization", authheader)

                import ssl
                context = ssl._create_unverified_context()

                req = urllib.Request(x)

                try:
                    import netrc, urlparse
                    n = netrc.netrc()
                    login, unused, password = n.authenticators(
                        urlparse.urlparse(x).hostname)
                    add_basic_auth("%s:%s" % (login, password), req)
                except (TypeError, ImportError, IOError,
                        netrc.NetrcParseError):
                    pass

            # If url returns 404 or similar, raise exception
                urlopen(req, timeout=20, context=context)
            except Exception as e:
                print(e)
                print('Error trying to access %s' % x)
                sys.exit(1)
        else:
            if not os.path.isfile(x):
                print("File not found: %s" % x)
                sys.exit(1)

    if args.sysupgrade:
        config.SYSUPGRADE_NEW = args.sysupgrade
    if args.testsuite:
        config.TEST_SUITE = args.testsuite
    else:
        if args.extend:
            # One or more test cases was specified at command-line, just boot first.
            config.TEST_SUITE = "flash"
        else:
            # No test suite or test cases specified, so just boot and interact.
            config.TEST_SUITE = "interact"
    if args.extend:
        config.EXTRA_TESTS = args.extend
        config.EXTRA_TESTS += ["Interact"]

    config.output_dir = os.path.abspath(args.output_dir) + os.sep
    try:
        os.mkdir(config.output_dir)
    except:
        pass

    if args.analysis:
        import analysis
        for cstr in dir(analysis):
            c = getattr(analysis, cstr)
            if inspect.isclass(c) and issubclass(c, analysis.Analysis):
                sys.stdout.write("Running analysis class = %s... " % c)
                console_log = open(args.analysis, 'r').read()
                from analysis.analysis import prepare_log
                try:
                    c().analyze(prepare_log(console_log), config.output_dir)
                    print("DONE!")
                except Exception as e:
                    print("FAILED!")
                    traceback.print_exc(file=sys.stdout)
                    continue
        exit(0)

    if args.board_type:
        library.print_bold("Selecting board from board type = %s" %
                           args.board_type)
        config.BOARD_NAMES = []
        possible_names = config.boardfarm_config
        if args.board_names:
            print("Board names = %s" % args.board_names)
            # Allow selection only from given set of board names
            possible_names = set(config.boardfarm_config) & set(
                args.board_names)
        for b in possible_names:
            if len(args.board_names) != 1 and \
               'available_for_autotests' in config.boardfarm_config[b] and \
               config.boardfarm_config[b]['available_for_autotests'] == False:
                # Skip this board
                continue
            if args.feature != []:
                if 'feature' not in config.boardfarm_config[b]:
                    continue
                features = config.boardfarm_config[b]['feature']
                if type(features) is str or type(features) is unicode:
                    features = [features]
                if set(args.feature) != set(args.feature) & set(features):
                    continue
            for t in args.board_type:
                if config.boardfarm_config[b]['board_type'].lower() == t.lower(
                ):
                    if args.filter:
                        if filter_boards(config.boardfarm_config[b],
                                         args.filter, b):
                            config.BOARD_NAMES.append(b)
                    else:
                        config.BOARD_NAMES.append(b)
        if not config.BOARD_NAMES:
            print(
                "ERROR! No boards meet selection requirements and have available_for_autotests = True."
            )
            sys.exit(1)
    else:
        if not args.board_names:
            print("ERROR")
            print("You must specify a board name with the '-n' argument:")
            print("./run-all.py -n 3000")
            print(
                "That same board name must be present in boardfarm configuration."
            )
            sys.exit(1)
        else:
            config.BOARD_NAMES = args.board_names

    config.WAN_PROTO = args.wan
    config.reboot_vms = args.reboot_vms
    config.setup_device_networking = not args.no_network
    config.bootargs = args.bootargs
    config.golden = args.golden
    config.features = args.feature

    return config
Example #7
0
def parse():
    '''
    Read command-line arguments, return a simple configuration for running tests.
    '''
    parser = argparse.ArgumentParser(
        description=
        'Connect to an available board, flash image(s), and run tests.',
        usage='bft [options...]',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=HELP_EPILOG)
    parser.add_argument('-l',
                        '--list_tests',
                        action='store_true',
                        help='List available tests and exit')
    parser.add_argument('-i',
                        '--inventory',
                        action='store_true',
                        help='List available boards and exit')
    parser.add_argument(
        '-y',
        '--batch',
        action='store_true',
        help='Run in unattended mode - do not spawn console on failed test')
    parser.add_argument('-t',
                        '--retry',
                        type=int,
                        default=0,
                        help='How many times to retry every test if it fails')
    parser.add_argument('-k',
                        '--kernel',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH of Kernel image to flash')
    parser.add_argument('-r',
                        '--rootfs',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH of Rootfs image to flash')
    parser.add_argument('-m',
                        '--meta_img_loc',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH to meta image to flash')
    parser.add_argument('-p',
                        '--package',
                        metavar='',
                        type=str,
                        action="append",
                        default=None,
                        help='URL or file PATH of ipk install after boot')
    parser.add_argument('-u',
                        '--uboot',
                        metavar='',
                        type=str,
                        default=None,
                        help=argparse.SUPPRESS)
    parser.add_argument('-s',
                        '--sysupgrade',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH to Sysupgrade image')
    parser.add_argument('-x',
                        '--testsuite',
                        metavar='',
                        type=str,
                        default=None,
                        help='NAME of test suite to run')
    parser.add_argument('-e',
                        '--extend',
                        metavar='',
                        type=str,
                        default=None,
                        action="append",
                        help='NAME of extra test to run')
    parser.add_argument('-n',
                        '--board_names',
                        metavar='',
                        type=str,
                        nargs='+',
                        default=[],
                        help='NAME(s) of boards to run on')
    parser.add_argument('-b',
                        '--board_type',
                        metavar='',
                        type=str,
                        nargs='+',
                        default=None,
                        help='MODEL(s) of board to connect to')
    parser.add_argument('-w',
                        '--wan',
                        metavar='',
                        type=str,
                        default='dhcp',
                        help='WAN protocol, dhcp (default) or pppoe')
    parser.add_argument('-v',
                        '--reboot-vms',
                        action="store_true",
                        help='Reboot VMs before starting tests')
    parser.add_argument('-f',
                        '--filter',
                        metavar='',
                        type=str,
                        default=None,
                        action="append",
                        help='Regex filter off arbitrary board parameters')
    parser.add_argument('-a',
                        '--analysis',
                        metavar='',
                        type=str,
                        default=None,
                        help='Only run post processing analysis on logs')
    owrt_tests_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                  "results", '')
    parser.add_argument('-o',
                        '--output_dir',
                        metavar='',
                        type=str,
                        default=owrt_tests_dir,
                        help='Directory to output results files too')
    parser.add_argument('-c',
                        '--config_file',
                        metavar='',
                        type=str,
                        default=boardfarm_config_location,
                        help='JSON config file for boardfarm')

    args = parser.parse_args()

    if args.list_tests:
        import tests
        # Print all classes that are a subclass of TestCase
        for e in dir(tests):
            thing = getattr(tests, e)
            if inspect.isclass(thing) and \
               issubclass(thing, unittest2.TestCase):
                try:
                    print("%20s - %s" % (e, thing.__doc__.split('\n')[0]))
                except:
                    print("%20s -" % e)
        sys.exit(0)

    try:
        if args.config_file.startswith("http"):
            data = urlopen(args.config_file).read().decode()
        else:
            data = open(args.config_file, 'r').read()
        config.boardfarm_config = json.loads(data)
    except Exception as e:
        print(e)
        print('Unable to access/read Board Farm configuration\n%s' %
              boardfarm_config_location)
        sys.exit(1)

    config.batch = args.batch

    if args.inventory:
        print("%11s  %15s  %5s  %25s  %25s  %s" %
              ('Name', 'Model', 'Auto', 'LAN', 'WAN', 'Notes'))
        bf = config.boardfarm_config
        for i, b in enumerate(sorted(bf)):
            if args.board_type is None or bf[b].get(
                    'board_type') in args.board_type:
                if not args.board_names or b in args.board_names:
                    info = {
                        'name': b,
                        'type': bf[b].get('board_type'),
                        'wlan': bf[b].get('wlan_device') != None,
                        'auto': bf[b].get('available_for_autotests', True),
                        'conn_cmd': bf[b].get('conn_cmd'),
                        'lan_device': bf[b].get('lan_device', ''),
                        'wan_device': bf[b].get('wan_device', ''),
                        'notes': bf[b].get('notes', "")
                    }
                    if not args.filter or (args.filter and filter_boards(
                            bf[b], args.filter)):
                        print(
                            "%(name)11s  %(type)15s  %(auto)5s  %(lan_device)25s  %(wan_device)25s  %(notes)s"
                            % info)
        print("To connect to a board by name:\n  ./bft -x connect -n NAME")
        print(
            "To connect to any board of a given model:\n  ./bft -x connect -b MODEL"
        )
        sys.exit(0)

    if hasattr(config, 'INSTALL_PKGS') is False:
        config.INSTALL_PKGS = ""

    config.retry = args.retry

    if args.package:
        for pkg in args.package:
            config.INSTALL_PKGS += " %s" % pkg

    config.UBOOT = args.uboot
    config.KERNEL = args.kernel
    config.ROOTFS = args.rootfs
    config.META_BUILD = args.meta_img_loc
    # Quick check to make sure file url/path arguments are reasonable
    for x in (config.UBOOT, config.KERNEL, config.ROOTFS, config.META_BUILD):
        if x is None:
            continue
        if x.startswith('http://') or x.startswith('https://'):
            try:
                # If url returns 404 or similar, raise exception
                urlopen(x, timeout=20)
            except Exception as e:
                print(e)
                print('Error trying to access %s' % x)
                sys.exit(1)
        else:
            if not os.path.isfile(x):
                print("File not found: %s" % x)
                sys.exit(1)

    if args.sysupgrade:
        config.SYSUPGRADE_NEW = args.sysupgrade
    if args.testsuite:
        config.TEST_SUITE = args.testsuite
    else:
        if args.extend:
            # One or more test cases was specified at command-line, just boot first.
            config.TEST_SUITE = "flash_only"
        else:
            # No test suite or test cases specified, so just boot and interact.
            config.TEST_SUITE = "interact"
    if args.extend:
        config.EXTRA_TESTS = args.extend
        config.EXTRA_TESTS += ["Interact"]

    config.output_dir = os.path.abspath(args.output_dir) + os.sep
    try:
        os.mkdir(config.output_dir)
    except:
        pass

    if args.analysis:
        import analysis
        for cstr in dir(analysis):
            c = getattr(analysis, cstr)
            if inspect.isclass(c) and issubclass(c, analysis.Analysis):
                console_log = open(args.analysis, 'r').read()
                from analysis.analysis import prepare_log
                c().analyze(prepare_log(console_log), config.output_dir)
        exit(0)

    if args.board_type:
        library.print_bold("Selecting board from board type = %s" %
                           args.board_type)
        config.BOARD_NAMES = []
        possible_names = config.boardfarm_config
        if args.board_names:
            print("Board names = %s" % args.board_names)
            # Allow selection only from given set of board names
            possible_names = set(config.boardfarm_config) & set(
                args.board_names)
        for b in possible_names:
            if len(args.board_names) != 1 and \
               'available_for_autotests' in config.boardfarm_config[b] and \
               config.boardfarm_config[b]['available_for_autotests'] == False:
                # Skip this board
                continue
            for t in args.board_type:
                if config.boardfarm_config[b]['board_type'].lower() == t.lower(
                ):
                    if args.filter:
                        if filter_boards(config.boardfarm_config[b],
                                         args.filter, b):
                            config.BOARD_NAMES.append(b)
                    else:
                        config.BOARD_NAMES.append(b)
        if not config.BOARD_NAMES:
            print(
                "ERROR! No boards meet selection requirements and have available_for_autotests = True."
            )
            sys.exit(1)
    else:
        if not args.board_names:
            print("ERROR")
            print("You must specify a board name with the '-n' argument:")
            print("./run-all.py -n 3000")
            print(
                "That same board name must be present in boardfarm configuration."
            )
            sys.exit(1)
        else:
            config.BOARD_NAMES = args.board_names

    config.WAN_PROTO = args.wan
    config.reboot_vms = args.reboot_vms

    return config
Example #8
0
def parse():
    '''
    Read command-line arguments, return a simple configuration for running tests.
    '''
    parser = argparse.ArgumentParser(description='Connect to an available board, flash image(s), and run tests.',
                                     usage='bft [options...]',
                                     formatter_class=argparse.RawDescriptionHelpFormatter,
                                     epilog=HELP_EPILOG)
    parser.add_argument('-l', '--list_tests', action='store_true', help='List available tests and exit')
    parser.add_argument('-i', '--inventory', action='store_true', help='List available boards and exit')
    parser.add_argument('-y', '--batch', action='store_true', help='Run in unattended mode - do not spawn console on failed test')
    parser.add_argument('-t', '--retry', type=int, default=0, help='How many times to retry every test if it fails')
    parser.add_argument('-k', '--kernel', metavar='', type=str, default=None, help='URL or file PATH of Kernel image to flash')
    parser.add_argument('-r', '--rootfs', metavar='', type=str, default=None, help='URL or file PATH of Rootfs image to flash')
    parser.add_argument('-m', '--meta_img_loc', metavar='', type=str, default=None, help='URL or file PATH to meta image to flash')
    parser.add_argument('-p', '--package', metavar='', type=str, action="append", default=None, help='URL or file PATH of ipk install after boot')
    parser.add_argument('-u', '--uboot', metavar='', type=str, default=None, help=argparse.SUPPRESS)
    parser.add_argument('-s', '--sysupgrade', metavar='', type=str, default=None, help='URL or file PATH to Sysupgrade image')
    parser.add_argument('-x', '--testsuite', metavar='', type=str, default=None, help='NAME of test suite to run')
    parser.add_argument('-e', '--extend', metavar='', type=str, default=None, action="append", help='NAME of extra test to run')
    parser.add_argument('-n', '--board_names', metavar='', type=str, nargs='+', default=[], help='NAME(s) of boards to run on')
    parser.add_argument('-b', '--board_type', metavar='', type=str, nargs='+', default=None, help='MODEL(s) of board to connect to')
    parser.add_argument('-w', '--wan', metavar='', type=str, default='dhcp', help='WAN protocol, dhcp (default) or pppoe')
    parser.add_argument('-v', '--reboot-vms', action="store_true", help='Reboot VMs before starting tests')
    parser.add_argument('-f', '--filter', metavar='', type=str, default=None, action="append", help='Regex filter off arbitrary board parameters')
    parser.add_argument('-a', '--analysis', metavar='', type=str, default=None, help='Only run post processing analysis on logs')
    owrt_tests_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "results", '')
    parser.add_argument('-o', '--output_dir', metavar='', type=str, default=owrt_tests_dir, help='Directory to output results files too')
    parser.add_argument('-c', '--config_file', metavar='', type=str, default=boardfarm_config_location, help='JSON config file for boardfarm')

    args = parser.parse_args()

    if args.list_tests:
        import tests
        # Print all classes that are a subclass of TestCase
        for e in dir(tests):
            thing = getattr(tests, e)
            if inspect.isclass(thing) and \
               issubclass(thing, unittest2.TestCase):
                try:
                    print("%20s - %s" % (e, thing.__doc__.split('\n')[0]))
                except:
                    print("%20s -" % e)
        sys.exit(0)

    try:
        if args.config_file.startswith("http"):
            data = urlopen(args.config_file).read().decode()
        else:
            data = open(args.config_file, 'r').read()
        config.boardfarm_config = json.loads(data)
    except Exception as e:
        print(e)
        print('Unable to access/read Board Farm configuration\n%s' % boardfarm_config_location)
        sys.exit(1)

    config.batch = args.batch

    if args.inventory:
        print("%11s  %15s  %5s  %25s  %25s  %s" % ('Name', 'Model', 'Auto', 'LAN', 'WAN', 'Notes'))
        bf = config.boardfarm_config
        for i, b in enumerate(sorted(bf)):
            if args.board_type is None or bf[b].get('board_type') in args.board_type:
                if not args.board_names or b in args.board_names:
                    info = {'name': b,
                            'type': bf[b].get('board_type'),
                            'wlan': bf[b].get('wlan_device') != None,
                            'auto': bf[b].get('available_for_autotests', True),
                            'conn_cmd': bf[b].get('conn_cmd'),
                            'lan_device': bf[b].get('lan_device', ''),
                            'wan_device': bf[b].get('wan_device', ''),
                            'notes': bf[b].get('notes', "")}
                    if not args.filter or (args.filter and filter_boards(bf[b], args.filter)):
                        print("%(name)11s  %(type)15s  %(auto)5s  %(lan_device)25s  %(wan_device)25s  %(notes)s" % info)
        print("To connect to a board by name:\n  ./bft -x connect -n NAME")
        print("To connect to any board of a given model:\n  ./bft -x connect -b MODEL")
        sys.exit(0)

    if hasattr(config, 'INSTALL_PKGS') is False:
        config.INSTALL_PKGS = ""

    config.retry = args.retry

    if args.package:
        for pkg in args.package:
            config.INSTALL_PKGS += " %s" % pkg

    config.UBOOT = args.uboot
    config.KERNEL = args.kernel
    config.ROOTFS = args.rootfs
    config.META_BUILD = args.meta_img_loc
    # Quick check to make sure file url/path arguments are reasonable
    for x in (config.UBOOT, config.KERNEL, config.ROOTFS, config.META_BUILD):
        if x is None:
            continue
        if x.startswith('http://') or x.startswith('https://'):
            try:
                # If url returns 404 or similar, raise exception
                urlopen(x, timeout=20)
            except Exception as e:
                print(e)
                print('Error trying to access %s' % x)
                sys.exit(1)
        else:
            if not os.path.isfile(x):
                print("File not found: %s" % x)
                sys.exit(1)

    if args.sysupgrade:
        config.SYSUPGRADE_NEW = args.sysupgrade
    if args.testsuite:
        config.TEST_SUITE = args.testsuite
    else:
        if args.extend:
            # One or more test cases was specified at command-line, just boot first.
            config.TEST_SUITE = "flash_only"
        else:
            # No test suite or test cases specified, so just boot and interact.
            config.TEST_SUITE = "interact"
    if args.extend:
        config.EXTRA_TESTS = args.extend
        config.EXTRA_TESTS += ["Interact"]

    config.output_dir = os.path.abspath(args.output_dir) + os.sep
    try:
        os.mkdir(config.output_dir)
    except:
        pass

    if args.analysis:
        import analysis
        for cstr in dir(analysis):
            c = getattr(analysis, cstr)
            if inspect.isclass(c) and issubclass(c, analysis.Analysis):
                console_log = open(args.analysis, 'r').read()
                from analysis.analysis import prepare_log
                c().analyze(prepare_log(console_log), config.output_dir)
        exit(0)

    if args.board_type:
        library.print_bold("Selecting board from board type = %s" % args.board_type)
        config.BOARD_NAMES = []
        possible_names = config.boardfarm_config
        if args.board_names:
            print("Board names = %s" % args.board_names)
            # Allow selection only from given set of board names
            possible_names = set(config.boardfarm_config) & set(args.board_names)
        for b in possible_names:
            if len(args.board_names) != 1 and \
               'available_for_autotests' in config.boardfarm_config[b] and \
               config.boardfarm_config[b]['available_for_autotests'] == False:
                # Skip this board
                continue
            for t in args.board_type:
                if config.boardfarm_config[b]['board_type'].lower() == t.lower():
                    if args.filter:
                        if filter_boards(config.boardfarm_config[b], args.filter, b):
                            config.BOARD_NAMES.append(b)
                    else:
                        config.BOARD_NAMES.append(b)
        if not config.BOARD_NAMES:
            print("ERROR! No boards meet selection requirements and have available_for_autotests = True.")
            sys.exit(1)
    else:
        if not args.board_names:
            print("ERROR")
            print("You must specify a board name with the '-n' argument:")
            print("./run-all.py -n 3000")
            print("That same board name must be present in boardfarm configuration.")
            sys.exit(1)
        else:
            config.BOARD_NAMES = args.board_names


    config.WAN_PROTO = args.wan
    config.reboot_vms = args.reboot_vms

    return config
Example #9
0
def parse():
    """
    Read command-line arguments, return a simple configuration for running tests.
    """
    parser = argparse.ArgumentParser(
        description="Connect to an available board, flash image(s), and run tests.",
        usage="bft [options...]",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=HELP_EPILOG,
    )
    parser.add_argument("-l", "--list_tests", action="store_true", help="List available tests and exit")
    parser.add_argument("-i", "--inventory", action="store_true", help="List available boards and exit")
    parser.add_argument(
        "-k", "--kernel", metavar="", type=str, default=None, help="URL or file PATH of Kernel image to flash"
    )
    parser.add_argument(
        "-r", "--rootfs", metavar="", type=str, default=None, help="URL or file PATH of Rootfs image to flash"
    )
    parser.add_argument(
        "-m", "--meta_img_loc", metavar="", type=str, default=None, help="URL or file PATH to meta image to flash"
    )
    parser.add_argument(
        "-p",
        "--package",
        metavar="",
        type=str,
        action="append",
        default=None,
        help="URL or file PATH of ipk install after boot",
    )
    parser.add_argument("-u", "--uboot", metavar="", type=str, default=None, help=argparse.SUPPRESS)
    parser.add_argument(
        "-s", "--sysupgrade", metavar="", type=str, default=None, help="URL or file PATH to Sysupgrade image"
    )
    parser.add_argument("-x", "--testsuite", metavar="", type=str, default=None, help="NAME of test suite to run")
    parser.add_argument(
        "-e", "--extend", metavar="", type=str, default=None, action="append", help="NAME of extra test to run"
    )
    parser.add_argument(
        "-n", "--board_names", metavar="", type=str, nargs="+", default=[], help="NAME(s) of boards to run on"
    )
    parser.add_argument(
        "-b", "--board_type", metavar="", type=str, nargs="+", default=None, help="MODEL(s) of board to connect to"
    )
    parser.add_argument(
        "-w", "--wan", metavar="", type=str, default="dhcp", help="WAN protocol, dhcp (default) or pppoe"
    )
    parser.add_argument("-v", "--reboot-vms", action="store_true", help="Reboot VMs before starting tests")
    parser.add_argument(
        "-f",
        "--filter",
        metavar="",
        type=str,
        default=None,
        action="append",
        help="Regex filter off arbitrary board parameters",
    )
    parser.add_argument(
        "-a", "--analysis", metavar="", type=str, default=None, help="Only run post processing analysis on logs"
    )
    owrt_tests_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "results", "")
    parser.add_argument(
        "-o", "--output_dir", metavar="", type=str, default=owrt_tests_dir, help="Directory to output results files too"
    )

    args = parser.parse_args()

    if args.list_tests:
        import tests

        # Print all classes that are a subclass of TestCase
        for e in dir(tests):
            thing = getattr(tests, e)
            if inspect.isclass(thing) and issubclass(thing, unittest2.TestCase):
                try:
                    print("%20s - %s" % (e, thing.__doc__.split("\n")[0]))
                except:
                    print("%20s -" % e)
        sys.exit(0)

    try:
        if boardfarm_config_location.startswith("http"):
            data = urlopen(boardfarm_config_location).read().decode()
        else:
            data = open(boardfarm_config_location, "r").read()
        config.boardfarm_config = json.loads(data)
    except Exception as e:
        print(e)
        print("Unable to access/read Board Farm configuration\n%s" % boardfarm_config_location)
        sys.exit(1)

    if args.inventory:
        print("%11s  %15s  %5s  %25s  %25s  %s" % ("Name", "Model", "Auto", "LAN", "WAN", "Notes"))
        bf = config.boardfarm_config
        for i, b in enumerate(sorted(bf)):
            if args.board_type is None or bf[b].get("board_type") in args.board_type:
                if not args.board_names or b in args.board_names:
                    info = {
                        "name": b,
                        "type": bf[b].get("board_type"),
                        "wlan": bf[b].get("wlan_device") != None,
                        "auto": bf[b].get("available_for_autotests", True),
                        "conn_cmd": bf[b].get("conn_cmd"),
                        "lan_device": bf[b].get("lan_device", ""),
                        "wan_device": bf[b].get("wan_device", ""),
                        "notes": bf[b].get("notes", ""),
                    }
                    if not args.filter or (args.filter and filter_boards(bf[b], args.filter)):
                        print("%(name)11s  %(type)15s  %(auto)5s  %(lan_device)25s  %(wan_device)25s  %(notes)s" % info)
        print("To connect to a board by name:\n  ./bft -x connect -n NAME")
        print("To connect to any board of a given model:\n  ./bft -x connect -b MODEL")
        sys.exit(0)

    if hasattr(config, "INSTALL_PKGS") is False:
        config.INSTALL_PKGS = ""

    if args.package:
        for pkg in args.package:
            config.INSTALL_PKGS += " %s" % pkg

    config.UBOOT = args.uboot
    config.KERNEL = args.kernel
    config.ROOTFS = args.rootfs
    config.META_BUILD = args.meta_img_loc
    # Quick check to make sure file url/path arguments are reasonable
    for x in (config.UBOOT, config.KERNEL, config.ROOTFS, config.META_BUILD):
        if x is None:
            continue
        if x.startswith("http://") or x.startswith("https://"):
            try:
                # If url returns 404 or similar, raise exception
                urlopen(x, timeout=20)
            except Exception as e:
                print(e)
                print("Error trying to access %s" % x)
                sys.exit(1)
        else:
            if not os.path.isfile(x):
                print("File not found: %s" % x)
                sys.exit(1)

    if args.sysupgrade:
        config.SYSUPGRADE_NEW = args.sysupgrade
    if args.testsuite:
        config.TEST_SUITE = args.testsuite
    else:
        if args.extend:
            # One or more test cases was specified at command-line, just boot first.
            config.TEST_SUITE = "flash_only"
        else:
            # No test suite or test cases specified, so just boot and interact.
            config.TEST_SUITE = "interact"
    if args.extend:
        config.EXTRA_TESTS = args.extend
        config.EXTRA_TESTS += ["Interact"]

    config.output_dir = os.path.abspath(args.output_dir) + os.sep
    try:
        os.mkdir(config.output_dir)
    except:
        pass

    if args.analysis:
        import analysis

        for cstr in dir(analysis):
            c = getattr(analysis, cstr)
            if inspect.isclass(c) and issubclass(c, analysis.Analysis):
                console_log = open(args.analysis, "r").read()
                from analysis.analysis import prepare_log

                c().analyze(prepare_log(console_log), config.output_dir)
        exit(0)

    if args.board_type:
        library.print_bold("Selecting board from board type = %s" % args.board_type)
        config.BOARD_NAMES = []
        possible_names = config.boardfarm_config
        if args.board_names:
            print("Board names = %s" % args.board_names)
            # Allow selection only from given set of board names
            possible_names = set(config.boardfarm_config) & set(args.board_names)
        for b in possible_names:
            if (
                len(args.board_names) != 1
                and "available_for_autotests" in config.boardfarm_config[b]
                and config.boardfarm_config[b]["available_for_autotests"] == False
            ):
                # Skip this board
                continue
            for t in args.board_type:
                if config.boardfarm_config[b]["board_type"].lower() == t.lower():
                    if args.filter:
                        if filter_boards(config.boardfarm_config[b], args.filter, b):
                            config.BOARD_NAMES.append(b)
                    else:
                        config.BOARD_NAMES.append(b)
        if not config.BOARD_NAMES:
            print("ERROR! No boards meet selection requirements and have available_for_autotests = True.")
            sys.exit(1)
    else:
        if not args.board_names:
            print("ERROR")
            print("You must specify a board name with the '-n' argument:")
            print("./run-all.py -n 3000")
            print("That same board name must be present in boardfarm configuration.")
            sys.exit(1)
        else:
            config.BOARD_NAMES = args.board_names

    config.WAN_PROTO = args.wan
    config.reboot_vms = args.reboot_vms

    return config