zephyr/scripts/tests/twister
Grzegorz Swiderski bb8b059e23 twister: Account for board & SoC extensions
Problem
-------

Board & SoC extensions are used to define out-of-tree board variants or
SoC qualifiers. When a board is extended, it has multiple directories
associated with it (each with its own `board.yml`), where twister should
be able to find additional platform files to support these qualifiers.
Currently, this doesn't work, because twister only traverses the primary
BOARD_DIR and ignores the rest.

The fix would've been trivial in the case of "legacy" platform files,
i.e. those of the form `<normalized_board_target>.yaml`, but it's less
straightforward for the newly introduced `twister.yaml` format.

A `twister.yaml` file contains platform configuration that can be shared
by multiple board targets and tweaked for specific targets by using the
top-level `variants` key. Normally, there is at most one `twister.yaml`
per board, but the file isn't necessarily unique to one board. Instead,
it's unique to one directory, which may define multiple boards (as is
the case with e.g. `boards/qemu/x86/`).

With extensions in the picture, the goal is to initialize platforms when
given multiple `twister.yaml` per board. The OOT files are expected to
only provide information about OOT board targets, without being able to
override in-tree targets (same principle as in the Zephyr build system).

Solution
--------

The `twister.yaml` handling is broken up into multiple passes - first
loading all the files, then splitting the `variants` keys apart from the
shared configuration, before constructing the Platform instances.

The purpose of the split is to treat the variant information as global,
instead of making unnecessary or faulty assumptions about locality.
Remember that the build system can derive board target names not only
from `board.yml`, but from `soc.yml` too. Considering that any board may
end up using an OOT-extended SoC (and hence multiple `soc.yml` files),
not every board target can be said to belong to some board dir.

Unlike the variant data, the remaining top-level config is still rooted
to the primary BOARD_DIR and inherited by the extension dirs from there.
This is quite intuitive in most imagined cases, but there is a caveat:
if a `twister.yaml` resides in an extension dir, then it is allowed to
have a top-level config of its own, but it will be silently ignored.
This is to support corner cases where, much like how a single board dir
can define multiple boards, a single board dir can also extend multiple
boards, or even do both. In those cases, the primary BOARD_DIR rule
should make it unambiguous which config belongs to which board, even if
it may seem counter-intuitive at first.

For concrete examples of what this means, please see the newly added
platform unit tests.

As part of these functional changes, a good chunk of logic is moved out
of `TestPlan.add_configurations()` into a new function in `platform.py`.
This is because recombining the top-level and variant configs requires
direct manipulation of the loaded YAML contents, which would be improper
to do outside of the module responsible for encapsulating this data.

Signed-off-by: Grzegorz Swiderski <grzegorz.swiderski@nordicsemi.no>
2025-02-14 21:01:33 +01:00
..
pytest_integration twister: harness: introduce shell harness 2025-02-08 08:13:46 +01:00
test_data twister: Remove 'xtools' toolchain variant references 2025-01-17 10:50:07 +01:00
conftest.py twister: support testing multiple toolchain variants 2025-01-08 12:58:59 +01:00
README.md
test_cmakecache.py
test_config_parser.py scripts: twister: drop support for space-separated lists 2024-12-04 14:14:53 -05:00
test_environment.py scripts: Fix CMake spelling 2024-10-30 16:32:24 -05:00
test_errors.py twister: test: update test case 2024-12-04 02:03:33 +01:00
test_handlers.py twister: handlers: Pass harness reason to instance 2024-12-17 11:37:40 +00:00
test_hardwaremap.py scripts: Fix twisterlib for ruff - UP015 2024-11-29 15:29:31 +01:00
test_harness.py twister: harness: recording: Allow multiple patterns 2025-01-16 22:38:51 +01:00
test_jobserver.py scripts: twister: Fix Unit Tests on Windows systems 2024-05-15 17:08:06 +02:00
test_log_helper.py
test_mixins.py python: Format and sort imports 2024-11-25 10:07:13 +01:00
test_platform.py twister: Account for board & SoC extensions 2025-02-14 21:01:33 +01:00
test_quarantine.py scripts: twisterlib: Enable multiple simulator support in twister 2024-11-25 08:31:28 +01:00
test_runner.py twister: coverage: Data collection and reporting per-test instance 2025-01-30 18:29:08 +01:00
test_scl.py
test_testinstance.py twister: support testing multiple toolchain variants 2025-01-08 12:58:59 +01:00
test_testplan.py twister: Account for board & SoC extensions 2025-02-14 21:01:33 +01:00
test_testsuite.py twister: test: update test case 2024-12-04 02:03:33 +01:00
test_twister.py scripts: Fix twisterlib for ruff - B028 2024-11-29 15:29:31 +01:00

Twister Testing

Running the tests require the environment variable ZEPHYR_BASE to be set.

Twister Testsuite are located in $ZEPHYR_BASE/scripts/tests directory with all the data files in $ZEPHYR_BASE/scripts/test_data directory.

Dependencies

Install all the dependencies using

pip install -r $ZEPHYR_BASE/scripts/requirements-build-test.txt

Executing testsuite

The testcases can be executed from the root directory using

pytest $ZEPHYR_BASE/scripts/tests/twister

Twister Coverage

The coverage for all the tests can be run using the command below. This will collect all the tests available.

coverage run -m pytest $ZEPHYR_BASE/scripts/tests/twister/

Then we can generate the coverage report for just twister script using

coverage report -m $ZEPHYR_BASE/scripts/pylib/twister/

To generate the coverage report for twister script use below command

coverage report -m $ZEPHYR_BASE/scripts/twister

The html coverage report for twister can be generated using

coverage html twister

If needed,the full coverage html report can be generated in every run of "pytest" in the tests directory using configuration file (setup.cfg).

Organization of tests

  • conftest.py: Contains common fixtures for use in testing the twister tool.
  • test_twister.py : Contains basic testcases for environment variables, verifying testcase & platform schema's.
  • test_testsuite_class.py : Contains testcases for Testsuite class (except reporting functionality) in twisterlib.py.
  • test_testinstance.py : Contains testcases for Testinstance and Testcase class.
  • test_reporting_testsuite.py : Contains testcases for reporting functionality of Testsuite class of twister.