Print phase-aware failure messages + write error log for a failed direct test.
(
ctx: DirectTestContext,
proc: RunningProcess,
returncode: int,
)
| 358 | |
| 359 | |
| 360 | def _print_direct_test_failure( |
| 361 | ctx: DirectTestContext, |
| 362 | proc: RunningProcess, |
| 363 | returncode: int, |
| 364 | ) -> None: |
| 365 | """Print phase-aware failure messages + write error log for a failed direct test.""" |
| 366 | phase_data = ctx.phase_tracker.get_phase() |
| 367 | |
| 368 | if phase_data and phase_data["phase"] == "EXECUTE": |
| 369 | print_error(f"[MESON] ❌ Test FAILED during execution (exit code {returncode})") |
| 370 | print_error(f"[MESON] Test: {ctx.meson_test_name}") |
| 371 | |
| 372 | compile_errors_dir = ctx.build_dir.parent / "compile-errors" |
| 373 | compile_errors_dir.mkdir(exist_ok=True) |
| 374 | test_name_slug = ctx.meson_test_name.replace("test_", "").replace("/", "_") |
| 375 | error_log_path = compile_errors_dir / f"{test_name_slug}.log" |
| 376 | |
| 377 | with open(error_log_path, "w", encoding="utf-8") as f: |
| 378 | f.write(f"# Test: {ctx.meson_test_name}\n") |
| 379 | f.write(f"# Exit code: {returncode}\n") |
| 380 | f.write(f"# Full test output below:\n\n") |
| 381 | f.write("--- Test Output ---\n\n") |
| 382 | f.write(str(proc.stdout)) |
| 383 | |
| 384 | print_error(f"[MESON] 📄 Full test output: {error_log_path}") |
| 385 | |
| 386 | stdout_lower = str(proc.stdout).lower() |
| 387 | has_doctest_output = any( |
| 388 | pattern in stdout_lower |
| 389 | for pattern in [ |
| 390 | "test cases:", |
| 391 | "assertions:", |
| 392 | "[doctest]", |
| 393 | "test case failed", |
| 394 | ] |
| 395 | ) |
| 396 | has_watchdog_timeout = "internal timeout watchdog triggered" in stdout_lower |
| 397 | |
| 398 | if returncode == 1 and not proc.stdout.strip(): |
| 399 | print_error("[MESON] ⚠️ No output - possible crash at startup") |
| 400 | elif returncode == 1 and has_watchdog_timeout and not has_doctest_output: |
| 401 | print_error( |
| 402 | "[MESON] ⚠️ Test killed by internal timeout watchdog (exceeded time limit)" |
| 403 | ) |
| 404 | print_error( |
| 405 | "[MESON] 💡 This is a timeout, not a crash. Consider adding to slow_tests in tests/meson.build" |
| 406 | ) |
| 407 | elif returncode == 1 and not has_doctest_output: |
| 408 | print_error( |
| 409 | "[MESON] ⚠️ Test failed during initialization (before doctest ran)" |
| 410 | ) |
| 411 | error_lines = [ |
| 412 | line.strip() |
| 413 | for line in str(proc.stdout).splitlines() |
| 414 | if "error" in line.lower() and line.strip() |
| 415 | ] |
| 416 | if error_lines: |
| 417 | print_error("[MESON] 🔍 Error messages found in output:") |
no test coverage detected