Skip to content

Commit

Permalink
twister: Add support for required snippets
Browse files Browse the repository at this point in the history
Adds support for twister to require using snippets on tests

Signed-off-by: Jamie McCrae <[email protected]>
  • Loading branch information
nordicjm committed Aug 3, 2023
1 parent d7504ab commit 52b344c
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 1 deletion.
1 change: 1 addition & 0 deletions scripts/pylib/twister/twisterlib/config_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class TwisterConfigParser:
"extra_conf_files": {"type": "list", "default": []},
"extra_overlay_confs" : {"type": "list", "default": []},
"extra_dtc_overlay_files": {"type": "list", "default": []},
"required_snippets": {"type": "list"},
"build_only": {"type": "bool", "default": False},
"build_on_all": {"type": "bool", "default": False},
"skip": {"type": "bool", "default": False},
Expand Down
4 changes: 4 additions & 0 deletions scripts/pylib/twister/twisterlib/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,10 @@ def run_cmake(self, args="", filter_stages=[]):
cmake_opts = ['-DBOARD={}'.format(self.platform.name)]
cmake_args.extend(cmake_opts)

for this_snippet in self.instance.testsuite.required_snippets:
cmake_opts = ['-DSNIPPET={}'.format(this_snippet)]
cmake_args.extend(cmake_opts)

cmake = shutil.which('cmake')
cmd = [cmake] + cmake_args

Expand Down
25 changes: 25 additions & 0 deletions scripts/pylib/twister/twisterlib/testplan.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import copy
import shutil
import random
import snippets
from pathlib import Path

logger = logging.getLogger('twister')
logger.setLevel(logging.DEBUG)
Expand Down Expand Up @@ -819,6 +821,29 @@ def apply_filters(self, **kwargs):
if plat.only_tags and not set(plat.only_tags) & ts.tags:
instance.add_filter("Excluded tags per platform (only_tags)", Filters.PLATFORM)

snippet_args = {"snippets": ts.required_snippets}
snippets2 = snippets.process_snippets_inter(snippet_args, [Path(ZEPHYR_BASE)])

for this_snippet in snippets2:
matched_snipped_board = False

if len(snippets2[this_snippet].appends) > 0:
continue

for this_board in snippets2[this_snippet].board2appends:
if this_board.startswith('/'):
match = re.search(this_board[1:-1], plat.name)
if match is not None:
matched_snipped_board = True
break
elif this_board == plat.name:
matched_snipped_board = True
break

if matched_snipped_board is False:
instance.add_filter("Snippet not supported", Filters.PLATFORM)
break

# platform_key is a list of unique platform attributes that form a unique key a test
# will match against to determine if it should be scheduled to run. A key containing a
# field name that the platform does not have will filter the platform.
Expand Down
5 changes: 5 additions & 0 deletions scripts/schemas/twister/testsuite-schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,11 @@ mapping:
"extra_sections":
type: any
required: false
"required_snippets":
type: seq
required: false
sequence:
- type: str
"filter":
type: str
required: false
Expand Down
16 changes: 16 additions & 0 deletions scripts/snippets.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,22 @@ def process_snippets(args: argparse.Namespace) -> Snippets:

return snippets

def process_snippets_inter(requested_snippets, snippet_roots) -> Snippets:
'''Process snippet.yml files under each *snippet_root*
by recursive search. Return a Snippets object describing
the results of the search.
'''
# This will contain information about all the snippets
# we discover in each snippet_root element.
snippets = Snippets(requested=requested_snippets)

# Process each path in snippet_root in order, adjusting
# snippets as needed for each one.
for root in snippet_roots:
process_snippets_in(root, snippets)

return snippets

def process_snippets_in(root_dir: Path, snippets: Snippets) -> None:
'''Process snippet.yml files in *root_dir*,
updating *snippets* as needed.'''
Expand Down
3 changes: 3 additions & 0 deletions scripts/twister
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pairs:
Extra configuration options to be merged with a master prj.conf
when building or running the test case.
required_snippets: <list of snippets>
Snippets that must be applied for the test case to run.
sysbuild: <True|False> (default False)
If true, build the sample using the sysbuild infrastructure. Filtering
will only be enabled for the main project, and is not supported for
Expand Down
10 changes: 9 additions & 1 deletion scripts/west_commands/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ def _parse_test_item(self, test_item):
extra_dtc_overlay_files = []
extra_overlay_confs = []
extra_conf_files = []
required_snippets = []
for section in [common, item]:
if not section:
continue
Expand All @@ -291,7 +292,8 @@ def _parse_test_item(self, test_item):
'extra_configs',
'extra_conf_files',
'extra_overlay_confs',
'extra_dtc_overlay_files'
'extra_dtc_overlay_files',
'required_snippets'
]:
extra = section.get(data)
if not extra:
Expand All @@ -314,6 +316,9 @@ def _parse_test_item(self, test_item):
elif data == 'extra_dtc_overlay_files':
extra_dtc_overlay_files.extend(arg_list)
continue
elif data == 'required_snippets':
required_snippets.extend(arg_list)
continue

if self.args.cmake_opts:
self.args.cmake_opts.extend(args)
Expand All @@ -331,6 +336,9 @@ def _parse_test_item(self, test_item):

if extra_overlay_confs:
args.append(f"OVERLAY_CONFIG=\"{';'.join(extra_overlay_confs)}\"")

if required_snippets:
args.append(f"SNIPPET=\"{';'.join(required_snippets)}\"")
# Build the final argument list
args_expanded = ["-D{}".format(a.replace('"', '')) for a in args]

Expand Down

0 comments on commit 52b344c

Please sign in to comment.