ci: ci_build_apps.py supports filter_expr

This commit is contained in:
Fu Hanxi
2022-11-29 16:14:26 +08:00
parent 9a1f2b95ea
commit 9a666c8ba0
2 changed files with 26 additions and 32 deletions

View File

@@ -23,10 +23,11 @@ def get_pytest_apps(
target: str, target: str,
config_rules_str: List[str], config_rules_str: List[str],
marker_expr: str, marker_expr: str,
filter_expr: str,
preserve_all: bool = False, preserve_all: bool = False,
extra_default_build_targets: Optional[List[str]] = None, extra_default_build_targets: Optional[List[str]] = None,
) -> List[App]: ) -> List[App]:
pytest_cases = get_pytest_cases(paths, target, marker_expr) pytest_cases = get_pytest_cases(paths, target, marker_expr, filter_expr)
_paths: Set[str] = set() _paths: Set[str] = set()
test_related_app_configs = defaultdict(set) test_related_app_configs = defaultdict(set)
@@ -126,6 +127,7 @@ def main(args: argparse.Namespace) -> None:
args.target, args.target,
args.config, args.config,
args.marker_expr, args.marker_expr,
args.filter_expr,
args.preserve_all, args.preserve_all,
extra_default_build_targets, extra_default_build_targets,
) )
@@ -181,8 +183,8 @@ if __name__ == '__main__':
parser.add_argument( parser.add_argument(
'-t', '-t',
'--target', '--target',
required=True, default='all',
help='Build apps for given target. could pass "all" to get apps for all targets', help='Build apps for given target',
) )
parser.add_argument( parser.add_argument(
'--config', '--config',
@@ -263,6 +265,12 @@ if __name__ == '__main__':
help='only build tests matching given mark expression. For example: -m "host_test and generic". Works only' help='only build tests matching given mark expression. For example: -m "host_test and generic". Works only'
'for pytest', 'for pytest',
) )
parser.add_argument(
'-k',
'--filter-expr',
help='only build tests matching given filter expression. For example: -k "test_hello_world". Works only'
'for pytest',
)
parser.add_argument( parser.add_argument(
'--default-build-test-rules', '--default-build-test-rules',
default=os.path.join(IDF_PATH, '.gitlab', 'ci', 'default-build-test-rules.yml'), default=os.path.join(IDF_PATH, '.gitlab', 'ci', 'default-build-test-rules.yml'),

View File

@@ -24,9 +24,7 @@ except ImportError:
if TYPE_CHECKING: if TYPE_CHECKING:
from _pytest.python import Function from _pytest.python import Function
IDF_PATH = os.path.abspath( IDF_PATH = os.path.abspath(os.getenv('IDF_PATH', os.path.join(os.path.dirname(__file__), '..', '..')))
os.getenv('IDF_PATH', os.path.join(os.path.dirname(__file__), '..', '..'))
)
def get_submodule_dirs(full_path: bool = False) -> List: def get_submodule_dirs(full_path: bool = False) -> List:
@@ -66,11 +64,7 @@ def get_submodule_dirs(full_path: bool = False) -> List:
def _check_git_filemode(full_path): # type: (str) -> bool def _check_git_filemode(full_path): # type: (str) -> bool
try: try:
stdout = ( stdout = subprocess.check_output(['git', 'ls-files', '--stage', full_path]).strip().decode('utf-8')
subprocess.check_output(['git', 'ls-files', '--stage', full_path])
.strip()
.decode('utf-8')
)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
return True return True
@@ -150,6 +144,7 @@ class PytestCase:
path: str path: str
name: str name: str
apps: Set[PytestApp] apps: Set[PytestApp]
nightly_run: bool nightly_run: bool
def __hash__(self) -> int: def __hash__(self) -> int:
@@ -185,14 +180,8 @@ class PytestCollectPlugin:
self.get_param(item, 'app_path', os.path.dirname(case_path)), self.get_param(item, 'app_path', os.path.dirname(case_path)),
) )
) )
configs = to_list( configs = to_list(parse_multi_dut_args(count, self.get_param(item, 'config', 'default')))
parse_multi_dut_args( targets = to_list(parse_multi_dut_args(count, self.get_param(item, 'target', target)))
count, self.get_param(item, 'config', 'default')
)
)
targets = to_list(
parse_multi_dut_args(count, self.get_param(item, 'target', target))
)
else: else:
app_paths = [os.path.dirname(case_path)] app_paths = [os.path.dirname(case_path)]
configs = ['default'] configs = ['default']
@@ -213,7 +202,10 @@ class PytestCollectPlugin:
def get_pytest_cases( def get_pytest_cases(
paths: Union[str, List[str]], target: str = 'all', marker_expr: Optional[str] = None paths: Union[str, List[str]],
target: str = 'all',
marker_expr: Optional[str] = None,
filter_expr: Optional[str] = None,
) -> List[PytestCase]: ) -> List[PytestCase]:
import pytest import pytest
from _pytest.config import ExitCode from _pytest.config import ExitCode
@@ -250,17 +242,15 @@ def get_pytest_cases(
with io.StringIO() as buf: with io.StringIO() as buf:
with redirect_stdout(buf): with redirect_stdout(buf):
cmd = ['--collect-only', path, '-q', '-m', _marker_expr] cmd = ['--collect-only', path, '-q', '-m', _marker_expr]
if filter_expr:
cmd.extend(['-k', filter_expr])
res = pytest.main(cmd, plugins=[collector]) res = pytest.main(cmd, plugins=[collector])
if res.value != ExitCode.OK: if res.value != ExitCode.OK:
if res.value == ExitCode.NO_TESTS_COLLECTED: if res.value == ExitCode.NO_TESTS_COLLECTED:
print( print(f'WARNING: no pytest app found for target {t} under path {path}')
f'WARNING: no pytest app found for target {t} under path {path}'
)
else: else:
print(buf.getvalue()) print(buf.getvalue())
raise RuntimeError( raise RuntimeError(f'pytest collection failed at {path} with command \"{" ".join(cmd)}\"')
f'pytest collection failed at {path} with command \"{" ".join(cmd)}\"'
)
cases.extend(collector.cases) cases.extend(collector.cases)
@@ -296,9 +286,7 @@ def get_ttfw_cases(paths: Union[str, List[str]]) -> List[Any]:
cases = [] cases = []
for path in to_list(paths): for path in to_list(paths):
assign = IDFAssignTest( assign = IDFAssignTest(path, os.path.join(IDF_PATH, '.gitlab', 'ci', 'target-test.yml'))
path, os.path.join(IDF_PATH, '.gitlab', 'ci', 'target-test.yml')
)
with contextlib.redirect_stdout(None): # swallow stdout with contextlib.redirect_stdout(None): # swallow stdout
try: try:
cases += assign.search_cases() cases += assign.search_cases()
@@ -308,9 +296,7 @@ def get_ttfw_cases(paths: Union[str, List[str]]) -> List[Any]:
return cases return cases
def get_ttfw_app_paths( def get_ttfw_app_paths(paths: Union[str, List[str]], target: Optional[str] = None) -> Set[str]:
paths: Union[str, List[str]], target: Optional[str] = None
) -> Set[str]:
""" """
Get the app paths from ttfw_idf under the given paths Get the app paths from ttfw_idf under the given paths
""" """