Skip to content

Commit e54ecec

Browse files
authored
Add storage migration for removing is_improvement flag (#14117)
1 parent 553ddfe commit e54ecec

3 files changed

Lines changed: 109 additions & 1 deletion

File tree

src/ert/storage/local_storage.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
logger = logging.getLogger(__name__)
3333

34-
_LOCAL_STORAGE_VERSION = 36
34+
_LOCAL_STORAGE_VERSION = 37
3535

3636

3737
def open_storage(
@@ -641,6 +641,7 @@ def _migrate(self, version: int) -> None:
641641
to34,
642642
to35,
643643
to36,
644+
to37,
644645
)
645646

646647
try: # ruff: ignore[too-many-statements-in-try-clause]
@@ -706,6 +707,7 @@ def _migrate(self, version: int) -> None:
706707
33: to34,
707708
34: to35,
708709
35: to36,
710+
36: to37,
709711
}
710712
for from_version in range(version, _LOCAL_STORAGE_VERSION):
711713
migrations[from_version].migrate(self.path)

src/ert/storage/migration/to37.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from __future__ import annotations
2+
3+
import json
4+
import logging
5+
from pathlib import Path
6+
7+
logger = logging.getLogger(__name__)
8+
9+
info = "Remove is_improvement flag from ensembles"
10+
11+
12+
def migrate(path: Path) -> None:
13+
ensemble_dir = path / "ensembles"
14+
if not ensemble_dir.exists():
15+
return
16+
for ens_dir in ensemble_dir.iterdir():
17+
index_file = ens_dir / "index.json"
18+
if not index_file.exists():
19+
continue
20+
21+
index_data = json.loads(index_file.read_text(encoding="utf-8"))
22+
ensemble_data = index_data.get("ensemble", {})
23+
24+
if "is_improvement" in ensemble_data:
25+
ensemble_data.pop("is_improvement")
26+
index_file.write_text(json.dumps(index_data, indent=2), encoding="utf-8")
27+
logger.info("Removed is_improvement flag from %s", index_file)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import json
2+
from pathlib import Path
3+
4+
import pytest
5+
6+
from ert.storage.migration.to37 import migrate
7+
8+
9+
def _write_index(ens_path: Path, index_data: dict) -> Path:
10+
ens_path.mkdir(parents=True)
11+
index_file = ens_path / "index.json"
12+
index_file.write_text(json.dumps(index_data), encoding="utf-8")
13+
return index_file
14+
15+
16+
@pytest.mark.parametrize(
17+
("original", "expected"),
18+
[
19+
pytest.param(
20+
{
21+
"id": "ens-id",
22+
"ensemble": {"name": "batch_0", "iteration": 0, "is_improvement": True},
23+
},
24+
{"id": "ens-id", "ensemble": {"name": "batch_0", "iteration": 0}},
25+
id="removes_is_improvement",
26+
),
27+
pytest.param(
28+
{"ensemble": {"name": "batch_1", "iteration": 1, "is_improvement": False}},
29+
{"ensemble": {"name": "batch_1", "iteration": 1}},
30+
id="removes_is_improvement_false",
31+
),
32+
pytest.param(
33+
{"ensemble": {"name": "batch_5", "iteration": 3, "is_improvement": True}},
34+
{"ensemble": {"name": "batch_5", "iteration": 3}},
35+
id="removes_is_improvement_other_values",
36+
),
37+
pytest.param(
38+
{"ensemble": {"name": "batch_0", "iteration": 0}},
39+
{"ensemble": {"name": "batch_0", "iteration": 0}},
40+
id="leaves_untouched_when_missing",
41+
),
42+
],
43+
)
44+
def test_that_migration_updates_ensemble_index(tmp_path, original, expected):
45+
root = tmp_path / "project"
46+
index_file = _write_index(root / "ensembles" / "ensemble_1", original)
47+
48+
migrate(root)
49+
50+
assert json.loads(index_file.read_text(encoding="utf-8")) == expected
51+
52+
53+
def test_that_migration_does_not_fail_on_unexpectedly_structured_dirs(tmp_path):
54+
root = tmp_path / "project"
55+
root.mkdir()
56+
migrate(root)
57+
58+
ensembles_dir = root / "ensembles"
59+
ensembles_dir.mkdir()
60+
migrate(root)
61+
62+
not_an_ensemble = ensembles_dir / "not_a_directory.json"
63+
not_an_ensemble.write_text("{}", encoding="utf-8")
64+
migrate(root)
65+
66+
ensemble_without_index_json = ensembles_dir / "ensemble_1"
67+
ensemble_without_index_json.mkdir()
68+
migrate(root)
69+
70+
assert not_an_ensemble.read_text(encoding="utf-8") == "{}"
71+
72+
73+
def test_that_migration_does_not_fail_on_index_without_ensemble_entry(tmp_path):
74+
root = tmp_path / "project"
75+
index_file = _write_index(root / "ensembles" / "ensemble_1", {"id": "ens-id"})
76+
77+
migrate(root)
78+
79+
assert json.loads(index_file.read_text(encoding="utf-8")) == {"id": "ens-id"}

0 commit comments

Comments
 (0)