修复测试模型路径并完善四路八路回归与文档

- 按文件哈希区分当前八路工程和历史 Amesim 基准,修复测试与清单中的旧路径。
- 四路审计从 JSON 按需生成 XML,八路新增只核对模式,并显式使用 UTF-8 与 LF。
- 将缺失高刚度夹具的测试替换为当前八路完整 BDF 运行,明确未恢复原 RK45 专项覆盖。
- 更新前端大型工程测试、历史活动回放入口、数据说明、现行规范和相关报告。

验证:全量后台 374 项通过、1 项条件跳过;前端 11 项通过、历史独立服务用例 1 项跳过;四路八路 AME 审计通过。
环境、缓存和运行产物保持忽略;本次未实施工程 JSON 字段精简。
This commit is contained in:
lujingze committed 2026-09-12 15:49:09 +00:00
1 parent 44b6ea74ab
commit b6c22a54f8
32 files changed
+318 -153

No files matched your search

@@ -0,0 +1,9 @@
# 八路历史冻结基准
路径复核:2026-09-12,版本 1.0.0。
本目录保存 2026 年 8 月回归输入和结果。当前可读取的来源为 [JSON](sources/test-mql-8.json)、[XML](sources/test-mql-8.xml) 及 [历史 AME](../../../data/AmesimModels/test_mql.ame),以 [manifest](manifest.json) 中的字节数和 SHA 为准。
`goldens/`、`runs/` 中的路径与源码状态是历史运行记录,不重新计算或覆盖;其中旧 `AmesimModels/test_mql.ame` 对应上述历史 AME。`tests/data/test_mql.ame` 是另一份当前归档,不能仅凭同名代入历史比较。显式启用的前端历史活动回放现在把新证据写到被忽略的 `test/live-browser-mql8/`,不会覆盖冻结运行报告。
普通功能/性能测试使用 [当前八路 corrected JSON](../../../data/test-mql-8-corrected.json)。相关测试与原报告的关系见 [路径修复记录](../../../../docs/other/2026-09-12-test-input-path-refresh.md)。
@@ -8,7 +8,7 @@
"bytes": 104110,
"xmlIsAuthoritative": true,
"referenceArchive": {
"path": "AmesimModels/test_mql.ame",
"path": "tests/data/AmesimModels/test_mql.ame",
"sha256": "cbc3aadd4569a49b3a63e5d66d4143ec16126c0f950df73fb637e07673c20fbb",
"bytes": 21708800,
"role": "authoritativePhysicalBaseline",
+1 -1
View File
@@ -12,7 +12,7 @@ Python 输出只有通过 AMESim baseline 对比后才能作为数值一致性
## 模型与源数据
- AMESim 源模型:`AmesimModels/test_mql.ame`
- AMESim 源模型:`tests/data/AmesimModels/test_mql.ame`
- Python 系统类:`app.simulation.examples.test_mql.system.TestMqlSystem`
- 结构运行入口:`app.simulation.examples.test_mql.run`
- 132 状态比较入口:`app.simulation.examples.test_mql.run_full_state_comparison`
+19 -15
View File
@@ -1,26 +1,30 @@
# 浏览器四路、八路测试工程
本目录中的 JSON/XML 仅保留以下两个可由网页“导入工程 JSON”识别的工程文件。已逐项核对对应 AME 图纸的元件、公开物理参数及端口连接;AME 单位与工程 SI 单位之间的换算已纳入检查。
版本:1.1.0;路径复核日期:2026-09-12。
| 浏览器工程 | Amesim 原文件 | 元件 / 参数 / 连接 |
本目录直接保留两个可由网页“导入工程 JSON”识别的工程。已重新逐项核对对应 AME 图纸的元件、公开物理参数及端口连接,包含 AME 单位到 SI 单位的换算。
| 浏览器工程(后续删改入口) | 对应 Amesim 原文件 | 元件 / 参数 / 连接 |
|---|---|---|
| [test-mql-4-corrected.json](test-mql-4-corrected.json) | [test_mql_4.ame](test_mql_4.ame) | 81 / 582 / 90 |
| [test-mql-8-corrected.json](test-mql-8-corrected.json) | [test_mql.ame](test_mql.ame) | 157 / 1092 / 178 |
网页当前只支持导入工程 JSON;XML 可从网页下载,用作后端输入。网页使用原生 BDF 和当前默认 `rtol=1e-8`,与 AME 内部积分器及历史数值设置不能视为相同。这里的参数对齐指模型物理参数与初值,不声称不同仿真器所有数值输出完全一致。
后续优化优先使用八路 corrected 工程;只有八路无法运行且短期不能修复时,再退回四路。具体要求见 [优化验证约定](../../docs/standard/optimization-benchmark-model.md)。网页使用原生 BDF、当前默认 `rtol=1e-8`;物理参数对齐不意味着与 AME 积分算法、历史数值设置和输出完全相同。
后续优化测试优先使用八路 corrected 工程;仅当八路跑不通且短期无法解决时,再使用四路。具体记录要求见 [优化验证约定](../../docs/standard/optimization-benchmark-model.md)。
XML 不作为另一份手工维护的工程。需要时从网页下载,或用原生输入转换入口从 JSON 生成。四路审计 `--check` 在内存中生成 XML;八路审计的 XML 证据放在被 Git 忽略的 `test/model-audit/mql8/corrected.xml`。
2026-09-11 整理时,两份工程内容保持不变。其他 JSON/XML 已按用途移出本目录,移动前后字节数及 SHA256 相同:
## 历史基准与辅助文件
| 原文件 | 当前路径 | 用途 |
|---|---|---|
| native-python-reference.json | [原生数值基准](../baselines/native/native-python-reference.json) | 50 网络冻结参考 |
| test-mql-4-amesim-reference.json | [四路 Amesim 曲线基准](../baselines/simulation/test_mql_4/test-mql-4-amesim-reference.json) | 72 曲线、57 时刻 |
| test-mql-4-corrected.xml | [四路执行 XML](../fixtures/amesim/test-mql-4-corrected.xml) | 与四路 JSON 同步的后端输入 |
| test-mql-8.json / test-mql-8.xml | [旧 JSON](../fixtures/legacy/test-mql-8.json) / [旧 XML](../fixtures/legacy/test-mql-8.xml) | 修正前输入及布局来源 |
| test_mql-full-branches-01-04.xml | [历史分支基准输入](../baselines/simulation/test_mql_full_branches/sources/test_mql-full-branches-01-04.xml) | 历史回归清单绑定的输入 |
| native-skill-test.xml | [原生通用测试输入](../fixtures/native-skill-test.xml) | 原生编译、执行与 CI 检查 |
| fixtures/high_stiffness_explicit_rk45.xml | [高刚度 RK45 输入](../fixtures/high_stiffness_explicit_rk45.xml) | 独立刚度回归用例 |
| 当前路径 | 用途与限制 |
|---|---|
| [AmesimModels/test_mql.ame](AmesimModels/test_mql.ame) | 2026-08-18 冻结基准的 AME,SHA 开头 `cbc3aadd`;与本目录当前 AME 的 `1ff0ea42` 不同 |
| [历史八路 JSON](../baselines/simulation/test_mql_8/sources/test-mql-8.json) / [XML](../baselines/simulation/test_mql_8/sources/test-mql-8.xml) | 与上述历史 AME 对应;由 [manifest](../baselines/simulation/test_mql_8/manifest.json) 锁定身份,不能替换为当前 corrected 工程 |
| [原生数值基准](../baselines/native/native-python-reference.json) | 50 个网络的冻结参考,不是浏览器工程 |
| [四路 Amesim 曲线基准](../baselines/simulation/test_mql_4/test-mql-4-amesim-reference.json) | 72 条曲线、57 个时刻,不是浏览器工程 |
| [历史分支 XML](../baselines/simulation/test_mql_full_branches/sources/test_mql-full-branches-01-04.xml) | 另一份历史回归清单绑定的输入 |
| [原生通用 XML](../fixtures/native-skill-test.xml) | 原生编译、执行与 CI 检查 |
| [参数表达式用例](../fixtures/parameter-expressions.json) | 前后端共享的参数语义测试数据,不是浏览器工程 |
AME 原文件及本目录中其他类型的资料保持原位。历史运行记录保留当时路径;活动测试、审计脚本、CI 和当前交付说明已更新到新路径。
2026-09-11 整理后,用户又移动/删除了部分文件。原 `tests/fixtures/amesim/test-mql-4-corrected.xml`、`tests/fixtures/legacy/test-mql-8.json/.xml`、`tests/fixtures/high_stiffness_explicit_rk45.xml` 当前均不存在。历史八路 sources 中的 JSON 也不是被删除 legacy JSON 的逐字节副本,不能冒充恢复了原文件。
高刚度 RK45 专项按用户决定改用 [当前八路完整运行测试](../test_current_mql8_simulation.py)。它验证当前 BDF 路径,不代表恢复了原 RK45 高刚度覆盖。文件身份、相关报告来源及验证结果见 [路径修复报告](../../docs/other/2026-09-12-test-input-path-refresh.md)。冻结运行记录中的旧路径是当时来源记录,当前位置以本说明和 manifest 为准。
+37 -18
View File
@@ -1,4 +1,4 @@
"""Audit the AME diagram against the corrected XML; emit an aligned browser project.
"""Audit the AME diagram against the current browser project; generate XML on demand.
Run from the repository root with .venv/bin/python. Does not run Amesim or use
the stale eight-branch compiled/result cache inside the four-branch archive.
@@ -27,9 +27,9 @@ from tests.test_test_mql_ame_contract import (
_public_model_type, _expected_parameters, _value_fields,
)
OUT = ROOT / 'test/solver-newton-20260911/mql4'
OUT = ROOT / 'test/model-audit/mql4'
AME = ROOT / 'tests/data/test_mql_4.ame'
XML = ROOT / 'tests/fixtures/amesim/test-mql-4-corrected.xml'
XML = OUT / 'aligned-input.xml'
REFERENCE = ROOT / 'tests/baselines/simulation/test_mql_4/test-mql-4-amesim-reference.json'
PROJECT = ROOT / 'tests/data/test-mql-4-corrected.json'
@@ -147,9 +147,17 @@ def audit_source():
}
def project_xml():
# The separately maintained XML fixture was deleted. Use the same input
# conversion as the native CLI; the AME remains the independent authority.
from app.simulation.native_codegen.input import load_input
xml, _ = load_input(PROJECT)
return xml
def xml_model(root=None):
if root is None:
root = ET.parse(XML).getroot()
root = ET.fromstring(project_xml())
nodes = {item.attrib['id']: {
'modelType': item.attrib['type'],
'modelVersion': item.attrib['modelVersion'],
@@ -257,8 +265,9 @@ def check_project_contract(project, xml_root):
def generate_project(source, source_edges, target, target_edges, xml_root, mapping):
layout_source = ROOT / 'tests/fixtures/legacy/test-mql-8.json'
layout = json.loads(layout_source.read_text())
layout_source = PROJECT
layout = json.loads(layout_source.read_text(encoding='utf-8'))
layout_sha = sha(layout_source)
layout_nodes = {node['id']: node for node in layout['nodes']}
reverse_mapping = {value: key for key, value in mapping.items()}
nodes = []
@@ -331,14 +340,14 @@ def generate_project(source, source_edges, target, target_edges, xml_root, mappi
project = {'projectSchemaVersion': 1, 'name': 'test-mql-4-AME-aligned', 'nodes': nodes,
'edges': edges, 'simulation': simulation}
check_project_contract(project, xml_root)
PROJECT.write_text(json.dumps(project, indent=2, ensure_ascii=False) + '\n')
PROJECT.write_text(json.dumps(project, indent=2, ensure_ascii=False) + '\n', encoding='utf-8', newline='\n')
generated_xml = OUT / 'aligned-input.xml'
xml_root.attrib['name'] = project['name']
ET.indent(xml_root)
ET.ElementTree(xml_root).write(generated_xml, encoding='utf-8', xml_declaration=True)
XML.write_bytes(generated_xml.read_bytes())
# Check the delivered JSON itself, including every exact endpoint and number.
json_nodes = {node['id']: node['data'] for node in json.loads(PROJECT.read_text())['nodes']}
json_nodes = {node['id']: node['data'] for node in json.loads(PROJECT.read_text(encoding='utf-8'))['nodes']}
for source_id, project_id in mapping.items():
assert json_nodes[project_id]['parameters'] == source[source_id]['parameters']
expected_edges = {tuple(sorted(((mapping[a], ap), (mapping[b], bp)))) for ((a, ap), (b, bp)) in source_edges}
@@ -354,34 +363,44 @@ def generate_project(source, source_edges, target, target_edges, xml_root, mappi
'nodeCount': len(nodes), 'edgeCount': len(edges), 'parameterCount': sum(len(n['data']['parameters']) for n in nodes),
'allMappedParametersExactlyMatchAme': True, 'allMappedConnectionPortsExactlyMatchAme': True,
'parameterChangesFromLegacyXml': parameter_changes, 'connectionPortChangesFromLegacyXml': changed_connections,
'layoutMetadataSource': {'path': str(layout_source.relative_to(ROOT)), 'sha256': sha(layout_source)},
'layoutMetadataSource': {'path': str(layout_source.relative_to(ROOT)), 'sha256': layout_sha},
'simulation': simulation,
'simulationSettingsNote': 'AME archive stores historical fixed-step settings. This JSON uses native BDF; rtol is supplied by the backend and is not stored in the project. Initial validation used 1e-7; the backend default was subsequently changed to 1e-8. The earlier official Standard variable-step reference remains tolerance 1e-7. Inspect actual run diagnostics; solver algorithms are not identical.'}
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--check', action='store_true', help='Validate delivered JSON/XML only; do not generate or write files.')
parser.add_argument('--check', action='store_true', help='Check current JSON parameters and exact connection ports against AME; generate XML in memory, without file writes.')
arguments = parser.parse_args()
if arguments.check:
print(json.dumps(check_project_contract(json.loads(PROJECT.read_text()), ET.parse(XML).getroot()), indent=2))
target, target_edges, xml_root = xml_model()
result = check_project_contract(json.loads(PROJECT.read_text(encoding='utf-8')), xml_root)
source, source_edges, _ = audit_source()
mapping = find_mapping(source, source_edges, target, target_edges, ports=True)
if mapping is None or len(source) != len(target) or len(source_edges) != len(target_edges):
raise ValueError('Current JSON differs from AME in components, parameters or connection ports.')
for source_id, target_id in mapping.items():
if source[source_id]['parameters'] != target[target_id]['parameters']:
raise ValueError(f'{target_id}: parameters do not exactly match AME.')
result['ameParametersAndConnectionPortsMatch'] = True
result['executionXmlSource'] = str(PROJECT.relative_to(ROOT))
print(json.dumps(result, indent=2))
return
OUT.mkdir(parents=True, exist_ok=True)
source, source_edges, audit = audit_source()
legacy_xml = OUT / 'legacy-corrected-input.xml'
if not legacy_xml.exists():
legacy_xml.write_bytes(XML.read_bytes())
XML.write_bytes(project_xml())
(OUT / 'input-before-audit.xml').write_bytes(XML.read_bytes())
target, target_edges, xml_root = xml_model()
mapping = find_mapping(source, source_edges, target, target_edges)
audit['correctedXml'] = {'path': str(XML.relative_to(ROOT)), 'sha256': sha(XML),
'parameterAndComponentTopologyIsomorphic': mapping is not None}
ref = json.loads(REFERENCE.read_text())
ref = json.loads(REFERENCE.read_text(encoding='utf-8'))
audit['reference'] = {'path': str(REFERENCE.relative_to(ROOT)), 'sha256': sha(REFERENCE),
'source': ref['source'], 'timeCount': len(ref['times']), 'seriesCount': len(ref['series']),
'ameHashMatches': ref['originalAmeSha256'] == sha(AME),
'xmlHashMatches': ref['xmlSha256'] == sha(XML),
'newAmesimRunPerformed': False}
(OUT / 'source-model.json').write_text(json.dumps({'nodes': source, 'edges': source_edges}, indent=2, ensure_ascii=False) + '\n')
(OUT / 'source-model.json').write_text(json.dumps({'nodes': source, 'edges': source_edges}, indent=2, ensure_ascii=False) + '\n', encoding='utf-8', newline='\n')
if not mapping:
mapping = find_mapping(source, source_edges, target, target_edges, parameters=False)
if mapping:
@@ -394,8 +413,8 @@ def main():
audit['generatedProject'] = generate_project(source, source_edges, target, target_edges, xml_root, mapping)
audit['correctedXml']['scope'] = 'Input XML snapshot before this generation; generatedProject describes the delivered corrected files.'
audit_text = json.dumps(audit, indent=2, ensure_ascii=False) + '\n'
(OUT / 'model-audit.json').write_text(audit_text)
(ROOT / 'tests/model_audit/test-mql-4-audit.json').write_text(audit_text)
(OUT / 'model-audit.json').write_text(audit_text, encoding='utf-8', newline='\n')
(ROOT / 'tests/model_audit/test-mql-4-audit.json').write_text(audit_text, encoding='utf-8', newline='\n')
print(json.dumps({key: value for key, value in audit.items() if key not in {'componentMapping', 'members', 'globals'}}, indent=2))
+2 -3
View File
@@ -1,17 +1,16 @@
from __future__ import annotations
import unittest
from pathlib import Path
from unittest.mock import Mock
from app.simulation.paths import HISTORICAL_MQL8_AME_PATH
from app.simulation.reporting.amesim_results import (
_resolve_result_members,
load_test_mql_amesim_results,
)
REPO_ROOT = Path(__file__).resolve().parents[1]
TEST_MQL_AME = REPO_ROOT / "AmesimModels" / "test_mql.ame"
TEST_MQL_AME = HISTORICAL_MQL8_AME_PATH
class AmesimResultsTests(unittest.TestCase):
+59
View File
@@ -0,0 +1,59 @@
"""Current eight-branch execution regression.
The deleted high_stiffness_explicit_rk45.xml is not reconstructed or renamed.
Per the user decision on 2026-09-12, exercise the corrected eight-branch JSON
through the real XML/native path. This does not claim the former RK45 coverage.
"""
from __future__ import annotations
import json
import math
import unittest
from xml.etree import ElementTree as ET
from app.main import run_system_xml_simulation
from app.simulation.native_codegen.input import load_input
from app.simulation.paths import CURRENT_MQL8_PROJECT_PATH
class CurrentMql8SimulationTests(unittest.TestCase):
def test_corrected_eight_branch_runs_its_complete_saved_configuration(self):
original = CURRENT_MQL8_PROJECT_PATH.read_bytes()
project = json.loads(original)
settings = project["simulation"]
xml, document = load_input(CURRENT_MQL8_PROJECT_PATH)
self.assertEqual(len(document.components), len(project["nodes"]))
self.assertEqual(len(document.connections), len(project["edges"]))
self.assertEqual(ET.fromstring(xml).get("unitSystem"), "SI")
result = run_system_xml_simulation(xml, cancel_check=lambda: False)
self.assertTrue(result["success"], result["message"])
self.assertEqual(result["status"], "completed")
self.assertFalse(result["partial"])
self.assertEqual(result["simulatedUntil"], settings["t_stop"])
integration = result["diagnostics"]["integration"]
self.assertEqual(integration["method"], settings["method"])
self.assertEqual(integration["rtol"], 1e-8)
self.assertEqual(result["diagnostics"]["native"]["backend"], "native-c")
# The current case includes a mechanical transition over the complete 10 s.
self.assertGreaterEqual(integration["totals"]["stateTransitionCount"], 1)
self.assertGreaterEqual(integration["totals"]["solverStartCount"], 2)
series = result["series"]
times = series["time"]
self.assertEqual(times[0], settings["t_start"])
self.assertEqual(times[-1], settings["t_stop"])
self.assertTrue(all(a < b for a, b in zip(times, times[1:])))
# Keep every requested output point, in addition to inserted event points.
step = settings["step"]
actual_grid = {round(t / step) for t in times if abs(t / step - round(t / step)) < 1e-8}
expected_grid = set(range(round(settings["t_start"] / step), round(settings["t_stop"] / step) + 1))
self.assertTrue(expected_grid.issubset(actual_grid))
for key, values in series.items():
self.assertEqual(len(values), len(times), key)
self.assertTrue(all(math.isfinite(value) for value in values), key)
self.assertEqual(CURRENT_MQL8_PROJECT_PATH.read_bytes(), original)
if __name__ == "__main__":
unittest.main()
@@ -1,74 +0,0 @@
from __future__ import annotations
import hashlib
import math
from pathlib import Path
import unittest
from app.main import run_system_xml_simulation
FIXTURE_PATH = (
Path(__file__).resolve().parent
/ "fixtures"
/ "high_stiffness_explicit_rk45.xml"
)
ORIGINAL_XML_SHA256 = (
"27048a99da0a21922d75785b760c3b5d04be3349b8aef6fbfedfd811d87ef1d5"
)
def short_explicit_rk45_xml() -> bytes:
original = FIXTURE_PATH.read_bytes()
canonical = original.replace(b"\r\n", b"\n").rstrip(b"\n")
if hashlib.sha256(canonical).hexdigest() != ORIGINAL_XML_SHA256:
raise AssertionError("The high-stiffness RK45 fixture differs from the user XML.")
if original.count(b'tStop="10"') != 1:
raise AssertionError("Expected one original simulation stop time.")
if original.count(b'sampleStep="0.02"') != 1:
raise AssertionError("Expected one original simulation sample step.")
return original.replace(
b'tStop="10"',
b'tStop="0.005"',
1,
).replace(
b'sampleStep="0.02"',
b'sampleStep="0.001"',
1,
)
class HighStiffnessExplicitRk45RegressionTests(unittest.TestCase):
def test_short_user_model_crosses_the_early_stiff_limit_event(self) -> None:
result = run_system_xml_simulation(
short_explicit_rk45_xml(),
cancel_check=lambda: False,
)
self.assertTrue(result["success"], result["message"])
self.assertEqual(result["status"], "completed")
self.assertFalse(result["partial"])
self.assertEqual(result["simulatedUntil"], 0.005)
self.assertNotIn("provided bounds", result["message"])
integration = result["diagnostics"]["integration"]
totals = integration["totals"]
self.assertEqual(integration["method"], "RK45")
self.assertGreaterEqual(totals["stateTransitionCount"], 1)
self.assertGreaterEqual(totals["solverStartCount"], 2)
series = result["series"]
times = series["time"]
self.assertEqual(times[0], 0.0)
self.assertEqual(times[-1], 0.005)
self.assertTrue(
all(first < second for first, second in zip(times, times[1:]))
)
self.assertTrue(any(0.0 < time < 0.001 for time in times))
for values in series.values():
self.assertEqual(len(values), len(times))
self.assertTrue(all(math.isfinite(value) for value in values))
if __name__ == "__main__":
unittest.main()
@@ -11,8 +11,8 @@ BASELINE_ROOT = REPOSITORY_ROOT / "tests" / "baselines" / "simulation"
GIT_ATTRIBUTES_PATH = REPOSITORY_ROOT / ".gitattributes"
EXPECTED_ATTRIBUTE_RULES = {
("tests/fixtures/legacy/test-mql-8.xml", "text", "eol=lf"),
("tests/fixtures/legacy/test-mql-8.json", "text", "eol=lf"),
("tests/baselines/simulation/**/sources/*", "text", "eol=lf"),
("tests/data/*.json", "text", "eol=lf"),
("tests/baselines/simulation/test_mql_full_branches/sources/test_mql-full-branches-01-04.xml", "text", "eol=lf"),
("tests/baselines/simulation/**/*.json", "text", "eol=lf"),
}
+5 -4
View File
@@ -14,14 +14,15 @@ import tarfile
import unittest
import xml.etree.ElementTree as ET
from app.simulation.paths import HISTORICAL_MQL8_AME_PATH, HISTORICAL_MQL8_PROJECT_PATH, HISTORICAL_MQL8_XML_PATH
from app.simulation.registry import get_component_model_spec
from app.simulation.reporting.amesim_results import load_test_mql_amesim_results
REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
AME_PATH = REPOSITORY_ROOT / "AmesimModels" / "test_mql.ame"
JSON_PATH = REPOSITORY_ROOT / "tests/baselines/simulation/test_mql_8/sources/test-mql-8.json"
XML_PATH = REPOSITORY_ROOT / "tests/baselines/simulation/test_mql_8/sources/test-mql-8.xml"
AME_PATH = HISTORICAL_MQL8_AME_PATH
JSON_PATH = HISTORICAL_MQL8_PROJECT_PATH
XML_PATH = HISTORICAL_MQL8_XML_PATH
MANIFEST_PATH = (
REPOSITORY_ROOT
/ "tests/baselines/simulation/test_mql_8/manifest.json"
@@ -512,7 +513,7 @@ class TestMqlAmeAuthorityContractTests(unittest.TestCase):
self.assertEqual(
reference,
{
"path": "AmesimModels/test_mql.ame",
"path": "tests/data/AmesimModels/test_mql.ame",
"sha256": EXPECTED_AME_SHA256,
"bytes": EXPECTED_AME_BYTES,
"role": "authoritativePhysicalBaseline",