Run self-contained loopback network autoresearch (--net). The ESP32 starts an HTTP server and uses its own HTTP client to fetch from 127.0.0.1 (localhost). No WiFi, no host involvement. Args: upload_port: Serial port for RPC communication serial_iface: Pre-created seria
(
upload_port: str,
serial_iface: "SerialInterface | None",
timeout: float = 60.0,
)
| 329 | |
| 330 | |
| 331 | async def run_net_loopback_autoresearch( |
| 332 | upload_port: str, |
| 333 | serial_iface: "SerialInterface | None", |
| 334 | timeout: float = 60.0, |
| 335 | ) -> int: |
| 336 | """Run self-contained loopback network autoresearch (--net). |
| 337 | |
| 338 | The ESP32 starts an HTTP server and uses its own HTTP client to fetch |
| 339 | from 127.0.0.1 (localhost). No WiFi, no host involvement. |
| 340 | |
| 341 | Args: |
| 342 | upload_port: Serial port for RPC communication |
| 343 | serial_iface: Pre-created serial interface |
| 344 | timeout: RPC timeout in seconds |
| 345 | |
| 346 | Returns: |
| 347 | Exit code (0 = success, 1 = failure) |
| 348 | """ |
| 349 | print() |
| 350 | print("=" * 60) |
| 351 | print("NETWORK AUTORESEARCH MODE: LOOPBACK (self-contained)") |
| 352 | print("=" * 60) |
| 353 | print() |
| 354 | |
| 355 | client: RpcClient | None = None |
| 356 | |
| 357 | try: |
| 358 | # Connect to device via RPC |
| 359 | print(f" Connecting to device on {upload_port}...") |
| 360 | client = RpcClient(upload_port, timeout=timeout, serial_interface=serial_iface) |
| 361 | await client.connect(boot_wait=3.0, drain_boot=True) |
| 362 | print(f" {Fore.GREEN}Connected to device{Style.RESET_ALL}") |
| 363 | |
| 364 | # Send the loopback test command |
| 365 | print("\n--- Running loopback HTTP test on ESP32 ---") |
| 366 | print(" ESP32 will start HTTP server and GET its own endpoints via 127.0.0.1") |
| 367 | print() |
| 368 | |
| 369 | response = await client.send("runNetLoopback", timeout=30.0) |
| 370 | test_result = response.data |
| 371 | |
| 372 | if not isinstance(test_result, dict): |
| 373 | print(f" {Fore.RED}Unexpected response: {test_result}{Style.RESET_ALL}") |
| 374 | return 1 |
| 375 | |
| 376 | # Display results |
| 377 | tests_passed = test_result.get("tests_passed", 0) |
| 378 | tests_failed = test_result.get("tests_failed", 0) |
| 379 | total = tests_passed + tests_failed |
| 380 | results = test_result.get("results", []) |
| 381 | |
| 382 | if test_result.get("error"): |
| 383 | print(f" {Fore.RED}Error: {test_result['error']}{Style.RESET_ALL}") |
| 384 | return 1 |
| 385 | |
| 386 | for r in results: |
| 387 | test_name = r.get("test", "?") |
| 388 | passed = r.get("passed", False) |
no test coverage detected