twister: support filtering tests using regex
Use --test-pattern to filter scenarios using regular expressions, for example: ./scripts/twister --test-pattern '^kernel.semaphore.*' -v will run all those test using this identifier pattern, and nothing else. Multiple patterns are possible. Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
5e4688fc15
commit
ac4aabc10d
@ -253,6 +253,12 @@ Artificially long but functional example:
|
||||
timeout would be multiplication of test timeout value, board-level timeout multiplier
|
||||
and global timeout multiplier (this parameter)""")
|
||||
|
||||
parser.add_argument(
|
||||
"--test-pattern", action="append",
|
||||
help="""Run only the tests matching the specified pattern. The pattern
|
||||
can include regular expressions.
|
||||
""")
|
||||
|
||||
test_xor_subtest.add_argument(
|
||||
"-s", "--test", "--scenario", action="append", type = norm_path,
|
||||
help="""Run only the specified test suite scenario. These are named by
|
||||
|
||||
@ -202,13 +202,12 @@ class TestPlan:
|
||||
|
||||
def discover(self):
|
||||
self.handle_modules()
|
||||
if self.options.test:
|
||||
self.run_individual_testsuite = self.options.test
|
||||
|
||||
self.test_config = TestConfiguration(self.env.test_config)
|
||||
|
||||
self.add_configurations()
|
||||
num = self.add_testsuites(testsuite_filter=self.run_individual_testsuite)
|
||||
num = self.add_testsuites(testsuite_filter=self.options.test,
|
||||
testsuite_pattern=self.options.test_pattern)
|
||||
|
||||
if num == 0:
|
||||
raise TwisterRuntimeError("No testsuites found at the specified location...")
|
||||
if self.load_errors:
|
||||
@ -507,9 +506,35 @@ class TestPlan:
|
||||
testcases.remove(case.detailed_name)
|
||||
return testcases
|
||||
|
||||
def add_testsuites(self, testsuite_filter=None):
|
||||
def _is_testsuite_selected(self, suite: TestSuite, testsuite_filter, testsuite_patterns_r):
|
||||
"""Check if the testsuite is selected by the user."""
|
||||
if not testsuite_filter and not testsuite_patterns_r:
|
||||
# no matching requested, include all testsuites
|
||||
return True
|
||||
if testsuite_filter:
|
||||
scenario = os.path.basename(suite.name)
|
||||
if (
|
||||
suite.name
|
||||
and (suite.name in testsuite_filter or scenario in testsuite_filter)
|
||||
):
|
||||
return True
|
||||
if testsuite_patterns_r:
|
||||
for r in testsuite_patterns_r:
|
||||
if r.search(suite.id):
|
||||
return True
|
||||
return False
|
||||
|
||||
def add_testsuites(self, testsuite_filter=None, testsuite_pattern=None):
|
||||
if testsuite_filter is None:
|
||||
testsuite_filter = []
|
||||
|
||||
testsuite_patterns_r = []
|
||||
if testsuite_pattern is None:
|
||||
testsuite_pattern = []
|
||||
else:
|
||||
for pattern in testsuite_pattern:
|
||||
testsuite_patterns_r.append(re.compile(pattern))
|
||||
|
||||
for root in self.env.test_roots:
|
||||
root = os.path.abspath(root)
|
||||
|
||||
@ -574,14 +599,11 @@ class TestPlan:
|
||||
else:
|
||||
suite.add_subcases(suite_dict)
|
||||
|
||||
if testsuite_filter:
|
||||
scenario = os.path.basename(suite.name)
|
||||
if (
|
||||
suite.name
|
||||
and (suite.name in testsuite_filter or scenario in testsuite_filter)
|
||||
):
|
||||
self.testsuites[suite.name] = suite
|
||||
elif suite.name in self.testsuites:
|
||||
if not self._is_testsuite_selected(suite, testsuite_filter,
|
||||
testsuite_patterns_r):
|
||||
# skip testsuite if they were not selected directly by the user
|
||||
continue
|
||||
if suite.name in self.testsuites:
|
||||
msg = (
|
||||
f"test suite '{suite.name}' in '{suite.yamlfile}' is already added"
|
||||
)
|
||||
|
||||
@ -570,6 +570,7 @@ def test_testplan_discover(
|
||||
env.test_config = tmp_tc
|
||||
testplan = TestPlan(env=env)
|
||||
testplan.options = mock.Mock(
|
||||
test_pattern=[],
|
||||
test='ts1',
|
||||
quarantine_list=[tmp_path / qf for qf in ql],
|
||||
quarantine_verify=qv
|
||||
@ -589,7 +590,7 @@ def test_testplan_discover(
|
||||
with pytest.raises(exception) if exception else nullcontext():
|
||||
testplan.discover()
|
||||
|
||||
testplan.add_testsuites.assert_called_once_with(testsuite_filter='ts1')
|
||||
testplan.add_testsuites.assert_called_once_with(testsuite_filter='ts1', testsuite_pattern=[])
|
||||
assert all([log in caplog.text for log in expected_logs])
|
||||
|
||||
|
||||
@ -1186,7 +1187,7 @@ TESTDATA_9 = [
|
||||
(['good_test/dummy.common.1', 'good_test/dummy.common.2', 'good_test/dummy.common.3'], False, True, 3, 1),
|
||||
(['good_test/dummy.common.1', 'good_test/dummy.common.2',
|
||||
'duplicate_test/dummy.common.1', 'duplicate_test/dummy.common.2'], False, True, 4, 1),
|
||||
(['dummy.common.1', 'dummy.common.2'], False, False, 2, 1),
|
||||
(['dummy.common.1', 'dummy.common.2'], False, False, 2, 2),
|
||||
(['good_test/dummy.common.1', 'good_test/dummy.common.2', 'good_test/dummy.common.3'], True, True, 0, 1),
|
||||
]
|
||||
|
||||
@ -1314,7 +1315,7 @@ tests:
|
||||
|
||||
testplan = TestPlan(env=env)
|
||||
|
||||
res = testplan.add_testsuites(testsuite_filter)
|
||||
res = testplan.add_testsuites(testsuite_filter, testsuite_pattern=[])
|
||||
|
||||
assert res == expected_suite_count
|
||||
assert testplan.load_errors == expected_errors
|
||||
|
||||
Loading…
Reference in New Issue
Block a user