纳管 AMESim 对齐基线、发布锁、回归测试及当前物理门禁调整。 更新日志仅记录已完成成果,并注明当前 HEAD 尚待真实 production 复跑与远端 workflow 验证。
178 lines
7.3 KiB
Python
178 lines
7.3 KiB
Python
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import unittest
|
|
|
|
from app.main import compile_system_xml_network
|
|
from app.simulation.benchmark_regression import (
|
|
evaluate_regression_golden,
|
|
load_regression_manifest,
|
|
run_regression_suite,
|
|
source_simulation_config,
|
|
)
|
|
from app.simulation.systems.generic import GenericFluidSystem
|
|
from app.system_xml import validate_system_xml_document
|
|
|
|
|
|
MANIFEST_PATH = Path(
|
|
"tests/baselines/simulation/test_mql_full_branches/manifest.json"
|
|
)
|
|
LONG_RUN_ENVIRONMENT = "RUN_TEST_MQL_FULL_BRANCHES_LONG_REGRESSION"
|
|
|
|
|
|
class MqlFullBranchesStaticRegressionTests(unittest.TestCase):
|
|
@classmethod
|
|
def setUpClass(cls) -> None:
|
|
cls.manifest = load_regression_manifest(MANIFEST_PATH)
|
|
cls.source_path = Path(cls.manifest["_sourcePath"])
|
|
cls.source_payload = cls.source_path.read_bytes()
|
|
cls.validation = validate_system_xml_document(cls.source_payload)
|
|
|
|
def test_authoritative_xml_hash_and_simulation_settings_are_fixed(self) -> None:
|
|
source = self.manifest["source"]
|
|
|
|
self.assertEqual(
|
|
hashlib.sha256(self.source_payload).hexdigest(), source["sha256"]
|
|
)
|
|
self.assertEqual(len(self.source_payload), source["bytes"])
|
|
self.assertEqual(
|
|
source_simulation_config(self.source_payload), source["simulation"]
|
|
)
|
|
|
|
def test_structure_snapshot_covers_the_historical_solver_shape(self) -> None:
|
|
self.assertTrue(self.validation.valid, self.validation.as_dict())
|
|
assert self.validation.document is not None
|
|
network = compile_system_xml_network(self.validation.document)
|
|
system = GenericFluidSystem(network)
|
|
expected = self.manifest["structure"]
|
|
pressure_flow = network.pressure_flow_structure_dict()
|
|
causal_execution = system.pressure_flow_solver.causal_execution_diagnostics()
|
|
jacobian = system.jacobian_sparsity_diagnostics()
|
|
|
|
self.assertEqual(len(network.components), expected["componentCount"])
|
|
self.assertEqual(len(network.connections), expected["connectionCount"])
|
|
self.assertEqual(
|
|
len(network.dynamic_components()), expected["dynamicComponentCount"]
|
|
)
|
|
self.assertEqual(
|
|
sum(component.state_size for component in network.dynamic_components()),
|
|
expected["stateCount"],
|
|
)
|
|
self.assertEqual(
|
|
len(network.result_variable_metadata()), expected["resultVariableCount"]
|
|
)
|
|
self.assertEqual(
|
|
pressure_flow["unknownCount"], expected["pressureFlowUnknownCount"]
|
|
)
|
|
self.assertEqual(
|
|
pressure_flow["equationCount"], expected["pressureFlowEquationCount"]
|
|
)
|
|
self.assertEqual(pressure_flow["isSquare"], expected["pressureFlowIsSquare"])
|
|
for key in (
|
|
"logicalEffortCoordinateCount",
|
|
"eliminatedEffortAliasCount",
|
|
"canonicalCoordinateCount",
|
|
"compatibilityScatterCount",
|
|
):
|
|
self.assertEqual(causal_execution[key], expected[key])
|
|
self.assertEqual(jacobian["nonzeroCount"], expected["jacobianNonzeroCount"])
|
|
self.assertEqual(
|
|
jacobian["colorGroupCount"], expected["jacobianColorGroupCount"]
|
|
)
|
|
self.assertEqual(
|
|
system.mechanical_state_reducer.has_state_events,
|
|
expected["hasMechanicalStateEvents"],
|
|
)
|
|
|
|
def test_three_production_repeats_replay_approved_goldens_exactly(self) -> None:
|
|
repository_root = Path(self.manifest["_repositoryRoot"])
|
|
evidence = self.manifest["acceptanceEvidence"]
|
|
self.assertEqual(evidence["status"], "approved")
|
|
self.assertEqual(evidence["lane"], "production")
|
|
self.assertEqual(evidence["repeatCount"], 3)
|
|
self.assertTrue(evidence["physicalValuesIdenticalAcrossRepeats"])
|
|
|
|
expected_counts = {"0.81s": 480, "2.10s": 720}
|
|
stable_signatures: dict[str, object] = {}
|
|
for report_reference in evidence["reports"]:
|
|
report_path = repository_root / report_reference["path"]
|
|
payload = report_path.read_bytes()
|
|
self.assertEqual(len(payload), report_reference["bytes"])
|
|
self.assertEqual(
|
|
hashlib.sha256(payload).hexdigest(),
|
|
report_reference["sha256"],
|
|
)
|
|
report = json.loads(payload)
|
|
self.assertEqual(report["lane"], "production")
|
|
self.assertEqual(
|
|
report["source"]["sha256"], self.manifest["source"]["sha256"]
|
|
)
|
|
|
|
for case_id in self.manifest["sequence"]:
|
|
case = next(
|
|
item for item in report["cases"] if item["caseId"] == case_id
|
|
)
|
|
self.assertEqual(case["outcome"], "completed")
|
|
self.assertTrue(case["acceptance"]["passed"])
|
|
summary = case["worker"]["summary"]
|
|
golden = self.manifest["_goldens"][case_id]["production"]
|
|
audit = evaluate_regression_golden(summary, golden)
|
|
self.assertTrue(audit["passed"], audit)
|
|
self.assertEqual(
|
|
audit["comparedValueCount"], expected_counts[case_id]
|
|
)
|
|
self.assertEqual(audit["maxAbsoluteError"], 0.0)
|
|
self.assertEqual(audit["maxToleranceRatio"], 0.0)
|
|
self.assertEqual(audit["issues"], [])
|
|
|
|
diagnostics = dict(summary["diagnostics"])
|
|
diagnostics.pop("performance", None)
|
|
signature = {
|
|
"physicalContract": summary["physicalContract"],
|
|
"eventTrace": summary["eventTrace"],
|
|
"outputContract": summary["outputContract"],
|
|
"diagnosticsWithoutPerformance": diagnostics,
|
|
}
|
|
if case_id not in stable_signatures:
|
|
stable_signatures[case_id] = signature
|
|
else:
|
|
self.assertEqual(stable_signatures[case_id], signature)
|
|
|
|
def test_both_horizons_have_the_expected_signal_schedule(self) -> None:
|
|
assert self.validation.document is not None
|
|
system = GenericFluidSystem(
|
|
compile_system_xml_network(self.validation.document)
|
|
)
|
|
|
|
for case_id in self.manifest["sequence"]:
|
|
variant = self.manifest["variants"][case_id]
|
|
actual = system.signal_resolver.event_times(
|
|
0.0, float(variant["stopTime"])
|
|
)
|
|
self.assertEqual(actual, tuple(variant["expectedSignalEventTimes"]))
|
|
|
|
|
|
@unittest.skipUnless(
|
|
os.getenv(LONG_RUN_ENVIRONMENT, "").strip().lower() in {"1", "true", "yes"},
|
|
f"Set {LONG_RUN_ENVIRONMENT}=1 to run bounded 0.81/2.10 s integration.",
|
|
)
|
|
class MqlFullBranchesLongRegressionTests(unittest.TestCase):
|
|
def test_both_horizons_complete_within_their_safety_budgets(self) -> None:
|
|
report = run_regression_suite(MANIFEST_PATH, lane="production")
|
|
outcomes = [case["outcome"] for case in report["cases"]]
|
|
self.assertEqual(outcomes, ["completed", "completed"], report["cases"])
|
|
self.assertTrue(
|
|
all(
|
|
case["acceptance"]["regressionGolden"]["passed"]
|
|
for case in report["cases"]
|
|
),
|
|
report["cases"],
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|