import json import tempfile import unittest from pathlib import Path import factory_host from ft1_protocol import FT1Session, ProtocolError, parse_ft1_line class FactoryHostTests(unittest.TestCase): def test_expand_args(self): args = factory_host.expand_args( ["--port", "{port}", "{firmware}", "--station", "{station}"], aboot=Path(r"D:\burn_tool\aboot.exe"), firmware=Path(r"D:\fw\prod.zip"), port="COM14", station="2", baudrate=115200, ) self.assertEqual(args[1], "COM14") self.assertEqual(args[2], r"D:\fw\prod.zip") self.assertEqual(args[-1], "2") def test_merge_and_config_round_trip(self): with tempfile.TemporaryDirectory() as temp: path = Path(temp) / "config.json" config = factory_host.load_config(path) config["flash"]["workers"] = 4 factory_host.save_config(config, path) loaded = factory_host.load_config(path) self.assertEqual(loaded["flash"]["workers"], 4) self.assertIn("protocol", loaded) def test_parse_command_template(self): self.assertEqual(factory_host.parse_command_template('"C:\\Program Files\\aboot.exe" --port COM14'), [r"C:\Program Files\aboot.exe", "--port", "COM14"]) def test_default_flash_waits_for_arom_usb(self): args = factory_host.DEFAULT_CONFIG["flash"]["args"] self.assertIn("-u", args) self.assertIn("-a", args) self.assertNotIn("{port}", args) def test_project_root_and_relative_path(self): self.assertTrue((factory_host.ROOT_DIR / "burn_tool").is_dir()) config = factory_host.load_config(factory_host.CONFIG_PATH) self.assertEqual( Path(config["firmwares"]["production"]).name, "EG800AKCN_11LG-FT1-factory-test.zip", ) self.assertTrue( factory_host.resolve_project_path(config["firmwares"]["production"]).is_file() ) self.assertTrue( factory_host.resolve_project_path(config["firmwares"]["official"]).is_file() ) def test_ft1_ignores_sdk_log_and_parses_node(self): self.assertIsNone(parse_ft1_line("DP1312EA is OK!")) message = parse_ft1_line( 'FT1 {"v":1,"type":"node_result","seq":3,"session":"BOOT-1",' '"uptime_ms":2450,"imei":"860123456789012","iccid":"","nfc_uid":"",' '"node":1,"name":"POWER_ADC","result":"PASS","code":0,"elapsed_ms":350,' '"data":{"voltage_mv":3865}}' ) self.assertEqual(message["data"]["voltage_mv"], 3865) def test_ft1_session_result_and_sequence_guard(self): session = FT1Session() start = parse_ft1_line( 'FT1 {"v":1,"type":"session_start","seq":1,"session":"BOOT-1",' '"uptime_ms":2050,"imei":"860123456789012","iccid":"","nfc_uid":"",' '"fw":"FACTORY_TEST_1.0.0","start_time":null}' ) session.apply(start) result = parse_ft1_line( 'FT1 {"v":1,"type":"session_result","seq":2,"session":"BOOT-1",' '"uptime_ms":40120,"result":"FAIL","fail_code":1203,"imei":"860123456789012",' '"iccid":"","nfc_uid":"","start_time":null,"duration_ms":38070,"nodes":' '{"BOOT_AUDIO":"PASS","POWER_ADC":"PASS","AUDIO_LOOPBACK":"FAIL",' '"ESIM":"WAIT","DATA_CALL":"WAIT","NFC":"WAIT"}}' ) session.apply(result) self.assertEqual(session.result, "FAIL") self.assertEqual(session.nodes["AUDIO_LOOPBACK"], "FAIL") self.assertTrue(session.complete) with self.assertRaises(ProtocolError): session.apply(result) def test_ft1_rejects_node_name_mismatch(self): with self.assertRaises(ProtocolError): parse_ft1_line( 'FT1 {"v":1,"type":"node_start","seq":2,"session":"BOOT-1",' '"uptime_ms":2100,"node":1,"name":"NFC"}' ) def test_ft1_control_messages(self): ready = parse_ft1_line( 'FT1 {"v":1,"type":"device_ready","seq":1,"session":"BOOT-1",' '"uptime_ms":100,"fw":"FACTORY_TEST_1.0.0"}' ) ack = parse_ft1_line( 'FT1 {"v":1,"type":"command_ack","seq":2,"session":"BOOT-1",' '"uptime_ms":120,"command":"START","accepted":true}' ) session = FT1Session() self.assertEqual(session.apply(ready), "设备已识别 FACTORY_TEST_1.0.0") self.assertEqual(session.apply(ack), "START 已确认") self.assertTrue(session.device_ready_seen) self.assertTrue(session.start_ack_seen) def test_ft1_status_snapshot_keeps_passed_nodes(self): first = parse_ft1_line( 'FT1 {"v":1,"type":"status_snapshot","seq":1,"session":"BOOT-1",' '"uptime_ms":100,"active_node":0,"nodes":{"BOOT_AUDIO":"WAIT",' '"POWER_ADC":"WAIT","AUDIO_LOOPBACK":"WAIT","ESIM":"WAIT",' '"DATA_CALL":"WAIT","NFC":"WAIT"}}' ) second = parse_ft1_line( 'FT1 {"v":1,"type":"status_snapshot","seq":2,"session":"BOOT-1",' '"uptime_ms":600,"active_node":1,"nodes":{"BOOT_AUDIO":"PASS",' '"POWER_ADC":"WAIT","AUDIO_LOOPBACK":"WAIT","ESIM":"WAIT",' '"DATA_CALL":"WAIT","NFC":"WAIT"}}' ) session = FT1Session() session.apply(first) session.apply(second) self.assertEqual(session.nodes["BOOT_AUDIO"], "PASS") self.assertEqual(session.current_node, "POWER_ADC") if __name__ == "__main__": unittest.main()