From 8bdf08c15dd28b85c5a23297a0261ceb33370ec5 Mon Sep 17 00:00:00 2001 From: Russell Date: Thu, 18 Nov 2021 23:47:16 -0500 Subject: [PATCH] enforce unique application step names (#105) --- foodx_devops_tools/pipeline_config/frames.py | 21 ++++++++++++++++ .../unit_tests/pipeline_config/test_frames.py | 25 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/foodx_devops_tools/pipeline_config/frames.py b/foodx_devops_tools/pipeline_config/frames.py index 4653d41..7e3a184 100644 --- a/foodx_devops_tools/pipeline_config/frames.py +++ b/foodx_devops_tools/pipeline_config/frames.py @@ -71,6 +71,27 @@ class ApplicationDefinition(pydantic.BaseModel): depends_on: typing.Optional[DependencyDeclarations] steps: ApplicationDeploymentSteps + @pydantic.validator("steps") + def check_applications( + cls: pydantic.BaseModel, steps_candidate: ApplicationDeploymentSteps + ) -> ApplicationDeploymentSteps: + """Validate ``steps`` field.""" + step_names: typing.List[str] = [ + x.name + for x in steps_candidate + if not isinstance(x, ApplicationStepDelay) + ] + if len(step_names) != len(set(step_names)): + message = "Application step names must be unique, {0}".format( + str(step_names) + ) + # log the message here because pydantic exception handling + # masks the true exception that caused a validation failure. + log.error(message) + raise ValueError(message) + + return steps_candidate + ApplicationDeclarations = typing.Dict[str, ApplicationDefinition] diff --git a/tests/ci/unit_tests/pipeline_config/test_frames.py b/tests/ci/unit_tests/pipeline_config/test_frames.py index cb26097..6070e41 100644 --- a/tests/ci/unit_tests/pipeline_config/test_frames.py +++ b/tests/ci/unit_tests/pipeline_config/test_frames.py @@ -458,6 +458,31 @@ def test_bad_dependency_raises(apply_applications_test): apply_applications_test(file_text) +def test_duplicate_step_names_raises(apply_applications_test): + file_text = """--- +frames: + frames: + f1: + applications: + a1: + steps: + - arm_file: something.json + mode: Incremental + name: same_name + resource_group: a1_group + - arm_file: something_else.json + mode: Incremental + name: same_name + resource_group: other_group + folder: some/f2-path +""" + + with pytest.raises( + FrameDefinitionsError, match=r"Application step names must be unique" + ): + apply_applications_test(file_text) + + def test_missing_name_raises(apply_applications_test): file_text = """--- frames: