diff --git a/antarest/__init__.py b/antarest/__init__.py
index 29e8eb67b6..f3685ed893 100644
--- a/antarest/__init__.py
+++ b/antarest/__init__.py
@@ -7,9 +7,9 @@
# Standard project metadata
-__version__ = "2.14.4"
+__version__ = "2.14.5"
__author__ = "RTE, Antares Web Team"
-__date__ = "2023-06-28"
+__date__ = "2023-08-11"
# noinspection SpellCheckingInspection
__credits__ = "(c) Réseau de Transport de l’Électricité (RTE)"
diff --git a/antarest/launcher/web.py b/antarest/launcher/web.py
index b1377b167f..c82fcf000b 100644
--- a/antarest/launcher/web.py
+++ b/antarest/launcher/web.py
@@ -199,7 +199,7 @@ def remove_result(
response_model=LauncherEnginesDTO,
)
def get_engines() -> Any:
- logger.info(f"Listing launch engines")
+ logger.info("Listing launch engines")
return LauncherEnginesDTO(engines=service.get_launchers())
@bp.get(
@@ -223,7 +223,7 @@ def get_load(
)
def get_solver_versions(
solver: str = Query(
- "local",
+ "default",
examples={
"Default solver": {
"description": "Get the solver versions of the default configuration",
diff --git a/antarest/study/storage/rawstudy/model/filesystem/ini_file_node.py b/antarest/study/storage/rawstudy/model/filesystem/ini_file_node.py
index bf65180824..a6ef0c3a23 100644
--- a/antarest/study/storage/rawstudy/model/filesystem/ini_file_node.py
+++ b/antarest/study/storage/rawstudy/model/filesystem/ini_file_node.py
@@ -8,25 +8,20 @@
import zipfile
from json import JSONDecodeError
from pathlib import Path
-from typing import List, Optional, cast, Dict, Any, Union, Callable
-
-from filelock import FileLock
+from typing import Any, Callable, Dict, List, Optional, Union, cast
from antarest.core.model import JSON, SUB_JSON
from antarest.study.storage.rawstudy.io.reader import IniReader
from antarest.study.storage.rawstudy.io.reader.ini_reader import IReader
-from antarest.study.storage.rawstudy.io.writer.ini_writer import (
- IniWriter,
-)
+from antarest.study.storage.rawstudy.io.writer.ini_writer import IniWriter
from antarest.study.storage.rawstudy.model.filesystem.config.model import (
FileStudyTreeConfig,
)
from antarest.study.storage.rawstudy.model.filesystem.context import (
ContextServer,
)
-from antarest.study.storage.rawstudy.model.filesystem.inode import (
- INode,
-)
+from antarest.study.storage.rawstudy.model.filesystem.inode import INode
+from filelock import FileLock
class IniFileNodeWarning(UserWarning):
diff --git a/antarest/study/storage/rawstudy/model/filesystem/matrix/input_series_matrix.py b/antarest/study/storage/rawstudy/model/filesystem/matrix/input_series_matrix.py
index 07cf23e85f..bcb1569d89 100644
--- a/antarest/study/storage/rawstudy/model/filesystem/matrix/input_series_matrix.py
+++ b/antarest/study/storage/rawstudy/model/filesystem/matrix/input_series_matrix.py
@@ -4,6 +4,7 @@
import numpy as np
import pandas as pd
+
from antarest.core.model import JSON
from antarest.core.utils.utils import StopWatch
from antarest.study.storage.rawstudy.model.filesystem.config.model import (
diff --git a/antarest/study/storage/variantstudy/model/command/icommand.py b/antarest/study/storage/variantstudy/model/command/icommand.py
index 85b1877cd8..8da2092efc 100644
--- a/antarest/study/storage/variantstudy/model/command/icommand.py
+++ b/antarest/study/storage/variantstudy/model/command/icommand.py
@@ -91,13 +91,11 @@ def apply(self, study_data: FileStudy) -> CommandOutput:
f"Failed to execute variant command {self.command_name}",
exc_info=e,
)
- return CommandOutput(
- status=False,
- message=(
- f"Unexpected exception occurred when trying"
- f" to apply command {self.command_name}: {e}"
- ),
+ message = (
+ f"Unexpected exception occurred when trying"
+ f" to apply command {self.command_name}: {e}"
)
+ return CommandOutput(status=False, message=message)
@abstractmethod
def to_dto(self) -> CommandDTO:
diff --git a/antarest/study/storage/variantstudy/model/command/remove_renewables_cluster.py b/antarest/study/storage/variantstudy/model/command/remove_renewables_cluster.py
index 96e3323c9f..28d47a3e33 100644
--- a/antarest/study/storage/variantstudy/model/command/remove_renewables_cluster.py
+++ b/antarest/study/storage/variantstudy/model/command/remove_renewables_cluster.py
@@ -1,20 +1,20 @@
-from typing import Any, List, Tuple, Dict
+from typing import Any, Dict, List, Tuple
from antarest.study.storage.rawstudy.model.filesystem.config.model import (
- FileStudyTreeConfig,
Area,
+ FileStudyTreeConfig,
)
from antarest.study.storage.rawstudy.model.filesystem.factory import FileStudy
from antarest.study.storage.variantstudy.business.utils_binding_constraint import (
remove_area_cluster_from_binding_constraints,
)
from antarest.study.storage.variantstudy.model.command.common import (
- CommandOutput,
CommandName,
+ CommandOutput,
)
from antarest.study.storage.variantstudy.model.command.icommand import (
- ICommand,
MATCH_SIGNATURE_SEPARATOR,
+ ICommand,
)
from antarest.study.storage.variantstudy.model.model import CommandDTO
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index e9779659c9..86ade2895a 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -1,6 +1,50 @@
Antares Web Changelog
=====================
+v2.14.5 (2023-08-11)
+--------------------
+
+### Features
+
+* **ui-i18n:** add missing adequacy patch translations (#1680) ([8a06461](https://github.com/AntaresSimulatorTeam/AntaREST/commit/8a06461f4118227b94be7f587d37ea2430c70505))
+* **ui:** removed the "patch" number from the list of versions in the simulation launch dialog when it's equal to 0 (#1698) ([1bc0156](https://github.com/AntaresSimulatorTeam/AntaREST/commit/1bc0156c3e08e321e9ccc396b95cadeabf1c1fc7))
+
+
+### Bug Fixes
+
+* **web:** modified API response model to prevent Watcher's ValidationError (#1526) ([b0e48d1](https://github.com/AntaresSimulatorTeam/AntaREST/commit/b0e48d1bd31463cb6ce5e9aefeff761c016d0b35))
+* **xpansion:** corrected field types for Xpansion parameters (sensitivity analysis) ([3e481b9](https://github.com/AntaresSimulatorTeam/AntaREST/commit/3e481b9c8866ecc3dc42e351552e1ded036f62ad))
+* **variant:** fixed implementation of the method for extracting the difference between two studies ([c534785](https://github.com/AntaresSimulatorTeam/AntaREST/commit/c5347851da867a19b990e05c6516bedc7508c8ce))
+* **api:** added missing `use_leeway` field and validation rules in the hydro configuration form (#1650) ([27e46e5](https://github.com/AntaresSimulatorTeam/AntaREST/commit/27e46e5bda77aed65c84e82931d426b4b69a43bd))
+* **export:** ZIP outputs are no longer compressed before export (used by Xpansion) (#1656) ([cba6261](https://github.com/AntaresSimulatorTeam/AntaREST/commit/cba62613e19712240f74f417854e95bd588ba95d))
+* **log-parser:** simplified analysis and improved accuracy in displaying simulation progress for a study (#1682) ([2442674](https://github.com/AntaresSimulatorTeam/AntaREST/commit/24426749e9b6100eb3ab4b7159f615444242b95a))
+* **table-mode:** corrected reading of UI information when the study has only one area (#1674) ([55c4181](https://github.com/AntaresSimulatorTeam/AntaREST/commit/55c4181b64959c5e191fed2256437fc95787199f))
+* **table-mode:** issue to read area information in the case where the study has only one area (#1690) ([87d9617](https://github.com/AntaresSimulatorTeam/AntaREST/commit/87d961703cebdc037671fe73988903eb14dd9547))
+* **command:** improve INI reader to support API PUT `/v1/studies/{uuid}/raw` (#1461) ([9e5cf25](https://github.com/AntaresSimulatorTeam/AntaREST/commit/9e5cf25b2f69890016ea36f3be0e9ac03c7695b6))
+* **variant:** fixed time series deletion of renewable clusters (#1693) ([4ba1b17](https://github.com/AntaresSimulatorTeam/AntaREST/commit/4ba1b17dd3c1b8ea62a5a02f39d15e94a4b9a331))
+* **launcher:** fixing launcher versions display and creation of the endpoint `/v1/launcher/versions` ([410afc2](https://github.com/AntaresSimulatorTeam/AntaREST/commit/410afc2e4ecbb296878985839ee27f84bc70d9d8))
+ and (#1672) ([a76f3a9](https://github.com/AntaresSimulatorTeam/AntaREST/commit/a76f3a9f01df0225d7fb54b20ba3ff599d749138))
+* **launcher:** set the default number of cores to 22 (instead of 12) (#1695) ([2c89799](https://github.com/AntaresSimulatorTeam/AntaREST/commit/2c8979916d46a0ed46a67bc75ac9a2e365e3f164))
+
+
+### Continuous Integration
+
+* upgrade mypy to v1.4.1 and Black to v23.7.0 for improved typing and formatting (#1685) ([7cff8c5](https://github.com/AntaresSimulatorTeam/AntaREST/commit/7cff8c56c38728a1b29eae0221bcc8226e9ca80c))
+
+
+### Tests
+
+* enhanced integration tests: refactored fixtures and resources ([70af9b1](https://github.com/AntaresSimulatorTeam/AntaREST/commit/70af9b167bf54d534696da8b781edda56ccee788))
+
+
+### Contributors
+
+laurent-laporte-pro,
+MartinBelthle,
+hdinia,
+skamril
+
+
v2.14.4 (2023-06-28)
--------------------
diff --git a/setup.py b/setup.py
index 610a0ca972..9a7fd1295c 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@
setuptools.setup(
name="AntaREST",
- version="2.14.4",
+ version="2.14.5",
description="Antares Server",
long_description=long_description,
long_description_content_type="text/markdown",
diff --git a/sonar-project.properties b/sonar-project.properties
index 2e78a84c9b..1156c995fd 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -6,5 +6,5 @@ sonar.exclusions=antarest/gui.py,antarest/main.py
sonar.python.coverage.reportPaths=coverage.xml
sonar.python.version=3.8
sonar.javascript.lcov.reportPaths=webapp/coverage/lcov.info
-sonar.projectVersion=2.14.4
+sonar.projectVersion=2.14.5
sonar.coverage.exclusions=antarest/gui.py,antarest/main.py,antarest/singleton_services.py,antarest/worker/archive_worker_service.py,webapp/**/*
\ No newline at end of file
diff --git a/tests/integration/launcher_blueprint/__init__.py b/tests/integration/launcher_blueprint/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/integration/launcher_blueprint/test_solver_versions.py b/tests/integration/launcher_blueprint/test_solver_versions.py
new file mode 100644
index 0000000000..34cf6737a9
--- /dev/null
+++ b/tests/integration/launcher_blueprint/test_solver_versions.py
@@ -0,0 +1,79 @@
+from typing import Sequence, Any
+from unittest.mock import patch
+
+import pytest
+from starlette.testclient import TestClient
+
+
+@pytest.mark.integration_test
+class TestSolverVersions:
+ """
+ The purpose of this unit test is to check the `/v1/launcher/versions` endpoint.
+ """
+
+ def test_get_solver_versions(
+ self,
+ client: TestClient,
+ user_access_token: str,
+ ) -> None:
+ # Fetch the default server version from the configuration file.
+ # NOTE: the value is defined in `tests/integration/assets/config.template.yml`.
+ res = client.get(
+ "/v1/launcher/versions",
+ headers={"Authorization": f"Bearer {user_access_token}"},
+ )
+ res.raise_for_status()
+ actual = res.json()
+ assert actual == ["700"]
+
+ res = client.get(
+ "/v1/launcher/versions?solver=default",
+ headers={"Authorization": f"Bearer {user_access_token}"},
+ )
+ res.raise_for_status()
+ actual = res.json()
+ assert actual == ["700"]
+
+ res = client.get(
+ "/v1/launcher/versions?solver=local",
+ headers={"Authorization": f"Bearer {user_access_token}"},
+ )
+ res.raise_for_status()
+ actual = res.json()
+ assert actual == ["700"]
+
+ res = client.get(
+ "/v1/launcher/versions?solver=slurm",
+ headers={"Authorization": f"Bearer {user_access_token}"},
+ )
+ res.raise_for_status()
+ actual = res.json()
+ assert actual == []
+
+ def test_get_solver_versions__default(
+ self,
+ client: TestClient,
+ user_access_token: str,
+ ) -> None:
+ """
+ This unit test checks that the default value
+ of the `solver` parameter is indeed "default".
+ """
+
+ def get_versions(_: Any, solver: str) -> Sequence[str]:
+ # To distinguish between the default value and the local value,
+ # we use a different value for each `solver` value.
+ versions = {"default": ["123"], "local": ["456"], "slurm": ["798"]}
+ return versions[solver]
+
+ with patch(
+ "antarest.launcher.service.LauncherService.get_solver_versions",
+ new=get_versions,
+ ):
+ res = client.get(
+ "/v1/launcher/versions",
+ headers={"Authorization": f"Bearer {user_access_token}"},
+ )
+ res.raise_for_status()
+ actual = res.json()
+ assert actual == ["123"]
diff --git a/tests/integration/test_integration_variantmanager_tool.py b/tests/integration/test_integration_variantmanager_tool.py
index cd7b3b3168..0dd9c02fb0 100644
--- a/tests/integration/test_integration_variantmanager_tool.py
+++ b/tests/integration/test_integration_variantmanager_tool.py
@@ -1,15 +1,16 @@
import os
import urllib.parse
-import zipfile
from pathlib import Path
from typing import List, Tuple
-
-import numpy as np
-from fastapi import FastAPI
-from starlette.testclient import TestClient
+from zipfile import ZipFile
from antarest.study.storage.rawstudy.io.reader import IniReader
-from antarest.study.storage.study_upgrader import get_current_version
+from antarest.study.storage.rawstudy.model.filesystem.matrix.constants import (
+ default_4_fixed_hourly,
+ default_8_fixed_hourly,
+ default_scenario_daily,
+ default_scenario_hourly,
+)
from antarest.study.storage.variantstudy.model.command.common import (
CommandName,
)
@@ -26,8 +27,17 @@
generate_study,
parse_commands,
)
+from fastapi import FastAPI
+from starlette.testclient import TestClient
-TEST_DIR: Path = Path(__file__).parent
+test_dir: Path = Path(__file__).parent
+
+
+def generate_csv_string(data: List[List[float]]) -> str:
+ csv_str = ""
+ for row in data:
+ csv_str += "\t".join(["{:.6f}".format(v) for v in row]) + "\n"
+ return csv_str
def generate_study_with_server(
@@ -64,7 +74,7 @@ def generate_study_with_server(
def test_variant_manager(app: FastAPI, tmp_path: str):
client = TestClient(app, raise_server_exceptions=False)
- commands = parse_commands(TEST_DIR / "assets" / "commands1.json")
+ commands = parse_commands(test_dir / "assets" / "commands1.json")
matrix_dir = Path(tmp_path) / "empty_matrix_store"
matrix_dir.mkdir(parents=True, exist_ok=True)
res, study_id = generate_study_with_server(
@@ -74,12 +84,11 @@ def test_variant_manager(app: FastAPI, tmp_path: str):
def test_parse_commands(tmp_path: str, app: FastAPI):
- # sourcery skip: low-code-quality
- base_dir = TEST_DIR / "assets"
+ base_dir = test_dir / "assets"
export_path = Path(tmp_path) / "commands"
study = "base_study"
study_path = Path(tmp_path) / study
- with zipfile.ZipFile(base_dir / "base_study.zip") as zip_output:
+ with ZipFile(base_dir / "base_study.zip") as zip_output:
zip_output.extractall(path=tmp_path)
output_dir = Path(export_path) / study
study_info = IniReader().read(study_path / "study.antares")
@@ -102,213 +111,157 @@ def test_parse_commands(tmp_path: str, app: FastAPI):
)
assert generated_study_path.exists() and generated_study_path.is_dir()
- single_column_empty_items = {
- "input/load/series/load_hub w.txt",
- "input/load/series/load_south.txt",
- "input/load/series/load_hub n.txt",
- "input/load/series/load_west.txt",
- "input/load/series/load_north.txt",
- "input/load/series/load_hub s.txt",
- "input/load/series/load_hub e.txt",
- "input/load/series/load_east.txt",
- "input/wind/series/wind_east.txt",
- "input/wind/series/wind_north.txt",
- "input/wind/series/wind_hub n.txt",
- "input/wind/series/wind_south.txt",
- "input/wind/series/wind_hub w.txt",
- "input/wind/series/wind_west.txt",
- "input/wind/series/wind_hub e.txt",
- "input/wind/series/wind_hub s.txt",
- "input/solar/series/solar_east.txt",
- "input/solar/series/solar_hub n.txt",
- "input/solar/series/solar_south.txt",
- "input/solar/series/solar_hub s.txt",
- "input/solar/series/solar_north.txt",
- "input/solar/series/solar_hub w.txt",
- "input/solar/series/solar_hub e.txt",
- "input/solar/series/solar_west.txt",
- "input/thermal/series/west/semi base/series.txt",
- "input/thermal/series/west/peak/series.txt",
- "input/thermal/series/west/base/series.txt",
- "input/thermal/series/north/semi base/series.txt",
- "input/thermal/series/north/peak/series.txt",
- "input/thermal/series/north/base/series.txt",
- "input/thermal/series/east/semi base/series.txt",
- "input/thermal/series/east/peak/series.txt",
- "input/thermal/series/east/base/series.txt",
- "input/thermal/series/south/semi base/series.txt",
- "input/thermal/series/south/peak/series.txt",
- "input/thermal/series/south/base/series.txt",
- "input/hydro/series/hub e/ror.txt",
- "input/hydro/series/south/ror.txt",
- "input/hydro/series/hub w/ror.txt",
- "input/hydro/series/hub s/ror.txt",
- "input/hydro/series/west/ror.txt",
- "input/hydro/series/hub n/ror.txt",
- "input/hydro/series/north/ror.txt",
- "input/hydro/series/east/ror.txt",
- }
- single_column_daily_empty_items = {
- "input/hydro/series/hub e/mod.txt",
- "input/hydro/series/south/mod.txt",
- "input/hydro/series/hub w/mod.txt",
- "input/hydro/series/hub s/mod.txt",
- "input/hydro/series/west/mod.txt",
- "input/hydro/series/hub n/mod.txt",
- "input/hydro/series/north/mod.txt",
- "input/hydro/series/east/mod.txt",
- }
- fixed_4_cols_empty_items = {
- "input/reserves/hub s.txt",
- "input/reserves/hub n.txt",
- "input/reserves/hub w.txt",
- "input/reserves/hub e.txt",
- }
- # noinspection SpellCheckingInspection
- fixed_8_cols_empty_items = {
- "input/misc-gen/miscgen-hub w.txt",
- "input/misc-gen/miscgen-hub e.txt",
- "input/misc-gen/miscgen-hub s.txt",
- "input/misc-gen/miscgen-hub n.txt",
- }
- matrix_items = (
- single_column_empty_items
- | single_column_daily_empty_items
- | fixed_4_cols_empty_items
- | fixed_8_cols_empty_items
+ single_column_empty_items = [
+ f"input{os.sep}load{os.sep}series{os.sep}load_hub w.txt",
+ f"input{os.sep}load{os.sep}series{os.sep}load_south.txt",
+ f"input{os.sep}load{os.sep}series{os.sep}load_hub n.txt",
+ f"input{os.sep}load{os.sep}series{os.sep}load_west.txt",
+ f"input{os.sep}load{os.sep}series{os.sep}load_north.txt",
+ f"input{os.sep}load{os.sep}series{os.sep}load_hub s.txt",
+ f"input{os.sep}load{os.sep}series{os.sep}load_hub e.txt",
+ f"input{os.sep}load{os.sep}series{os.sep}load_east.txt",
+ f"input{os.sep}wind{os.sep}series{os.sep}wind_east.txt",
+ f"input{os.sep}wind{os.sep}series{os.sep}wind_north.txt",
+ f"input{os.sep}wind{os.sep}series{os.sep}wind_hub n.txt",
+ f"input{os.sep}wind{os.sep}series{os.sep}wind_south.txt",
+ f"input{os.sep}wind{os.sep}series{os.sep}wind_hub w.txt",
+ f"input{os.sep}wind{os.sep}series{os.sep}wind_west.txt",
+ f"input{os.sep}wind{os.sep}series{os.sep}wind_hub e.txt",
+ f"input{os.sep}wind{os.sep}series{os.sep}wind_hub s.txt",
+ f"input{os.sep}solar{os.sep}series{os.sep}solar_east.txt",
+ f"input{os.sep}solar{os.sep}series{os.sep}solar_hub n.txt",
+ f"input{os.sep}solar{os.sep}series{os.sep}solar_south.txt",
+ f"input{os.sep}solar{os.sep}series{os.sep}solar_hub s.txt",
+ f"input{os.sep}solar{os.sep}series{os.sep}solar_north.txt",
+ f"input{os.sep}solar{os.sep}series{os.sep}solar_hub w.txt",
+ f"input{os.sep}solar{os.sep}series{os.sep}solar_hub e.txt",
+ f"input{os.sep}solar{os.sep}series{os.sep}solar_west.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}west{os.sep}semi base{os.sep}series.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}west{os.sep}peak{os.sep}series.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}west{os.sep}base{os.sep}series.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}north{os.sep}semi base{os.sep}series.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}north{os.sep}peak{os.sep}series.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}north{os.sep}base{os.sep}series.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}east{os.sep}semi base{os.sep}series.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}east{os.sep}peak{os.sep}series.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}east{os.sep}base{os.sep}series.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}south{os.sep}semi base{os.sep}series.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}south{os.sep}peak{os.sep}series.txt",
+ f"input{os.sep}thermal{os.sep}series{os.sep}south{os.sep}base{os.sep}series.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}hub e{os.sep}ror.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}south{os.sep}ror.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}hub w{os.sep}ror.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}hub s{os.sep}ror.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}west{os.sep}ror.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}hub n{os.sep}ror.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}north{os.sep}ror.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}east{os.sep}ror.txt",
+ ]
+ single_column_daily_empty_items = [
+ f"input{os.sep}hydro{os.sep}series{os.sep}hub e{os.sep}mod.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}south{os.sep}mod.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}hub w{os.sep}mod.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}hub s{os.sep}mod.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}west{os.sep}mod.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}hub n{os.sep}mod.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}north{os.sep}mod.txt",
+ f"input{os.sep}hydro{os.sep}series{os.sep}east{os.sep}mod.txt",
+ ]
+ fixed_4_cols_empty_items = [
+ f"input{os.sep}reserves{os.sep}hub s.txt",
+ f"input{os.sep}reserves{os.sep}hub n.txt",
+ f"input{os.sep}reserves{os.sep}hub w.txt",
+ f"input{os.sep}reserves{os.sep}hub e.txt",
+ ]
+ fixed_8_cols_empty_items = [
+ f"input{os.sep}misc-gen{os.sep}miscgen-hub w.txt",
+ f"input{os.sep}misc-gen{os.sep}miscgen-hub e.txt",
+ f"input{os.sep}misc-gen{os.sep}miscgen-hub s.txt",
+ f"input{os.sep}misc-gen{os.sep}miscgen-hub n.txt",
+ ]
+ single_column_empty_data = generate_csv_string(default_scenario_hourly)
+ single_column_daily_empty_data = generate_csv_string(
+ default_scenario_daily
)
-
- ignorable_items = {
- "Desktop.ini",
- "study.antares",
- "settings/comments.txt",
- "settings/resources/study.ico",
- }
-
- # fmt: off
- single_column_empty_matrix = np.zeros((8760, 1), dtype=np.float64)
- single_column_daily_empty_matrix = np.zeros((365, 1), dtype=np.float64)
- fixed_4_columns_empty_matrix = np.zeros((8760, 4), dtype=np.float64)
- fixed_8_columns_empty_matrix = np.zeros((8760, 8), dtype=np.float64)
- # fmt: on
-
+ fixed_4_columns_empty_data = generate_csv_string(default_4_fixed_hourly)
+ fixed_8_columns_empty_data = generate_csv_string(default_8_fixed_hourly)
for root, dirs, files in os.walk(study_path):
+ rel_path = root[len(str(study_path)) + 1 :]
for item in files:
- cfg_path = Path(root).joinpath(item)
- cfg_relpath = cfg_path.relative_to(study_path).as_posix()
-
- if cfg_relpath in ignorable_items:
+ if item in [
+ "comments.txt",
+ "study.antares",
+ "Desktop.ini",
+ "study.ico",
+ ]:
continue
-
- # print(f"Reading config data '{cfg_relpath}'...", file=sys.stderr)
- actual_cfg_path = generated_study_path / cfg_relpath
- if cfg_relpath in matrix_items:
- data = np.loadtxt(
- actual_cfg_path,
- delimiter="\t",
- dtype=np.float64,
- ndmin=2,
- )
- else:
- data = actual_cfg_path.read_text()
-
- if cfg_relpath in single_column_empty_items:
+ elif f"{rel_path}{os.sep}{item}" in single_column_empty_items:
assert (
- data.all() == single_column_empty_matrix.all(),
- f"Invalid single_column_empty_matrix '{actual_cfg_path}'",
- )
- elif cfg_relpath in single_column_daily_empty_items:
+ generated_study_path / rel_path / item
+ ).read_text() == single_column_empty_data
+ elif (
+ f"{rel_path}{os.sep}{item}" in single_column_daily_empty_items
+ ):
assert (
- data.all() == single_column_daily_empty_matrix.all(),
- f"Invalid single_column_daily_empty_matrix '{actual_cfg_path}'",
- )
- elif cfg_relpath in fixed_4_cols_empty_items:
+ generated_study_path / rel_path / item
+ ).read_text() == single_column_daily_empty_data
+ elif f"{rel_path}{os.sep}{item}" in fixed_4_cols_empty_items:
assert (
- data.all() == fixed_4_columns_empty_matrix.all(),
- f"Invalid fixed_4_columns_empty_matrix '{actual_cfg_path}'",
- )
- elif cfg_relpath in fixed_8_cols_empty_items:
+ generated_study_path / rel_path / item
+ ).read_text() == fixed_4_columns_empty_data
+ elif f"{rel_path}{os.sep}{item}" in fixed_8_cols_empty_items:
assert (
- data.all() == fixed_8_columns_empty_matrix.all(),
- f"Invalid fixed_8_columns_empty_matrix '{actual_cfg_path}'",
- )
+ generated_study_path / rel_path / item
+ ).read_text() == fixed_8_columns_empty_data
else:
- assert (
- data == cfg_path.read_text(),
- f"Invalid config '{actual_cfg_path}'",
- )
+ actual = (study_path / rel_path / item).read_text()
+ expected = (generated_study_path / rel_path / item).read_text()
+ assert actual.strip() == expected.strip()
def test_diff_local(tmp_path: Path):
- # Extract resources in `assets`
- assets_dir = tmp_path.joinpath("assets")
- assets_dir.mkdir()
- raw_study_dir = assets_dir.joinpath("raw_study")
- variant_study_dir = assets_dir.joinpath("variant_study")
- for src in [
- TEST_DIR.joinpath("assets/base_study.zip"),
- TEST_DIR.joinpath("assets/variant_study.zip"),
- ]:
- with zipfile.ZipFile(src) as zip_output:
- zip_output.extractall(path=assets_dir)
- assets_dir.joinpath("base_study").replace(raw_study_dir)
-
- # Extract the commands used to "regenerate" the studies
- results_dir = tmp_path.joinpath("results")
- commands_dir = results_dir.joinpath("commands")
- raw_study_commands = commands_dir.joinpath("raw_study")
- variant_study_commands = commands_dir.joinpath("variant_study")
- extract_commands(raw_study_dir, raw_study_commands)
- extract_commands(variant_study_dir, variant_study_commands),
+ base_dir = test_dir / "assets"
+ export_path = Path(tmp_path) / "generation_result"
+ base_study = "base_study"
+ variant_study = "variant_study"
+ output_study_commands = Path(export_path) / "output_study_commands"
+ output_study_path = Path(tmp_path) / base_study
+ base_study_commands = Path(export_path) / base_study
+ variant_study_commands = Path(export_path) / variant_study
+ variant_study_path = Path(tmp_path) / variant_study
- study_version = get_current_version(raw_study_dir)
+ for study in [base_study, variant_study]:
+ with ZipFile(base_dir / f"{study}.zip") as zip_output:
+ zip_output.extractall(path=tmp_path)
+ extract_commands(Path(tmp_path) / study, Path(export_path) / study)
- raw_generated_dir = results_dir.joinpath("raw_generated")
res = generate_study(
- raw_study_commands,
- "raw1",
- output=str(raw_generated_dir),
- study_version=study_version,
+ base_study_commands, None, str(Path(export_path) / "base_generated")
)
- assert res.success
- variant_generated_dir = results_dir.joinpath("variant_generated")
res = generate_study(
variant_study_commands,
- "variant1",
- output=str(variant_generated_dir),
- study_version=study_version,
+ None,
+ str(Path(export_path) / "variant_generated"),
)
- assert res.success
- # Calculates the differences between the RAW study and the variant study.
generate_diff(
- raw_study_commands,
- variant_study_commands,
- commands_dir,
- study_version=study_version,
+ base_study_commands, variant_study_commands, output_study_commands
)
- # After calculating the differences, the `generate_diff` function generates a list
- # of commands that only contains the differences between the two studies.
- # These differences are then applied to the original RAW study to regenerate
- # a study in the final state.
res = generate_study(
- commands_dir,
- "diff1",
- output=str(raw_generated_dir),
- study_version=study_version,
+ output_study_commands, None, output=str(output_study_path)
)
assert res.success
- # Quick compare generated raw and variant
- for raw_path in raw_generated_dir.glob("**/*"):
- if raw_path.is_dir() or raw_path.name in [
- "comments.txt",
- "study.antares",
- "Desktop.ini",
- "study.ico",
- ]:
- continue
- relpath = raw_path.relative_to(raw_generated_dir)
- variant_path = variant_generated_dir.joinpath(relpath)
- raw_text = raw_path.read_text(encoding="utf-8")
- variant_text = variant_path.read_text(encoding="utf-8")
- assert raw_text == variant_text, f"Invalid path '{relpath}'"
+ assert output_study_path.exists() and output_study_path.is_dir()
+ for root, dirs, files in os.walk(variant_study_path):
+ rel_path = root[len(str(variant_study_path)) + 1 :]
+ for item in files:
+ if item in [
+ "comments.txt",
+ "study.antares",
+ "Desktop.ini",
+ "study.ico",
+ ]:
+ continue
+ actual = (variant_study_path / rel_path / item).read_text()
+ expected = (output_study_path / rel_path / item).read_text()
+ assert actual.strip() == expected.strip()
diff --git a/tests/storage/repository/antares_io/reader/test_ini_reader.py b/tests/storage/repository/antares_io/reader/test_ini_reader.py
index 0782447f6f..a24c1373e4 100644
--- a/tests/storage/repository/antares_io/reader/test_ini_reader.py
+++ b/tests/storage/repository/antares_io/reader/test_ini_reader.py
@@ -2,7 +2,6 @@
from pathlib import Path
import pytest
-
from antarest.study.storage.rawstudy.io.reader import IniReader
from antarest.study.storage.rawstudy.io.reader.ini_reader import (
MultipleSameKeysIniReader,
diff --git a/tests/variantstudy/model/command/test_create_area.py b/tests/variantstudy/model/command/test_create_area.py
index 58fecacbdf..0118c0bb71 100644
--- a/tests/variantstudy/model/command/test_create_area.py
+++ b/tests/variantstudy/model/command/test_create_area.py
@@ -4,6 +4,7 @@
import pytest
from antarest.study.storage.rawstudy.model.filesystem.config.model import (
+ ENR_MODELLING,
transform_name_to_id,
ENR_MODELLING,
)
diff --git a/tests/variantstudy/model/command/test_remove_renewables_cluster.py b/tests/variantstudy/model/command/test_remove_renewables_cluster.py
index 562c6d72ad..9e0e7efb61 100644
--- a/tests/variantstudy/model/command/test_remove_renewables_cluster.py
+++ b/tests/variantstudy/model/command/test_remove_renewables_cluster.py
@@ -1,8 +1,8 @@
from checksumdir import dirhash
from antarest.study.storage.rawstudy.model.filesystem.config.model import (
- transform_name_to_id,
ENR_MODELLING,
+ transform_name_to_id,
)
from antarest.study.storage.rawstudy.model.filesystem.factory import FileStudy
from antarest.study.storage.variantstudy.model.command.create_area import (
diff --git a/webapp/package.json b/webapp/package.json
index a7bb313af9..4d5db51074 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -1,6 +1,6 @@
{
"name": "antares-web",
- "version": "2.14.4",
+ "version": "2.14.5",
"private": true,
"engines": {
"node": "18.16.1"
diff --git a/webapp/src/components/App/Studies/LauncherDialog.tsx b/webapp/src/components/App/Studies/LauncherDialog.tsx
index 9698a79efa..136c6b5ca7 100644
--- a/webapp/src/components/App/Studies/LauncherDialog.tsx
+++ b/webapp/src/components/App/Studies/LauncherDialog.tsx
@@ -47,7 +47,7 @@ import CheckBoxFE from "../../common/fieldEditors/CheckBoxFE";
import { convertVersions } from "../../../services/utils";
const LAUNCH_DURATION_MAX_HOURS = 240;
-const LAUNCH_LOAD_DEFAULT = 12;
+const LAUNCH_LOAD_DEFAULT = 22;
const LAUNCH_LOAD_SLIDER = { step: 1, min: 1, max: 24 };
interface Props {
diff --git a/webapp/src/services/utils/index.ts b/webapp/src/services/utils/index.ts
index be007f5836..5dc7a3fa70 100644
--- a/webapp/src/services/utils/index.ts
+++ b/webapp/src/services/utils/index.ts
@@ -148,8 +148,17 @@ export const exportText = (fileData: string, filename: string): void => {
link.remove();
};
-export const displayVersionName = (version: string): string =>
- version.split("").join(".");
+/**
+ * Gets the appropriate version name to display.
+ * The patch version is not displayed because it is not relevant.
+ * Its value is always 0 from the server.
+ *
+ * Ex: '820' -> '8.2'
+ *
+ * @param v Version in format '[major][minor]0' (ex: '820').
+ * @returns Version in format '[major].[minor]' (ex: '8.2').
+ */
+export const displayVersionName = (v: string): string => `${v[0]}.${v[1]}`;
export const convertVersions = (versions: Array): Array =>
versions.map((version) => ({