Guard that the given repository occurs in config exactly once.

This commit is contained in:
Dan Helfman 2019-02-18 12:58:39 -08:00
parent 2a4d4247e3
commit 766a03375a
4 changed files with 70 additions and 11 deletions

View File

@ -403,8 +403,7 @@ def collect_configuration_run_summary_logs(config_filenames, args):
)
yield logging.makeLogRecord(dict(levelno=logging.CRITICAL, msg=error))
# TODO: What to do if the given repository doesn't match any configured repositories (across all config
# files)? Where to validate and error on that?
validate.guard_configuration_contains_repository(args.repository, configs)
for config_filename, config in configs.items():
try:

View File

@ -107,3 +107,29 @@ def parse_configuration(config_filename, schema_filename):
apply_logical_validation(config_filename, parsed_result)
return parsed_result
def guard_configuration_contains_repository(repository, configurations):
'''
Given a repository path and a dict mapping from config filename to corresponding parsed config
dict, ensure that the repository is declared exactly once in all of the configurations.
Raise ValueError if the repository is not found in a configuration, or is declared multiple
times.
'''
if not repository:
return
count = len(
tuple(
config_repository
for config in configurations.values()
for config_repository in config['repositories']
if repository == config_repository
)
)
if count == 0:
raise ValueError('Repository {} not found in configuration files'.format(repository))
if count > 1:
raise ValueError('Repository {} found in multiple configuration files'.format(repository))

View File

@ -49,38 +49,42 @@ def test_run_commands_handles_multiple_json_outputs_in_array():
def test_collect_configuration_run_summary_logs_info_for_success():
flexmock(module.validate).should_receive('parse_configuration').and_return({'test.yaml': {}})
flexmock(module.validate).should_receive('guard_configuration_contains_repository')
flexmock(module).should_receive('run_configuration')
args = flexmock(repository=None)
logs = tuple(module.collect_configuration_run_summary_logs(('test.yaml',), args=()))
logs = tuple(module.collect_configuration_run_summary_logs(('test.yaml',), args=args))
assert any(log for log in logs if log.levelno == module.logging.INFO)
def test_collect_configuration_run_summary_logs_critical_for_parse_error():
flexmock(module.validate).should_receive('parse_configuration').and_raise(ValueError)
flexmock(module).should_receive('run_configuration')
flexmock(module.validate).should_receive('guard_configuration_contains_repository')
args = flexmock(repository=None)
logs = tuple(module.collect_configuration_run_summary_logs(('test.yaml',), args=()))
logs = tuple(module.collect_configuration_run_summary_logs(('test.yaml',), args=args))
assert any(log for log in logs if log.levelno == module.logging.CRITICAL)
def test_collect_configuration_run_summary_logs_critical_for_run_error():
flexmock(module.validate).should_receive('parse_configuration').and_return({'test.yaml': {}})
flexmock(module.validate).should_receive('guard_configuration_contains_repository')
flexmock(module).should_receive('run_configuration').and_raise(ValueError)
args = flexmock(repository=None)
logs = tuple(module.collect_configuration_run_summary_logs(('test.yaml',), args=()))
logs = tuple(module.collect_configuration_run_summary_logs(('test.yaml',), args=args))
assert any(log for log in logs if log.levelno == module.logging.CRITICAL)
def test_collect_configuration_run_summary_logs_critical_for_missing_configs():
flexmock(module.validate).should_receive('parse_configuration').and_return({'test.yaml': {}})
flexmock(module.validate).should_receive('guard_configuration_contains_repository')
flexmock(module).should_receive('run_configuration')
args = flexmock(config_paths=(), repository=None)
logs = tuple(
module.collect_configuration_run_summary_logs(
config_filenames=(), args=flexmock(config_paths=())
)
)
logs = tuple(module.collect_configuration_run_summary_logs(config_filenames=(), args=args))
assert any(log for log in logs if log.levelno == module.logging.CRITICAL)

View File

@ -90,3 +90,33 @@ def test_apply_logical_validation_does_not_raise_or_warn_if_archive_name_format_
def test_apply_logical_validation_does_not_raise_otherwise():
module.apply_logical_validation('config.yaml', {'retention': {'keep_secondly': 1000}})
def test_guard_configuration_contains_repository_does_not_raise_when_repository_in_config():
module.guard_configuration_contains_repository(
repository='repo', configurations={'config.yaml': {'repositories': ['repo']}}
)
def test_guard_configuration_contains_repository_does_not_raise_when_repository_not_given():
module.guard_configuration_contains_repository(
repository=None, configurations={'config.yaml': {'repositories': ['repo']}}
)
def test_guard_configuration_contains_repository_errors_when_repository_missing_from_config():
with pytest.raises(ValueError):
module.guard_configuration_contains_repository(
repository='nope', configurations={'config.yaml': {'repositories': ['repo', 'repo2']}}
)
def test_guard_configuration_contains_repository_errors_when_repository_matches_config_twice():
with pytest.raises(ValueError):
module.guard_configuration_contains_repository(
repository='repo',
configurations={
'config.yaml': {'repositories': ['repo', 'repo2']},
'other.yaml': {'repositories': ['repo']},
},
)