From 752c3769874596d012cd8325099d2ae20123f989 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 9 Feb 2025 09:07:14 -0700 Subject: test/py: Shorten u_boot_console This fixture name is quite long and results in lots of verbose code. We know this is U-Boot so the 'u_boot_' part is not necessary. But it is also a bit of a misnomer, since it provides access to all the information available to tests. It is not just the console. It would be too confusing to use con as it would be confused with config and it is probably too short. So shorten it to 'ubman'. Signed-off-by: Simon Glass Link: https://lore.kernel.org/u-boot/CAFLszTgPa4aT_J9h9pqeTtLCVn4x2JvLWRcWRD8NaN3uoSAtyA@mail.gmail.com/ --- test/py/conftest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test/py/conftest.py') diff --git a/test/py/conftest.py b/test/py/conftest.py index 31043a697e2..863f56c1152 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -486,8 +486,8 @@ def u_boot_config(request): return console.config @pytest.fixture(scope='function') -def u_boot_console(request): - """Generate the value of a test's u_boot_console fixture. +def ubman(request): + """Generate the value of a test's ubman fixture. Args: request: The pytest request. -- cgit v1.2.3 From d9ed4b75add4b4ccc37cf32b54cd9c77f48e3396 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 9 Feb 2025 09:07:15 -0700 Subject: test/py: Drop u_boot_ prefix on test files We know this is U-Boot so the prefix serves no purpose other than to make things longer and harder to read. Drop it and rename the files. Signed-off-by: Simon Glass Reviewed-by: Mattijs Korpershoek # test_android / test_dfu --- test/py/conftest.py | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'test/py/conftest.py') diff --git a/test/py/conftest.py b/test/py/conftest.py index 863f56c1152..8d0e786ee5c 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -7,7 +7,7 @@ # test, at shutdown etc. These hooks perform functions such as: # - Parsing custom command-line options. # - Pullilng in user-specified board configuration. -# - Creating the U-Boot console test fixture. +# - Creating the ubman test fixture. # - Creating the HTML log file. # - Monitoring each test's results. # - Implementing custom pytest markers. @@ -25,12 +25,12 @@ import re from _pytest.runner import runtestprotocol import subprocess import sys +from spawn import BootFail, Timeout, Unexpected, handle_exception import time -from u_boot_spawn import BootFail, Timeout, Unexpected, handle_exception -# Globals: The HTML log file, and the connection to the U-Boot console. +# Globals: The HTML log file, and the top-level fixture log = None -console = None +ubman_fix = None TEST_PY_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -247,7 +247,7 @@ def pytest_configure(config): ubconfig.buildconfig.update(parser.items('root')) global log - global console + global ubman_fix global ubconfig (board_type, board_type_extra, board_identity, build_dir, build_dir_extra, @@ -343,11 +343,11 @@ def pytest_configure(config): os.environ['U_BOOT_' + v.upper()] = getattr(ubconfig, v) if board_type.startswith('sandbox'): - import u_boot_console_sandbox - console = u_boot_console_sandbox.ConsoleSandbox(log, ubconfig) + import console_sandbox + ubman_fix = console_sandbox.ConsoleSandbox(log, ubconfig) else: - import u_boot_console_exec_attach - console = u_boot_console_exec_attach.ConsoleExecAttach(log, ubconfig) + import console_board + ubman_fix = console_board.ConsoleExecAttach(log, ubconfig) def generate_ut_subtest(metafunc, fixture_name, sym_path): @@ -366,7 +366,7 @@ def generate_ut_subtest(metafunc, fixture_name, sym_path): Returns: Nothing. """ - fn = console.config.build_dir + sym_path + fn = ubman_fix.config.build_dir + sym_path try: with open(fn, 'rt') as f: lines = f.readlines() @@ -407,8 +407,8 @@ def generate_config(metafunc, fixture_name): """ subconfigs = { - 'brd': console.config.brd, - 'env': console.config.env, + 'brd': ubman_fix.config.brd, + 'env': ubman_fix.config.env, } parts = fixture_name.split('__') if len(parts) < 2: @@ -470,7 +470,7 @@ def u_boot_log(request): The fixture value. """ - return console.log + return ubman_fix.log @pytest.fixture(scope='session') def u_boot_config(request): @@ -483,7 +483,7 @@ def u_boot_config(request): The fixture value. """ - return console.config + return ubman_fix.config @pytest.fixture(scope='function') def ubman(request): @@ -499,18 +499,18 @@ def ubman(request): pytest.skip('Cannot get target connection') return None try: - console.ensure_spawned() + ubman_fix.ensure_spawned() except OSError as err: - handle_exception(ubconfig, console, log, err, 'Lab failure', True) + handle_exception(ubconfig, ubman_fix, log, err, 'Lab failure', True) except Timeout as err: - handle_exception(ubconfig, console, log, err, 'Lab timeout', True) + handle_exception(ubconfig, ubman_fix, log, err, 'Lab timeout', True) except BootFail as err: - handle_exception(ubconfig, console, log, err, 'Boot fail', True, - console.get_spawn_output()) + handle_exception(ubconfig, ubman_fix, log, err, 'Boot fail', True, + ubman.get_spawn_output()) except Unexpected: - handle_exception(ubconfig, console, log, err, 'Unexpected test output', + handle_exception(ubconfig, ubman_fix, log, err, 'Unexpected test output', False) - return console + return ubman_fix anchors = {} tests_not_run = [] @@ -623,8 +623,8 @@ def cleanup(): Nothing. """ - if console: - console.close() + if ubman_fix: + ubman_fix.close() if log: with log.section('Status Report', 'status_report'): log.status_pass('%d passed' % len(tests_passed)) @@ -845,7 +845,7 @@ def pytest_runtest_protocol(item, nextitem): test_durations[item.name] = duration if failure_cleanup: - console.drain_console() + ubman_fix.drain_console() test_list.append(item.name) tests_not_run.remove(item.name) @@ -855,7 +855,7 @@ def pytest_runtest_protocol(item, nextitem): except: # If something went wrong with logging, it's better to let the test # process continue, which may report other exceptions that triggered - # the logging issue (e.g. console.log wasn't created). Hence, just + # the logging issue (e.g. ubman_fix.log wasn't created). Hence, just # squash the exception. If the test setup failed due to e.g. syntax # error somewhere else, this won't be seen. However, once that issue # is fixed, if this exception still exists, it will then be logged as @@ -868,6 +868,6 @@ def pytest_runtest_protocol(item, nextitem): log.end_section(item.name) if failure_cleanup: - console.cleanup_spawn() + ubman_fix.cleanup_spawn() return True -- cgit v1.2.3 From 0043428777f8b4dabd8124aa60f53fc7a14c9369 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 9 Feb 2025 09:07:18 -0700 Subject: test/py: Show info about module-loading It is sometimes tricky to figure out what modules test.py is loading when it starts up. The result can be a silent failure with no clue as to what when wrong. Add a section which lists the modules loaded as well as those not found. Signed-off-by: Simon Glass --- test/py/conftest.py | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'test/py/conftest.py') diff --git a/test/py/conftest.py b/test/py/conftest.py index 8d0e786ee5c..e59897c1f78 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -289,19 +289,26 @@ def pytest_configure(config): ubconfig = ArbitraryAttributeContainer() ubconfig.brd = dict() ubconfig.env = dict() - - modules = [ - (ubconfig.brd, 'u_boot_board_' + board_type_filename), - (ubconfig.env, 'u_boot_boardenv_' + board_type_filename), - (ubconfig.env, 'u_boot_boardenv_' + board_type_filename + '_' + - board_identity_filename), - ] - for (dict_to_fill, module_name) in modules: - try: - module = __import__(module_name) - except ImportError: - continue - dict_to_fill.update(module.__dict__) + not_found = [] + + with log.section('Loading lab modules', 'load_modules'): + modules = [ + (ubconfig.brd, 'u_boot_board_' + board_type_filename), + (ubconfig.env, 'u_boot_boardenv_' + board_type_filename), + (ubconfig.env, 'u_boot_boardenv_' + board_type_filename + '_' + + board_identity_filename), + ] + for (dict_to_fill, module_name) in modules: + try: + module = __import__(module_name) + except ImportError: + not_found.append(module_name) + continue + dict_to_fill.update(module.__dict__) + log.info(f"Loaded {module}") + + if not_found: + log.warning(f"Failed to find modules: {' '.join(not_found)}") ubconfig.buildconfig = dict() -- cgit v1.2.3 From 9a04b9a4392fc0ee49596bb63b7706beb29034de Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 15 Mar 2025 14:25:51 +0000 Subject: test/py: Allow tests to be filtered by role Some test can only be run by a particular board in a lab, e.g. because they are loaded with an OS image used by the test. Add a way to specify this in tests. Signed-off-by: Simon Glass --- test/py/conftest.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'test/py/conftest.py') diff --git a/test/py/conftest.py b/test/py/conftest.py index e59897c1f78..5aea85647af 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -334,6 +334,7 @@ def pytest_configure(config): ubconfig.dtb = build_dir + '/arch/sandbox/dts/test.dtb' ubconfig.connection_ok = True ubconfig.timing = config.getoption('timing') + ubconfig.role = config.getoption('role') env_vars = ( 'board_type', @@ -760,6 +761,26 @@ def setup_singlethread(item): if worker_id and worker_id != 'master': pytest.skip('must run single-threaded') +def setup_role(item): + """Process any 'role' marker for a test. + + Skip this test if the role does not match. + + Args: + item (pytest.Item): The pytest test item + """ + required_roles = [] + for roles in item.iter_markers('role'): + role = roles.args[0] + if role.startswith('!'): + if ubconfig.role == role[1:]: + pytest.skip(f'role "{ubconfig.role}" not supported') + return + else: + required_roles.append(role) + if required_roles and ubconfig.role not in required_roles: + pytest.skip(f'board "{ubconfig.role}" not supported') + def start_test_section(item): anchors[item.name] = log.start_section(item.name) @@ -781,6 +802,7 @@ def pytest_runtest_setup(item): setup_buildconfigspec(item) setup_requiredtool(item) setup_singlethread(item) + setup_role(item) def pytest_runtest_protocol(item, nextitem): """pytest hook: Called to execute a test. -- cgit v1.2.3