Example #1
0
 def test_import_tests(self):
     '''
     Verify we can import all boardfarm tests.
     '''
     from boardfarm import tests
     tests.init(None)
     # Also make sure something is in tests.available_tests
     self.assertGreater(len(tests.available_tests), 10)
Example #2
0
    def list_tests(self):
        '''
        Search for all available tests and return a dict.
        '''

        from boardfarm import tests, config
        tests.init(config)
        return tests.available_tests
Example #3
0
    def list_tests(self):
        '''
        Search for all available tests and return a dict.
        '''
        # TODO: can go away once devices are not imported
        from boardfarm.lib import DeviceManager
        device_mgr = DeviceManager.device_manager()
        from boardfarm import devices
        devices.set_device_manager(device_mgr)
        # END

        from boardfarm import tests, config
        tests.init(config)
        return tests.available_tests
Example #4
0
 def test_import_tests(self):
     '''
     Verify we can import all boardfarm tests.
     '''
     # unfortunately for now, we have to set the device manager
     # in boardfarm.devices before we can import tests.
     # Delete this part when tests no longer import from boardfarm.devices
     from boardfarm.lib import DeviceManager
     from boardfarm import devices
     devices.set_device_manager(DeviceManager.device_manager())
     from boardfarm import tests
     tests.init(None)
     # Also make sure something is in tests.available_tests
     self.assertGreater(len(tests.available_tests), 10)
Example #5
0
def parse():
    """Read command-line arguments, parse and store all values in boardfarm_config
    Config can be fetched locally or remotely using HTTP.
    After parsing the config, devices from generic locations are moved inside selected
    boards.
    This method also initializes parameters for tests.

    :raises exception: Unable to access/read boardfarm configuration
    :return: boardfarm config module containing boardfarm_config
    :rtype: module
    """
    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('-a',
                        '--analysis',
                        metavar='',
                        type=str,
                        default=None,
                        help='Only run post processing analysis on logs')
    parser.add_argument('-b',
                        '--board_type',
                        metavar='',
                        type=str,
                        nargs='+',
                        default=None,
                        help='MODEL(s) of board to connect to')
    parser.add_argument('-c',
                        '--config_file',
                        metavar='',
                        type=str,
                        default=None,
                        help='JSON config file for boardfarm')
    parser.add_argument('-e',
                        '--extend',
                        metavar='',
                        type=str,
                        default=None,
                        action="append",
                        help='NAME of extra test to run')
    parser.add_argument('-f',
                        '--filter',
                        metavar='',
                        type=str,
                        default=None,
                        action="append",
                        help='Regex filter off arbitrary board parameters')
    parser.add_argument(
        '-g',
        '--golden',
        metavar='',
        type=str,
        default=[],
        nargs='+',
        help='Path to JSON results to compare against (golden master)')
    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('-l',
                        '--list_tests',
                        action='store_true',
                        help='List available tests and exit')
    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('-n',
                        '--board_names',
                        metavar='',
                        type=str,
                        nargs='+',
                        default=[],
                        help='NAME(s) of boards to run on')
    owrt_tests_dir = os.path.join(os.getcwd(), "results", '')
    parser.add_argument('-o',
                        '--output_dir',
                        metavar='',
                        type=str,
                        default=owrt_tests_dir,
                        help='Directory to output results files too')
    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('-q',
                        '--feature',
                        metavar='',
                        type=str,
                        default=[],
                        nargs='+',
                        help='Features required for this test run')
    parser.add_argument('-r',
                        '--rootfs',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH of Rootfs image to flash')
    parser.add_argument('-s',
                        '--sysupgrade',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH to Sysupgrade image')
    parser.add_argument('-t',
                        '--retry',
                        type=int,
                        default=0,
                        help='How many times to retry every test if it fails')
    parser.add_argument('-u',
                        '--uboot',
                        metavar='',
                        type=str,
                        default=None,
                        help=argparse.SUPPRESS)
    parser.add_argument('-w',
                        '--wan',
                        metavar='',
                        type=str,
                        default='dhcp',
                        help='WAN protocol, dhcp (default) or pppoe')
    parser.add_argument('-x',
                        '--testsuite',
                        metavar='',
                        type=str,
                        default=None,
                        help='NAME of test suite to run')
    parser.add_argument(
        '-y',
        '--batch',
        action='store_true',
        help='Run in unattended mode - do not spawn console on failed test')
    parser.add_argument('-z',
                        '--no-network',
                        action='store_true',
                        help='Skip basic network tests when booting')
    parser.add_argument(
        '--bootargs',
        metavar='',
        type=str,
        default=None,
        help='bootargs to set or append to default args (board dependant)')
    parser.add_argument('--nfsroot',
                        metavar='',
                        type=str,
                        default=None,
                        help='URL or file PATH of Rootfs image to flash')
    parser.add_argument('--version',
                        action='store_true',
                        help='show version and exit')
    parser.add_argument(
        '--nostrict',
        action='store_true',
        help='ignores failure to import a tests from a testsuite')
    parser.add_argument('--regex_config',
                        metavar='',
                        type=str,
                        default=[],
                        action="append",
                        help='Regex substitution for board config')
    parser.add_argument(
        '--err_dict',
        metavar='',
        type=str,
        default=[],
        nargs='+',
        help='Path to JSON containing the error injection dictionary')

    args = parser.parse_args()

    if args.version:
        print('%s %s' % (os.path.basename(sys.argv[0]), boardfarm.__version__))
        if boardfarm.plugins:
            print("Installed Plugins:")
            for key in sorted(boardfarm.plugins):
                print(
                    "%s %s" %
                    (key, getattr(boardfarm.plugins[key], '__version__', '')))
            print("Python: %s" % sys.version)
        sys.exit(0)

    if args.list_tests:
        try:
            from boardfarm import tests
            tests.init(config)
        except TestImportError as e:
            print(e)
            sys.exit(1)
        for k, v in sorted(tests.available_tests.items()):
            try:
                print("%20s - %s" % (k, v.__doc__.split('\n')[0]))
            except:
                print("%20s -" % k)
        sys.exit(0)

    try:
        if args.config_file is not None:
            config.boardfarm_config_location = args.config_file
        config.boardfarm_config_location, config.boardfarm_config = boardfarm.lib.test_configurator.get_station_config(
            config.boardfarm_config_location, bool(args.config_file))
    except Exception as e:
        print(e)
        print('Unable to access/read boardfarm configuration from %s' %
              config.boardfarm_config_location)
        sys.exit(1)

    # Check if boardfarm configuration is empty
    if not config.boardfarm_config:
        print("ERROR! Boardfarm config at %s is empty, so" % args.config_file)
        print("either all stations are in use or disabled.")
        sys.exit(10)
    # Check if given board type(s) have any overlap with available board types from config
    if args.board_type:
        all_board_types = []
        for key in config.boardfarm_config:
            elem = config.boardfarm_config[key].get('board_type', None) \
                    if type(config.boardfarm_config[key]) is dict else None
            if elem:
                all_board_types.append(elem)

        if not (set(args.board_type) & set(all_board_types)):
            print("ERROR! You specified board types: %s " %
                  " ".join(args.board_type))
            print("but that is not an existing & available type of board.")
            print("Please choose a board type from:")
            print("\n".join([" * %s" % x for x in set(all_board_types)]))
            sys.exit(10)
    # Check if given board name(s) are present in available boards
    if args.board_names:
        all_board_names = [
            key for key in config.boardfarm_config if key != "locations"
        ]
        if not (set(args.board_names) & set(all_board_names)):
            print("ERROR! You specified board names: %s " %
                  " ".join(args.board_names))
            print("but that is not an existing & available board.")
            print("Please choose a board name from:")
            print("\n".join([" * %s" % x for x in sorted(all_board_names)]))
            sys.exit(10)

    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 boardfarm.lib.test_configurator.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 'mirror://' in x:
            # we need to check the mirror later once the board is selected
            continue
        if x.startswith('http://') or x.startswith('https://'):
            if not check_url(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:
        from boardfarm 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 boardfarm.analysis.analysis import prepare_log
                try:
                    c().analyze(prepare_log(console_log), config.output_dir)
                    print("DONE!")
                except Exception:
                    print("FAILED!")
                    traceback.print_exc(file=sys.stdout)
                    continue
        exit(0)

    config.BOARD_NAMES = boardfarm.lib.test_configurator.filter_station_config(
        config.boardfarm_config,
        board_type=args.board_type,
        board_names=args.board_names,
        board_features=args.feature,
        board_filter=args.filter)
    if args.board_type:
        if not config.BOARD_NAMES:
            print(
                "ERROR! No boards meet selection requirements and have available_for_autotests = True."
            )
            sys.exit(10)
    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)

    if args.err_dict:
        config.update_error_injection_dict(args.err_dict)

    # grab golden master results
    if args.golden:
        config.golden = args.golden
    config.golden_master_results = {}
    if config.golden is not []:
        import requests
        for g in config.golden:
            try:
                config.golden_master_results.update(requests.get(g).json())
            except:
                print("Failed to fetch golden master results from %s" % g)
                sys.exit(15)

    config.WAN_PROTO = args.wan
    config.setup_device_networking = not args.no_network
    config.bootargs = args.bootargs
    config.golden = args.golden
    config.features = args.feature
    config.TEST_SUITE_NOSTRICT = args.nostrict
    config.regex_config = args.regex_config

    return config
Example #6
0
    def runTest(self):
        board = self.dev.board
        lib.common.test_msg(
            "Press Ctrl-] to stop interaction and return to menu")
        board.sendline()
        try:
            board.interact()
        except:
            return

        while True:
            print("\n\nCurrent station")
            print("  Board console: %s" % self.config.board.get('conn_cmd'))
            self.print_dynamic_devices()
            print('Pro-tip: Increase kernel message verbosity with\n'
                  '    echo "7 7 7 7" > /proc/sys/kernel/printk')
            print("Menu")
            i = 2
            if board.consoles is None:
                print("  1: Enter console")
                i += 1
            else:
                i = 1
                for c in board.consoles:
                    print("  %s: Enter console" % i)
                    i += 1

            print("  %s: List all tests" % i)
            i += 1
            print("  %s: Run test" % i)
            i += 1
            print("  %s: Reset board" % i)
            i += 1
            print("  %s: Enter interactive python shell" % i)
            i += 1
            if len(self.config.devices) > 0:
                print("  Type a device name to connect: %s" %
                      self.config.devices)
            print("  x: Exit")
            key = input("Please select: ")

            if key in self.config.devices:
                d = getattr(self.config, key)
                d.interact()

            i = 1
            for c in board.consoles:
                if key == str(i):
                    c.interact()
                i += 1

            if key == str(i):
                try:
                    tests.init(self.config)
                except Exception as e:
                    print("Unable to re-import tests!")
                    print(e)
                else:
                    print("Available tests:")
                    print('\n'.join(tests.available_tests.keys()))
                continue
            i += 1

            if key == str(i):
                try:
                    tests.init(self.config)
                except Exception as e:
                    print("Unable to re-import tests!")
                    print(e)
                else:
                    # TODO: use an index instead of test name
                    print("Type test to run: ")
                    test = sys.stdin.readline().strip()

                    try:
                        tests.available_tests[test](self.config, self.dev,
                                                    self.env_helper).run()
                    except Exception as e:
                        lib.common.test_msg(
                            "Failed to find and/or run test, continuing..")
                        print(e)
                        continue

                continue
            i += 1

            if key == str(i):
                board.reset()
                print("Press Ctrl-] to stop interaction and return to menu")
                board.interact()
                continue
            i += 1

            if key == str(i):
                print("Enter python shell, press Ctrl-D to exit")
                try:
                    import readline  # optional, will allow Up/Down/History in the console
                    assert readline  # silence pyflakes
                    import code
                    vars = globals().copy()
                    vars.update(locals())
                    shell = code.InteractiveConsole(vars)
                    shell.interact()
                except:
                    print("Unable to spawn interactive shell!")
                continue
            i += 1

            if key == "x":
                break
Example #7
0
def test_interact(config, env_helper, devices, pytestconfig):
    board = devices.board
    msg = colored(
        "\nInteractive console test",
        color="green",
        attrs=["bold"],
    )
    msg1 = colored(
        "\nPress Ctrl-] to stop interaction and return to menu",
        color="cyan",
        attrs=["bold"],
    )

    lib.common.test_msg(f"{msg}\n{msg1}")
    try:
        board.sendline()
    except AttributeError:
        board._sendline()
    try:
        board.interact()
    except Exception as error:
        print(error)
        return

    name_list = [i["name"] for i in board.config.get("devices")]

    while True:
        print("\n\nCurrent station")
        print("  Board console: %s" % board.config.get("conn_cmd"))
        print_dynamic_devices(board.dev)
        print("Pro-tip: Increase kernel message verbosity with\n"
              '    echo "7 7 7 7" > /proc/sys/kernel/printk')
        print("Menu")
        i = 2
        if board.consoles is None:
            print("  1: Enter console")
            i += 1
        else:
            i = 1
            for _ in board.consoles:
                print("  %s: Enter console" % i)
                i += 1

        print("  %s: List all tests" % i)
        i += 1
        print("  %s: Run test" % i)
        i += 1
        print("  %s: Reset board" % i)
        i += 1
        print("  %s: Enter interactive python shell" % i)
        i += 1
        if name_list:
            print(f"  Type a device name to connect: {name_list}")
        print("  x: Exit")
        while True:
            try:
                key = input("Please select: ")
                break
            except Exception:
                logger.error("Received exception on input. Try again.")
        if key in name_list:
            d = get_device_by_name(key)
            d.interact()

        i = 1
        for c in board.consoles:
            if key == str(i):
                c.interact()
            i += 1

        if key == str(i):
            run_pytest_test("", False)
            continue
        i += 1
        if key == str(i):
            try:
                tests.init(board.config)
            except Exception as e:
                print("Unable to re-import tests!")
                print(e)
            else:
                logger.error("Type test to run: ")
                test = sys.stdin.readline().strip()
                if test == "":
                    logger.error(
                        colored(
                            "Empty string in input, try again!",
                            color="red",
                            attrs=["bold"],
                        ))
                    continue
                if test in tests.available_tests and issubclass(
                        tests.available_tests[test],
                        boardfarm.tests.bft_base_test.BftBaseTest,
                ):
                    logger.info(f"\nRunning legacy bft test {test}\n")
                else:
                    logger.info(f"\nRunning pytest {test}\n")
                run_pytest_test(test,
                                pytestconfig.getoption("--bfskip_contingency"))
            continue
        i += 1
        if key == str(i):
            board.reset()
            print("Press Ctrl-] to stop interaction and return to menu")
            board.interact()
            continue
        i += 1

        if key == str(i):
            print("Enter python shell, press Ctrl-D to exit")
            set_logfile_read(board)
            try:
                import readline  # optional, will allow Up/Down/History in the console

                assert readline  # silence pyflakes
                import code

                vars = globals().copy()
                vars.update(locals())
                shell = code.InteractiveConsole(vars)
                shell.interact()
            except Exception as error:
                print(error)
                print("Unable to spawn interactive shell!")
            continue
        i += 1

        if key == "x":
            break
Example #8
0
def parse():
    """Read command-line arguments, parse and store all values in boardfarm_config.

    Config can be fetched locally or remotely using HTTP.
    After parsing the config, devices from generic locations are moved inside selected
    boards.
    This method also initializes parameters for tests.

    :raises exception: Unable to access/read boardfarm configuration
    :return: boardfarm config module containing boardfarm_config
    :rtype: module
    """
    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(
        "-a",
        "--analysis",
        metavar="",
        type=str,
        default=None,
        help="Only run post processing analysis on logs",
    )
    parser.add_argument(
        "-b",
        "--board_type",
        metavar="",
        type=str,
        nargs="+",
        default=None,
        help="MODEL(s) of board to connect to",
    )
    parser.add_argument(
        "-c",
        "--config_file",
        metavar="",
        type=str,
        default=None,
        help="JSON config file for boardfarm",
    )
    parser.add_argument(
        "-e",
        "--extend",
        metavar="",
        type=str,
        default=None,
        action="append",
        help="NAME of extra test to run",
    )
    parser.add_argument(
        "-f",
        "--filter",
        metavar="",
        type=str,
        default=None,
        action="append",
        help="Regex filter off arbitrary board parameters",
    )
    parser.add_argument(
        "-g",
        "--golden",
        metavar="",
        type=str,
        default=[],
        nargs="+",
        help="Path to JSON results to compare against (golden master)",
    )
    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("-l",
                        "--list_tests",
                        action="store_true",
                        help="List available tests and exit")
    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(
        "-n",
        "--board_names",
        metavar="",
        type=str,
        nargs="+",
        default=[],
        help="NAME(s) of boards to run on",
    )
    owrt_tests_dir = os.path.join(os.getcwd(), "results", "")
    parser.add_argument(
        "-o",
        "--output_dir",
        metavar="",
        type=str,
        default=owrt_tests_dir,
        help="Directory to output results files too",
    )
    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(
        "-q",
        "--feature",
        metavar="",
        type=str,
        default=[],
        nargs="+",
        help="Features required for this test run",
    )
    parser.add_argument(
        "-r",
        "--rootfs",
        metavar="",
        type=str,
        default=None,
        help="URL or file PATH of Rootfs image to flash",
    )
    parser.add_argument(
        "-s",
        "--sysupgrade",
        metavar="",
        type=str,
        default=None,
        help="URL or file PATH to Sysupgrade image",
    )
    parser.add_argument(
        "-t",
        "--retry",
        type=int,
        default=0,
        help="How many times to retry every test if it fails",
    )
    parser.add_argument("-u",
                        "--uboot",
                        metavar="",
                        type=str,
                        default=None,
                        help=argparse.SUPPRESS)
    parser.add_argument(
        "-w",
        "--wan",
        metavar="",
        type=str,
        default="dhcp",
        help="WAN protocol, dhcp (default) or pppoe",
    )
    parser.add_argument(
        "-x",
        "--testsuite",
        metavar="",
        type=str,
        default=None,
        help="NAME of test suite to run",
    )
    parser.add_argument(
        "-y",
        "--batch",
        action="store_true",
        help="Run in unattended mode - do not spawn console on failed test",
    )
    parser.add_argument(
        "-z",
        "--no-network",
        action="store_true",
        help="Skip basic network tests when booting",
    )
    parser.add_argument(
        "--bootargs",
        metavar="",
        type=str,
        default=None,
        help="bootargs to set or append to default args (board dependant)",
    )
    parser.add_argument(
        "--nfsroot",
        metavar="",
        type=str,
        default=None,
        help="URL or file PATH of Rootfs image to flash",
    )
    parser.add_argument("--version",
                        action="store_true",
                        help="show version and exit")
    parser.add_argument(
        "--nostrict",
        action="store_true",
        help="ignores failure to import a tests from a testsuite",
    )
    parser.add_argument(
        "--regex_config",
        metavar="",
        type=str,
        default=[],
        action="append",
        help="Regex substitution for board config",
    )
    parser.add_argument(
        "--err_dict",
        metavar="",
        type=str,
        default=[],
        nargs="+",
        help="Path to JSON containing the error injection dictionary",
    )
    parser.add_argument(
        "--arm",
        metavar="",
        type=str,
        default=None,
        help="URL or file PATH of Arm software image to flash.",
    )
    parser.add_argument(
        "--atom",
        metavar="",
        type=str,
        default=None,
        help="URL or file PATH of Atom software image to flash.",
    )
    parser.add_argument(
        "--combined",
        metavar="",
        type=str,
        default=None,
        help="URL or file PATH of ARM&ATOM Combined software image to flash.",
    )

    args = parser.parse_args()

    if args.version:
        print("%s %s" % (os.path.basename(sys.argv[0]), boardfarm.__version__))
        if boardfarm.plugins:
            print("Installed Plugins:")
            for key in sorted(boardfarm.plugins):
                print(
                    "%s %s" %
                    (key, getattr(boardfarm.plugins[key], "__version__", "")))
            print("Python: %s" % sys.version)
        sys.exit(0)

    if args.list_tests:
        try:
            from boardfarm import tests

            tests.init(config)
        except TestImportError as e:
            print(e)
            sys.exit(1)
        for k, v in sorted(tests.available_tests.items()):
            try:
                print("%20s - %s" % (k, v.__doc__.split("\n")[0]))
            except Exception as error:
                print(error)
                print("%20s -" % k)
        sys.exit(0)

    try:
        if args.config_file is not None:
            config.boardfarm_config_location = args.config_file
        (
            config.boardfarm_config_location,
            config.boardfarm_config,
        ) = boardfarm.lib.test_configurator.get_station_config(
            config.boardfarm_config_location, bool(args.config_file))
    except Exception as e:
        print(e)
        print("Unable to access/read boardfarm configuration from %s" %
              config.boardfarm_config_location)
        sys.exit(1)

    # Check if boardfarm configuration is empty
    if not config.boardfarm_config:
        print("ERROR! Boardfarm config at %s is empty, so" % args.config_file)
        print("either all stations are in use or disabled.")
        sys.exit(10)
    # Check if given board type(s) have any overlap with available board types from config
    if args.board_type:
        all_board_types = []
        for key in config.boardfarm_config:
            elem = (config.boardfarm_config[key].get("board_type", None)
                    if type(config.boardfarm_config[key]) is dict else None)
            if elem:
                all_board_types.append(elem)

        if not (set(args.board_type) & set(all_board_types)):
            print("ERROR! You specified board types: %s " %
                  " ".join(args.board_type))
            print("but that is not an existing & available type of board.")
            print("Please choose a board type from:")
            print("\n".join([" * %s" % x for x in set(all_board_types)]))
            sys.exit(10)
    # Check if given board name(s) are present in available boards
    if args.board_names:
        all_board_names = [
            key for key in config.boardfarm_config if key != "locations"
        ]
        if not (set(args.board_names) & set(all_board_names)):
            print("ERROR! You specified board names: %s " %
                  " ".join(args.board_names))
            print("but that is not an existing & available board.")
            print("Please choose a board name from:")
            print("\n".join([" * %s" % x for x in sorted(all_board_names)]))
            sys.exit(10)

    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") is not 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 boardfarm.lib.test_configurator.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.ARM = args.arm
    config.ATOM = args.atom
    config.COMBINED = args.combined
    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,
            config.ARM,
            config.ATOM,
            config.COMBINED,
    ):
        if x is None:
            continue
        if "mirror://" in x:
            # we need to check the mirror later once the board is selected
            continue
        if x.startswith("http://") or x.startswith("https://"):
            if not check_url(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 Exception as error:
        print(error)
        pass

    if args.analysis:
        from boardfarm 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 boardfarm.analysis.analysis import prepare_log

                try:
                    c().analyze(prepare_log(console_log), config.output_dir)
                    print("DONE!")
                except Exception:
                    print("FAILED!")
                    traceback.print_exc(file=sys.stdout)
                    continue
        exit(0)

    config.BOARD_NAMES = boardfarm.lib.test_configurator.filter_station_config(
        config.boardfarm_config,
        board_type=args.board_type,
        board_names=args.board_names,
        board_features=args.feature,
        board_filter=args.filter,
    )
    if args.board_type:
        if not config.BOARD_NAMES:
            print(
                "ERROR! No boards meet selection requirements and have available_for_autotests = True."
            )
            sys.exit(10)
    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)

    if args.err_dict:
        config.update_error_injection_dict(args.err_dict)

    # grab golden master results
    if args.golden:
        config.golden = args.golden
    config.golden_master_results = {}
    if config.golden is not []:
        import requests

        for g in config.golden:
            try:
                config.golden_master_results.update(requests.get(g).json())
            except Exception as error:
                print(error)
                print("Failed to fetch golden master results from %s" % g)
                sys.exit(15)

    config.WAN_PROTO = args.wan
    config.setup_device_networking = not args.no_network
    config.bootargs = args.bootargs
    config.golden = args.golden
    config.features = args.feature
    config.TEST_SUITE_NOSTRICT = args.nostrict
    config.regex_config = args.regex_config

    return config
    difference2 = [tc for tc in pytest_list if tc not in tc_list]
    if difference1 != []:
        print("Missed tc's to add pytest markers for testsuite {}: {}".format(
            testsuite, str(difference1)))
    if difference2 != []:
        print(
            "Unexpected tc's with pytest markers for testsuite {}: {}".format(
                testsuite, str(difference2)))
    if difference1 == [] and difference2 == []:
        print("Pytest marker updation successful for testsuite {}".format(
            testsuite))


for testsuite in testsuites_list:
    tc_list = get_tc_list(testsuite)
    tests.init()
    for test in tc_list:
        # Grep the testcase class name to get the source file
        pytest_marker = "@pytest.mark." + testsuite
        file_name = inspect.getmodule(tests.available_tests[test]).__file__
        class_name = "class " + test

        existing_marker = check_existing_marker(testsuite, file_name, test)

        # add marker if the testcase is not already marked
        if not existing_marker:
            with open(file_name, "r") as file:
                filedata = file.read()

            # add pytest to import section
            if "import pytest" not in filedata:
Example #10
0
    def list_tests(self):
        """Search for all available tests and return a dict."""
        from boardfarm import config, tests

        tests.init(config)
        return tests.available_tests
Example #11
0
    def test_main(self):
        """Function to interact menu."""
        if "pytest" in sys.modules:
            logger.warning(
                colored(
                    f"DEPRECATION WARNING: use pytest interact to have test discovery and fixture invocation",
                    color="red",
                    attrs=["bold"],
                ))

        board = self.dev.board
        lib.common.test_msg(
            "Press Ctrl-] to stop interaction and return to menu")
        board.sendline()
        try:
            board.interact()
        except Exception as error:
            print(error)
            return

        while True:
            print("\n\nCurrent station")
            print("  Board console: %s" % self.config.board.get("conn_cmd"))
            self.print_dynamic_devices()
            print("Pro-tip: Increase kernel message verbosity with\n"
                  '    echo "7 7 7 7" > /proc/sys/kernel/printk')
            print("Menu")
            i = 2
            if board.consoles is None:
                print("  1: Enter console")
                i += 1
            else:
                i = 1
                for c in board.consoles:
                    print("  %s: Enter console" % i)
                    i += 1

            print("  %s: List all tests" % i)
            i += 1
            print("  %s: Run test" % i)
            i += 1
            print("  %s: Reset board" % i)
            i += 1
            print("  %s: Enter interactive python shell" % i)
            i += 1
            if len(self.config.devices) > 0:
                print("  Type a device name to connect: %s" %
                      self.config.devices)
            print("  x: Exit")
            key = input("Please select: ")

            if key in self.config.devices:
                d = getattr(self.config, key)
                d.interact()

            i = 1
            for c in board.consoles:
                if key == str(i):
                    c.interact()
                i += 1

            if key == str(i):
                try:
                    tests.init(self.config)
                except Exception as e:
                    print("Unable to re-import tests!")
                    print(e)
                else:
                    print("Available tests:")
                    print("\n".join(tests.available_tests.keys()))
                continue
            i += 1

            if key == str(i):
                try:
                    tests.init(self.config)
                except Exception as e:
                    print("Unable to re-import tests!")
                    print(e)
                else:
                    # TODO: use an index instead of test name
                    print("Type test to run: ")
                    test = sys.stdin.readline().strip()

                    try:
                        tests.available_tests[test](self.config, self.dev,
                                                    self.env_helper).run()
                    except Exception as e:
                        lib.common.test_msg(
                            "Failed to find and/or run test, continuing..")
                        print(e)
                        continue
                    finally:
                        func = getattr(
                            tests.available_tests[test].__class__,
                            "teardown_class",
                            None,
                        )
                        if func:
                            try:
                                tests.available_tests[test].teardown_wrapper(
                                    func)
                            except Exception as e:
                                print(e)
                                print(
                                    "This should never happen. TearDown should be fail-safe"
                                )

                continue
            i += 1

            if key == str(i):
                board.reset()
                print("Press Ctrl-] to stop interaction and return to menu")
                board.interact()
                continue
            i += 1

            if key == str(i):
                print("Enter python shell, press Ctrl-D to exit")
                try:
                    import readline  # optional, will allow Up/Down/History in the console

                    assert readline  # silence pyflakes
                    import code

                    vars = globals().copy()
                    vars.update(locals())
                    shell = code.InteractiveConsole(vars)
                    shell.interact()
                except Exception as error:
                    print(error)
                    print("Unable to spawn interactive shell!")
                continue
            i += 1

            if key == "x":
                break