Skip to content

Commit 8944883

Browse files
authored
Merge pull request #1017 from PowerGridModel/feature/make-test-dataset-helper-fn
Test case creation: add helper function to create test case
2 parents 1e19f7d + 725f1df commit 8944883

File tree

2 files changed

+120
-1
lines changed

2 files changed

+120
-1
lines changed

src/power_grid_model/utils.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@
4848
_DEPRECATED_JSON_DESERIALIZATION_MSG = f"{_DEPRECATED_FUNCTION_MSG} Please use json_deserialize_to_file instead."
4949
_DEPRECATED_JSON_SERIALIZATION_MSG = f"{_DEPRECATED_FUNCTION_MSG} Please use json_serialize_from_file instead."
5050

51+
LICENSE_TEXT = (
52+
"SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>\n\n"
53+
"SPDX-License-Identifier: MPL-2.0"
54+
"\n"
55+
)
56+
5157

5258
def get_dataset_scenario(dataset: BatchDataset, scenario: int) -> SingleDataset:
5359
"""
@@ -398,3 +404,62 @@ def self_test():
398404
print("Self test finished.")
399405
except Exception as e:
400406
raise PowerGridError from e
407+
408+
409+
def _make_test_case(
410+
*,
411+
output_path: Path,
412+
input_data: SingleDataset,
413+
params: dict,
414+
output_data: Dataset,
415+
output_dataset_type: DatasetType,
416+
update_data: Dataset | None = None,
417+
):
418+
"""
419+
Create and save a validation test case dataset, including input, update (optional), output, and parameters.
420+
421+
Args:
422+
save_path: Directory path where the test case files will be saved.
423+
input_data: Input dataset for the test case.
424+
params: Dictionary of parameters used for the test case. It may include calculation method, tolerances, etc.
425+
An example of parameters could be:
426+
params = {
427+
"calculation_method": "newton_raphson",
428+
"rtol": 1e-6,
429+
"atol": 1e-6,
430+
}
431+
output_data: Output dataset for the test case.
432+
output_dataset_type: The type of the output dataset (e.g., sym_output, asym_output, sc_output).
433+
update_data: Optional batch update dataset.
434+
435+
Raises:
436+
ValueError: If the output_dataset_type is not recognized.
437+
438+
Side Effects:
439+
Writes JSON files for input, update (if provided), output, and parameters,
440+
all relevant license files, to save_path.
441+
"""
442+
output_file_stem = output_dataset_type.name if isinstance(output_dataset_type, DatasetType) else None
443+
if output_dataset_type in [DatasetType.input, DatasetType.update] or output_file_stem is None:
444+
raise ValueError(
445+
f"Invalid output dataset type: {output_dataset_type}. Expected one of: sym_output, asym_output, sc_output."
446+
)
447+
448+
output_path.mkdir(parents=True, exist_ok=True)
449+
json_serialize_to_file(file_path=output_path / "input.json", data=input_data, dataset_type=DatasetType.input)
450+
(output_path / "input.json.license").write_text(data=LICENSE_TEXT, encoding="utf-8")
451+
452+
if update_data is not None:
453+
json_serialize_to_file(
454+
file_path=output_path / "update_batch.json", data=update_data, dataset_type=DatasetType.update
455+
)
456+
(output_path / "update_batch.json.license").write_text(data=LICENSE_TEXT, encoding="utf-8")
457+
output_file_stem += "_batch"
458+
json_serialize_to_file(
459+
file_path=output_path / f"{output_file_stem}.json", data=output_data, dataset_type=output_dataset_type
460+
)
461+
(output_path / f"{output_file_stem}.json.license").write_text(data=LICENSE_TEXT, encoding="utf-8")
462+
463+
params_json = json.dumps(params, indent=2)
464+
(output_path / "params.json").write_text(data=params_json, encoding="utf-8")
465+
(output_path / "params.json.license").write_text(data=LICENSE_TEXT, encoding="utf-8")

tests/unit/test_utils.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
#
33
# SPDX-License-Identifier: MPL-2.0
44

5+
import json
56
from pathlib import Path
67
from unittest.mock import MagicMock, mock_open, patch
78

89
import numpy as np
910
import pytest
1011

11-
from power_grid_model import initialize_array
12+
from power_grid_model import DatasetType, initialize_array
1213
from power_grid_model._core.power_grid_meta import power_grid_meta_data
1314
from power_grid_model.data_types import Dataset
1415
from power_grid_model.utils import (
16+
LICENSE_TEXT,
17+
_make_test_case,
1518
get_component_batch_size,
1619
get_dataset_batch_size,
1720
get_dataset_scenario,
@@ -164,3 +167,54 @@ def test_msgpack_serialize(serialize_mock: MagicMock, open_mock: MagicMock):
164167

165168
def test_self_test():
166169
self_test()
170+
171+
172+
@pytest.mark.parametrize(
173+
("output_dataset_type", "output_file_name", "update_data"),
174+
(
175+
(DatasetType.sym_output, "sym_output_batch.json", {"version": "1.0", "data": "update_data"}),
176+
(DatasetType.sym_output, "sym_output.json", None),
177+
(DatasetType.asym_output, "asym_output_batch.json", {"version": "1.0", "data": "update_data"}),
178+
(DatasetType.asym_output, "asym_output.json", None),
179+
(DatasetType.sc_output, "sc_output_batch.json", {"version": "1.0", "data": "update_data"}),
180+
(DatasetType.sc_output, "sc_output.json", None),
181+
),
182+
)
183+
@patch.object(Path, "write_text", autospec=True)
184+
@patch("power_grid_model.utils.json_serialize_to_file")
185+
def test__make_test_case(
186+
serialize_to_file_mock: MagicMock, write_text_mock: MagicMock, output_dataset_type, output_file_name, update_data
187+
):
188+
input_data: Dataset = {"version": "1.0", "data": "input_data"}
189+
output_data: Dataset = {"version": "1.0", "data": "output_data"}
190+
output_path = Path("test_path")
191+
params = {"param1": "value1", "param2": "value2"}
192+
193+
_make_test_case(
194+
output_path=output_path,
195+
input_data=input_data,
196+
output_data=output_data,
197+
params=params,
198+
output_dataset_type=output_dataset_type,
199+
update_data=update_data,
200+
)
201+
202+
serialize_to_file_mock.assert_any_call(
203+
file_path=output_path / "input.json", data=input_data, dataset_type=DatasetType.input
204+
)
205+
serialize_to_file_mock.assert_any_call(
206+
file_path=output_path / output_file_name, data=output_data, dataset_type=output_dataset_type
207+
)
208+
write_text_mock.assert_any_call(output_path / "params.json", data=json.dumps(params, indent=2), encoding="utf-8")
209+
for file_name in ["input.json.license", f"{output_file_name}.license", "params.json.license"]:
210+
write_text_mock.assert_any_call(output_path / file_name, data=LICENSE_TEXT, encoding="utf-8")
211+
if update_data is not None:
212+
write_text_mock.assert_any_call(output_path / "update_batch.json.license", data=LICENSE_TEXT, encoding="utf-8")
213+
serialize_to_file_mock.assert_any_call(
214+
file_path=output_path / "update_batch.json", data=update_data, dataset_type=DatasetType.update
215+
)
216+
assert write_text_mock.call_count == 5
217+
assert serialize_to_file_mock.call_count == 3
218+
else:
219+
assert write_text_mock.call_count == 4
220+
assert serialize_to_file_mock.call_count == 2

0 commit comments

Comments
 (0)