Skip to content

Commit

Permalink
test: introduce yaml builders
Browse files Browse the repository at this point in the history
Remove minimal model case
  • Loading branch information
jsolaas committed Nov 6, 2024
1 parent c13ae30 commit 75a73a8
Show file tree
Hide file tree
Showing 10 changed files with 493 additions and 137 deletions.
1 change: 0 additions & 1 deletion src/libecalc/fixtures/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from .cases.consumer_with_time_slots_models import * # noqa: F403
from .cases.ltp_export import ltp_export_yaml
from .cases.ltp_export.ltp_power_from_shore_yaml import ltp_pfs_yaml_factory
from .cases.minimal import * # noqa: F403
from .compressor_process_simulations.compressor_process_simulations import * # noqa: F403
from .conftest import (
fuel_gas,
Expand Down
2 changes: 0 additions & 2 deletions src/libecalc/fixtures/cases/minimal/__init__.py

This file was deleted.

66 changes: 0 additions & 66 deletions src/libecalc/fixtures/cases/minimal/minimal_dto.py

This file was deleted.

39 changes: 0 additions & 39 deletions src/libecalc/fixtures/cases/minimal/minimal_yaml.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from libecalc.presentation.yaml.yaml_types.time_series.yaml_time_series import (
YamlTimeSeriesCollection,
)
from libecalc.presentation.yaml.yaml_types.yaml_default_datetime import YamlDefaultDatetime
from libecalc.presentation.yaml.yaml_types.yaml_variable import (
YamlVariable,
YamlVariableReferenceId,
Expand Down Expand Up @@ -437,12 +438,12 @@ def installations(self) -> Iterable[YamlInstallation]:
@property
def start(self) -> Optional[datetime.datetime]:
start_value = self._internal_datamodel.get(EcalcYamlKeywords.start)
return convert_date_to_datetime(start_value) if start_value is not None else None
return TypeAdapter(YamlDefaultDatetime).validate_python(start_value) if start_value is not None else None

@property
def end(self) -> Optional[datetime.datetime]:
end_value = self._internal_datamodel.get(EcalcYamlKeywords.end)
return convert_date_to_datetime(end_value) if end_value is not None else None
return TypeAdapter(YamlDefaultDatetime).validate_python(end_value) if end_value is not None else None

@property
def dates(self):
Expand Down
4 changes: 3 additions & 1 deletion src/libecalc/presentation/yaml/yaml_types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@

class YamlBase(BaseModel, ABC):
model_config = ConfigDict(
populate_by_name=True, alias_generator=lambda field_name: field_name.upper(), extra="forbid"
populate_by_name=True,
alias_generator=lambda field_name: field_name.upper(),
extra="forbid",
)
108 changes: 107 additions & 1 deletion src/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import json
from io import StringIO
from pathlib import Path
from typing import cast

import pytest
import yaml

from libecalc.common.math.numbers import Numbers
from libecalc.examples import advanced, simple
Expand All @@ -11,6 +14,16 @@
consumer_system_v2,
ltp_export,
)
from libecalc.presentation.yaml.configuration_service import ConfigurationService
from libecalc.presentation.yaml.yaml_entities import ResourceStream
from libecalc.presentation.yaml.yaml_models.yaml_model import ReaderType, YamlConfiguration, YamlValidator
from libecalc.presentation.yaml.yaml_types.components.yaml_asset import YamlAsset
from tests.libecalc.yaml_builder import (
YamlAssetBuilder,
YamlEnergyUsageModelDirectBuilder,
YamlFuelConsumerBuilder,
YamlInstallationBuilder,
)


def _round_floats(obj):
Expand Down Expand Up @@ -44,7 +57,6 @@ def rounded_snapshot(data: dict, snapshot_name: str):
"consumer_system_v2": (Path(consumer_system_v2.__file__).parent / "data" / "consumer_system_v2.yaml").absolute(),
}


# The value should be the name of a fixture returning the YamlCase for the example
valid_example_yaml_case_fixture_names = {
"simple": "simple_yaml",
Expand Down Expand Up @@ -110,3 +122,97 @@ def valid_example_case_yaml_case(request) -> YamlCase:
"""
yaml_case = request.getfixturevalue(request.param[1])
return yaml_case


class YamlAssetConfigurationService(ConfigurationService):
def __init__(self, model: YamlAsset, name: str):
self._name = name
self._model = model
self._source = None

@property
def name(self):
return self._name

@property
def source(self):
return self.get_yaml()

def get_yaml(self) -> str:
if self._source is not None:
return self._source
data = self._model.model_dump(by_alias=True, exclude_unset=True, mode="json")
return yaml.dump(data)

def get_configuration(self) -> YamlValidator:
stream = ResourceStream(name=self._name, stream=StringIO(self.get_yaml()))
main_yaml_model = YamlConfiguration.Builder.get_yaml_reader(ReaderType.PYYAML).read(
main_yaml=stream,
enable_include=True,
)
return cast(YamlValidator, main_yaml_model)


@pytest.fixture
def yaml_asset_configuration_service_factory():
def yaml_asset_configuration_service(model: YamlAsset, name: str):
return YamlAssetConfigurationService(model=model, name=name)

return yaml_asset_configuration_service


@pytest.fixture
def yaml_asset_builder_factory():
return lambda: YamlAssetBuilder()


@pytest.fixture
def yaml_installation_builder_factory():
return lambda: YamlInstallationBuilder()


@pytest.fixture
def minimal_installation_yaml_factory(yaml_installation_builder_factory):
def minimal_installation_yaml(
name: str = "DefaultInstallation",
consumer_name: str = "flare",
fuel_name: str = "fuel",
fuel_rate: int | str = 50,
):
return (
yaml_installation_builder_factory()
.with_test_data()
.with_name(name)
.with_fuel_consumers(
[
YamlFuelConsumerBuilder()
.with_test_data()
.with_name(consumer_name)
.with_fuel(fuel_name)
.with_energy_usage_model(
YamlEnergyUsageModelDirectBuilder().with_test_data().with_fuel_rate(fuel_rate).build()
)
.build()
]
)
.build()
)

return minimal_installation_yaml


@pytest.fixture
def minimal_model_yaml_factory(minimal_installation_yaml_factory):
def minimal_model_yaml(fuel_rate: int | str = 50):
fuel_name = "fuel"
installation = minimal_installation_yaml_factory(fuel_name="fuel", fuel_rate=fuel_rate)
model = (
YamlAssetBuilder()
.with_test_data(fuel_name=fuel_name)
.with_installations([installation])
.with_start("2020-01-01")
.with_end("2023-01-01")
)
return YamlAssetConfigurationService(model.build(), name="minimal_model")

return minimal_model_yaml
32 changes: 20 additions & 12 deletions src/tests/libecalc/integration/test_minimal_is_valid.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,41 @@
from datetime import datetime

import pytest

from libecalc.application.energy_calculator import EnergyCalculator
from libecalc.application.graph_result import GraphResult
from libecalc.common.variables import VariablesMap
from libecalc.common.time_utils import Frequency
from libecalc.presentation.json_result.mapper import get_asset_result
from libecalc.presentation.json_result.result import EcalcModelResult
from libecalc.presentation.yaml.model import YamlModel
from libecalc.presentation.yaml.resource import Resource
from libecalc.presentation.yaml.resource_service import ResourceService
from libecalc.presentation.yaml.yaml_models.yaml_model import YamlValidator


class EmptyResourceService(ResourceService):
def get_resources(self, configuration: YamlValidator) -> dict[str, Resource]:
return {}


@pytest.fixture
def minimal_asset_result(minimal_model_dto_factory):
minimal_dto = minimal_model_dto_factory()
graph = minimal_dto.get_graph()
variables = VariablesMap(
time_vector=[datetime(2020, 1, 1), datetime(2022, 1, 1)],
variables={},
def minimal_asset_result(minimal_model_yaml_factory):
minimal_configuration_service = minimal_model_yaml_factory()
model = YamlModel(
configuration_service=minimal_configuration_service,
resource_service=EmptyResourceService(),
output_frequency=Frequency.NONE,
)
graph = model.get_graph()
energy_calculator = EnergyCalculator(graph=graph)
consumer_results = energy_calculator.evaluate_energy_usage(variables)
consumer_results = energy_calculator.evaluate_energy_usage(model.variables)
emission_results = energy_calculator.evaluate_emissions(
variables_map=variables,
variables_map=model.variables,
consumer_results=consumer_results,
)
return get_asset_result(
GraphResult(
graph=graph,
consumer_results=consumer_results,
variables_map=variables,
variables_map=model.variables,
emission_results=emission_results,
)
)
Expand Down
Loading

0 comments on commit 75a73a8

Please sign in to comment.