From b464a9bcded292041d25328ba6718d56c49cdea9 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 28 Oct 2024 15:20:59 +0100 Subject: [PATCH 01/38] use tempdir for behave tests --- tests/end_to_end/cucumber/{steps => }/__init__.py | 0 tests/end_to_end/cucumber/features/__init__.py | 0 tests/end_to_end/cucumber/features/environment.py | 6 ++++++ .../end_to_end/cucumber/features/steps/__init__.py | 0 .../cucumber/{ => features}/steps/steps.py | 14 +++++++++----- 5 files changed, 15 insertions(+), 5 deletions(-) rename tests/end_to_end/cucumber/{steps => }/__init__.py (100%) create mode 100644 tests/end_to_end/cucumber/features/__init__.py create mode 100644 tests/end_to_end/cucumber/features/environment.py create mode 100644 tests/end_to_end/cucumber/features/steps/__init__.py rename tests/end_to_end/cucumber/{ => features}/steps/steps.py (93%) diff --git a/tests/end_to_end/cucumber/steps/__init__.py b/tests/end_to_end/cucumber/__init__.py similarity index 100% rename from tests/end_to_end/cucumber/steps/__init__.py rename to tests/end_to_end/cucumber/__init__.py diff --git a/tests/end_to_end/cucumber/features/__init__.py b/tests/end_to_end/cucumber/features/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/end_to_end/cucumber/features/environment.py b/tests/end_to_end/cucumber/features/environment.py new file mode 100644 index 000000000..4dd9a9a57 --- /dev/null +++ b/tests/end_to_end/cucumber/features/environment.py @@ -0,0 +1,6 @@ +import tempfile +from pathlib import Path + + +def before_scenario(context, scenario): + context.temp_dir = Path(tempfile.TemporaryDirectory().name) diff --git a/tests/end_to_end/cucumber/features/steps/__init__.py b/tests/end_to_end/cucumber/features/steps/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/end_to_end/cucumber/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py similarity index 93% rename from tests/end_to_end/cucumber/steps/steps.py rename to tests/end_to_end/cucumber/features/steps/steps.py index 429d99261..2a9443966 100644 --- a/tests/end_to_end/cucumber/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -1,19 +1,23 @@ import json import math import os +import shutil import subprocess from pathlib import Path - +from pytest import fixture import numpy as np from behave import * from utils_functions import get_mpi_command, get_conf + @given('the study path is "{string}"') def study_path_is(context, string): - context.study_path = os.path.join(Path() / "../../", - string.replace("/", os.sep)) + # context.study_path + context.study_path = Path() / "../../" / string + context.tmp_study = context.temp_dir / context.study_path.name + shutil.copytree(context.study_path, context.tmp_study) def build_outer_loop_command(context, n: int, option_file: str = "options.json"): @@ -51,8 +55,8 @@ def run_outer_loop(context, n, option_file: str = "options.json"): print(f"Running command: {command}") old_cwd = os.getcwd() - lp_path = Path(context.study_path) / "lp" if (Path(context.study_path) / "lp").exists() else Path( - context.study_path) + lp_path = Path(context.tmp_study) / "lp" if (Path(context.tmp_study) / "lp").exists() else Path( + context.tmp_study) os.chdir(lp_path) process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) From 80a019d12fba374b1a4a778c3f4c0c09a8da6a3c Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 29 Oct 2024 13:26:16 +0100 Subject: [PATCH 02/38] move utils functions --- .../Benders_criterion_output_tests.feature | 13 +++++++ .../cucumber/features/steps/steps.py | 6 +++- tests/end_to_end/examples/example_test.py | 32 ++--------------- tests/end_to_end/utils_functions.py | 36 +++++++++++++++++++ 4 files changed, 56 insertions(+), 31 deletions(-) create mode 100644 tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature diff --git a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature new file mode 100644 index 000000000..fbcbb42c4 --- /dev/null +++ b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature @@ -0,0 +1,13 @@ +Feature: outer loop tests + + @fast @short @Benders + Scenario: a system with 4 nodes, on 1 timestep, 2 scenarios + Given the study path is "data_test/external_loop_test" + When I run outer loop with 1 proc(s) + Then the simulation takes less than 5 seconds + And the simulation succeeds + And the expected overall cost is 92.70005 + And the solution is + | variable | value | + | G_p_max_0_0 | 2.900004 | + diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 2a9443966..19702c201 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -4,7 +4,6 @@ import shutil import subprocess from pathlib import Path -from pytest import fixture import numpy as np from behave import * @@ -146,6 +145,11 @@ def check_other_outputs(context): assert (is_column_full_of_zeros(context.positive_unsupplied_energy_file, 2)) +@then("the LOLD.txt is:") +def check_other_outputs(context): + expected_solution = {row['variable']: float(row['value']) for row in context.table} + assert_dict_allclose(context.outputs["solution"]["values"], expected_solution) + def get_results_file_path_from_logs(logs: bytes) -> str: for line in logs.splitlines(): if b'Optimization results available in : ' in line: diff --git a/tests/end_to_end/examples/example_test.py b/tests/end_to_end/examples/example_test.py index 343298e6e..47bc6c958 100644 --- a/tests/end_to_end/examples/example_test.py +++ b/tests/end_to_end/examples/example_test.py @@ -3,7 +3,6 @@ import shutil import subprocess import sys -import zipfile from enum import Enum from pathlib import Path @@ -11,7 +10,7 @@ import pytest from src.python.antares_xpansion.candidates_reader import CandidatesReader - +from tests.end_to_end.utils_functions import read_outputs ALL_STUDIES_PATH = Path("../../../data_test/examples") RELATIVE_TOLERANCE = 1e-4 RELATIVE_TOLERANCE_LIGHT = 1e-2 @@ -22,22 +21,6 @@ class BendersMethod(Enum): BENDERS_BY_BATCH = "benders_by_batch" -def get_json_filepath(output_dir, folder, filename): - op = [] - for path in Path(output_dir).iterdir(): - for jsonpath in Path(path / folder).rglob(filename): - op.append(jsonpath) - assert len(op) == 1 - return op[0] - -def get_json_file_data(output_dir, folder, filename): - data = None - for path in Path(output_dir).iterdir(): - if path.suffix == ".zip": - with zipfile.ZipFile(path, "r") as archive: - data = json.loads(archive.read(folder+"/"+filename)) - return data - def remove_outputs(study_path): output_path = study_path / "output" @@ -120,18 +103,7 @@ def verify_solution(study_path, expected_values, expected_investment_solution, method: BendersMethod = BendersMethod.BENDERS, use_archive=True): output_path = study_path / "output" - if use_archive: - json_data = get_json_file_data(output_path, "expansion", "out.json") - options_data = get_json_file_data(output_path, "lp", "options.json") - else: - json_path = get_json_filepath(output_path, "expansion", "out.json") - options_path = get_json_filepath(output_path, "lp", "options.json") - - with open(str(json_path), "r") as json_file: - json_data = json.load(json_file) - - with open(str(options_path), "r") as options_file: - options_data = json.load(options_file) + json_data, options_data = read_outputs(output_path, use_archive) solution = json_data["solution"] investment_solution = solution["values"] diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index 856567248..91d087f9f 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -1,5 +1,7 @@ +import json import os import sys +import zipfile from pathlib import Path import yaml @@ -38,3 +40,37 @@ def get_mpi_command(allow_run_as_root=False, nproc: int = 1): return [MPI_LAUNCHER, "--allow-run-as-root", MPI_N, nproc_str, "--oversubscribe"] else: return [MPI_LAUNCHER, MPI_N, nproc_str, "--oversubscribe"] + + +def get_json_filepath(output_dir, folder, filename): + op = [] + for path in Path(output_dir).iterdir(): + for jsonpath in Path(path / folder).rglob(filename): + op.append(jsonpath) + assert len(op) == 1 + return op[0] + + +def get_json_file_data(output_dir, folder, filename): + data = None + for path in Path(output_dir).iterdir(): + if path.suffix == ".zip": + with zipfile.ZipFile(path, "r") as archive: + data = json.loads(archive.read(folder + "/" + filename)) + return data + + +def read_outputs(output_path, use_archive): + if use_archive: + json_data = get_json_file_data(output_path, "expansion", "out.json") + options_data = get_json_file_data(output_path, "lp", "options.json") + else: + json_path = get_json_filepath(output_path, "expansion", "out.json") + options_path = get_json_filepath(output_path, "lp", "options.json") + + with open(str(json_path), "r") as json_file: + json_data = json.load(json_file) + + with open(str(options_path), "r") as options_file: + options_data = json.load(options_file) + return json_data, options_data From 4cd68d5486140bf979f8bdf0267b38842ad4eda5 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 29 Oct 2024 13:59:40 +0100 Subject: [PATCH 03/38] use study copy for tests --- .../Benders_criterion_output_tests.feature | 18 +++++++++--------- .../cucumber/features/steps/steps.py | 14 +++++++++----- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature index fbcbb42c4..1f783ad1b 100644 --- a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature +++ b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature @@ -1,13 +1,13 @@ Feature: outer loop tests @fast @short @Benders - Scenario: a system with 4 nodes, on 1 timestep, 2 scenarios - Given the study path is "data_test/external_loop_test" - When I run outer loop with 1 proc(s) - Then the simulation takes less than 5 seconds - And the simulation succeeds - And the expected overall cost is 92.70005 - And the solution is - | variable | value | - | G_p_max_0_0 | 2.900004 | + Scenario: xpansion-test-01 + Given the study path is "data_test/examples/xpansion-test-01" + When I run antares-xpansion with the benders method and 1 proc(s) + Then the simulation takes less than 300 seconds +# And the simulation succeeds +# And the expected overall cost is 92.70005 +# And the solution is +# | variable | value | +# | G_p_max_0_0 | 2.900004 | diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 19702c201..1c773cb0f 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -7,7 +7,8 @@ import numpy as np from behave import * -from utils_functions import get_mpi_command, get_conf +from utils_functions import get_mpi_command, get_conf, read_outputs + @@ -70,13 +71,16 @@ def run_outer_loop(context, n, option_file: str = "options.json"): os.chdir(old_cwd) -@when('I run antares-xpansion in memory with the {method} method and {n:d} proc(s)') -def run_antares_xpansion(context, method, n): - command = build_launch_command(context.study_path, method, n, True) +@when('I run antares-xpansion with the {method} method and {n:d} proc(s)') +@when('I run antares-xpansion in {memory} with the {method} method and {n:d} proc(s)') +def run_antares_xpansion(context, method, memory=None, n: int = 1): + memory = True if memory is not None else False + command = build_launch_command(context.tmp_study, method, n, memory) process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True) out, err = process.communicate() context.return_code = process.returncode - context.outputs = read_json_file(Path(get_results_file_path_from_logs(out))) + output_path = context.tmp_study / "output" + context.outputs, context.options_data = read_outputs(output_path, use_archive=True) @then("the simulation takes less than {seconds:d} seconds") From 726cb5cf192f61445294a918415ef8de0f6261d1 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 29 Oct 2024 14:39:00 +0100 Subject: [PATCH 04/38] update outputs parsing --- .../Benders_criterion_output_tests.feature | 2 +- .../cucumber/features/steps/steps.py | 12 ++-- tests/end_to_end/examples/example_test.py | 5 +- tests/end_to_end/utils_functions.py | 71 +++++++++++++++---- 4 files changed, 67 insertions(+), 23 deletions(-) diff --git a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature index 1f783ad1b..83d747455 100644 --- a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature +++ b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature @@ -5,7 +5,7 @@ Feature: outer loop tests Given the study path is "data_test/examples/xpansion-test-01" When I run antares-xpansion with the benders method and 1 proc(s) Then the simulation takes less than 300 seconds -# And the simulation succeeds + And the simulation succeeds # And the expected overall cost is 92.70005 # And the solution is # | variable | value | diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 1c773cb0f..53f4f2a29 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -41,12 +41,6 @@ def read_json_file(output_path): return outputs -def read_file(output_path): - with open(output_path, 'r') as file: - outputs = file.readlines() - return outputs - - @when('I run outer loop with {n:d} proc(s) and "{option_file}" as option file') @when('I run outer loop with {n:d} proc(s)') def run_outer_loop(context, n, option_file: str = "options.json"): @@ -80,7 +74,11 @@ def run_antares_xpansion(context, method, memory=None, n: int = 1): out, err = process.communicate() context.return_code = process.returncode output_path = context.tmp_study / "output" - context.outputs, context.options_data = read_outputs(output_path, use_archive=True) + outputs = read_outputs(output_path, use_archive=True, lold=True, positive_unsupplied_energy=True) + context.outputs = outputs.out_json + context.options_data = outputs.options_json + context.lold = outputs.lold + context.positive_unsupplied_energy = outputs.positive_unsupplied_energy @then("the simulation takes less than {seconds:d} seconds") diff --git a/tests/end_to_end/examples/example_test.py b/tests/end_to_end/examples/example_test.py index 47bc6c958..3afafb126 100644 --- a/tests/end_to_end/examples/example_test.py +++ b/tests/end_to_end/examples/example_test.py @@ -102,8 +102,9 @@ def assert_convergence(solution, options_data, method: BendersMethod): def verify_solution(study_path, expected_values, expected_investment_solution, method: BendersMethod = BendersMethod.BENDERS, use_archive=True): output_path = study_path / "output" - - json_data, options_data = read_outputs(output_path, use_archive) + outputs = read_outputs(output_path, use_archive) + json_data = outputs.out_json + options_data = outputs.options_json solution = json_data["solution"] investment_solution = solution["values"] diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index 91d087f9f..90d65e589 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -5,6 +5,7 @@ from pathlib import Path import yaml +from dataclasses import dataclass # File CONFIG_FILE_PATH # yaml file containing executable name @@ -42,7 +43,7 @@ def get_mpi_command(allow_run_as_root=False, nproc: int = 1): return [MPI_LAUNCHER, MPI_N, nproc_str, "--oversubscribe"] -def get_json_filepath(output_dir, folder, filename): +def get_filepath(output_dir, folder, filename): op = [] for path in Path(output_dir).iterdir(): for jsonpath in Path(path / folder).rglob(filename): @@ -51,26 +52,70 @@ def get_json_filepath(output_dir, folder, filename): return op[0] -def get_json_file_data(output_dir, folder, filename): - data = None +def read_file(output_path): + with open(output_path, 'r') as file: + outputs = file.readlines() + return outputs + + +class FilesToRead: + out_json: Path + options_json: Path + lold: Path = None + positive_unsupplied_energy: Path = None + + +class Outputs: + out_json: str + options_json: str + lold: str + positive_unsupplied_energy: str + + +def get_out_data(output_dir, files_to_read: FilesToRead) -> Outputs: for path in Path(output_dir).iterdir(): if path.suffix == ".zip": with zipfile.ZipFile(path, "r") as archive: - data = json.loads(archive.read(folder + "/" + filename)) - return data + out: Outputs + out.out_json = json.loads(archive.read(files_to_read.out_json)) + out.out_json = json.loads(archive.read(files_to_read.out_json)) + if files_to_read.lold: + out.lold = archive.read(files_to_read.lold).decode('utf-8') + if files_to_read.positive_unsupplied_energy: + out.positive_unsupplied_energy = archive.read(files_to_read.positive_unsupplied_energy).decode( + 'utf-8') + return out + return None + + +def read_outputs(output_path, use_archive=True, lold=False, positive_unsupplied_energy=False): + files_to_read: FilesToRead + files_to_read.out_json = Path("expansion") / "out.json" + files_to_read.options_json = Path("lp") / "options.json" + + if lold: + files_to_read.lold = Path("lp") / "LOLD.txt" + if positive_unsupplied_energy: + files_to_read.positive_unsupplied_energy = Path("lp") / "PositiveUnsuppliedEnergy.txt" -def read_outputs(output_path, use_archive): if use_archive: - json_data = get_json_file_data(output_path, "expansion", "out.json") - options_data = get_json_file_data(output_path, "lp", "options.json") + return get_out_data(output_path, files_to_read) else: - json_path = get_json_filepath(output_path, "expansion", "out.json") - options_path = get_json_filepath(output_path, "lp", "options.json") + out: Outputs + json_path = get_filepath(output_path, "expansion", "out.json") + options_path = get_filepath(output_path, "lp", "options.json") with open(str(json_path), "r") as json_file: - json_data = json.load(json_file) + out.out_json = json.load(json_file) with open(str(options_path), "r") as options_file: - options_data = json.load(options_file) - return json_data, options_data + out.options_json = json.load(options_file) + + if lold: + out.lold = read_file(get_filepath(output_path, "lp", "LOLD.txt")) + if positive_unsupplied_energy: + out.positive_unsupplied_energy = read_file( + get_filepath(output_path, "lp", "PositiveUnsuppliedEnergy.txt")) + + return out From 75354cd8c04a0b86aad89f2180707d0c1b34f311 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 29 Oct 2024 14:59:03 +0100 Subject: [PATCH 05/38] fix --- tests/end_to_end/utils_functions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index 90d65e589..9e8e5fd88 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -76,7 +76,7 @@ def get_out_data(output_dir, files_to_read: FilesToRead) -> Outputs: for path in Path(output_dir).iterdir(): if path.suffix == ".zip": with zipfile.ZipFile(path, "r") as archive: - out: Outputs + out: Outputs = None out.out_json = json.loads(archive.read(files_to_read.out_json)) out.out_json = json.loads(archive.read(files_to_read.out_json)) if files_to_read.lold: @@ -90,7 +90,7 @@ def get_out_data(output_dir, files_to_read: FilesToRead) -> Outputs: def read_outputs(output_path, use_archive=True, lold=False, positive_unsupplied_energy=False): - files_to_read: FilesToRead + files_to_read: FilesToRead = None files_to_read.out_json = Path("expansion") / "out.json" files_to_read.options_json = Path("lp") / "options.json" @@ -102,7 +102,7 @@ def read_outputs(output_path, use_archive=True, lold=False, positive_unsupplied_ if use_archive: return get_out_data(output_path, files_to_read) else: - out: Outputs + out: Outputs = None json_path = get_filepath(output_path, "expansion", "out.json") options_path = get_filepath(output_path, "lp", "options.json") From be2e741c35958a39428ad6d163a4fd234ba02bb9 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 29 Oct 2024 15:02:21 +0100 Subject: [PATCH 06/38] Run Benders test with cucumber --- .github/workflows/build_ubuntu.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_ubuntu.yml b/.github/workflows/build_ubuntu.yml index f6e4bafd1..a8ea1aace 100644 --- a/.github/workflows/build_ubuntu.yml +++ b/.github/workflows/build_ubuntu.yml @@ -150,12 +150,18 @@ jobs: run: | cmake --build _build --config Release -j$(nproc) - - name: Run cucumber on outer_loop tests + - name: outer_loop tests with cucumber uses: ./.github/workflows/cucumber-tests with: feature: "features/outer_loop_tests.feature" mpi_path: ${{ github.workspace }}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin + - name: tests Benders Outputs with cucumber + uses: ./.github/workflows/cucumber-tests + with: + feature: "features/Benders_criterion_output_tests.feature" + mpi_path: ${{ github.workspace }}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin + - name: Test run: | From 5b0caf78d2782e17f7c9f49466160ccbc1d85661 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 29 Oct 2024 16:34:53 +0100 Subject: [PATCH 07/38] use default ctor --- tests/end_to_end/utils_functions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index 9e8e5fd88..abdd1cd32 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -76,7 +76,7 @@ def get_out_data(output_dir, files_to_read: FilesToRead) -> Outputs: for path in Path(output_dir).iterdir(): if path.suffix == ".zip": with zipfile.ZipFile(path, "r") as archive: - out: Outputs = None + out = Outputs() out.out_json = json.loads(archive.read(files_to_read.out_json)) out.out_json = json.loads(archive.read(files_to_read.out_json)) if files_to_read.lold: @@ -90,7 +90,7 @@ def get_out_data(output_dir, files_to_read: FilesToRead) -> Outputs: def read_outputs(output_path, use_archive=True, lold=False, positive_unsupplied_energy=False): - files_to_read: FilesToRead = None + files_to_read = FilesToRead() files_to_read.out_json = Path("expansion") / "out.json" files_to_read.options_json = Path("lp") / "options.json" @@ -102,7 +102,7 @@ def read_outputs(output_path, use_archive=True, lold=False, positive_unsupplied_ if use_archive: return get_out_data(output_path, files_to_read) else: - out: Outputs = None + out = Outputs() json_path = get_filepath(output_path, "expansion", "out.json") options_path = get_filepath(output_path, "lp", "options.json") From 1b5bf312b657d7c252608b0167ef1eaab415e578 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 29 Oct 2024 16:43:01 +0100 Subject: [PATCH 08/38] as_posix --- tests/end_to_end/utils_functions.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index abdd1cd32..f6dd5491c 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -77,12 +77,13 @@ def get_out_data(output_dir, files_to_read: FilesToRead) -> Outputs: if path.suffix == ".zip": with zipfile.ZipFile(path, "r") as archive: out = Outputs() - out.out_json = json.loads(archive.read(files_to_read.out_json)) - out.out_json = json.loads(archive.read(files_to_read.out_json)) + out.out_json = json.loads(archive.read(files_to_read.out_json.as_posix())) + out.options_json = json.loads(archive.read(files_to_read.out_json.as_posix())) if files_to_read.lold: - out.lold = archive.read(files_to_read.lold).decode('utf-8') + out.lold = archive.read(files_to_read.lold.as_posix()).decode('utf-8') if files_to_read.positive_unsupplied_energy: - out.positive_unsupplied_energy = archive.read(files_to_read.positive_unsupplied_energy).decode( + out.positive_unsupplied_energy = archive.read( + files_to_read.positive_unsupplied_energy.as_posix()).decode( 'utf-8') return out From 4a4dfc641a928f2a6fc9c1ebd150e1a58d1dd410 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 29 Oct 2024 17:05:50 +0100 Subject: [PATCH 09/38] user input --- tests/end_to_end/utils_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index f6dd5491c..a69b4e780 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -78,7 +78,7 @@ def get_out_data(output_dir, files_to_read: FilesToRead) -> Outputs: with zipfile.ZipFile(path, "r") as archive: out = Outputs() out.out_json = json.loads(archive.read(files_to_read.out_json.as_posix())) - out.options_json = json.loads(archive.read(files_to_read.out_json.as_posix())) + out.options_json = json.loads(archive.read(files_to_read.options_json.as_posix())) if files_to_read.lold: out.lold = archive.read(files_to_read.lold.as_posix()).decode('utf-8') if files_to_read.positive_unsupplied_energy: From 49f7b98709c42cf8e50a20dbf4d6fb6817be56a4 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 30 Oct 2024 12:32:57 +0100 Subject: [PATCH 10/38] update --- .../benders/benders_core/BendersMathLogger.h | 2 +- .../Benders_criterion_output_tests.feature | 30 ++++++++-- .../cucumber/features/steps/steps.py | 55 +++++++++++++++++-- 3 files changed, 78 insertions(+), 9 deletions(-) diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h index 861128678..3d3b9eddb 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h @@ -45,7 +45,7 @@ class LogDestination { }; template std::ostream& LogDestination::operator<<(const T& obj) { - return (*stream_) << std::left << std::setw(width_) << obj; + return (*stream_) << "| " << std::left << std::setw(width_) << obj; } void PrintBendersData(LogDestination& log_destination, const CurrentIterationData& data, const HEADERSTYPE& type, diff --git a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature index 83d747455..b9d812457 100644 --- a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature +++ b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature @@ -6,8 +6,30 @@ Feature: outer loop tests When I run antares-xpansion with the benders method and 1 proc(s) Then the simulation takes less than 300 seconds And the simulation succeeds -# And the expected overall cost is 92.70005 -# And the solution is -# | variable | value | -# | G_p_max_0_0 | 2.900004 | + And the expected Positive Unsupplied Energy is: + | Outer loop | Ite | area1 | area2 | flex | peak | pv | semibase | store_in | store_out + | 0 | 1 | 5.3771400000e+05 | 4.3137090000e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.6208000000e+07 | 0.0000000000e+00 + | 0 | 2 | 3.5308500000e+04 | 3.1096971069e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.5156337018e+07 | 1.9520000000e-02 + | 0 | 3 | 1.6400000000e+03 | 2.5707979522e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4800616055e+07 | 2.0230000000e-02 + | 0 | 4 | 1.9800000000e+02 | 2.3400869580e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4641367990e+07 | 2.1180000000e-02 + | 0 | 5 | 1.5000000000e+01 | 2.2326080240e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4563004605e+07 | 2.1210000000e-02 + | 0 | 6 | 5.2566603689e+01 | 2.1822119631e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4526012326e+07 | 2.1190000000e-02 + | 0 | 7 | 1.3160579423e+02 | 2.1580236056e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4515297112e+07 | 2.1410000000e-02 + | 0 | 8 | 1.1480289711e+02 | 2.1459011556e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4510396117e+07 | 2.1350000000e-02 + | 0 | 9 | 1.0640144856e+02 | 2.1399579801e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4510156683e+07 | 2.1600000000e-02 + | 0 | 10 | 1.0220072428e+02 | 2.1369066777e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4507996161e+07 | 2.1630000000e-02 + | 0 | 11 | 1.0010036214e+02 | 2.1353880070e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4506928012e+07 | 2.1620000000e-02 + | 0 | 12 | 9.9050181069e+01 | 2.1346301325e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4506394365e+07 | 2.1610000000e-02 + | 0 | 13 | 9.8525090534e+01 | 2.1342512929e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4506126957e+07 | 2.1610000000e-02 + | 0 | 14 | 9.8262545267e+01 | 2.1340618754e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505993242e+07 | 2.1610000000e-02 + | 0 | 15 | 9.8131272633e+01 | 2.1339671667e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505926384e+07 | 2.1610000000e-02 + | 0 | 16 | 9.8065636316e+01 | 2.1339198123e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505892955e+07 | 2.1610000000e-02 + | 0 | 17 | 9.8032818157e+01 | 2.1338961351e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505876240e+07 | 2.1610000000e-02 + | 0 | 18 | 9.8016409078e+01 | 2.1338842965e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505867883e+07 | 2.1610000000e-02 + | 0 | 19 | 1.1900000000e+02 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 + | 0 | 20 | 3.2080000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 + | 0 | 21 | 1.4810000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 + | 0 | 22 | 1.4810000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 + + diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 53f4f2a29..6a687b633 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -147,10 +147,57 @@ def check_other_outputs(context): assert (is_column_full_of_zeros(context.positive_unsupplied_energy_file, 2)) -@then("the LOLD.txt is:") -def check_other_outputs(context): - expected_solution = {row['variable']: float(row['value']) for row in context.table} - assert_dict_allclose(context.outputs["solution"]["values"], expected_solution) +def read_table_from_file(filename): + current_results = [] + + with open(filename, 'r') as file: + # Read the header line and remove the leading pipe + headers = file.readline().strip().split('|')[1:] # Skip the first empty element + + # Read each subsequent line + for line in file: + # Strip whitespace and split by '|', skipping the first element + values = line.strip().split('|')[1:] # Skip the first empty element + # Create a dictionary for the current row + row_dict = {headers[i].strip(): values[i].strip() for i in range(len(headers))} + current_results.append(row_dict) + + return current_results + + +def read_table_from_string(raw_data): + current_results = [] + + # Split the raw data into lines + lines = raw_data.strip().split('\n') + + # Read the header line and remove the leading pipe + headers = lines[0].strip().split('|')[1:] # Skip the first empty element + + # Read each subsequent line + for line in lines[1:]: + # Strip whitespace and split by '|', skipping the first element + values = line.strip().split('|')[1:] # Skip the first empty element + # Create a dictionary for the current row + row_dict = {headers[i].strip(): float(values[i].strip()) for i in range(len(headers))} + current_results.append(row_dict) + + return current_results + + +@then("the expected Positive Unsupplied Energy is:") +def check_positive_unsupplied_energy(context): + results = read_table_from_string(context.positive_unsupplied_energy) + headers = context.table.headings + + assert len(context.table) == len(results) + for i, row in enumerate(context.table): + for header in headers: + expected_value = float(row[header]) + actual = results[i][header] + + np.testing.assert_allclose(actual, expected_value, rtol=1e-6, atol=0, + err_msg=f"Mismatch in row {i + 1}, column '{header}': expected {expected_value}, got {actual_value}") def get_results_file_path_from_logs(logs: bytes) -> str: for line in logs.splitlines(): From 64c0fa08177ab4ded9b70d2cb7d861c6cbb28060 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Thu, 31 Oct 2024 10:12:22 +0100 Subject: [PATCH 11/38] daa --- src/cpp/benders/benders_core/BendersMathLogger.cpp | 13 +++++++++++++ .../benders/benders_core/BendersMathLogger.h | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/cpp/benders/benders_core/BendersMathLogger.cpp b/src/cpp/benders/benders_core/BendersMathLogger.cpp index b0aa1c1a3..3c4ed9313 100644 --- a/src/cpp/benders/benders_core/BendersMathLogger.cpp +++ b/src/cpp/benders/benders_core/BendersMathLogger.cpp @@ -155,27 +155,40 @@ void PrintBendersData(LogDestination& log_destination, const CurrentIterationData& data, const HEADERSTYPE& type, const BENDERSMETHOD& method) { log_destination << data.it; + log_destination.InsertDelimiter(); log_destination << std::scientific << std::setprecision(10) << data.lb; + log_destination.InsertDelimiter(); if (method == BENDERSMETHOD::BENDERS) { log_destination << std::scientific << std::setprecision(10) << data.ub; + log_destination.InsertDelimiter(); log_destination << std::scientific << std::setprecision(10) << data.best_ub; + log_destination.InsertDelimiter(); log_destination << std::scientific << std::setprecision(2) << data.best_ub - data.lb; + log_destination.InsertDelimiter(); log_destination << std::scientific << std::setprecision(2) << (data.best_ub - data.lb) / data.best_ub; + log_destination.InsertDelimiter(); } log_destination << data.min_simplexiter; + log_destination.InsertDelimiter(); log_destination << data.max_simplexiter; + log_destination.InsertDelimiter(); if (type == HEADERSTYPE::LONG || method == BENDERSMETHOD::BENDERS_BY_BATCH) { log_destination << data.number_of_subproblem_solved; + log_destination.InsertDelimiter(); } if (type == HEADERSTYPE::LONG) { log_destination << data.cumulative_number_of_subproblem_solved; + log_destination.InsertDelimiter(); } log_destination << std::setprecision(2) << data.iteration_time; + log_destination.InsertDelimiter(); log_destination << std::setprecision(2) << data.timer_master; + log_destination.InsertDelimiter(); log_destination << std::setprecision(2) << data.subproblems_walltime; + log_destination.InsertDelimiter(); if (type == HEADERSTYPE::LONG) { log_destination << std::setprecision(2) diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h index 3d3b9eddb..a57cfa25b 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h @@ -37,6 +37,7 @@ class LogDestination { template std::ostream& operator<<(const T& obj); + std::ostream& InsertDelimiter() { return *stream_ << "| "; } private: std::ofstream file_stream_; @@ -45,7 +46,7 @@ class LogDestination { }; template std::ostream& LogDestination::operator<<(const T& obj) { - return (*stream_) << "| " << std::left << std::setw(width_) << obj; + return (*stream_) << std::left << std::setw(width_) << obj; } void PrintBendersData(LogDestination& log_destination, const CurrentIterationData& data, const HEADERSTYPE& type, From 5a7564ef537c527329b9c13c75011be5e3d1622b Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 4 Nov 2024 11:01:13 +0100 Subject: [PATCH 12/38] insert delimiter --- .../benders/benders_core/BendersMathLogger.cpp | 15 +++++++++++++++ .../benders/benders_core/BendersMathLogger.h | 9 ++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/cpp/benders/benders_core/BendersMathLogger.cpp b/src/cpp/benders/benders_core/BendersMathLogger.cpp index 3c4ed9313..74512aa49 100644 --- a/src/cpp/benders/benders_core/BendersMathLogger.cpp +++ b/src/cpp/benders/benders_core/BendersMathLogger.cpp @@ -82,11 +82,15 @@ LogDestination::LogDestination(const std::filesystem::path& file_path, std::cerr << err_msg.str(); } } +void LogDestination::setDelimiter(const std::string& delimiter) { + delimiter_ = delimiter; +} void MathLoggerBehaviour::write_header() { setHeadersList(); for (const auto& header : Headers()) { LogsDestination() << header; + LogsDestination().InsertDelimiter(); } LogsDestination() << std::endl; } @@ -185,18 +189,22 @@ void PrintBendersData(LogDestination& log_destination, log_destination << std::setprecision(2) << data.iteration_time; log_destination.InsertDelimiter(); + log_destination << std::setprecision(2) << data.timer_master; log_destination.InsertDelimiter(); + log_destination << std::setprecision(2) << data.subproblems_walltime; log_destination.InsertDelimiter(); if (type == HEADERSTYPE::LONG) { log_destination << std::setprecision(2) << data.subproblems_cumulative_cputime; + log_destination.InsertDelimiter(); log_destination << std::setprecision(2) << getDurationNotSolving(data.iteration_time, data.timer_master, data.subproblems_walltime); + log_destination.InsertDelimiter(); } log_destination << std::endl; } @@ -206,22 +214,29 @@ void PrintExternalLoopData(LogDestination& log_destination, const HEADERSTYPE& type, const BENDERSMETHOD& method) { log_destination << data.outer_loop_current_iteration_data.benders_num_run; + log_destination.InsertDelimiter(); log_destination << std::scientific << std::setprecision(10) << data.outer_loop_current_iteration_data.max_criterion; + log_destination.InsertDelimiter(); log_destination << data.outer_loop_current_iteration_data.max_criterion_area; + log_destination.InsertDelimiter(); log_destination << std::scientific << std::setprecision(10) << data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub; + log_destination.InsertDelimiter(); log_destination << std::scientific << std::setprecision(10) << data.outer_loop_current_iteration_data.external_loop_lambda; + log_destination.InsertDelimiter(); log_destination << std::scientific << std::setprecision(10) << data.outer_loop_current_iteration_data.external_loop_lambda_min; + log_destination.InsertDelimiter(); log_destination << std::scientific << std::setprecision(10) << data.outer_loop_current_iteration_data.external_loop_lambda_max; + log_destination.InsertDelimiter(); PrintBendersData(log_destination, data, type, method); } void MathLoggerBaseExternalLoop::Print(const CurrentIterationData& data) { diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h index a57cfa25b..02e54e3af 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h @@ -37,12 +37,16 @@ class LogDestination { template std::ostream& operator<<(const T& obj); - std::ostream& InsertDelimiter() { return *stream_ << "| "; } + std::ostream& InsertDelimiter() { return *stream_ << delimiter_; } private: std::ofstream file_stream_; std::ostream* stream_; std::streamsize width_ = 40; + std::string delimiter_ = "|"; + + public: + void setDelimiter(const std::string& delimiter); }; template std::ostream& LogDestination::operator<<(const T& obj) { @@ -216,9 +220,12 @@ template void MathLoggerExternalLoopSpecific::Print( const CurrentIterationData& data) { LogsDestination() << data.outer_loop_current_iteration_data.benders_num_run; + LogsDestination().InsertDelimiter(); LogsDestination() << data.it; + LogsDestination().InsertDelimiter(); for (const auto& t : data.outer_loop_current_iteration_data.*ptr_) { LogsDestination() << std::scientific << std::setprecision(10) << t; + LogsDestination().InsertDelimiter(); } LogsDestination() << std::endl; } From 0ed669cede646ced52bdc32912abc6a471b98b44 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 4 Nov 2024 11:41:03 +0100 Subject: [PATCH 13/38] update --- .../benders_core/BendersMathLogger.cpp | 4 +- .../benders/benders_core/BendersMathLogger.h | 1 + .../Benders_criterion_output_tests.feature | 46 +++++++++--------- .../cucumber/features/steps/steps.py | 48 +++++++------------ 4 files changed, 43 insertions(+), 56 deletions(-) diff --git a/src/cpp/benders/benders_core/BendersMathLogger.cpp b/src/cpp/benders/benders_core/BendersMathLogger.cpp index 74512aa49..143c9885f 100644 --- a/src/cpp/benders/benders_core/BendersMathLogger.cpp +++ b/src/cpp/benders/benders_core/BendersMathLogger.cpp @@ -88,6 +88,7 @@ void LogDestination::setDelimiter(const std::string& delimiter) { void MathLoggerBehaviour::write_header() { setHeadersList(); + LogsDestination().InsertDelimiter(); for (const auto& header : Headers()) { LogsDestination() << header; LogsDestination().InsertDelimiter(); @@ -158,6 +159,7 @@ double getDurationNotSolving(double iteration, double master, void PrintBendersData(LogDestination& log_destination, const CurrentIterationData& data, const HEADERSTYPE& type, const BENDERSMETHOD& method) { + log_destination.InsertDelimiter(); log_destination << data.it; log_destination.InsertDelimiter(); log_destination << std::scientific << std::setprecision(10) << data.lb; @@ -213,6 +215,7 @@ void PrintExternalLoopData(LogDestination& log_destination, const CurrentIterationData& data, const HEADERSTYPE& type, const BENDERSMETHOD& method) { + log_destination.InsertDelimiter(); log_destination << data.outer_loop_current_iteration_data.benders_num_run; log_destination.InsertDelimiter(); log_destination << std::scientific << std::setprecision(10) @@ -236,7 +239,6 @@ void PrintExternalLoopData(LogDestination& log_destination, log_destination << std::scientific << std::setprecision(10) << data.outer_loop_current_iteration_data.external_loop_lambda_max; - log_destination.InsertDelimiter(); PrintBendersData(log_destination, data, type, method); } void MathLoggerBaseExternalLoop::Print(const CurrentIterationData& data) { diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h index 02e54e3af..9b1fdc0eb 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h @@ -219,6 +219,7 @@ void MathLoggerExternalLoopSpecific::setHeadersList() { template void MathLoggerExternalLoopSpecific::Print( const CurrentIterationData& data) { + LogsDestination().InsertDelimiter(); LogsDestination() << data.outer_loop_current_iteration_data.benders_num_run; LogsDestination().InsertDelimiter(); LogsDestination() << data.it; diff --git a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature index b9d812457..feee65af0 100644 --- a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature +++ b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature @@ -7,29 +7,29 @@ Feature: outer loop tests Then the simulation takes less than 300 seconds And the simulation succeeds And the expected Positive Unsupplied Energy is: - | Outer loop | Ite | area1 | area2 | flex | peak | pv | semibase | store_in | store_out - | 0 | 1 | 5.3771400000e+05 | 4.3137090000e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.6208000000e+07 | 0.0000000000e+00 - | 0 | 2 | 3.5308500000e+04 | 3.1096971069e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.5156337018e+07 | 1.9520000000e-02 - | 0 | 3 | 1.6400000000e+03 | 2.5707979522e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4800616055e+07 | 2.0230000000e-02 - | 0 | 4 | 1.9800000000e+02 | 2.3400869580e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4641367990e+07 | 2.1180000000e-02 - | 0 | 5 | 1.5000000000e+01 | 2.2326080240e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4563004605e+07 | 2.1210000000e-02 - | 0 | 6 | 5.2566603689e+01 | 2.1822119631e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4526012326e+07 | 2.1190000000e-02 - | 0 | 7 | 1.3160579423e+02 | 2.1580236056e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4515297112e+07 | 2.1410000000e-02 - | 0 | 8 | 1.1480289711e+02 | 2.1459011556e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4510396117e+07 | 2.1350000000e-02 - | 0 | 9 | 1.0640144856e+02 | 2.1399579801e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4510156683e+07 | 2.1600000000e-02 - | 0 | 10 | 1.0220072428e+02 | 2.1369066777e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4507996161e+07 | 2.1630000000e-02 - | 0 | 11 | 1.0010036214e+02 | 2.1353880070e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4506928012e+07 | 2.1620000000e-02 - | 0 | 12 | 9.9050181069e+01 | 2.1346301325e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4506394365e+07 | 2.1610000000e-02 - | 0 | 13 | 9.8525090534e+01 | 2.1342512929e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4506126957e+07 | 2.1610000000e-02 - | 0 | 14 | 9.8262545267e+01 | 2.1340618754e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505993242e+07 | 2.1610000000e-02 - | 0 | 15 | 9.8131272633e+01 | 2.1339671667e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505926384e+07 | 2.1610000000e-02 - | 0 | 16 | 9.8065636316e+01 | 2.1339198123e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505892955e+07 | 2.1610000000e-02 - | 0 | 17 | 9.8032818157e+01 | 2.1338961351e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505876240e+07 | 2.1610000000e-02 - | 0 | 18 | 9.8016409078e+01 | 2.1338842965e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505867883e+07 | 2.1610000000e-02 - | 0 | 19 | 1.1900000000e+02 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 - | 0 | 20 | 3.2080000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 - | 0 | 21 | 1.4810000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 - | 0 | 22 | 1.4810000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 + | Outer loop | Ite | area1 | area2 | flex | peak | pv | semibase | store_in | store_out | + | 0 | 1 | 5.3771400000e+05 | 4.3137090000e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.6208000000e+07 | 0.0000000000e+00 | + | 0 | 2 | 3.5308500000e+04 | 3.1096971069e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.5156337018e+07 | 1.9520000000e-02 | + | 0 | 3 | 1.6400000000e+03 | 2.5707979522e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4800616055e+07 | 2.0230000000e-02 | + | 0 | 4 | 1.9800000000e+02 | 2.3400869580e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4641367990e+07 | 2.1180000000e-02 | + | 0 | 5 | 1.5000000000e+01 | 2.2326080240e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4563004605e+07 | 2.1210000000e-02 | + | 0 | 6 | 5.2566603689e+01 | 2.1822119631e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4526012326e+07 | 2.1190000000e-02 | + | 0 | 7 | 1.3160579423e+02 | 2.1580236056e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4515297112e+07 | 2.1410000000e-02 | + | 0 | 8 | 1.1480289711e+02 | 2.1459011556e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4510396117e+07 | 2.1350000000e-02 | + | 0 | 9 | 1.0640144856e+02 | 2.1399579801e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4510156683e+07 | 2.1600000000e-02 | + | 0 | 10 | 1.0220072428e+02 | 2.1369066777e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4507996161e+07 | 2.1630000000e-02 | + | 0 | 11 | 1.0010036214e+02 | 2.1353880070e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4506928012e+07 | 2.1620000000e-02 | + | 0 | 12 | 9.9050181069e+01 | 2.1346301325e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4506394365e+07 | 2.1610000000e-02 | + | 0 | 13 | 9.8525090534e+01 | 2.1342512929e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4506126957e+07 | 2.1610000000e-02 | + | 0 | 14 | 9.8262545267e+01 | 2.1340618754e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505993242e+07 | 2.1610000000e-02 | + | 0 | 15 | 9.8131272633e+01 | 2.1339671667e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505926384e+07 | 2.1610000000e-02 | + | 0 | 16 | 9.8065636316e+01 | 2.1339198123e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505892955e+07 | 2.1610000000e-02 | + | 0 | 17 | 9.8032818157e+01 | 2.1338961351e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505876240e+07 | 2.1610000000e-02 | + | 0 | 18 | 9.8016409078e+01 | 2.1338842965e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4505867883e+07 | 2.1610000000e-02 | + | 0 | 19 | 1.1900000000e+02 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 | + | 0 | 20 | 3.2080000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 | + | 0 | 21 | 1.4810000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 | + | 0 | 22 | 1.4810000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 | diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 6a687b633..df46f05cf 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -1,3 +1,5 @@ +import csv +import io import json import math import os @@ -10,8 +12,6 @@ from utils_functions import get_mpi_command, get_conf, read_outputs - - @given('the study path is "{string}"') def study_path_is(context, string): # context.study_path @@ -147,40 +147,22 @@ def check_other_outputs(context): assert (is_column_full_of_zeros(context.positive_unsupplied_energy_file, 2)) -def read_table_from_file(filename): - current_results = [] - +def read_cucumber_table_from_file(filename): with open(filename, 'r') as file: - # Read the header line and remove the leading pipe - headers = file.readline().strip().split('|')[1:] # Skip the first empty element - - # Read each subsequent line - for line in file: - # Strip whitespace and split by '|', skipping the first element - values = line.strip().split('|')[1:] # Skip the first empty element - # Create a dictionary for the current row - row_dict = {headers[i].strip(): values[i].strip() for i in range(len(headers))} - current_results.append(row_dict) - - return current_results + reader = csv.reader(file, delimiter='|') + header = [item.strip() for item in + next(reader)[1:-1]] # Store the header row, ignoring the first and last columns + current_results = [{header[index]: item.strip() for index, item in enumerate(row[1:-1])} for row in + reader] + return current_results def read_table_from_string(raw_data): - current_results = [] - - # Split the raw data into lines - lines = raw_data.strip().split('\n') - - # Read the header line and remove the leading pipe - headers = lines[0].strip().split('|')[1:] # Skip the first empty element - - # Read each subsequent line - for line in lines[1:]: - # Strip whitespace and split by '|', skipping the first element - values = line.strip().split('|')[1:] # Skip the first empty element - # Create a dictionary for the current row - row_dict = {headers[i].strip(): float(values[i].strip()) for i in range(len(headers))} - current_results.append(row_dict) + reader = csv.reader(io.StringIO(raw_data), delimiter='|') + header = [item.strip() for item in + next(reader)[1:-1]] # Store the header row, ignoring the first and last columns + current_results = [{header[index]: item.strip() for index, item in enumerate(row[1:-1])} for row in + reader] return current_results @@ -188,6 +170,7 @@ def read_table_from_string(raw_data): @then("the expected Positive Unsupplied Energy is:") def check_positive_unsupplied_energy(context): results = read_table_from_string(context.positive_unsupplied_energy) + print(f"*********** {results} ************") headers = context.table.headings assert len(context.table) == len(results) @@ -199,6 +182,7 @@ def check_positive_unsupplied_energy(context): np.testing.assert_allclose(actual, expected_value, rtol=1e-6, atol=0, err_msg=f"Mismatch in row {i + 1}, column '{header}': expected {expected_value}, got {actual_value}") + def get_results_file_path_from_logs(logs: bytes) -> str: for line in logs.splitlines(): if b'Optimization results available in : ' in line: From 5bac492dc903ea30353d146519fca0301e50287a Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 5 Nov 2024 12:09:25 +0100 Subject: [PATCH 14/38] small changes --- .../features/Benders_criterion_output_tests.feature | 4 ++-- tests/end_to_end/cucumber/features/steps/steps.py | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature index feee65af0..606669227 100644 --- a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature +++ b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature @@ -1,4 +1,4 @@ -Feature: outer loop tests +Feature: Benders Criterion files @fast @short @Benders Scenario: xpansion-test-01 @@ -6,7 +6,7 @@ Feature: outer loop tests When I run antares-xpansion with the benders method and 1 proc(s) Then the simulation takes less than 300 seconds And the simulation succeeds - And the expected Positive Unsupplied Energy is: + And the expected Positive Unsupplied Energy is | Outer loop | Ite | area1 | area2 | flex | peak | pv | semibase | store_in | store_out | | 0 | 1 | 5.3771400000e+05 | 4.3137090000e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.6208000000e+07 | 0.0000000000e+00 | | 0 | 2 | 3.5308500000e+04 | 3.1096971069e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.5156337018e+07 | 1.9520000000e-02 | diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index df46f05cf..42379b5f8 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -72,6 +72,11 @@ def run_antares_xpansion(context, method, memory=None, n: int = 1): command = build_launch_command(context.tmp_study, method, n, memory) process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True) out, err = process.communicate() + print(out) + print("*****************") + print(err) + print("*****************") + context.return_code = process.returncode output_path = context.tmp_study / "output" outputs = read_outputs(output_path, use_archive=True, lold=True, positive_unsupplied_energy=True) @@ -167,19 +172,19 @@ def read_table_from_string(raw_data): return current_results -@then("the expected Positive Unsupplied Energy is:") +@then("the expected Positive Unsupplied Energy is") def check_positive_unsupplied_energy(context): results = read_table_from_string(context.positive_unsupplied_energy) print(f"*********** {results} ************") headers = context.table.headings - assert len(context.table) == len(results) + # assert len(context.table) == len(results) for i, row in enumerate(context.table): for header in headers: expected_value = float(row[header]) - actual = results[i][header] + actual_value = results[i][header] - np.testing.assert_allclose(actual, expected_value, rtol=1e-6, atol=0, + np.testing.assert_allclose(actual_value, expected_value, rtol=1e-6, atol=0, err_msg=f"Mismatch in row {i + 1}, column '{header}': expected {expected_value}, got {actual_value}") From 1586ef47fa0ee2d586d48a2bfad1971251c07561 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 5 Nov 2024 15:32:47 +0100 Subject: [PATCH 15/38] read floats --- tests/end_to_end/cucumber/features/steps/steps.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 42379b5f8..d18473ac5 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -175,14 +175,12 @@ def read_table_from_string(raw_data): @then("the expected Positive Unsupplied Energy is") def check_positive_unsupplied_energy(context): results = read_table_from_string(context.positive_unsupplied_energy) - print(f"*********** {results} ************") headers = context.table.headings - # assert len(context.table) == len(results) for i, row in enumerate(context.table): for header in headers: expected_value = float(row[header]) - actual_value = results[i][header] + actual_value = float(results[i][header]) np.testing.assert_allclose(actual_value, expected_value, rtol=1e-6, atol=0, err_msg=f"Mismatch in row {i + 1}, column '{header}': expected {expected_value}, got {actual_value}") From 2e73072cca6a88cac0289511673df8b1b7602222 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 5 Nov 2024 16:24:38 +0100 Subject: [PATCH 16/38] update test --- .../cucumber/features/steps/steps.py | 61 +++++++++---------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index d18473ac5..7412eaf3d 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -118,24 +118,38 @@ def check_solution(context): assert_dict_allclose(context.outputs["solution"]["values"], expected_solution) -def is_column_full_of_zeros(filename, column_index, abs_tol=1e-9): +def read_table_from_string(raw_data): + reader = csv.reader(io.StringIO(raw_data), delimiter='|') + header = [item.strip() for item in + next(reader)[1:-1]] # Store the header row, ignoring the first and last columns + current_results = [{header[index]: item.strip() for index, item in enumerate(row[1:-1])} for row in + reader] + + return current_results + + +def read_cucumber_table_from_file(filename): with open(filename, 'r') as file: - # Skip the header - next(file) + reader = csv.reader(file, delimiter='|') + header = [item.strip() for item in + next(reader)[1:-1]] # Store the header row, ignoring the first and last columns + current_results = [{header[index]: item.strip() for index, item in enumerate(row[1:-1])} for row in + reader] + return current_results - # Check each line in the file - for line in file: - columns = line.split() - # Ensure column exists - if column_index >= len(columns): - print(f"Error: Missing column at index {column_index} in line: {line.strip()}") - return False +def is_file_full_of_zeros(filename, abs_tol=1e-9): + data = read_cucumber_table_from_file(filename) + + for line_number, line in enumerate(data): + for key, value in line.items(): + if key in ["Outer loop", "Ite"]: + continue try: - value = float(columns[column_index]) + value = float(value) except (ValueError, IndexError): - print(f"Error parsing line: {line.strip()}") + print(f"Error parsing line: {line_number} at column {key}") return False # Use math.isclose to compare to zero with tolerance @@ -145,32 +159,13 @@ def is_column_full_of_zeros(filename, column_index, abs_tol=1e-9): return True - @then("LOLD.txt and PositiveUnsuppliedEnergy.txt files are full of zeros") def check_other_outputs(context): - assert (is_column_full_of_zeros(context.loss_of_load_file, 2)) - assert (is_column_full_of_zeros(context.positive_unsupplied_energy_file, 2)) - + assert (is_file_full_of_zeros(context.loss_of_load_file)) + assert (is_file_full_of_zeros(context.positive_unsupplied_energy_file)) -def read_cucumber_table_from_file(filename): - with open(filename, 'r') as file: - reader = csv.reader(file, delimiter='|') - header = [item.strip() for item in - next(reader)[1:-1]] # Store the header row, ignoring the first and last columns - current_results = [{header[index]: item.strip() for index, item in enumerate(row[1:-1])} for row in - reader] - return current_results -def read_table_from_string(raw_data): - reader = csv.reader(io.StringIO(raw_data), delimiter='|') - header = [item.strip() for item in - next(reader)[1:-1]] # Store the header row, ignoring the first and last columns - current_results = [{header[index]: item.strip() for index, item in enumerate(row[1:-1])} for row in - reader] - - return current_results - @then("the expected Positive Unsupplied Energy is") def check_positive_unsupplied_energy(context): From 53cc8fabb114b9de738e928bc4688ee144ecfd95 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 5 Nov 2024 16:32:31 +0100 Subject: [PATCH 17/38] enable new tests --- .github/workflows/build_centos7.yml | 4 ++-- .github/workflows/build_oracle8.yml | 4 ++-- .github/workflows/build_ubuntu.yml | 14 +++++++------- .github/workflows/build_windows.yml | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build_centos7.yml b/.github/workflows/build_centos7.yml index 2fa536992..022dd5029 100644 --- a/.github/workflows/build_centos7.yml +++ b/.github/workflows/build_centos7.yml @@ -176,10 +176,10 @@ jobs: cmake --build _build --config Release -j$(nproc) - - name: Run cucumber on outer_loop tests + - name: Tests with Cucumber uses: ./.github/workflows/cucumber-tests with: - feature: "features/outer_loop_tests.feature" + # feature: "features/outer_loop_tests.feature" mpi_path: ${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin - name: Cache vcpkg binary dir diff --git a/.github/workflows/build_oracle8.yml b/.github/workflows/build_oracle8.yml index 583fb57d7..0ab49eac4 100644 --- a/.github/workflows/build_oracle8.yml +++ b/.github/workflows/build_oracle8.yml @@ -146,10 +146,10 @@ jobs: cmake --build _build --config Release -j$(nproc) - - name: Run cucumber on outer_loop tests + - name: Tests with Cucumber uses: ./.github/workflows/cucumber-tests with: - feature: "features/outer_loop_tests.feature" + # feature: "features/outer_loop_tests.feature" mpi_path: ${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin - name: Running unit tests diff --git a/.github/workflows/build_ubuntu.yml b/.github/workflows/build_ubuntu.yml index a8ea1aace..6799595c6 100644 --- a/.github/workflows/build_ubuntu.yml +++ b/.github/workflows/build_ubuntu.yml @@ -150,17 +150,17 @@ jobs: run: | cmake --build _build --config Release -j$(nproc) - - name: outer_loop tests with cucumber + - name: Tests with Cucumber uses: ./.github/workflows/cucumber-tests with: - feature: "features/outer_loop_tests.feature" + # feature: "features/outer_loop_tests.feature" mpi_path: ${{ github.workspace }}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin - - name: tests Benders Outputs with cucumber - uses: ./.github/workflows/cucumber-tests - with: - feature: "features/Benders_criterion_output_tests.feature" - mpi_path: ${{ github.workspace }}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin + # - name: tests Benders Outputs with cucumber + # uses: ./.github/workflows/cucumber-tests + # with: + # feature: "features/Benders_criterion_output_tests.feature" + # mpi_path: ${{ github.workspace }}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin - name: Test diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml index f5e3225aa..6339c17dd 100644 --- a/.github/workflows/build_windows.yml +++ b/.github/workflows/build_windows.yml @@ -128,10 +128,10 @@ jobs: cmake --build _build --config Release -j4 - - name: Run cucumber on outer_loop tests + - name: Tests with Cucumber uses: ./.github/workflows/cucumber-tests with: - feature: "features/outer_loop_tests.feature" + # feature: "features/outer_loop_tests.feature" mpi_path: /c/Program Files/Microsoft MPI/Bin From 4ea2efdb95dfc46d8c6a8740bbac81956530018d Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 5 Nov 2024 16:40:53 +0100 Subject: [PATCH 18/38] checking lold --- .../Benders_criterion_output_tests.feature | 26 ++++++++++++++++++- .../cucumber/features/steps/steps.py | 15 ++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature index 606669227..02320906e 100644 --- a/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature +++ b/tests/end_to_end/cucumber/features/Benders_criterion_output_tests.feature @@ -6,7 +6,7 @@ Feature: Benders Criterion files When I run antares-xpansion with the benders method and 1 proc(s) Then the simulation takes less than 300 seconds And the simulation succeeds - And the expected Positive Unsupplied Energy is + And the expected positive unsupplied energy is | Outer loop | Ite | area1 | area2 | flex | peak | pv | semibase | store_in | store_out | | 0 | 1 | 5.3771400000e+05 | 4.3137090000e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.6208000000e+07 | 0.0000000000e+00 | | 0 | 2 | 3.5308500000e+04 | 3.1096971069e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.5156337018e+07 | 1.9520000000e-02 | @@ -30,6 +30,30 @@ Feature: Benders Criterion files | 0 | 20 | 3.2080000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 | | 0 | 21 | 1.4810000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 | | 0 | 22 | 1.4810000000e+03 | 3.2167972574e+06 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 2.4866362811e+07 | 2.2450000000e-02 | + And the expected loss of load is + | Outer loop | Ite | area1 | area2 | flex | peak | pv | semibase | store_in | store_out | + | 0 | 1 | 3.6366666667e+02 | 1.8480000000e+03 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 2 | 4.6333333333e+01 | 1.2103333333e+03 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 3 | 5.0000000000e+00 | 9.8900000000e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 4 | 6.6666666667e-01 | 8.8600000000e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 5 | 3.3333333333e-01 | 8.3900000000e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 6 | 3.3333333333e-01 | 8.2300000000e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 7 | 6.6666666667e-01 | 8.1633333333e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 8 | 6.6666666667e-01 | 8.1333333333e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 9 | 6.6666666667e-01 | 8.1066666667e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 10 | 6.6666666667e-01 | 8.0933333333e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 11 | 6.6666666667e-01 | 8.0733333333e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 12 | 6.6666666667e-01 | 8.0733333333e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 13 | 6.6666666667e-01 | 8.0733333333e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 14 | 6.6666666667e-01 | 8.0733333333e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 15 | 6.6666666667e-01 | 8.0733333333e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 16 | 6.6666666667e-01 | 8.0733333333e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 17 | 6.6666666667e-01 | 8.0733333333e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 18 | 6.6666666667e-01 | 8.0733333333e+02 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7360000000e+03 | 0.0000000000e+00 | + | 0 | 19 | 1.0000000000e+00 | 1.1003333333e+03 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7150000000e+03 | 0.0000000000e+00 | + | 0 | 20 | 7.3333333333e+00 | 1.1003333333e+03 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7150000000e+03 | 0.0000000000e+00 | + | 0 | 21 | 3.0000000000e+00 | 1.1003333333e+03 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7150000000e+03 | 0.0000000000e+00 | + | 0 | 22 | 3.0000000000e+00 | 1.1003333333e+03 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 0.0000000000e+00 | 8.7150000000e+03 | 0.0000000000e+00 | diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 7412eaf3d..e2493b44e 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -165,13 +165,20 @@ def check_other_outputs(context): assert (is_file_full_of_zeros(context.positive_unsupplied_energy_file)) - - -@then("the expected Positive Unsupplied Energy is") +@then("the expected positive unsupplied energy is") def check_positive_unsupplied_energy(context): results = read_table_from_string(context.positive_unsupplied_energy) - headers = context.table.headings + check_cucumber_table(context, results) + +@then("the expected loss of load is") +def check_loss_of_load_is(context): + results = read_table_from_string(context.lold) + check_cucumber_table(context, results) + + +def check_cucumber_table(context, results): + headers = context.table.headings for i, row in enumerate(context.table): for header in headers: expected_value = float(row[header]) From 59ca9188c3cfca6d2a300d4bf23f03f42a9261f9 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 10:16:21 +0100 Subject: [PATCH 19/38] switch case archive --- tests/end_to_end/cucumber/features/steps/steps.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index e2493b44e..7d1bba41f 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -72,14 +72,16 @@ def run_antares_xpansion(context, method, memory=None, n: int = 1): command = build_launch_command(context.tmp_study, method, n, memory) process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True) out, err = process.communicate() - print(out) - print("*****************") - print(err) - print("*****************") + # print(out) + # print("*****************") + # print(err) context.return_code = process.returncode output_path = context.tmp_study / "output" - outputs = read_outputs(output_path, use_archive=True, lold=True, positive_unsupplied_energy=True) + outputs = read_outputs(output_path, use_archive=not memory, lold=True, positive_unsupplied_energy=True) + print("*****************") + print(outputs.out_json) + print("*****************") context.outputs = outputs.out_json context.options_data = outputs.options_json context.lold = outputs.lold From dfa13c2726f5d9497b984179062628036b1a7ae2 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 10:35:57 +0100 Subject: [PATCH 20/38] update --- .../cucumber/features/steps/steps.py | 18 ++++++++++++------ .../cucumber/features/weights.feature | 9 +++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 7d1bba41f..139376834 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -72,16 +72,17 @@ def run_antares_xpansion(context, method, memory=None, n: int = 1): command = build_launch_command(context.tmp_study, method, n, memory) process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True) out, err = process.communicate() - # print(out) - # print("*****************") - # print(err) + print("*********************** Begin stdout ***********************") + print(out) + print("*********************** End stdout ***********************") + + print("*********************** Begin stderr ***********************") + print(err) + print("*********************** End stderr ***********************") context.return_code = process.returncode output_path = context.tmp_study / "output" outputs = read_outputs(output_path, use_archive=not memory, lold=True, positive_unsupplied_energy=True) - print("*****************") - print(outputs.out_json) - print("*****************") context.outputs = outputs.out_json context.options_data = outputs.options_json context.lold = outputs.lold @@ -103,6 +104,11 @@ def check_overall_cost(context, value): np.testing.assert_allclose(value, context.outputs["solution"]["overall_cost"], rtol=1e-6, atol=0) +@then("the expected investment cost is {value:g}") +def check_overall_cost(context, value): + np.testing.assert_allclose(value, context.outputs["solution"]["investment_cost"], rtol=1e-6, atol=0) + + def assert_dict_allclose(actual, expected, rtol=1e-06, atol=0): for key in expected: np.testing.assert_allclose( diff --git a/tests/end_to_end/cucumber/features/weights.feature b/tests/end_to_end/cucumber/features/weights.feature index 68b00ab30..ca396e126 100644 --- a/tests/end_to_end/cucumber/features/weights.feature +++ b/tests/end_to_end/cucumber/features/weights.feature @@ -7,3 +7,12 @@ Feature: add weights on MC years Given the study path is "examples/SmallTestFiveCandidatesWithWeights" When I run antares-xpansion in memory with the benders method and 1 proc(s) Then the simulation succeeds + And the expected overall cost is 24232177891.450203 + And the expected investment cost is 230600000.0 + And the solution is + | variable | value | + | battery | 1000.0 | + | peak | 1500.0000 | + | pv | 1000.0000 | + | semibase | 200.0 | + | transmission_line | 0.0 | From eb00a279ad86b6ee35d76d929926ddc66386d85b Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 10:48:03 +0100 Subject: [PATCH 21/38] update --- tests/end_to_end/cucumber/features/steps/steps.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 139376834..47cfbe0b9 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -82,6 +82,7 @@ def run_antares_xpansion(context, method, memory=None, n: int = 1): context.return_code = process.returncode output_path = context.tmp_study / "output" + subprocess.run(["ls", str(output_path)]) outputs = read_outputs(output_path, use_archive=not memory, lold=True, positive_unsupplied_energy=True) context.outputs = outputs.out_json context.options_data = outputs.options_json From b7aef6d3c54e1a8b45accf4246d33bfc069622c3 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 11:00:25 +0100 Subject: [PATCH 22/38] fix ci running on docker --- examples/SmallTestFiveCandidatesWithWeights/output/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/SmallTestFiveCandidatesWithWeights/output/.gitkeep diff --git a/examples/SmallTestFiveCandidatesWithWeights/output/.gitkeep b/examples/SmallTestFiveCandidatesWithWeights/output/.gitkeep new file mode 100644 index 000000000..e69de29bb From 1c8a5465e26b93dbe5e27c22ddecf14a17e981b9 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 11:06:55 +0100 Subject: [PATCH 23/38] update tests --- tests/cpp/logger/logger_test.cpp | 28 +++++++++++++++++++ .../cucumber/features/steps/steps.py | 1 - 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/cpp/logger/logger_test.cpp b/tests/cpp/logger/logger_test.cpp index 662c1220e..60fc3acc5 100644 --- a/tests/cpp/logger/logger_test.cpp +++ b/tests/cpp/logger/logger_test.cpp @@ -1016,36 +1016,52 @@ TEST(MathLoggerBendersBaseTest, DataInFileLong) { data.iteration_time - data.timer_master - data.subproblems_walltime; std::ostringstream expected_msg; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.it; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.lb; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.ub; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.best_ub; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(2) << data.best_ub - data.lb; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(2) << (data.best_ub - data.lb) / data.best_ub; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.min_simplexiter; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.max_simplexiter; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.number_of_subproblem_solved; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.cumulative_number_of_subproblem_solved; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.iteration_time; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.timer_master; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_walltime; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_cumulative_cputime; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << time_not_solving; + expected_msg << "|"; expected_msg << std::endl; auto log_file = CreateRandomSubDir(std::filesystem::temp_directory_path()) / "log.txt"; @@ -1076,28 +1092,40 @@ TEST(MathLoggerBendersBaseTest, DataInStdOutShort) { data.iteration_time - data.timer_master - data.subproblems_walltime; std::ostringstream expected_msg; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.it; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.lb; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.ub; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.best_ub; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(2) << data.best_ub - data.lb; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(2) << (data.best_ub - data.lb) / data.best_ub; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.min_simplexiter; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.max_simplexiter; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.iteration_time; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.timer_master; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_walltime; + expected_msg << "|"; expected_msg << std::endl; std::stringstream redirectedStdout; diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 47cfbe0b9..139376834 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -82,7 +82,6 @@ def run_antares_xpansion(context, method, memory=None, n: int = 1): context.return_code = process.returncode output_path = context.tmp_study / "output" - subprocess.run(["ls", str(output_path)]) outputs = read_outputs(output_path, use_archive=not memory, lold=True, positive_unsupplied_energy=True) context.outputs = outputs.out_json context.options_data = outputs.options_json From 54745453b4fc2c926e24c6eba60984b9f029d4b2 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 11:11:45 +0100 Subject: [PATCH 24/38] debug --- tests/end_to_end/utils_functions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index a69b4e780..3e8b3be69 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -46,7 +46,9 @@ def get_mpi_command(allow_run_as_root=False, nproc: int = 1): def get_filepath(output_dir, folder, filename): op = [] for path in Path(output_dir).iterdir(): + print(f"----------{path}---------------") for jsonpath in Path(path / folder).rglob(filename): + print(f"----------{jsonpath}---------------") op.append(jsonpath) assert len(op) == 1 return op[0] From db1e2fc2defb76e981f2f648b2cebd584e489e02 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 11:13:21 +0100 Subject: [PATCH 25/38] debug --- tests/end_to_end/utils_functions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index 3e8b3be69..52178e986 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -50,6 +50,7 @@ def get_filepath(output_dir, folder, filename): for jsonpath in Path(path / folder).rglob(filename): print(f"----------{jsonpath}---------------") op.append(jsonpath) + print(f"op = {op}***************************") assert len(op) == 1 return op[0] From 0367ce42c2f1b97deddc2a6ce74b4a044ce602da Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 11:22:25 +0100 Subject: [PATCH 26/38] clean output before the simulation --- tests/end_to_end/cucumber/features/steps/steps.py | 4 +++- tests/end_to_end/examples/example_test.py | 11 +---------- tests/end_to_end/utils_functions.py | 8 ++++++++ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 139376834..89a47b21a 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -9,7 +9,7 @@ import numpy as np from behave import * -from utils_functions import get_mpi_command, get_conf, read_outputs +from utils_functions import get_mpi_command, get_conf, read_outputs, remove_outputs @given('the study path is "{string}"') @@ -69,6 +69,8 @@ def run_outer_loop(context, n, option_file: str = "options.json"): @when('I run antares-xpansion in {memory} with the {method} method and {n:d} proc(s)') def run_antares_xpansion(context, method, memory=None, n: int = 1): memory = True if memory is not None else False + # Clean study output + remove_outputs(context.tmp_study) command = build_launch_command(context.tmp_study, method, n, memory) process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True) out, err = process.communicate() diff --git a/tests/end_to_end/examples/example_test.py b/tests/end_to_end/examples/example_test.py index 3afafb126..1f96b558b 100644 --- a/tests/end_to_end/examples/example_test.py +++ b/tests/end_to_end/examples/example_test.py @@ -10,7 +10,7 @@ import pytest from src.python.antares_xpansion.candidates_reader import CandidatesReader -from tests.end_to_end.utils_functions import read_outputs +from tests.end_to_end.utils_functions import read_outputs, remove_outputs ALL_STUDIES_PATH = Path("../../../data_test/examples") RELATIVE_TOLERANCE = 1e-4 RELATIVE_TOLERANCE_LIGHT = 1e-2 @@ -21,15 +21,6 @@ class BendersMethod(Enum): BENDERS_BY_BATCH = "benders_by_batch" - -def remove_outputs(study_path): - output_path = study_path / "output" - if os.path.isdir(output_path): - for f in Path(output_path).iterdir(): - if f.is_dir(): - shutil.rmtree(f) - - def launch_xpansion(install_dir, study_path, allow_run_as_root=False, nproc: int = 4): # Clean study output remove_outputs(study_path) diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index 52178e986..fe003ba56 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -1,5 +1,6 @@ import json import os +import shutil import sys import zipfile from pathlib import Path @@ -43,6 +44,13 @@ def get_mpi_command(allow_run_as_root=False, nproc: int = 1): return [MPI_LAUNCHER, MPI_N, nproc_str, "--oversubscribe"] +def remove_outputs(study_path): + output_path = study_path / "output" + if os.path.isdir(output_path): + for f in Path(output_path).iterdir(): + if f.is_dir(): + shutil.rmtree(f) + def get_filepath(output_dir, folder, filename): op = [] for path in Path(output_dir).iterdir(): From 37e70858baffdbef2a36f785dde6312ebe21cac7 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 11:30:09 +0100 Subject: [PATCH 27/38] remove and re-create outputs --- tests/end_to_end/utils_functions.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index fe003ba56..54c0dac82 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -47,9 +47,8 @@ def get_mpi_command(allow_run_as_root=False, nproc: int = 1): def remove_outputs(study_path): output_path = study_path / "output" if os.path.isdir(output_path): - for f in Path(output_path).iterdir(): - if f.is_dir(): - shutil.rmtree(f) + shutil.rmtree(output_path) + os.makedirs(output_path) def get_filepath(output_dir, folder, filename): op = [] From 554a693c292017900e8015f6640a626a5818cf42 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 11:37:08 +0100 Subject: [PATCH 28/38] update log tests --- tests/cpp/logger/logger_test.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/cpp/logger/logger_test.cpp b/tests/cpp/logger/logger_test.cpp index 60fc3acc5..5deeb1b15 100644 --- a/tests/cpp/logger/logger_test.cpp +++ b/tests/cpp/logger/logger_test.cpp @@ -867,8 +867,10 @@ TEST(MathLoggerBendersByBatchTest, HeadersListStdOutShort) { std::streamsize width = 25; std::ostringstream expected_msg; + expected_msg << "|"; for (const auto& header : headers_manager.HeadersList()) { expected_msg << std::setw(width) << std::left << header; + expected_msg << "|"; } expected_msg << std::endl; std::stringstream redirectedStdout; @@ -886,8 +888,10 @@ TEST(MathLoggerBendersByBatchTest, HeadersListFileLong) { std::streamsize width = 25; std::ostringstream expected_msg; + expected_msg << "|"; for (const auto& header : headers_manager.HeadersList()) { expected_msg << std::setw(width) << std::left << header; + expected_msg << "|"; } expected_msg << std::endl; auto log_file = @@ -919,27 +923,39 @@ TEST(MathLoggerBendersByBatchTest, DataInFileLong) { data.iteration_time - data.timer_master - data.subproblems_walltime; std::ostringstream expected_msg; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.it; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.lb; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.min_simplexiter; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.max_simplexiter; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.number_of_subproblem_solved; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.cumulative_number_of_subproblem_solved; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.iteration_time; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.timer_master; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_walltime; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_cumulative_cputime; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << time_not_solving; + expected_msg << "|"; expected_msg << std::endl; auto log_file = CreateRandomSubDir(std::filesystem::temp_directory_path()) / "log.txt"; @@ -970,20 +986,29 @@ TEST(MathLoggerBendersByBatchTest, DataInStdOutShort) { data.iteration_time - data.timer_master - data.subproblems_walltime; std::ostringstream expected_msg; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.it; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.lb; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.min_simplexiter; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.max_simplexiter; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << data.number_of_subproblem_solved; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.iteration_time; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.timer_master; + expected_msg << "|"; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_walltime; + expected_msg << "|"; expected_msg << std::endl; std::stringstream redirectedStdout; From d14d3f8184fe57c41e42a7a09fec2e62c07d8318 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 12:06:46 +0100 Subject: [PATCH 29/38] use sys path --- .../cucumber/features/steps/steps.py | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 89a47b21a..0e95d7060 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -5,6 +5,7 @@ import os import shutil import subprocess +import sys from pathlib import Path import numpy as np from behave import * @@ -28,10 +29,15 @@ def build_outer_loop_command(context, n: int, option_file: str = "options.json") return command -def build_launch_command(study_dir: str, method: str, nproc: int, in_memory: bool): - command = f"python ../../src/python/launch.py --installDir {get_conf('DEFAULT_INSTALL_DIR')} --dataDir {study_dir} --method {method} -n {nproc} --oversubscribe" +def build_launch_command(study_dir: Path, method: str, nproc: int, in_memory: bool): + command = [ + sys.executable, + "../../src/python/launch.py", "--installDir", str(get_conf('DEFAULT_INSTALL_DIR')), "--dataDir", + str(study_dir), "--method", + method, "-n", str(nproc), "--oversubscribe"] if in_memory: - command += " --memory" + command.append("--memory") + print(command) return command @@ -71,18 +77,8 @@ def run_antares_xpansion(context, method, memory=None, n: int = 1): memory = True if memory is not None else False # Clean study output remove_outputs(context.tmp_study) - command = build_launch_command(context.tmp_study, method, n, memory) - process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True) - out, err = process.communicate() - print("*********************** Begin stdout ***********************") - print(out) - print("*********************** End stdout ***********************") - - print("*********************** Begin stderr ***********************") - print(err) - print("*********************** End stderr ***********************") + run_command(context.tmp_study, memory, method, n) - context.return_code = process.returncode output_path = context.tmp_study / "output" outputs = read_outputs(output_path, use_archive=not memory, lold=True, positive_unsupplied_energy=True) context.outputs = outputs.out_json @@ -91,6 +87,21 @@ def run_antares_xpansion(context, method, memory=None, n: int = 1): context.positive_unsupplied_energy = outputs.positive_unsupplied_energy +def run_command(study_path, memory, method, n_mpi): + command = build_launch_command(study_path, method, n_mpi, memory) + print(f"Running command: {command}") + process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True) + out, err = process.communicate() + if process.returncode != 0: + print("*********************** Begin stdout ***********************") + print(out) + print("*********************** End stdout ***********************") + + print("*********************** Begin stderr ***********************") + print(err) + print("*********************** End stderr ***********************") + + @then("the simulation takes less than {seconds:d} seconds") def check_simu_time(context, seconds): assert context.outputs["run_duration"] <= seconds From 08ab4a543b7dcaf9adb7446fc709d955959d7cc9 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 12:19:40 +0100 Subject: [PATCH 30/38] check return code --- tests/end_to_end/cucumber/features/steps/steps.py | 4 +++- tests/end_to_end/utils_functions.py | 9 +-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 0e95d7060..325638191 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -77,7 +77,7 @@ def run_antares_xpansion(context, method, memory=None, n: int = 1): memory = True if memory is not None else False # Clean study output remove_outputs(context.tmp_study) - run_command(context.tmp_study, memory, method, n) + context.return_code = run_command(context.tmp_study, memory, method, n) output_path = context.tmp_study / "output" outputs = read_outputs(output_path, use_archive=not memory, lold=True, positive_unsupplied_energy=True) @@ -101,6 +101,8 @@ def run_command(study_path, memory, method, n_mpi): print(err) print("*********************** End stderr ***********************") + return process.returncode + @then("the simulation takes less than {seconds:d} seconds") def check_simu_time(context, seconds): diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index 54c0dac82..54d44a5a9 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -28,13 +28,9 @@ def get_conf(key: str): def get_mpi_command(allow_run_as_root=False, nproc: int = 1): - MPI_LAUNCHER = "" - MPI_N = "" nproc_str = str(nproc) if sys.platform.startswith("win32"): - MPI_LAUNCHER = "mpiexec" - MPI_N = "-n" - return [MPI_LAUNCHER, MPI_N, nproc_str] + return ["mpiexec", "-n", nproc_str] elif sys.platform.startswith("linux"): MPI_LAUNCHER = "mpirun" MPI_N = "-np" @@ -53,11 +49,8 @@ def remove_outputs(study_path): def get_filepath(output_dir, folder, filename): op = [] for path in Path(output_dir).iterdir(): - print(f"----------{path}---------------") for jsonpath in Path(path / folder).rglob(filename): - print(f"----------{jsonpath}---------------") op.append(jsonpath) - print(f"op = {op}***************************") assert len(op) == 1 return op[0] From 197eb8b1b588add36614d8ffa38bea03aa5b9047 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 6 Nov 2024 12:58:14 +0100 Subject: [PATCH 31/38] fix command --- tests/end_to_end/cucumber/features/steps/steps.py | 13 +++++++++---- tests/end_to_end/examples/example_test.py | 3 +-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 325638191..65187f61d 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -29,7 +29,7 @@ def build_outer_loop_command(context, n: int, option_file: str = "options.json") return command -def build_launch_command(study_dir: Path, method: str, nproc: int, in_memory: bool): +def build_launch_command(study_dir: Path, method: str, nproc: int, in_memory: bool, allow_run_as_root: bool = False): command = [ sys.executable, "../../src/python/launch.py", "--installDir", str(get_conf('DEFAULT_INSTALL_DIR')), "--dataDir", @@ -38,6 +38,8 @@ def build_launch_command(study_dir: Path, method: str, nproc: int, in_memory: bo if in_memory: command.append("--memory") print(command) + if allow_run_as_root: + command.append("--allow-run-as-root") return command @@ -77,7 +79,9 @@ def run_antares_xpansion(context, method, memory=None, n: int = 1): memory = True if memory is not None else False # Clean study output remove_outputs(context.tmp_study) - context.return_code = run_command(context.tmp_study, memory, method, n) + + context.return_code = run_command(context.tmp_study, memory=memory, method=method, n_mpi=n, + allow_run_as_root=get_conf("allow_run_as_root")) output_path = context.tmp_study / "output" outputs = read_outputs(output_path, use_archive=not memory, lold=True, positive_unsupplied_energy=True) @@ -87,8 +91,9 @@ def run_antares_xpansion(context, method, memory=None, n: int = 1): context.positive_unsupplied_energy = outputs.positive_unsupplied_energy -def run_command(study_path, memory, method, n_mpi): - command = build_launch_command(study_path, method, n_mpi, memory) +def run_command(study_path, memory, method, n_mpi, allow_run_as_root=False): + command = build_launch_command(study_path, method, nproc=n_mpi, in_memory=memory, + allow_run_as_root=allow_run_as_root) print(f"Running command: {command}") process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True) out, err = process.communicate() diff --git a/tests/end_to_end/examples/example_test.py b/tests/end_to_end/examples/example_test.py index 1f96b558b..7ff314504 100644 --- a/tests/end_to_end/examples/example_test.py +++ b/tests/end_to_end/examples/example_test.py @@ -1,5 +1,3 @@ -import json -import os import shutil import subprocess import sys @@ -11,6 +9,7 @@ from src.python.antares_xpansion.candidates_reader import CandidatesReader from tests.end_to_end.utils_functions import read_outputs, remove_outputs + ALL_STUDIES_PATH = Path("../../../data_test/examples") RELATIVE_TOLERANCE = 1e-4 RELATIVE_TOLERANCE_LIGHT = 1e-2 From 5e99a39de95d0aa34855e9c957a9699c2479dfed Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Thu, 7 Nov 2024 13:37:20 +0100 Subject: [PATCH 32/38] print logs --- .../end_to_end/cucumber/features/steps/steps.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 65187f61d..513e2032a 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -97,14 +97,14 @@ def run_command(study_path, memory, method, n_mpi, allow_run_as_root=False): print(f"Running command: {command}") process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True) out, err = process.communicate() - if process.returncode != 0: - print("*********************** Begin stdout ***********************") - print(out) - print("*********************** End stdout ***********************") - - print("*********************** Begin stderr ***********************") - print(err) - print("*********************** End stderr ***********************") + # if process.returncode != 0: + print("*********************** Begin stdout ***********************") + print(out) + print("*********************** End stdout ***********************") + + print("*********************** Begin stderr ***********************") + print(err) + print("*********************** End stderr ***********************") return process.returncode From 9dba1132ba3b655f7ef164e29b02dc96365f3b1a Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Thu, 7 Nov 2024 18:04:50 +0100 Subject: [PATCH 33/38] shell =False --- .../cucumber/features/steps/steps.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index 513e2032a..df41f0369 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -95,16 +95,16 @@ def run_command(study_path, memory, method, n_mpi, allow_run_as_root=False): command = build_launch_command(study_path, method, nproc=n_mpi, in_memory=memory, allow_run_as_root=allow_run_as_root) print(f"Running command: {command}") - process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True) + process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) out, err = process.communicate() - # if process.returncode != 0: - print("*********************** Begin stdout ***********************") - print(out) - print("*********************** End stdout ***********************") - - print("*********************** Begin stderr ***********************") - print(err) - print("*********************** End stderr ***********************") + if process.returncode != 0: + print("*********************** Begin stdout ***********************") + print(out) + print("*********************** End stdout ***********************") + + print("*********************** Begin stderr ***********************") + print(err) + print("*********************** End stderr ***********************") return process.returncode From 45ab2f181100edf6ff8c6c73af878bf54a661b67 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 8 Nov 2024 12:43:59 +0100 Subject: [PATCH 34/38] use invisible delimiter --- .../benders/benders_core/BendersMathLogger.h | 2 +- tests/cpp/logger/logger_test.cpp | 107 +++++++++--------- .../cucumber/features/steps/steps.py | 4 +- 3 files changed, 57 insertions(+), 56 deletions(-) diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h index 9b1fdc0eb..c1a62c16f 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h @@ -43,7 +43,7 @@ class LogDestination { std::ofstream file_stream_; std::ostream* stream_; std::streamsize width_ = 40; - std::string delimiter_ = "|"; + std::string delimiter_ = "\t"; public: void setDelimiter(const std::string& delimiter); diff --git a/tests/cpp/logger/logger_test.cpp b/tests/cpp/logger/logger_test.cpp index 5deeb1b15..b0feeaaf7 100644 --- a/tests/cpp/logger/logger_test.cpp +++ b/tests/cpp/logger/logger_test.cpp @@ -743,6 +743,7 @@ TEST_F(MasterLoggerTest, LogSwitchToInteger) { ASSERT_TRUE(_logger->_switchToIntegerCall); ASSERT_TRUE(_logger2->_switchToIntegerCall); } +static constexpr const char* const DELIMITER = "|"; TEST(LogDestinationTest, WithInvalidEmptyFilePath) { const std::filesystem::path invalid_file_path(""); @@ -867,10 +868,10 @@ TEST(MathLoggerBendersByBatchTest, HeadersListStdOutShort) { std::streamsize width = 25; std::ostringstream expected_msg; - expected_msg << "|"; + expected_msg << DELIMITER; for (const auto& header : headers_manager.HeadersList()) { expected_msg << std::setw(width) << std::left << header; - expected_msg << "|"; + expected_msg << DELIMITER; } expected_msg << std::endl; std::stringstream redirectedStdout; @@ -888,10 +889,10 @@ TEST(MathLoggerBendersByBatchTest, HeadersListFileLong) { std::streamsize width = 25; std::ostringstream expected_msg; - expected_msg << "|"; + expected_msg << DELIMITER; for (const auto& header : headers_manager.HeadersList()) { expected_msg << std::setw(width) << std::left << header; - expected_msg << "|"; + expected_msg << DELIMITER; } expected_msg << std::endl; auto log_file = @@ -923,39 +924,39 @@ TEST(MathLoggerBendersByBatchTest, DataInFileLong) { data.iteration_time - data.timer_master - data.subproblems_walltime; std::ostringstream expected_msg; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.it; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.lb; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.min_simplexiter; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.max_simplexiter; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.number_of_subproblem_solved; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.cumulative_number_of_subproblem_solved; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.iteration_time; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.timer_master; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_walltime; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_cumulative_cputime; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << time_not_solving; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::endl; auto log_file = CreateRandomSubDir(std::filesystem::temp_directory_path()) / "log.txt"; @@ -986,29 +987,29 @@ TEST(MathLoggerBendersByBatchTest, DataInStdOutShort) { data.iteration_time - data.timer_master - data.subproblems_walltime; std::ostringstream expected_msg; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.it; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.lb; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.min_simplexiter; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.max_simplexiter; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.number_of_subproblem_solved; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.iteration_time; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.timer_master; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_walltime; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::endl; std::stringstream redirectedStdout; @@ -1041,52 +1042,52 @@ TEST(MathLoggerBendersBaseTest, DataInFileLong) { data.iteration_time - data.timer_master - data.subproblems_walltime; std::ostringstream expected_msg; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.it; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.lb; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.ub; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.best_ub; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(2) << data.best_ub - data.lb; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(2) << (data.best_ub - data.lb) / data.best_ub; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.min_simplexiter; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.max_simplexiter; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.number_of_subproblem_solved; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.cumulative_number_of_subproblem_solved; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.iteration_time; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.timer_master; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_walltime; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_cumulative_cputime; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << time_not_solving; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::endl; auto log_file = CreateRandomSubDir(std::filesystem::temp_directory_path()) / "log.txt"; @@ -1117,40 +1118,40 @@ TEST(MathLoggerBendersBaseTest, DataInStdOutShort) { data.iteration_time - data.timer_master - data.subproblems_walltime; std::ostringstream expected_msg; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.it; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.lb; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.ub; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(10) << data.best_ub; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(2) << data.best_ub - data.lb; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::scientific << std::setprecision(2) << (data.best_ub - data.lb) / data.best_ub; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.min_simplexiter; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << data.max_simplexiter; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.iteration_time; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.timer_master; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::left << std::setw(width) << std::setprecision(2) << data.subproblems_walltime; - expected_msg << "|"; + expected_msg << DELIMITER; expected_msg << std::endl; std::stringstream redirectedStdout; diff --git a/tests/end_to_end/cucumber/features/steps/steps.py b/tests/end_to_end/cucumber/features/steps/steps.py index df41f0369..85b876945 100644 --- a/tests/end_to_end/cucumber/features/steps/steps.py +++ b/tests/end_to_end/cucumber/features/steps/steps.py @@ -147,7 +147,7 @@ def check_solution(context): def read_table_from_string(raw_data): - reader = csv.reader(io.StringIO(raw_data), delimiter='|') + reader = csv.reader(io.StringIO(raw_data), delimiter='\t') header = [item.strip() for item in next(reader)[1:-1]] # Store the header row, ignoring the first and last columns current_results = [{header[index]: item.strip() for index, item in enumerate(row[1:-1])} for row in @@ -158,7 +158,7 @@ def read_table_from_string(raw_data): def read_cucumber_table_from_file(filename): with open(filename, 'r') as file: - reader = csv.reader(file, delimiter='|') + reader = csv.reader(file, delimiter='\t') header = [item.strip() for item in next(reader)[1:-1]] # Store the header row, ignoring the first and last columns current_results = [{header[index]: item.strip() for index, item in enumerate(row[1:-1])} for row in From a863482c8122f00b099070207abb8ac8e1e8ca9e Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 8 Nov 2024 12:56:58 +0100 Subject: [PATCH 35/38] notify N/A when there is no max criterion area --- .../benders/benders_core/BendersStructsDatas.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersStructsDatas.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersStructsDatas.h index 5aba0ec6e..d11659950 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersStructsDatas.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersStructsDatas.h @@ -15,8 +15,8 @@ struct OuterLoopCurrentIterationData{ double external_loop_lambda = 0.; double external_loop_lambda_min = 0.; double external_loop_lambda_max = 0.; - std::string max_criterion_area; - std::string max_criterion_area_best_it; + std::string max_criterion_area = "N/A"; + std::string max_criterion_area_best_it = "N/A"; }; /*! \struct * struct that hold current Benders iteration From 48707baeb719cd020078876e70cb7b048dbef361 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 8 Nov 2024 13:04:29 +0100 Subject: [PATCH 36/38] clean --- .github/workflows/build_ubuntu.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/build_ubuntu.yml b/.github/workflows/build_ubuntu.yml index 6799595c6..0c7dbf26d 100644 --- a/.github/workflows/build_ubuntu.yml +++ b/.github/workflows/build_ubuntu.yml @@ -156,13 +156,6 @@ jobs: # feature: "features/outer_loop_tests.feature" mpi_path: ${{ github.workspace }}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin - # - name: tests Benders Outputs with cucumber - # uses: ./.github/workflows/cucumber-tests - # with: - # feature: "features/Benders_criterion_output_tests.feature" - # mpi_path: ${{ github.workspace }}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin - - - name: Test run: | export PATH=${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin:$PATH From 16095a415ae99d4d532992eeb27068afe24a4d0b Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 8 Nov 2024 13:08:57 +0100 Subject: [PATCH 37/38] [logger test] update delimiter --- tests/cpp/logger/logger_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cpp/logger/logger_test.cpp b/tests/cpp/logger/logger_test.cpp index b0feeaaf7..779d553a0 100644 --- a/tests/cpp/logger/logger_test.cpp +++ b/tests/cpp/logger/logger_test.cpp @@ -743,7 +743,7 @@ TEST_F(MasterLoggerTest, LogSwitchToInteger) { ASSERT_TRUE(_logger->_switchToIntegerCall); ASSERT_TRUE(_logger2->_switchToIntegerCall); } -static constexpr const char* const DELIMITER = "|"; +static constexpr const char* const DELIMITER = "\t"; TEST(LogDestinationTest, WithInvalidEmptyFilePath) { const std::filesystem::path invalid_file_path(""); From 95b2b1e6f69f8386c93f311aa94bd7656248e84e Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 8 Nov 2024 13:18:54 +0100 Subject: [PATCH 38/38] decoupling lold and positive**** --- tests/end_to_end/utils_functions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/end_to_end/utils_functions.py b/tests/end_to_end/utils_functions.py index 54d44a5a9..7958f4953 100644 --- a/tests/end_to_end/utils_functions.py +++ b/tests/end_to_end/utils_functions.py @@ -118,8 +118,8 @@ def read_outputs(output_path, use_archive=True, lold=False, positive_unsupplied_ if lold: out.lold = read_file(get_filepath(output_path, "lp", "LOLD.txt")) - if positive_unsupplied_energy: - out.positive_unsupplied_energy = read_file( - get_filepath(output_path, "lp", "PositiveUnsuppliedEnergy.txt")) + if positive_unsupplied_energy: + out.positive_unsupplied_energy = read_file( + get_filepath(output_path, "lp", "PositiveUnsuppliedEnergy.txt")) return out