diff --git a/.vscode/settings.json b/.vscode/settings.json index c79e8b8e..6d4e71b6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,4 +10,5 @@ "python.testing.cwd": "${workspaceFolder}", "python.testing.pytestEnabled": true, "python.testing.unittestEnabled": false, + "python.defaultInterpreterPath": ".venv/bin/python", } diff --git a/src/data_factory_testing_framework/models/_pipeline.py b/src/data_factory_testing_framework/models/_pipeline.py index e3518188..27527c64 100644 --- a/src/data_factory_testing_framework/models/_pipeline.py +++ b/src/data_factory_testing_framework/models/_pipeline.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, List +from typing import TYPE_CHECKING, Any, List, Union from data_factory_testing_framework.exceptions import ActivityNotFoundError @@ -79,10 +79,25 @@ def validate_and_append_default_parameters(self, parameters: List[RunParameter]) return parameters + def _get_default_value_for_variable(self, variable_value: dict[str, Any]) -> Union[str, int, bool, List[Any]]: + """Get the default value of a variable.""" + if variable_value["type"] == "String": + return variable_value.get("defaultValue", "") + elif variable_value["type"] == "Integer": + return variable_value.get("defaultValue", 0) + elif variable_value["type"] == "Boolean": + return variable_value.get("defaultValue", False) + elif variable_value["type"] == "Array": + return variable_value.get("defaultValue", []) + else: + raise NotImplementedError(f"Type {variable_value['type']} not implemented") + def get_run_variables(self) -> List[PipelineRunVariable]: """Get the run variables for the pipeline. This can be used to generate the instance variables for a pipeline run.""" run_variables = [] for variable_name, variable_value in self.variables.items(): - run_variables.append(PipelineRunVariable(variable_name, variable_value.get("default_value", None))) + run_variables.append( + PipelineRunVariable(variable_name, self._get_default_value_for_variable(variable_value)) + ) return run_variables diff --git a/tests/functional/variables_default_value/pipeline/default_variables.json b/tests/functional/variables_default_value/pipeline/default_variables.json new file mode 100644 index 00000000..a280ad50 --- /dev/null +++ b/tests/functional/variables_default_value/pipeline/default_variables.json @@ -0,0 +1,114 @@ +{ + "name": "default_variables", + "properties": { + "activities": [ + { + "name": "Set outputStringVar", + "type": "SetVariable", + "dependsOn": [], + "policy": { + "secureOutput": false, + "secureInput": false + }, + "userProperties": [], + "typeProperties": { + "variableName": "pipelineReturnValue", + "value": [ + { + "key": "outputStringVar", + "value": { + "type": "Expression", + "content": "@if(equals(variables('stringVar'), null), 'is null', concat('is not null: ', variables('stringVar')))\n" + } + } + ], + "setSystemVariable": true + } + }, + { + "name": "Set outputIntVar", + "type": "SetVariable", + "dependsOn": [], + "policy": { + "secureOutput": false, + "secureInput": false + }, + "userProperties": [], + "typeProperties": { + "variableName": "pipelineReturnValue", + "value": [ + { + "key": "outputIntVar", + "value": { + "type": "Expression", + "content": "@if(equals(variables('intVar'), null), 'is null', concat('is not null: ', variables('intVar')))\n" + } + } + ], + "setSystemVariable": true + } + }, + { + "name": "Set outputBoolVar", + "type": "SetVariable", + "dependsOn": [], + "policy": { + "secureOutput": false, + "secureInput": false + }, + "userProperties": [], + "typeProperties": { + "variableName": "pipelineReturnValue", + "value": [ + { + "key": "outputBoolVar", + "value": { + "type": "Expression", + "content": "@if(equals(variables('boolVar'), null), 'is null', concat('is not null: ', variables('boolVar')))\n" + } + } + ], + "setSystemVariable": true + } + }, + { + "name": "Set outputArrayVar", + "type": "SetVariable", + "dependsOn": [], + "policy": { + "secureOutput": false, + "secureInput": false + }, + "userProperties": [], + "typeProperties": { + "variableName": "pipelineReturnValue", + "value": [ + { + "key": "outputArrayVar", + "value": { + "type": "Expression", + "content": "@if(equals(variables('arrayVar'), null), 'is null', concat('is not null: ', variables('arrayVar')))\n" + } + } + ], + "setSystemVariable": true + } + } + ], + "variables": { + "stringVar": { + "type": "String" + }, + "intVar": { + "type": "Integer" + }, + "boolVar": { + "type": "Boolean" + }, + "arrayVar": { + "type": "Array" + } + }, + "annotations": [] + } +} diff --git a/tests/functional/variables_default_value/test_variables_default.py b/tests/functional/variables_default_value/test_variables_default.py new file mode 100644 index 00000000..6d5cec81 --- /dev/null +++ b/tests/functional/variables_default_value/test_variables_default.py @@ -0,0 +1,40 @@ +import pytest +from data_factory_testing_framework import TestFramework, TestFrameworkType + + +def test_string_default_variables(request: pytest.FixtureRequest) -> None: + # Arrange + test_framework = TestFramework( + framework_type=TestFrameworkType.DataFactory, root_folder_path=request.fspath.dirname + ) + pipeline = test_framework.get_pipeline_by_name("default_variables") + + # Act + activities = test_framework.evaluate_pipeline( + pipeline, + [], + ) + + # Assert + activity = next(activities) + assert activity.name == "Set outputStringVar" + assert activity.type_properties["value"][0]["key"] == "outputStringVar" + assert activity.type_properties["value"][0]["value"].result == "is not null: " + + activity = next(activities) + assert activity.name == "Set outputIntVar" + assert activity.type_properties["value"][0]["key"] == "outputIntVar" + assert activity.type_properties["value"][0]["value"].result == "is not null: 0" + + activity = next(activities) + assert activity.name == "Set outputBoolVar" + assert activity.type_properties["value"][0]["key"] == "outputBoolVar" + assert activity.type_properties["value"][0]["value"].result == "is not null: False" + + activity = next(activities) + assert activity.name == "Set outputArrayVar" + assert activity.type_properties["value"][0]["key"] == "outputArrayVar" + assert activity.type_properties["value"][0]["value"].result == "is not null: []" + + with pytest.raises(StopIteration): + next(activities) diff --git a/tests/unit/models/pipelines/test_pipeline_resource.py b/tests/unit/models/pipelines/test_pipeline_resource.py index a8e05f97..a07b8444 100644 --- a/tests/unit/models/pipelines/test_pipeline_resource.py +++ b/tests/unit/models/pipelines/test_pipeline_resource.py @@ -41,6 +41,92 @@ def test_when_validate_parameters_is_accurate_should_pass() -> None: assert parameters[2].value == "pipelineParameterValue3" +@pytest.mark.parametrize( + ("variable_spec", "expected_value"), + [ + ( + { + "type": "String", + "defaultValue": "stringDefault", + }, + "stringDefault", + ), + ( + { + "type": "String", + }, + "", + ), + ( + { + "type": "String", + "defaultValue": "", + }, + "", + ), + ( + { + "type": "Boolean", + "defaultValue": True, + }, + True, + ), + ( + { + "type": "Boolean", + }, + False, + ), + ( + { + "type": "Integer", + "defaultValue": 1, + }, + 1, + ), + ( + { + "type": "Integer", + }, + 0, + ), + ( + { + "type": "Array", + "defaultValue": ["a", "b"], + }, + ["a", "b"], + ), + ( + { + "type": "Array", + }, + [], + ), + ], +) +def test_when_get_run_variables_default_values_should_be_used( + variable_spec: dict[str, str], expected_value: object +) -> None: + # Arrange + pipeline = Pipeline( + pipeline_id="some-id", + name="pipeline", + activities=[], + variables={ + "variable": variable_spec, + }, + ) + + # Act + variables = pipeline.get_run_variables() + + # Assert + assert len(variables) == 1 + assert variables[0].name == "variable" + assert variables[0].value == expected_value + + def test_when_validate_parameters_is_missing_run_parameter_should_throw_error() -> None: # Arrange pipeline = Pipeline(