81 lines
3.3 KiB
Python
81 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from cognitive_agent.application.seat_service import REPOSITORY_ROOT, SeatDemoService
|
|
from cognitive_agent.infrastructure.can.hardware import HardwareSafetyError
|
|
|
|
|
|
class SimulatedHardwareIntegrationTests(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self.service = SeatDemoService(REPOSITORY_ROOT)
|
|
self.service.simulated_hardware_enabled = True
|
|
self.temporary_directory = tempfile.TemporaryDirectory()
|
|
self.addCleanup(self.temporary_directory.cleanup)
|
|
self.service.artifact_root = Path(self.temporary_directory.name)
|
|
|
|
def test_normal_simulated_hardware_is_explicit_and_isolated(self) -> None:
|
|
result = self.service.process(
|
|
"副驾靠背调到50%",
|
|
provider="local",
|
|
execution_mode="simulated_hardware",
|
|
)
|
|
|
|
self.assertEqual(result["status"], "succeeded")
|
|
report = result["execution_report"]
|
|
self.assertEqual(report["spec"]["mode"], "hil")
|
|
self.assertEqual(report["metadata"]["labels"]["simulation"], "true")
|
|
self.assertEqual(
|
|
report["metadata"]["labels"]["seat_feedback"],
|
|
"simulated_hardware",
|
|
)
|
|
telemetry = report["spec"]["results"][0]["telemetry"]
|
|
self.assertTrue(telemetry["simulation"])
|
|
self.assertFalse(telemetry["physical_can_opened"])
|
|
|
|
def test_each_fault_scenario_produces_a_failed_simulated_report(self) -> None:
|
|
expected_errors = {
|
|
"feedback_timeout": "FeedbackTimeout",
|
|
"adapter_disconnect": "CanAdapterDisconnected",
|
|
"motor_stall": "MotorStall",
|
|
"firmware_mismatch": "FirmwareMismatch",
|
|
"partial_feedback": "PartialFeedback",
|
|
}
|
|
for scenario, error_type in expected_errors.items():
|
|
with self.subTest(scenario=scenario):
|
|
result = self.service.process(
|
|
"副驾靠背调到50%",
|
|
provider="local",
|
|
execution_mode="simulated_hardware",
|
|
simulation_fault=scenario,
|
|
)
|
|
self.assertEqual(result["status"], "execution_failed")
|
|
report = result["execution_report"]
|
|
self.assertEqual(
|
|
report["metadata"]["labels"]["fault_scenario"], scenario
|
|
)
|
|
telemetry = report["spec"]["results"][0]["telemetry"]
|
|
self.assertEqual(telemetry["error_type"], error_type)
|
|
self.assertFalse(telemetry["physical_can_opened"])
|
|
|
|
def test_simulated_hardware_requires_server_side_enablement(self) -> None:
|
|
self.service.simulated_hardware_enabled = False
|
|
with self.assertRaises(HardwareSafetyError):
|
|
self.service.process(
|
|
"副驾靠背调到50%",
|
|
provider="local",
|
|
execution_mode="simulated_hardware",
|
|
)
|
|
|
|
def test_runtime_publishes_fault_catalog_without_enabling_real_hardware(self) -> None:
|
|
runtime = self.service.runtime_info()
|
|
self.assertTrue(runtime["simulated_hardware"]["enabled"])
|
|
self.assertFalse(runtime["simulated_hardware"]["physical_can_opened"])
|
|
self.assertIn("motor_stall", runtime["simulated_hardware"]["fault_scenarios"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|