diff --git a/.github/workflows/webviz.yml b/.github/workflows/webviz.yml index 6192c2853..728685514 100644 --- a/.github/workflows/webviz.yml +++ b/.github/workflows/webviz.yml @@ -93,10 +93,10 @@ jobs: bandit --recursive src/ mypy src/ tests/ - # - name: 🤖 Run tests - # working-directory: ./backend - # run: | - # pytest ./tests + - name: 🤖 Run tests + working-directory: ./backend + run: | + pytest ./tests/unit build_docker_images: runs-on: ubuntu-latest diff --git a/backend/src/services/sumo_access/queries/parameters.py b/backend/src/services/sumo_access/queries/parameters.py index 37805a608..f1b8e94bf 100644 --- a/backend/src/services/sumo_access/queries/parameters.py +++ b/backend/src/services/sumo_access/queries/parameters.py @@ -5,7 +5,7 @@ class SumoEnsembleParameter(BaseModel): name: str - groupname: Optional[str] + groupname: Optional[str] = None values: Union[List[float], List[int], List[str]] realizations: List[int] diff --git a/backend/tests/integration/services/conftest.py b/backend/tests/integration/services/conftest.py new file mode 100644 index 000000000..f29f4599c --- /dev/null +++ b/backend/tests/integration/services/conftest.py @@ -0,0 +1,18 @@ +import os + +import pytest +from sumo.wrapper import SumoClient + + +@pytest.fixture(name="sumo_token") +def fixture_sumo_token() -> str: + token = os.getenv("SUMO_TOKEN") + if token is None: + client = SumoClient(env="dev") + token = client.authenticate() + return token + + +@pytest.fixture(name="sumo_case_uuid") +def fixture_sumo_case_uuid() -> str: + return "10f41041-2c17-4374-a735-bb0de62e29dc" diff --git a/backend/tests/integration/services/sumo_access/test_parameter_access.py b/backend/tests/integration/services/sumo_access/test_parameter_access.py new file mode 100644 index 000000000..49802e0e2 --- /dev/null +++ b/backend/tests/integration/services/sumo_access/test_parameter_access.py @@ -0,0 +1,19 @@ +import pytest + +from services.sumo_access.parameter_access import ParameterAccess + + +@pytest.fixture(name="parameter_access_instance") +def get_parameter_access_instance(sumo_token: str, sumo_case_uuid: str) -> ParameterAccess: + return ParameterAccess(sumo_token, sumo_case_uuid, "iter-0") + + +def test_init(parameter_access_instance: ParameterAccess, sumo_case_uuid: str) -> None: + assert len(parameter_access_instance.case_collection) == 1 + assert parameter_access_instance.case_collection[0].uuid == sumo_case_uuid + + +def test_get_parameters_and_sensitivities(parameter_access_instance: ParameterAccess) -> None: + parameters_and_sensitivities = parameter_access_instance.get_parameters_and_sensitivities() + assert len(parameters_and_sensitivities.parameters) == 113 + assert len(parameters_and_sensitivities.sensitivities) == 1 diff --git a/backend/tests/unit/__init__.py b/backend/tests/unit/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/backend/tests/unit/services/__init__.py b/backend/tests/unit/services/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/backend/tests/unit/services/sumo_access/test_parameter_access_helpers.py b/backend/tests/unit/services/sumo_access/test_parameter_access_helpers.py new file mode 100644 index 000000000..f13f834f7 --- /dev/null +++ b/backend/tests/unit/services/sumo_access/test_parameter_access_helpers.py @@ -0,0 +1,126 @@ +from typing import List, Dict, Union +import pytest + +import pandas as pd +from services.sumo_access.parameter_access import ( + create_ensemble_parameter, + create_ensemble_sensitivities, + find_sensitivity_type, + create_ensemble_sensitivity_cases, +) +from services.sumo_access.parameter_types import ( + EnsembleParameter, + EnsembleSensitivity, + EnsembleSensitivityCase, + SensitivityType, +) + +from services.sumo_access.queries.parameters import SumoEnsembleParameter + + +@pytest.mark.parametrize( + "sumo_param_input, expected_output", + [ + ( + SumoEnsembleParameter( + name="LOG10_PARAM", groupname="group1", values=[1.0, 1.0, 1.0], realizations=[0, 1, 2] + ), + EnsembleParameter( + name="LOG10_PARAM", + is_logarithmic=True, + is_numerical=True, + is_constant=True, + group_name="group1", + descriptive_name="LOG10_PARAM (log)", + values=[1.0, 1.0, 1.0], + realizations=[0, 1, 2], + ), + ), + ( + SumoEnsembleParameter(name="PARAM", values=[1.0, 2.0, 3.0], realizations=[0, 1, 2]), + EnsembleParameter( + name="PARAM", + is_logarithmic=False, + is_numerical=True, + is_constant=False, + group_name=None, + descriptive_name="PARAM", + values=[1.0, 2.0, 3.0], + realizations=[0, 1, 2], + ), + ), + ], +) +def test_create_ensemble_parameter(sumo_param_input: SumoEnsembleParameter, expected_output: EnsembleParameter) -> None: + ensemble_param = create_ensemble_parameter(sumo_param_input) + assert ensemble_param == expected_output + + +@pytest.mark.parametrize( + "sumo_param_input, expected_output", + [ + ( + [ + SumoEnsembleParameter( + name="SENSNAME", groupname=None, values=["SENS_A", "SENS_B", "SENS_B"], realizations=[0, 1, 2] + ), + SumoEnsembleParameter( + name="SENSCASE", groupname=None, values=["p10_p90", "low", "high"], realizations=[0, 1, 2] + ), + ], + [ + EnsembleSensitivity( + name="SENS_A", + type=SensitivityType.MONTECARLO, + cases=[EnsembleSensitivityCase(name="p10_p90", realizations=[0])], + ), + EnsembleSensitivity( + name="SENS_B", + type=SensitivityType.SCENARIO, + cases=[ + EnsembleSensitivityCase(name="high", realizations=[2]), + EnsembleSensitivityCase(name="low", realizations=[1]), + ], + ), + ], + ), + ], +) +def test_create_ensemble_sensitivities( + sumo_param_input: SumoEnsembleParameter, expected_output: EnsembleParameter +) -> None: + sensitivities = create_ensemble_sensitivities(sumo_param_input) + + assert sensitivities == expected_output + + +@pytest.mark.parametrize( + "sens_case_names, expected_output", + [ + (["p10_p90"], SensitivityType.MONTECARLO), + (["case1", "case2"], SensitivityType.SCENARIO), + ], +) +def test_find_sensitivity_type(sens_case_names: List[str], expected_output: SensitivityType) -> None: + assert find_sensitivity_type(sens_case_names) == expected_output + + +@pytest.mark.parametrize( + "sens_case_input, expected_output", + [ + ( + {"case": ["case1", "case1", "case2", "case2"], "REAL": [0, 1, 2, 3]}, + [ + EnsembleSensitivityCase(name="case1", realizations=[0, 1]), + EnsembleSensitivityCase(name="case2", realizations=[2, 3]), + ], + ), + ], +) +def test_create_ensemble_sensitivity_cases( + sens_case_input: Dict[str, list[Union[str, float]]], expected_output: List[EnsembleSensitivityCase] +) -> None: + df = pd.DataFrame(sens_case_input) + cases = create_ensemble_sensitivity_cases(df) + + assert cases == expected_output