1"""Unit tests for RTL macro definition loading and propagation."""
3from __future__
import annotations
7from pathlib
import Path
9from unittest.mock
import MagicMock, patch
13_accel_mock = MagicMock()
14sys.modules[
"esiaccel.esiCppAccel"] = _accel_mock
16from esiaccel.cosim
import simulator
17from esiaccel.cosim
import pytest
as cosim_pytest
21 script = (Path(__file__).parents[2] /
"cosim_dpi_server" /
"esi-cosim.py")
22 spec = importlib.util.spec_from_file_location(
"esi_cosim", script)
23 assert spec
is not None
24 assert spec.loader
is not None
25 module = importlib.util.module_from_spec(spec)
26 spec.loader.exec_module(module)
33 definitions_file = tmp_path /
"macros.json"
34 definitions_file.write_text(
52 with pytest.raises(FileNotFoundError,
53 match=
"Macro definitions file not found"):
57 definitions_file = tmp_path /
"macros.json"
58 definitions_file.write_text(
"{")
60 with pytest.raises(ValueError, match=
"is not valid JSON"):
63 @pytest.mark.parametrize("contents", ["[]", '"macro"', "null"])
65 definitions_file = tmp_path /
"macros.json"
66 definitions_file.write_text(contents)
68 with pytest.raises(ValueError, match=
"must contain a JSON object"):
72 definitions_file = tmp_path /
"macros.json"
73 definitions_file.write_text(json.dumps({
"BAD": [
"value"]}))
75 with pytest.raises(ValueError, match=
"expected a scalar or null"):
82 sources_dir = tmp_path /
"sources"
84 (sources_dir /
"macros.json").write_text(
89 config = cosim_pytest.CosimPytestConfig(
90 source_generator=
lambda _config, _tmp_dir: sources_dir,
92 "OVERRIDE":
"explicit",
95 macro_definitions_file=
"macros.json",
98 assert cosim_pytest._resolve_macro_definitions(config, sources_dir) == {
100 "OVERRIDE":
"explicit",
105 sources_dir = tmp_path /
"sources"
107 definitions_file = tmp_path /
"macros.json"
108 definitions_file.write_text(json.dumps({
"FROM_FILE":
"absolute"}))
109 config = cosim_pytest.CosimPytestConfig(
110 source_generator=
lambda _config, _tmp_dir: sources_dir,
111 macro_definitions_file=definitions_file,
114 assert cosim_pytest._resolve_macro_definitions(config, sources_dir) == {
115 "FROM_FILE":
"absolute",
119 sources_dir = tmp_path /
"sources"
121 (sources_dir /
"macros.json").write_text(json.dumps({
"FROM_FILE":
"1"}))
122 config = cosim_pytest.CosimPytestConfig(
123 source_generator=
lambda _config, _tmp_dir: sources_dir,
124 macro_definitions={
"FROM_CONFIG":
None},
125 macro_definitions_file=
"macros.json",
127 expected_simulator = object()
129 with patch.object(cosim_pytest,
131 return_value=expected_simulator)
as get_simulator:
132 result = cosim_pytest._create_simulator(config, sources_dir,
135 assert result
is expected_simulator
136 assert get_simulator.call_args.args[-1] == {
147 source_dir = tmp_path /
"hw"
149 definitions_file = tmp_path /
"macros.json"
150 definitions_file.write_text(
155 fake_simulator = MagicMock()
156 fake_simulator.compile.return_value = 0
157 fake_simulator.run.return_value = 17
159 with patch.object(cli,
"get_simulator",
160 return_value=fake_simulator)
as get_simulator:
161 result = cli.__main__([
164 str(definitions_file),
168 "OVERRIDE=command-line",
177 assert get_simulator.call_args.kwargs[
"macro_definitions"] == {
179 "OVERRIDE":
"command-line",
182 fake_simulator.run.assert_called_once_with([
"argument"],
test_define_file_is_overridden_by_command_line_definitions(self, tmp_path)
test_non_scalar_value_raises(self, tmp_path)
test_missing_file_raises(self, tmp_path)
test_invalid_json_raises(self, tmp_path)
test_non_object_json_raises(self, tmp_path, contents)
test_loads_and_normalizes_scalar_values(self, tmp_path)
test_create_simulator_passes_resolved_macros(self, tmp_path)
test_resolves_absolute_file(self, tmp_path)
test_resolves_relative_file_and_explicit_overrides(self, tmp_path)
Dict[str, Optional[str]] load_macro_definitions(Path path)