Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 157 additions & 6 deletions ci/commit_pragma_mapping.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,175 @@
#
# Each key is a regex path to match.
# Under each path is optionally each key:
# stop_on_match: Whether to stop processing other entries if when a match is found.
# For example, if "src/tests/ftest*" matches, we don't want to also process ".*"
# test-tag <string|dict>: Either direct test tags for this path or:
# handler: either "direct" or "FtestTagMap" for special handling. Default is "direct"
# stop_on_match: Whether to stop processing other entries if when a match is found.
# For example, if "src/tests/ftest*" matches, we don't want to also process ".*"
# tags: the tags to use for a match
# need-unit-test <bool|dict>: Either a direct boolean value or:
# stop_on_match: Whether to stop processing other entries for this path when a match is found.
# val: Whether this path needs unit tests. Default is True.

ftest-only: &ftest-only
stop_on_match: True
need-unit-test: False

# Special handling for ftest, defaulting to pr
src/tests/ftest*:
<<: *ftest-only
test-tag:
handler: FtestTagMap
stop_on_match: True
tags: pr
need-unit-test:
stop_on_match: True
val: False

src/tests/suite/daos_aggregate_ec.c:
test-tag: test_daos_aggregate_ec
<<: *ftest-only

src/tests/suite/daos_array.c:
test-tag: test_daos_array
<<: *ftest-only

src/tests/suite/daos_base_tx.c:
test-tag: test_daos_single_rdg_tx
<<: *ftest-only

src/tests/suite/daos_capa.c:
test-tag: test_daos_capability
<<: *ftest-only

src/tests/suite/daos_checksum.c:
test-tag: test_daos_checksum
<<: *ftest-only

src/tests/suite/daos_container.c:
test-tag: test_daos_container
<<: *ftest-only

src/tests/suite/daos_cr.c:
test-tag: test_daos_cat_recov_core
<<: *ftest-only

src/tests/suite/daos_dedup.c:
test-tag: test_daos_dedup
<<: *ftest-only

src/tests/suite/daos_degraded.c:
test-tag: test_daos_degraded_mode
<<: *ftest-only

src/tests/suite/daos_degrade_ec.c:
test-tag: test_daos_degraded_ec
<<: *ftest-only

src/tests/suite/daos_dist_tx.c:
test-tag: test_daos_distributed_tx
<<: *ftest-only

src/tests/suite/daos_drain_simple.c:
test-tag: test_daos_drain_simple
<<: *ftest-only

src/tests/suite/daos_epoch.c:
test-tag: test_daos_epoch
<<: *ftest-only

src/tests/suite/daos_epoch_recovery.c:
test-tag: test_daos_epoch_recovery
<<: *ftest-only

src/tests/suite/daos_extend_simple.c:
test-tag: test_daos_extend_simple
<<: *ftest-only

src/tests/suite/daos_kv.c:
test-tag: test_daos_kv
<<: *ftest-only

src/tests/suite/daos_md_replication.c:
test-tag: test_daos_md_replication
<<: *ftest-only

src/tests/suite/daos_mgmt.c:
test-tag: test_daos_management
<<: *ftest-only

src/tests/suite/daos_nvme_recovery.c:
test-tag: DaosCoreTestNvme
<<: *ftest-only

src/tests/suite/daos_obj_array.c:
test-tag: test_daos_object_array
<<: *ftest-only

src/tests/suite/daos_obj.c:
test-tag: test_daos_io test_daos_ec_io
<<: *ftest-only

src/tests/suite/daos_obj_ec.c:
test-tag: test_daos_ec_obj
<<: *ftest-only

src/tests/suite/daos_oid_alloc.c:
test-tag: test_daos_oid_allocator
<<: *ftest-only

src/tests/suite/daos_pipeline.c:
test-tag: test_daos_pipeline
<<: *ftest-only

src/tests/suite/daos_pool.c:
test-tag: test_daos_pool
<<: *ftest-only

src/tests/suite/daos_rebuild.c:
test-tag: DaosCoreTestRebuild
<<: *ftest-only

src/tests/suite/daos_rebuild_ec.c:
test-tag: test_daos_rebuild_ec
<<: *ftest-only

src/tests/suite/daos_rebuild_interactive.c:
test-tag: test_daos_rebuild_interactive
<<: *ftest-only

src/tests/suite/daos_rebuild_simple.c:
test-tag: test_daos_rebuild_simple
<<: *ftest-only

src/tests/suite/daos_upgrade.c:
test-tag: test_daos_upgrade
<<: *ftest-only

src/tests/suite/daos_verify_consistency.c:
test-tag: test_daos_verify_consistency
<<: *ftest-only

src/tests/suite/dfs_par_test.c:
test-tag: test_daos_dfs_parallel
<<: *ftest-only

src/tests/suite/dfs_sys_unit_test.c:
test-tag: test_daos_dfs_sys
<<: *ftest-only

src/tests/suite/dfs_test.c:
test-tag: dfs_test
<<: *ftest-only

src/tests/suite/dfs_unit_test.c:
test-tag: test_daos_dfs_unit
<<: *ftest-only

src/tests/suite/dfuse_test.c:
test-tag: DaosCoreTestDfuse
<<: *ftest-only

# Run all daos_test for common daos_test files
src/tests/suite/:
test-tag: daos_test
<<: *ftest-only


# Individual code areas
src/client/dfs/:
Expand Down
78 changes: 35 additions & 43 deletions ci/gen_commit_pragmas.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,18 +150,22 @@ def read_commit_pragma_mapping():
raise TypeError(
f'Expected {bool} for val, not '
f'{type(config[path_match][pragma_key]["val"])}')
elif pragma_key == 'stop_on_match':
if not isinstance(pragma_config, bool):
raise TypeError(f'Expected {bool} for stop_on_match, not {type(pragma_config)}')
else:
raise ValueError(f'Invalid pragma key: {pragma_key}')

return config


def __get_test_tag(test_tag_config, paths):
def __get_test_tag(commit_pragma_mapping, paths, default='pr'):
"""Get the Test-tag pragma.

Args:
test_tag_config (dict): test-tag config. E.g. {path1: foo, path2: {tags: pr}}
commit_pragma_mapping (dict): full commit pragma mapping config
paths (list): paths to get tags for
default (str): default tag to use if a path does not have a test-tag config

Returns:
str: Test-tag pragma for these paths
Expand All @@ -172,58 +176,65 @@ def __get_test_tag(test_tag_config, paths):
all_tags = set()

for path in paths:
for _pattern, _config in test_tag_config.items():
for _pattern, config in commit_pragma_mapping.items():
if re.search(rf'{_pattern}', path):
if isinstance(_config, str):
_config = {
'tags': _config,
'handler': 'direct',
'stop_on_match': False
test_tag_config = config.get('test-tag', default)
if isinstance(test_tag_config, str):
test_tag_config = {
'tags': test_tag_config,
'handler': 'direct'
}
_handler = _config['handler']
_handler = test_tag_config['handler']
if _handler == 'FtestTagMap':
# Special ftest handling
try:
all_tags.update(ftest_tag_map.minimal_tags(path))
except KeyError:
# Use default from config
all_tags.update(_config['tags'].split(' '))
all_tags.update(test_tag_config['tags'].split(' '))
elif _handler == 'direct':
# Use direct tags from config
all_tags.update(_config['tags'].split(' '))
all_tags.update(test_tag_config['tags'].split(' '))
else:
raise ValueError(f'Invalid handler: {_config["handler"]}')
raise ValueError(f'Invalid handler: {test_tag_config["handler"]}')

if _config['stop_on_match']:
if test_tag_config.get('stop_on_match', config.get('stop_on_match', False)):
# Don't process further entries for this path
break

# Make sure the test-tag we get from the config are valid tags in ftest
ftest_unique_tags = ftest_tag_map.unique_tags()
invalid_tags = all_tags - ftest_unique_tags
if invalid_tags:
raise ValueError(f'test-tag does not match any tests: {", ".join(invalid_tags)}')

return ' '.join(sorted(all_tags))


def __get_need_unit_test(need_unit_test_config, paths):
def __get_need_unit_test(commit_pragma_mapping, paths, default=True):
"""Determine whether we need to run unit tests for these paths.

Args:
need_unit_test_config (dict): need-unit-test config. E.g. {path1: True, path2: False}
commit_pragma_mapping (dict): full commit pragma mapping config
paths (list): paths to match on
default (bool): default value to use if a path does not have a need-unit-test config

Returns:
bool: whether we need to run unit tests for these paths
"""
for path in paths:
for _pattern, _config in need_unit_test_config.items():
for _pattern, config in commit_pragma_mapping.items():
if re.search(rf'{_pattern}', path):
if isinstance(_config, bool):
_config = {
'val': _config,
'stop_on_match': False
unit_test_config = config.get('need-unit-test', default)
if isinstance(unit_test_config, bool):
unit_test_config = {
'val': unit_test_config
}
if _config['val']:
if unit_test_config['val']:
# If any path matches with a True value, we need to run unit tests
return True

if _config['stop_on_match']:
if unit_test_config.get('stop_on_match', config.get('stop_on_match', False)):
# Don't process further entries for this path
break

Expand Down Expand Up @@ -254,30 +265,11 @@ def gen_commit_pragmas(target):

commit_pragma_mapping = read_commit_pragma_mapping()

def __pragma_config(pragma_key, default):
"""Return the configs for a single pragma key.

Args:
pragma_key (str): key to get for each path. E.g. 'test-tag'
default (obj): default value if a path does not have the key

Returns:
dict: each path mapping to its pragma_key value

For example:
config = {path: {test-tag: tag_config}}
__pragma_config('test-tag', default) -> {path: tag_config}
"""
return {
path_match: path_config.get(pragma_key, default)
for path_match, path_config in commit_pragma_mapping.items()
}

test_tag = __get_test_tag(__pragma_config('test-tag', 'pr'), modified_files)
test_tag = __get_test_tag(commit_pragma_mapping, modified_files)
if test_tag:
pragmas['Test-tag'] = test_tag

need_unit_test = __get_need_unit_test(__pragma_config('need-unit-test', True), modified_files)
need_unit_test = __get_need_unit_test(commit_pragma_mapping, modified_files)
if modified_files and not need_unit_test:
pragmas['Skip-unit-tests'] = True
pragmas['Skip-fault-injection-test'] = True
Expand Down
Loading