From 675759f8fde26f63fcce18fe1521d6a5a21d76d1 Mon Sep 17 00:00:00 2001
From: Hatim Dinia <33469289+hdinia@users.noreply.github.com>
Date: Wed, 4 Sep 2024 11:01:18 +0200
Subject: [PATCH 1/2] fix(ui): add missing `i18n` key and styles on `EmptyView`
(#2127)
---
webapp/src/components/common/MatrixInput/index.tsx | 2 +-
webapp/src/components/common/page/SimpleContent.tsx | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/webapp/src/components/common/MatrixInput/index.tsx b/webapp/src/components/common/MatrixInput/index.tsx
index c48e67d508..d035a94cce 100644
--- a/webapp/src/components/common/MatrixInput/index.tsx
+++ b/webapp/src/components/common/MatrixInput/index.tsx
@@ -183,7 +183,7 @@ function MatrixInput({
isPercentDisplayEnabled={enablePercentDisplay}
/>
) : (
- !isLoading &&
+ !isLoading &&
)}
{openImportDialog && (
diff --git a/webapp/src/components/common/page/SimpleContent.tsx b/webapp/src/components/common/page/SimpleContent.tsx
index 6be0cd51b0..03c8525eec 100644
--- a/webapp/src/components/common/page/SimpleContent.tsx
+++ b/webapp/src/components/common/page/SimpleContent.tsx
@@ -16,6 +16,7 @@ function EmptyView(props: EmptyViewProps) {
Date: Wed, 4 Sep 2024 13:53:40 +0200
Subject: [PATCH 2/2] ci(test): parallel pytest execution (#2133)
Enable the use of pytest-xdist to run tests in parallel, in CI
or developer env.
Following issues with parallel execution of tests are solved :
- some checks depended on the consistency at 2 moments in time of the
result of disk_usage, which was anyway not a good idea (dependent on
what happens elsewhere on the machine). It's now replaced with mocking
- some parameterized tests had random sort order, which is not allowed
by pytest-xdist (all workers must have exactly the same tests in the
same order)
- the command_factory test checked something in its teardown, assuming
all tests were executed in the same process, which is not the case
anymore. The same check is done as a separate unit tests.
Possible remaining issue which could cause some timeouts:
some services hold FileLock which have the same identifier
accross multiple tests.
Signed-off-by: Sylvain Leclerc
---
.github/workflows/main.yml | 2 +-
requirements-test.txt | 4 +-
.../test_filesystem_endpoints.py | 26 +-
.../filesystem_blueprint/test_model.py | 13 +-
.../filesystem/config/test_utils.py | 4 +-
tests/variantstudy/test_command_factory.py | 766 +++++++++---------
6 files changed, 410 insertions(+), 405 deletions(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 5a7b9ad212..91523a511d 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -53,7 +53,7 @@ jobs:
pip install -r requirements-dev.txt
- name: Test with pytest
run: |
- pytest --cov antarest --cov-report xml
+ pytest --cov antarest --cov-report xml -n auto
- name: Archive code coverage results
if: matrix.os == 'ubuntu-20.04'
uses: actions/upload-artifact@v4
diff --git a/requirements-test.txt b/requirements-test.txt
index 8e408b2677..10a360d7f4 100644
--- a/requirements-test.txt
+++ b/requirements-test.txt
@@ -1,7 +1,9 @@
-r requirements.txt
checksumdir~=1.2.0
-pytest~=6.2.5
+pytest~=8.3.0
+pytest-xdist~=3.6.0
pytest-cov~=4.0.0
+pytest-mock~=3.14.0
# In this version DataFrame conversion to Excel is done using 'xlsxwriter' library.
# But Excel files reading is done using 'openpyxl' library, during testing only.
diff --git a/tests/integration/filesystem_blueprint/test_filesystem_endpoints.py b/tests/integration/filesystem_blueprint/test_filesystem_endpoints.py
index d1e344e73d..ac1e9a36ff 100644
--- a/tests/integration/filesystem_blueprint/test_filesystem_endpoints.py
+++ b/tests/integration/filesystem_blueprint/test_filesystem_endpoints.py
@@ -13,10 +13,10 @@
import datetime
import operator
import re
-import shutil
import typing as t
from pathlib import Path
+from pytest_mock import MockerFixture
from starlette.testclient import TestClient
from tests.integration.conftest import RESOURCES_DIR
@@ -93,6 +93,7 @@ def test_lifecycle(
client: TestClient,
user_access_token: str,
admin_access_token: str,
+ mocker: MockerFixture,
) -> None:
"""
Test the lifecycle of the filesystem endpoints.
@@ -102,7 +103,7 @@ def test_lifecycle(
caplog: pytest caplog fixture.
client: test client (tests.integration.conftest.client_fixture).
user_access_token: access token of a classic user (tests.integration.conftest.user_access_token_fixture).
- admin_access_token: access token of an admin user (tests.integration.conftest.admin_access_token_fixture).
+ admin_access_token: access token of an admin user (tests.integration.conftestin_access_token_fixture).
"""
# NOTE: all the following paths are based on the configuration defined in the app_fixture.
archive_dir = tmp_path / "archive_dir"
@@ -165,26 +166,25 @@ def test_lifecycle(
err_count += 1
# Known filesystem
+ mocker.patch("shutil.disk_usage", return_value=(100, 200, 300))
res = client.get("/v1/filesystem/ws", headers=user_headers)
assert res.status_code == 200, res.json()
actual = sorted(res.json(), key=operator.itemgetter("name"))
- # Both mount point are in the same filesystem, which is the `tmp_path` filesystem
- total_bytes, used_bytes, free_bytes = shutil.disk_usage(tmp_path)
expected = [
{
"name": "default",
"path": str(default_workspace),
- "total_bytes": total_bytes,
- "used_bytes": used_bytes,
- "free_bytes": free_bytes,
+ "total_bytes": 100,
+ "used_bytes": 200,
+ "free_bytes": 300,
"message": AnyDiskUsagePercent(),
},
{
"name": "ext",
"path": str(ext_workspace_path),
- "total_bytes": total_bytes,
- "used_bytes": used_bytes,
- "free_bytes": free_bytes,
+ "total_bytes": 100,
+ "used_bytes": 200,
+ "free_bytes": 300,
"message": AnyDiskUsagePercent(),
},
]
@@ -206,9 +206,9 @@ def test_lifecycle(
expected = {
"name": "default",
"path": str(default_workspace),
- "total_bytes": total_bytes,
- "used_bytes": used_bytes,
- "free_bytes": free_bytes,
+ "total_bytes": 100,
+ "used_bytes": 200,
+ "free_bytes": 300,
"message": AnyDiskUsagePercent(),
}
assert actual == expected
diff --git a/tests/integration/filesystem_blueprint/test_model.py b/tests/integration/filesystem_blueprint/test_model.py
index 2e4932dd9c..48742b499b 100644
--- a/tests/integration/filesystem_blueprint/test_model.py
+++ b/tests/integration/filesystem_blueprint/test_model.py
@@ -16,6 +16,8 @@
import shutil
from pathlib import Path
+from pytest_mock import MockerFixture
+
from antarest.core.filesystem_blueprint import FileInfoDTO, FilesystemDTO, MountPointDTO
@@ -63,15 +65,16 @@ def test_from_path__missing_file(self) -> None:
assert dto.free_bytes == 0
assert dto.message.startswith("N/A:"), dto.message
- def test_from_path__file(self, tmp_path: Path) -> None:
+ def test_from_path__file(self, tmp_path: Path, mocker: MockerFixture) -> None:
+ mocker.patch("shutil.disk_usage", return_value=(100, 200, 300))
+
name = "foo"
dto = asyncio.run(MountPointDTO.from_path(name, tmp_path))
- total_bytes, used_bytes, free_bytes = shutil.disk_usage(tmp_path)
assert dto.name == name
assert dto.path == tmp_path
- assert dto.total_bytes == total_bytes
- assert dto.used_bytes == used_bytes
- assert dto.free_bytes == free_bytes
+ assert dto.total_bytes == 100
+ assert dto.used_bytes == 200
+ assert dto.free_bytes == 300
assert re.fullmatch(r"\d+(?:\.\d+)?% used", dto.message), dto.message
diff --git a/tests/storage/repository/filesystem/config/test_utils.py b/tests/storage/repository/filesystem/config/test_utils.py
index 3fed1bc5ba..cf470df38f 100644
--- a/tests/storage/repository/filesystem/config/test_utils.py
+++ b/tests/storage/repository/filesystem/config/test_utils.py
@@ -33,12 +33,12 @@ def test_transform_name_to_id__valid_chars(name):
assert transform_name_to_id(name, lower=False) == name
-@pytest.mark.parametrize("name", set(string.punctuation) - set(VALID_CHARS))
+@pytest.mark.parametrize("name", sorted(set(string.punctuation) - set(VALID_CHARS)))
def test_transform_name_to_id__punctuation(name):
assert not transform_name_to_id(name)
-@pytest.mark.parametrize("name", set(string.whitespace) - set(VALID_CHARS))
+@pytest.mark.parametrize("name", sorted(set(string.whitespace) - set(VALID_CHARS)))
def test_transform_name_to_id__whitespace(name):
assert not transform_name_to_id(name)
diff --git a/tests/variantstudy/test_command_factory.py b/tests/variantstudy/test_command_factory.py
index f20985f808..b78ba393e5 100644
--- a/tests/variantstudy/test_command_factory.py
+++ b/tests/variantstudy/test_command_factory.py
@@ -13,6 +13,7 @@
import importlib
import itertools
import pkgutil
+from typing import List, Set
from unittest.mock import Mock
import pytest
@@ -25,18 +26,385 @@
from antarest.study.storage.variantstudy.model.command.icommand import ICommand
from antarest.study.storage.variantstudy.model.model import CommandDTO
+COMMANDS: List[CommandDTO] = [
+ CommandDTO(
+ action=CommandName.CREATE_AREA.value,
+ args={"area_name": "area_name"},
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_AREA.value,
+ args=[
+ {"area_name": "area_name"},
+ {"area_name": "area2"},
+ ],
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_AREA.value,
+ args={"id": "id"},
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_AREA.value,
+ args=[{"id": "id"}],
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_DISTRICT.value,
+ args={
+ "name": "id",
+ "filter_items": ["a"],
+ "output": True,
+ "comments": "",
+ },
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_DISTRICT.value,
+ args=[
+ {
+ "name": "id",
+ "base_filter": "add-all",
+ "output": True,
+ "comments": "",
+ }
+ ],
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_DISTRICT.value,
+ args={"id": "id"},
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_DISTRICT.value,
+ args=[{"id": "id"}],
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_LINK.value,
+ args={
+ "area1": "area1",
+ "area2": "area2",
+ "parameters": {},
+ "series": "series",
+ },
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_LINK.value,
+ args=[
+ {
+ "area1": "area1",
+ "area2": "area2",
+ "parameters": {},
+ "series": "series",
+ }
+ ],
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_LINK.value,
+ args={
+ "area1": "area1",
+ "area2": "area2",
+ },
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_LINK.value,
+ args=[
+ {
+ "area1": "area1",
+ "area2": "area2",
+ }
+ ],
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_BINDING_CONSTRAINT.value,
+ args={"name": "name"},
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_BINDING_CONSTRAINT.value,
+ args=[
+ {
+ "name": "name",
+ "enabled": True,
+ "time_step": "hourly",
+ "operator": "equal",
+ "values": "values",
+ "group": "group_1",
+ },
+ ],
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_BINDING_CONSTRAINT.value,
+ args={
+ "id": "id",
+ "enabled": True,
+ "time_step": "hourly",
+ "operator": "equal",
+ "values": "values",
+ },
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_BINDING_CONSTRAINT.value,
+ args=[
+ {
+ "id": "id",
+ "enabled": True,
+ "time_step": "hourly",
+ "operator": "equal",
+ }
+ ],
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_BINDING_CONSTRAINT.value,
+ args={"id": "id"},
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_BINDING_CONSTRAINT.value,
+ args=[{"id": "id"}],
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_THERMAL_CLUSTER.value,
+ args={
+ "area_id": "area_name",
+ "cluster_name": "cluster_name",
+ "parameters": {
+ "group": "group",
+ "unitcount": "unitcount",
+ "nominalcapacity": "nominalcapacity",
+ "marginal-cost": "marginal-cost",
+ "market-bid-cost": "market-bid-cost",
+ },
+ "prepro": "prepro",
+ "modulation": "modulation",
+ },
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_THERMAL_CLUSTER.value,
+ args=[
+ {
+ "area_id": "area_name",
+ "cluster_name": "cluster_name",
+ "parameters": {
+ "group": "group",
+ "unitcount": "unitcount",
+ "nominalcapacity": "nominalcapacity",
+ "marginal-cost": "marginal-cost",
+ "market-bid-cost": "market-bid-cost",
+ },
+ "prepro": "prepro",
+ "modulation": "modulation",
+ }
+ ],
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_THERMAL_CLUSTER.value,
+ args={"area_id": "area_name", "cluster_id": "cluster_name"},
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_THERMAL_CLUSTER.value,
+ args=[{"area_id": "area_name", "cluster_id": "cluster_name"}],
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_RENEWABLES_CLUSTER.value,
+ args={
+ "area_id": "area_name",
+ "cluster_name": "cluster_name",
+ "parameters": {
+ "name": "name",
+ "ts-interpretation": "power-generation",
+ },
+ },
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_RENEWABLES_CLUSTER.value,
+ args=[
+ {
+ "area_id": "area_name",
+ "cluster_name": "cluster_name",
+ "parameters": {
+ "name": "name",
+ "ts-interpretation": "power-generation",
+ },
+ }
+ ],
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_RENEWABLES_CLUSTER.value,
+ args={"area_id": "area_name", "cluster_id": "cluster_name"},
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_RENEWABLES_CLUSTER.value,
+ args=[{"area_id": "area_name", "cluster_id": "cluster_name"}],
+ ),
+ CommandDTO(
+ action=CommandName.REPLACE_MATRIX.value,
+ args={"target": "target_element", "matrix": "matrix"},
+ ),
+ CommandDTO(
+ action=CommandName.REPLACE_MATRIX.value,
+ args=[{"target": "target_element", "matrix": "matrix"}],
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_CONFIG.value,
+ args={"target": "target", "data": {}},
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_CONFIG.value,
+ args=[{"target": "target", "data": {}}],
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_COMMENTS.value,
+ args={"comments": "comments"},
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_COMMENTS.value,
+ args=[{"comments": "comments"}],
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_FILE.value,
+ args={
+ "target": "settings/resources/study",
+ "b64Data": "",
+ },
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_DISTRICT.value,
+ args={"id": "id", "filter_items": ["a"]},
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_DISTRICT.value,
+ args=[{"id": "id", "base_filter": "add-all"}],
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_PLAYLIST.value,
+ args=[{"active": True, "items": [1, 3], "reverse": False}],
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_PLAYLIST.value,
+ args={
+ "active": True,
+ "items": [1, 3],
+ "weights": {1: 5.0},
+ "reverse": False,
+ },
+ ),
+ CommandDTO(
+ action=CommandName.UPDATE_SCENARIO_BUILDER.value,
+ args={
+ "data": {
+ "ruleset test": {
+ "l": {"area1": {"0": 1}},
+ "ntc": {"area1 / area2": {"1": 23}},
+ "t": {"area1": {"thermal": {"1": 2}}},
+ },
+ }
+ },
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_ST_STORAGE.value,
+ args={
+ "area_id": "area 1",
+ "parameters": {
+ "name": "Storage 1",
+ "group": "Battery",
+ "injectionnominalcapacity": 0,
+ "withdrawalnominalcapacity": 0,
+ "reservoircapacity": 0,
+ "efficiency": 1,
+ "initiallevel": 0,
+ "initialleveloptim": False,
+ },
+ "pmax_injection": "matrix://59ea6c83-6348-466d-9530-c35c51ca4c37",
+ "pmax_withdrawal": "matrix://5f988548-dadc-4bbb-8ce8-87a544dbf756",
+ "lower_rule_curve": "matrix://8ce4fcea-cc97-4d2c-b641-a27a53454612",
+ "upper_rule_curve": "matrix://8ce614c8-c687-41af-8b24-df8a49cc52af",
+ "inflows": "matrix://df9b25e1-e3f7-4a57-8182-0ff9791439e5",
+ },
+ ),
+ CommandDTO(
+ action=CommandName.CREATE_ST_STORAGE.value,
+ args=[
+ {
+ "area_id": "area 1",
+ "parameters": {
+ "efficiency": 1,
+ "group": "Battery",
+ "initiallevel": 0,
+ "initialleveloptim": False,
+ "injectionnominalcapacity": 0,
+ "name": "Storage 1",
+ "reservoircapacity": 0,
+ "withdrawalnominalcapacity": 0,
+ },
+ "pmax_injection": "matrix://59ea6c83-6348-466d-9530-c35c51ca4c37",
+ "pmax_withdrawal": "matrix://5f988548-dadc-4bbb-8ce8-87a544dbf756",
+ "lower_rule_curve": "matrix://8ce4fcea-cc97-4d2c-b641-a27a53454612",
+ "upper_rule_curve": "matrix://8ce614c8-c687-41af-8b24-df8a49cc52af",
+ "inflows": "matrix://df9b25e1-e3f7-4a57-8182-0ff9791439e5",
+ },
+ {
+ "area_id": "area 1",
+ "parameters": {
+ "efficiency": 0.94,
+ "group": "Battery",
+ "initiallevel": 0,
+ "initialleveloptim": False,
+ "injectionnominalcapacity": 0,
+ "name": "Storage 2",
+ "reservoircapacity": 0,
+ "withdrawalnominalcapacity": 0,
+ },
+ "pmax_injection": "matrix://3f5b3746-3995-49b7-a6da-622633472e05",
+ "pmax_withdrawal": "matrix://4b64a31f-927b-4887-b4cd-adcddd39bdcd",
+ "lower_rule_curve": "matrix://16c7c3ae-9824-4ef2-aa68-51145884b025",
+ "upper_rule_curve": "matrix://9a6104e9-990a-415f-a6e2-57507e13b58c",
+ "inflows": "matrix://e8923768-9bdd-40c2-a6ea-2da2523be727",
+ },
+ ],
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_ST_STORAGE.value,
+ args={
+ "area_id": "area 1",
+ "storage_id": "storage 1",
+ },
+ ),
+ CommandDTO(
+ action=CommandName.REMOVE_ST_STORAGE.value,
+ args=[
+ {
+ "area_id": "area 1",
+ "storage_id": "storage 1",
+ },
+ {
+ "area_id": "area 1",
+ "storage_id": "storage 2",
+ },
+ ],
+ ),
+ CommandDTO(
+ action=CommandName.GENERATE_THERMAL_CLUSTER_TIMESERIES.value,
+ args=[{}],
+ ),
+]
+
+
+@pytest.fixture
+def command_factory() -> CommandFactory:
+ def get_matrix_id(matrix: str) -> str:
+ # str.removeprefix() is not available in Python 3.8
+ prefix = "matrix://"
+ if matrix.startswith(prefix):
+ return matrix[len(prefix) :]
+ return matrix
+
+ return CommandFactory(
+ generator_matrix_constants=Mock(spec=GeneratorMatrixConstants),
+ matrix_service=Mock(spec=MatrixService, get_matrix_id=get_matrix_id),
+ patch_service=Mock(spec=PatchService),
+ )
+
class TestCommandFactory:
- # noinspection SpellCheckingInspection
- def setup_class(self):
+ def _get_command_classes(self) -> Set[str]:
"""
- Set up the test class.
-
Imports all modules from the `antarest.study.storage.variantstudy.model.command` package
and creates a set of command class names derived from the `ICommand` abstract class.
The objective is to ensure that the unit test covers all commands in this package.
-
- This method is executed once before any tests in the test class are run.
"""
for module_loader, name, ispkg in pkgutil.iter_modules(["antarest/study/storage/variantstudy/model/command"]):
importlib.import_module(
@@ -44,383 +412,21 @@ def setup_class(self):
package="antarest.study.storage.variantstudy.model.command",
)
abstract_commands = {"AbstractBindingConstraintCommand"}
- self.command_class_set = {
- cmd.__name__ for cmd in ICommand.__subclasses__() if cmd.__name__ not in abstract_commands
- }
+ return {cmd.__name__ for cmd in ICommand.__subclasses__() if cmd.__name__ not in abstract_commands}
+
+ def test_all_commands_are_tested(self, command_factory: CommandFactory):
+ commands = sum([command_factory.to_command(command_dto=cmd) for cmd in COMMANDS], [])
+ tested_classes = {c.__class__.__name__ for c in commands}
+
+ assert self._get_command_classes().issubset(tested_classes)
# noinspection SpellCheckingInspection
@pytest.mark.parametrize(
"command_dto",
- [
- CommandDTO(
- action=CommandName.CREATE_AREA.value,
- args={"area_name": "area_name"},
- ),
- CommandDTO(
- action=CommandName.CREATE_AREA.value,
- args=[
- {"area_name": "area_name"},
- {"area_name": "area2"},
- ],
- ),
- CommandDTO(
- action=CommandName.REMOVE_AREA.value,
- args={"id": "id"},
- ),
- CommandDTO(
- action=CommandName.REMOVE_AREA.value,
- args=[{"id": "id"}],
- ),
- CommandDTO(
- action=CommandName.CREATE_DISTRICT.value,
- args={
- "name": "id",
- "filter_items": ["a"],
- "output": True,
- "comments": "",
- },
- ),
- CommandDTO(
- action=CommandName.CREATE_DISTRICT.value,
- args=[
- {
- "name": "id",
- "base_filter": "add-all",
- "output": True,
- "comments": "",
- }
- ],
- ),
- CommandDTO(
- action=CommandName.REMOVE_DISTRICT.value,
- args={"id": "id"},
- ),
- CommandDTO(
- action=CommandName.REMOVE_DISTRICT.value,
- args=[{"id": "id"}],
- ),
- CommandDTO(
- action=CommandName.CREATE_LINK.value,
- args={
- "area1": "area1",
- "area2": "area2",
- "parameters": {},
- "series": "series",
- },
- ),
- CommandDTO(
- action=CommandName.CREATE_LINK.value,
- args=[
- {
- "area1": "area1",
- "area2": "area2",
- "parameters": {},
- "series": "series",
- }
- ],
- ),
- CommandDTO(
- action=CommandName.REMOVE_LINK.value,
- args={
- "area1": "area1",
- "area2": "area2",
- },
- ),
- CommandDTO(
- action=CommandName.REMOVE_LINK.value,
- args=[
- {
- "area1": "area1",
- "area2": "area2",
- }
- ],
- ),
- CommandDTO(
- action=CommandName.CREATE_BINDING_CONSTRAINT.value,
- args={"name": "name"},
- ),
- CommandDTO(
- action=CommandName.CREATE_BINDING_CONSTRAINT.value,
- args=[
- {
- "name": "name",
- "enabled": True,
- "time_step": "hourly",
- "operator": "equal",
- "values": "values",
- "group": "group_1",
- },
- ],
- ),
- CommandDTO(
- action=CommandName.UPDATE_BINDING_CONSTRAINT.value,
- args={
- "id": "id",
- "enabled": True,
- "time_step": "hourly",
- "operator": "equal",
- "values": "values",
- },
- ),
- CommandDTO(
- action=CommandName.UPDATE_BINDING_CONSTRAINT.value,
- args=[
- {
- "id": "id",
- "enabled": True,
- "time_step": "hourly",
- "operator": "equal",
- }
- ],
- ),
- CommandDTO(
- action=CommandName.REMOVE_BINDING_CONSTRAINT.value,
- args={"id": "id"},
- ),
- CommandDTO(
- action=CommandName.REMOVE_BINDING_CONSTRAINT.value,
- args=[{"id": "id"}],
- ),
- CommandDTO(
- action=CommandName.CREATE_THERMAL_CLUSTER.value,
- args={
- "area_id": "area_name",
- "cluster_name": "cluster_name",
- "parameters": {
- "group": "group",
- "unitcount": "unitcount",
- "nominalcapacity": "nominalcapacity",
- "marginal-cost": "marginal-cost",
- "market-bid-cost": "market-bid-cost",
- },
- "prepro": "prepro",
- "modulation": "modulation",
- },
- ),
- CommandDTO(
- action=CommandName.CREATE_THERMAL_CLUSTER.value,
- args=[
- {
- "area_id": "area_name",
- "cluster_name": "cluster_name",
- "parameters": {
- "group": "group",
- "unitcount": "unitcount",
- "nominalcapacity": "nominalcapacity",
- "marginal-cost": "marginal-cost",
- "market-bid-cost": "market-bid-cost",
- },
- "prepro": "prepro",
- "modulation": "modulation",
- }
- ],
- ),
- CommandDTO(
- action=CommandName.REMOVE_THERMAL_CLUSTER.value,
- args={"area_id": "area_name", "cluster_id": "cluster_name"},
- ),
- CommandDTO(
- action=CommandName.REMOVE_THERMAL_CLUSTER.value,
- args=[{"area_id": "area_name", "cluster_id": "cluster_name"}],
- ),
- CommandDTO(
- action=CommandName.CREATE_RENEWABLES_CLUSTER.value,
- args={
- "area_id": "area_name",
- "cluster_name": "cluster_name",
- "parameters": {
- "name": "name",
- "ts-interpretation": "power-generation",
- },
- },
- ),
- CommandDTO(
- action=CommandName.CREATE_RENEWABLES_CLUSTER.value,
- args=[
- {
- "area_id": "area_name",
- "cluster_name": "cluster_name",
- "parameters": {
- "name": "name",
- "ts-interpretation": "power-generation",
- },
- }
- ],
- ),
- CommandDTO(
- action=CommandName.REMOVE_RENEWABLES_CLUSTER.value,
- args={"area_id": "area_name", "cluster_id": "cluster_name"},
- ),
- CommandDTO(
- action=CommandName.REMOVE_RENEWABLES_CLUSTER.value,
- args=[{"area_id": "area_name", "cluster_id": "cluster_name"}],
- ),
- CommandDTO(
- action=CommandName.REPLACE_MATRIX.value,
- args={"target": "target_element", "matrix": "matrix"},
- ),
- CommandDTO(
- action=CommandName.REPLACE_MATRIX.value,
- args=[{"target": "target_element", "matrix": "matrix"}],
- ),
- CommandDTO(
- action=CommandName.UPDATE_CONFIG.value,
- args={"target": "target", "data": {}},
- ),
- CommandDTO(
- action=CommandName.UPDATE_CONFIG.value,
- args=[{"target": "target", "data": {}}],
- ),
- CommandDTO(
- action=CommandName.UPDATE_COMMENTS.value,
- args={"comments": "comments"},
- ),
- CommandDTO(
- action=CommandName.UPDATE_COMMENTS.value,
- args=[{"comments": "comments"}],
- ),
- CommandDTO(
- action=CommandName.UPDATE_FILE.value,
- args={
- "target": "settings/resources/study",
- "b64Data": "",
- },
- ),
- CommandDTO(
- action=CommandName.UPDATE_DISTRICT.value,
- args={"id": "id", "filter_items": ["a"]},
- ),
- CommandDTO(
- action=CommandName.UPDATE_DISTRICT.value,
- args=[{"id": "id", "base_filter": "add-all"}],
- ),
- CommandDTO(
- action=CommandName.UPDATE_PLAYLIST.value,
- args=[{"active": True, "items": [1, 3], "reverse": False}],
- ),
- CommandDTO(
- action=CommandName.UPDATE_PLAYLIST.value,
- args={
- "active": True,
- "items": [1, 3],
- "weights": {1: 5.0},
- "reverse": False,
- },
- ),
- CommandDTO(
- action=CommandName.UPDATE_SCENARIO_BUILDER.value,
- args={
- "data": {
- "ruleset test": {
- "l": {"area1": {"0": 1}},
- "ntc": {"area1 / area2": {"1": 23}},
- "t": {"area1": {"thermal": {"1": 2}}},
- },
- }
- },
- ),
- CommandDTO(
- action=CommandName.CREATE_ST_STORAGE.value,
- args={
- "area_id": "area 1",
- "parameters": {
- "name": "Storage 1",
- "group": "Battery",
- "injectionnominalcapacity": 0,
- "withdrawalnominalcapacity": 0,
- "reservoircapacity": 0,
- "efficiency": 1,
- "initiallevel": 0,
- "initialleveloptim": False,
- },
- "pmax_injection": "matrix://59ea6c83-6348-466d-9530-c35c51ca4c37",
- "pmax_withdrawal": "matrix://5f988548-dadc-4bbb-8ce8-87a544dbf756",
- "lower_rule_curve": "matrix://8ce4fcea-cc97-4d2c-b641-a27a53454612",
- "upper_rule_curve": "matrix://8ce614c8-c687-41af-8b24-df8a49cc52af",
- "inflows": "matrix://df9b25e1-e3f7-4a57-8182-0ff9791439e5",
- },
- ),
- CommandDTO(
- action=CommandName.CREATE_ST_STORAGE.value,
- args=[
- {
- "area_id": "area 1",
- "parameters": {
- "efficiency": 1,
- "group": "Battery",
- "initiallevel": 0,
- "initialleveloptim": False,
- "injectionnominalcapacity": 0,
- "name": "Storage 1",
- "reservoircapacity": 0,
- "withdrawalnominalcapacity": 0,
- },
- "pmax_injection": "matrix://59ea6c83-6348-466d-9530-c35c51ca4c37",
- "pmax_withdrawal": "matrix://5f988548-dadc-4bbb-8ce8-87a544dbf756",
- "lower_rule_curve": "matrix://8ce4fcea-cc97-4d2c-b641-a27a53454612",
- "upper_rule_curve": "matrix://8ce614c8-c687-41af-8b24-df8a49cc52af",
- "inflows": "matrix://df9b25e1-e3f7-4a57-8182-0ff9791439e5",
- },
- {
- "area_id": "area 1",
- "parameters": {
- "efficiency": 0.94,
- "group": "Battery",
- "initiallevel": 0,
- "initialleveloptim": False,
- "injectionnominalcapacity": 0,
- "name": "Storage 2",
- "reservoircapacity": 0,
- "withdrawalnominalcapacity": 0,
- },
- "pmax_injection": "matrix://3f5b3746-3995-49b7-a6da-622633472e05",
- "pmax_withdrawal": "matrix://4b64a31f-927b-4887-b4cd-adcddd39bdcd",
- "lower_rule_curve": "matrix://16c7c3ae-9824-4ef2-aa68-51145884b025",
- "upper_rule_curve": "matrix://9a6104e9-990a-415f-a6e2-57507e13b58c",
- "inflows": "matrix://e8923768-9bdd-40c2-a6ea-2da2523be727",
- },
- ],
- ),
- CommandDTO(
- action=CommandName.REMOVE_ST_STORAGE.value,
- args={
- "area_id": "area 1",
- "storage_id": "storage 1",
- },
- ),
- CommandDTO(
- action=CommandName.REMOVE_ST_STORAGE.value,
- args=[
- {
- "area_id": "area 1",
- "storage_id": "storage 1",
- },
- {
- "area_id": "area 1",
- "storage_id": "storage 2",
- },
- ],
- ),
- CommandDTO(
- action=CommandName.GENERATE_THERMAL_CLUSTER_TIMESERIES.value,
- args=[{}],
- ),
- ],
+ COMMANDS,
)
@pytest.mark.unit_test
- def test_command_factory(self, command_dto: CommandDTO):
- def get_matrix_id(matrix: str) -> str:
- # str.removeprefix() is not available in Python 3.8
- prefix = "matrix://"
- if matrix.startswith(prefix):
- return matrix[len(prefix) :]
- return matrix
-
- command_factory = CommandFactory(
- generator_matrix_constants=Mock(spec=GeneratorMatrixConstants),
- matrix_service=Mock(spec=MatrixService, get_matrix_id=get_matrix_id),
- patch_service=Mock(spec=PatchService),
- )
+ def test_command_factory(self, command_dto: CommandDTO, command_factory: CommandFactory):
commands = command_factory.to_command(command_dto=command_dto)
if isinstance(command_dto.args, dict):
@@ -440,12 +446,6 @@ def get_matrix_id(matrix: str) -> str:
assert actual_args == expected_args
assert actual_version == expected_version
- self.command_class_set.discard(type(commands[0]).__name__)
-
- def teardown_class(self):
- # Check that all command classes have been tested
- assert not self.command_class_set
-
@pytest.mark.unit_test
def test_unknown_command():