Skip to content

Commit

Permalink
Cucumber: add short tests & refactor some steps (#2382)
Browse files Browse the repository at this point in the history
  • Loading branch information
pet-mit authored Oct 4, 2024
1 parent ad66898 commit da70910
Show file tree
Hide file tree
Showing 10 changed files with 316 additions and 109 deletions.
2 changes: 1 addition & 1 deletion src/tests/cucumber/features/medium_tests.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Feature: medium tests
Scenario: 035 Mixed Expansion - Smart grid model 2
Given the study path is "medium-tests/035 Mixed Expansion - Smart grid model 2"
When I run antares simulator
Then the simulation takes less than 15 seconds
Then the simulation takes less than 30 seconds
And the simulation succeeds
And the expected value of the annual system cost is 3.725e+10
And the minimum annual system cost is 3.642e+10
Expand Down
110 changes: 99 additions & 11 deletions src/tests/cucumber/features/short_tests.feature
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,121 @@ Feature: short tests
When I run antares simulator
Then the simulation takes less than 5 seconds
And the simulation succeeds
And the annual system cost is
| EXP | STD | MIN | MAX |
| 0 | 0 | 0 | 0 |
And the annual system cost is 0

@fast @short
Scenario: 002 Thermal fleet - Base
Given the study path is "short-tests/002 Thermal fleet - Base"
When I run antares simulator
Then the simulation takes less than 5 seconds
And the simulation succeeds
And the annual system cost is
| EXP | STD | MIN | MAX |
| 2.729e+7 | 0 | 2.729e+7 | 2.729e+7 |
And the annual system cost is 2.729e+7
And in area "AREA", during year 1, loss of load lasts 1 hours
And in area "AREA", unsupplied energy on "02 JAN 09:00" of year 1 is of 52 MW
And in area "AREA", unsupplied energy on "2 JAN 09:00" of year 1 is of 52 MW

@fast @short
Scenario: 003 Thermal fleet - Must-run
Given the study path is "short-tests/003 Thermal fleet - Must-run"
When I run antares simulator
Then the simulation takes less than 5 seconds
And the simulation succeeds
And the annual system cost is
| EXP | STD | MIN | MAX |
| 2.751e+7 | 0 | 2.751e+7 | 2.751e+7 |
And the annual system cost is 2.751e+7
And in area "AREA", during year 1, loss of load lasts 1 hours
And in area "AREA", unsupplied energy on "2 JAN 09:00" of year 1 is of 52 MW
And in area "AREA", during year 1, hourly production of "non-dispatchable semi base" is always equal to 300 MWh

@fast @short
Scenario: 004 Thermal fleet - Partial must-run
Given the study path is "short-tests/004 Thermal fleet - Partial must-run"
When I run antares simulator
Then the simulation takes less than 5 seconds
And the simulation succeeds
And the annual system cost is 2.751e+7
And in area "AREA", during year 1, loss of load lasts 1 hours
And in area "AREA", unsupplied energy on "2 JAN 09:00" of year 1 is of 52 MW
And in area "AREA", during year 1, hourly production of "semi base" is always greater than 300 MWh

@fast @short
Scenario: 005 Thermal fleet - Minimum stable power and min up down times
Given the study path is "short-tests/005 Thermal fleet - Minimum stable power and min up down times"
When I run antares simulator
Then the simulation takes less than 5 seconds
And the simulation succeeds
And the annual system cost is 2.75816e+07
And in area "AREA", the units of "base" produce between 400 and 900 MWh hourly
And in area "AREA", the units of "semi base" produce between 100 and 300 MWh hourly
And in area "AREA", the units of "peak" produce between 10 and 100 MWh hourly
# Ideally, we would also check min up & down durations in this test. But is not possible, since clusters defined
# in this test have a unitcount > 1
# TODO : create similar tests with unitcount = 1, and implement the following steps:
# And in area "AREA", unit "base" respects a minimum up duration of 24 hours, and a minimum down duration of 24 hours
# And in area "AREA", unit "semi base" respects a minimum up duration of 6 hours, and a minimum down duration of 12 hours
# And in area "AREA", unit "peak" respects a minimum up duration of 2 hours, and a minimum down duration of 2 hours

@fast @short
Scenario: 006 Thermal fleet - Extra costs
# Like previous test, but with extra non-proportional (NP) costs
# NP costs = 1756400 ; OP costs = 2.75816e+07 (like test 5) => Total cost = 2.9338e+07
Given the study path is "short-tests/006 Thermal fleet - Extra costs"
When I run antares simulator
Then the simulation takes less than 5 seconds
And the simulation succeeds
And the annual system cost is 2.9338e+07
And in area "AREA", during year 1, total non-proportional cost is 1756400
And in area "AREA", the units of "base" produce between 400 and 900 MWh hourly
And in area "AREA", the units of "semi base" produce between 100 and 300 MWh hourly
And in area "AREA", the units of "peak" produce between 10 and 100 MWh hourly
# Ideally, we would also check min up & down durations in this test. But is not possible, since clusters defined
# in this test have a unitcount > 1
# TODO : create similar tests with unitcount = 1, and implement the following steps:
# And in area "AREA", unit "base" respects a minimum up duration of 24 hours, and a minimum down duration of 24 hours
# And in area "AREA", unit "semi base" respects a minimum up duration of 6 hours, and a minimum down duration of 12 hours
# And in area "AREA", unit "peak" respects a minimum up duration of 2 hours, and a minimum down duration of 2 hours

@fast @short
Scenario: 007 Thermal fleet - Fast unit commitment
# This example is the first of a set of two that are comparing the two unit-commitment modes of Antares.
# Fast mode
# => overall cost is not great, there are a lot of startups, and min up & down time are considered equal
Given the study path is "short-tests/007 Thermal fleet - Fast unit commitment"
When I run antares simulator
Then the simulation takes less than 5 seconds
And the simulation succeeds
And the annual system cost is 2.98912e+07
And in area "AREA", during year 1, total non-proportional cost is 1861400
And in area "AREA", the units of "base" produce between 400 and 900 MWh hourly
And in area "AREA", the units of "semi base" produce between 100 and 300 MWh hourly
And in area "AREA", the units of "peak" produce between 10 and 100 MWh hourly
And in area "AREA", during year 1, loss of load lasts 1 hours
And in area "AREA", unsupplied energy on "2 JAN 09:00" of year 1 is of 52 MW
# Ideally, we would also check min up & down durations in this test. But is not possible, since clusters defined
# in this test have a unitcount > 1
# TODO : create similar tests with unitcount = 1, and implement the following steps:
# And in area "AREA", unit "base" respects a minimum up duration of 24 hours, and a minimum down duration of 24 hours
# And in area "AREA", unit "semi base" respects a minimum up duration of 12 hours, and a minimum down duration of 12 hours
# And in area "AREA", unit "peak" respects a minimum up duration of 2 hours, and a minimum down duration of 2 hours

@fast @short
Scenario: 008 Thermal fleet - Accurate unit commitment
# Like previous test, but with unit commitment
# => overall cost is better, there are less startups, and min up & down time are not equal
Given the study path is "short-tests/008 Thermal fleet - Accurate unit commitment"
When I run antares simulator
Then the simulation takes less than 5 seconds
And the simulation succeeds
And the annual system cost is 2.97339e+07
And in area "AREA", during year 1, total non-proportional cost is 1680900
And in area "AREA", the units of "base" produce between 400 and 900 MWh hourly
And in area "AREA", the units of "semi base" produce between 100 and 300 MWh hourly
And in area "AREA", the units of "peak" produce between 10 and 100 MWh hourly
And in area "AREA", during year 1, loss of load lasts 1 hours
And in area "AREA", unsupplied energy on "02 JAN 09:00" of year 1 is of 52 MW
And in area "AREA", unsupplied energy on "2 JAN 09:00" of year 1 is of 52 MW
# Ideally, we would also check min up & down durations in this test. But is not possible, since clusters defined
# in this test have a unitcount > 1
# TODO : create similar tests with unitcount = 1, and implement the following steps:
# And in area "AREA", unit "base" respects a minimum up duration of 24 hours, and a minimum down duration of 24 hours
# And in area "AREA", unit "semi base" respects a minimum up duration of 6 hours, and a minimum down duration of 12 hours
# And in area "AREA", unit "peak" respects a minimum up duration of 2 hours, and a minimum down duration of 2 hours

@fast @short
Scenario: 021 Four areas - DC law
Expand Down
3 changes: 2 additions & 1 deletion src/tests/cucumber/features/steps/assertions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Custom assertions

def assert_double_close(expected, actual, relative_tolerance):
assert abs((actual - expected) / max(1e-6, expected)) <= relative_tolerance
assert abs((actual - expected) / max(1e-6, expected)) <= relative_tolerance, \
f"Values are not close: expected = {expected} ; actual = {actual}"
22 changes: 0 additions & 22 deletions src/tests/cucumber/features/steps/context_utils.py

This file was deleted.

37 changes: 0 additions & 37 deletions src/tests/cucumber/features/steps/output_utils.py

This file was deleted.

24 changes: 16 additions & 8 deletions src/tests/cucumber/features/steps/simulator_utils.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
# Methods to run Antares simulator

import subprocess
import glob
import yaml
from pathlib import Path
from study_input_handler import study_input_handler
from output_utils import parse_output_folder_from_logs
from study_output_handler import study_output_handler


def get_solver_path():
with open("conf.yaml") as file:
content = yaml.full_load(file)
content = yaml.full_load(file)
return content.get("antares-solver")

SOLVER_PATH = get_solver_path() # we only need to run this once

SOLVER_PATH = get_solver_path() # we only need to run this once


def run_simulation(context):
activate_simu_outputs(context) # TODO : remove this and update studies instead
init_simu(context)
command = build_antares_solver_command(context)
print(f"Running command: {command}")
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
out, err = process.communicate()
context.output_path = parse_output_folder_from_logs(out)
context.return_code = process.returncode
context.annual_system_cost = None
context.hourly_values = None
context.soh = study_output_handler(context.output_path)


def activate_simu_outputs(context):
def init_simu(context):
sih = study_input_handler(Path(context.study_path))
# read metadata
context.nbyears = int(sih.get_value(variable="nbyears", file_nick_name="general"))
# activate year-by-year results # TODO : remove this and update studies instead
sih.set_value(variable="synthesis", value="true", file_nick_name="general")
sih.set_value(variable="year-by-year", value="true", file_nick_name="general")

Expand All @@ -45,3 +47,9 @@ def build_antares_solver_command(context):
command.append('--force-parallel=4')
return command


def parse_output_folder_from_logs(logs: bytes) -> str:
for line in logs.splitlines():
if b'Output folder : ' in line:
return line.split(b'Output folder : ')[1].decode('ascii')
raise LookupError("Could not parse output folder in output logs")
Loading

0 comments on commit da70910

Please sign in to comment.