Merge branch 'ci/support_filter_pytest_cases_with_sdconfig_name' into 'master'

ci: support filter pytest with sdkconfig name

See merge request espressif/esp-idf!29581
This commit is contained in:
Fu Hanxi 2024-03-14 16:34:31 +08:00
commit d3473bed30
4 changed files with 62 additions and 2 deletions

View File

@ -436,6 +436,7 @@ def pytest_configure(config: Config) -> None:
if '--collect-only' not in config.invocation_params.args:
config.stash[IDF_PYTEST_EMBEDDED_KEY] = IdfPytestEmbedded(
config_name=config.getoption('sdkconfig'),
target=target,
apps=apps,
)

View File

@ -48,6 +48,7 @@ class IdfPytestEmbedded:
self,
target: t.Union[t.List[str], str],
*,
config_name: t.Optional[str] = None,
single_target_duplicate_mode: bool = False,
apps: t.Optional[t.List[App]] = None,
):
@ -60,6 +61,8 @@ class IdfPytestEmbedded:
if not self.target:
raise ValueError('`target` should not be empty')
self.config_name = config_name
# these are useful while gathering all the multi-dut test cases
# when this mode is activated,
#
@ -226,7 +229,18 @@ class IdfPytestEmbedded:
and self.get_param(_item, 'target', None) is not None
]
# 4. filter by `self.apps_list`, skip the test case if not listed
# 4. filter according to the sdkconfig, if there's param 'config' defined
if self.config_name:
_items = []
for item in items:
case = item_to_case_dict[item]
if self.config_name not in set(app.config or DEFAULT_SDKCONFIG for app in case.apps):
self.additional_info[case.name]['skip_reason'] = f'Only run with sdkconfig {self.config_name}'
else:
_items.append(item)
items[:] = _items
# 5. filter by `self.apps_list`, skip the test case if not listed
# should only be used in CI
_items = []
for item in items:

View File

@ -50,6 +50,7 @@ def get_pytest_cases(
paths: t.Union[str, t.List[str]],
target: str = CollectMode.ALL,
*,
config_name: t.Optional[str] = None,
marker_expr: t.Optional[str] = None,
filter_expr: t.Optional[str] = None,
apps: t.Optional[t.List[App]] = None,
@ -67,6 +68,7 @@ def get_pytest_cases(
:param paths: paths to search for pytest scripts
:param target: target or keywords to get test cases for, detailed above
:param config_name: sdkconfig name
:param marker_expr: pytest marker expression, `-m`
:param filter_expr: pytest filter expression, `-k`
:param apps: built app list, skip the tests required by apps not in the list
@ -81,7 +83,7 @@ def get_pytest_cases(
return cases
def _get_pytest_cases(_target: str, _single_target_duplicate_mode: bool = False) -> t.List[PytestCase]:
collector = IdfPytestEmbedded(_target, single_target_duplicate_mode=_single_target_duplicate_mode, apps=apps)
collector = IdfPytestEmbedded(_target, config_name=config_name, single_target_duplicate_mode=_single_target_duplicate_mode, apps=apps)
with io.StringIO() as buf:
with redirect_stdout(buf):

View File

@ -118,3 +118,46 @@ def test_multi_with_marker_and_app_path(work_dirpath: Path) -> None:
cases = get_pytest_cases([str(work_dirpath)], 'esp32c2,esp32c2,esp32c2')
assert len(cases) == 1
assert cases[0].targets == ['esp32c2', 'esp32c2', 'esp32c2']
def test_filter_with_sdkconfig_name(work_dirpath: Path) -> None:
script = work_dirpath / 'pytest_filter_with_sdkconfig_name.py'
script.write_text(
textwrap.dedent(
'''
import pytest
@pytest.mark.esp32
@pytest.mark.parametrize(
'config', [
'foo',
'bar',
], indirect=True
)
def test_filter_with_sdkconfig_name_single_dut(dut):
pass
@pytest.mark.esp32
@pytest.mark.parametrize(
'count', [2], indirect=True
)
@pytest.mark.parametrize(
'config', [
'foo|bar',
'bar|baz',
], indirect=True
)
def test_filter_with_sdkconfig_name_multi_dut(dut):
pass
'''
)
)
cases = get_pytest_cases([str(work_dirpath)], 'esp32', config_name='foo')
assert len(cases) == 1
cases = get_pytest_cases([str(work_dirpath)], 'esp32,esp32', config_name='foo')
assert len(cases) == 1
cases = get_pytest_cases([str(work_dirpath)], 'esp32,esp32', config_name='bar')
assert len(cases) == 2