- 按文件哈希区分当前八路工程和历史 Amesim 基准,修复测试与清单中的旧路径。 - 四路审计从 JSON 按需生成 XML,八路新增只核对模式,并显式使用 UTF-8 与 LF。 - 将缺失高刚度夹具的测试替换为当前八路完整 BDF 运行,明确未恢复原 RK45 专项覆盖。 - 更新前端大型工程测试、历史活动回放入口、数据说明、现行规范和相关报告。 验证:全量后台 374 项通过、1 项条件跳过;前端 11 项通过、历史独立服务用例 1 项跳过;四路八路 AME 审计通过。 环境、缓存和运行产物保持忽略;本次未实施工程 JSON 字段精简。
60 lines
2.8 KiB
Python
60 lines
2.8 KiB
Python
"""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()
|