Skip to content

Commit 0011309

Browse files
committed
+ tests
1 parent 63f5e8d commit 0011309

1 file changed

Lines changed: 188 additions & 0 deletions

File tree

test/test_report.py

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import importlib.util
2+
import sys
3+
import types
4+
from pathlib import Path
5+
6+
import numpy as np
7+
import pytest
8+
import xarray as xr
9+
import yaml
10+
11+
12+
def _module_available(name: str) -> bool:
13+
if name in sys.modules:
14+
return True
15+
try:
16+
return importlib.util.find_spec(name) is not None
17+
except ValueError:
18+
return False
19+
20+
21+
# Stub heavy dependencies so importing the package works in minimal test envs.
22+
if not _module_available("openmc"):
23+
openmc_stub = types.ModuleType("openmc")
24+
openmc_stub.__path__ = []
25+
for cls_name in (
26+
"StatePoint",
27+
"Tally",
28+
"Filter",
29+
"CellFilter",
30+
"SurfaceFilter",
31+
"MaterialFilter",
32+
"EnergyFilter",
33+
"ParticleFilter",
34+
"Materials",
35+
"Material",
36+
"Geometry",
37+
"Settings",
38+
"Tallies",
39+
"Model",
40+
"DAGMCUniverse",
41+
):
42+
setattr(openmc_stub, cls_name, type(cls_name, (), {}))
43+
sys.modules.setdefault("openmc", openmc_stub)
44+
45+
openmc_data_stub = types.ModuleType("openmc.data")
46+
openmc_data_stub.zam = lambda _name: (1, 1, 0)
47+
sys.modules.setdefault("openmc.data", openmc_data_stub)
48+
49+
try:
50+
import pydagmc as _pydagmc # noqa: F401
51+
except Exception:
52+
pydagmc_stub = types.ModuleType("pydagmc")
53+
pydagmc_stub.Model = type("Model", (), {})
54+
sys.modules["pydagmc"] = pydagmc_stub
55+
56+
try:
57+
import cad_to_dagmc as _cad_to_dagmc # noqa: F401
58+
except Exception:
59+
cad_stub = types.ModuleType("cad_to_dagmc")
60+
cad_stub.CadToDagmc = type("CadToDagmc", (), {})
61+
sys.modules["cad_to_dagmc"] = cad_stub
62+
63+
if not _module_available("sandy"):
64+
sys.modules.setdefault("sandy", types.ModuleType("sandy"))
65+
66+
from openmc_fusion_benchmarks.benchmark_results import BenchmarkResults
67+
from openmc_fusion_benchmarks.report import (
68+
PlotStyle,
69+
ReportConfig,
70+
ReportMetadata,
71+
ResultSource,
72+
build_report,
73+
)
74+
from openmc_fusion_benchmarks.report.renderers import render_plots_for_report, render_yaml
75+
76+
77+
def _write_structured_group(filepath: Path, group: str, tally_name: str) -> None:
78+
ds = xr.Dataset(
79+
{
80+
"mean": xr.DataArray(
81+
np.arange(4.0).reshape(2, 1, 2),
82+
dims=("cell", "nuclide", "score"),
83+
coords={
84+
"cell": [0, 1],
85+
"nuclide": np.array(["total"], dtype="U"),
86+
"score": np.array(["flux", "heating"], dtype="U"),
87+
},
88+
),
89+
"mc_std": xr.DataArray(
90+
np.full((2, 1, 2), 0.1),
91+
dims=("cell", "nuclide", "score"),
92+
coords={
93+
"cell": [0, 1],
94+
"nuclide": np.array(["total"], dtype="U"),
95+
"score": np.array(["flux", "heating"], dtype="U"),
96+
},
97+
),
98+
}
99+
)
100+
ds["mean"].attrs["tally_id"] = 1
101+
ds["mean"].attrs["tally_name"] = tally_name
102+
ds["mc_std"].attrs["tally_id"] = 1
103+
ds["mc_std"].attrs["tally_name"] = tally_name
104+
ds.to_netcdf(filepath, mode="a" if filepath.exists() else "w", engine="h5netcdf", group=group)
105+
106+
107+
@pytest.fixture
108+
def results_pair(tmp_path):
109+
exp_path = tmp_path / "reference_results.h5"
110+
calc_path = tmp_path / "benchmark_results.h5"
111+
_write_structured_group(exp_path, group="tally_1", tally_name="tally_1")
112+
_write_structured_group(calc_path, group="tally_1", tally_name="tally_1")
113+
return BenchmarkResults.from_file(exp_path), BenchmarkResults.from_file(calc_path)
114+
115+
116+
def test_build_report(results_pair, tmp_path):
117+
exp, calc = results_pair
118+
metadata = ReportMetadata(title="Test", benchmark_id="bench")
119+
sources = [
120+
ResultSource(name="experiment", kind="experiment", results=exp),
121+
ResultSource(name="calculation", kind="calculation", results=calc),
122+
]
123+
config = ReportConfig(output_dir=tmp_path)
124+
125+
report = build_report(metadata, sources, config)
126+
127+
assert report.metadata.title == "Test"
128+
assert report.data["benchmark_id"] == "bench"
129+
assert report.data["sources"][0]["name"] == "experiment"
130+
assert report.plots[0].tally_name == "tally_1"
131+
assert isinstance(report.plots[0].style, PlotStyle)
132+
133+
134+
def test_render_yaml(results_pair, tmp_path):
135+
exp, calc = results_pair
136+
metadata = ReportMetadata(title="Test", benchmark_id="bench")
137+
sources = [
138+
ResultSource(name="experiment", kind="experiment", results=exp),
139+
ResultSource(name="calculation", kind="calculation", results=calc),
140+
]
141+
config = ReportConfig(output_dir=tmp_path)
142+
143+
report = build_report(metadata, sources, config)
144+
output_path = render_yaml(report, tmp_path / "report.yaml")
145+
146+
assert output_path.exists()
147+
payload = yaml.safe_load(output_path.read_text())
148+
assert payload["benchmark_id"] == "bench"
149+
assert payload["sources"][1]["name"] == "calculation"
150+
151+
152+
def test_render_plots_for_report_records_plot_entries(results_pair, tmp_path, monkeypatch):
153+
exp, calc = results_pair
154+
metadata = ReportMetadata(title="Test", benchmark_id="bench")
155+
sources = [
156+
ResultSource(name="experiment", kind="experiment", results=exp),
157+
ResultSource(name="calculation", kind="calculation", results=calc),
158+
]
159+
config = ReportConfig(output_dir=tmp_path)
160+
report = build_report(metadata, sources, config)
161+
162+
class DummyArtifacts:
163+
def __init__(self, tally):
164+
self.tally_name = tally
165+
self.absolute_plot = tmp_path / f"{tally}_absolute.png"
166+
self.ce_plot = tmp_path / f"{tally}_ce.png"
167+
168+
def _fake_build_plot_artifacts(tally_name, experiment, calculation, output_dir):
169+
return DummyArtifacts(tally_name)
170+
171+
def _fake_render_plots(artifacts, experiment, calculation, style=None):
172+
artifacts.absolute_plot.write_text("ok")
173+
artifacts.ce_plot.write_text("ok")
174+
175+
monkeypatch.setattr(
176+
"openmc_fusion_benchmarks.report.renderers.build_plot_artifacts",
177+
_fake_build_plot_artifacts,
178+
)
179+
monkeypatch.setattr(
180+
"openmc_fusion_benchmarks.report.renderers.render_plots",
181+
_fake_render_plots,
182+
)
183+
184+
entries = render_plots_for_report(report, tmp_path / "plots")
185+
186+
assert entries
187+
assert report.data["plots"][0]["tally"] == "tally_1"
188+
assert Path(entries[0]["absolute_plot"]).exists()

0 commit comments

Comments
 (0)