(*--------------------------------------------------------------------------- Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. SPDX-License-Identifier: ISC ---------------------------------------------------------------------------*) (** Unit tests for {!E2e} — pure logic only, no VMs. *) (* --------------------------------------------------------------------------- Helpers --------------------------------------------------------------------------- *) let result_testable = Alcotest.testable E2e.pp_result (fun a b -> match (a, b) with | E2e.Pass a, E2e.Pass b -> String.equal a b | Fail a, Fail b -> String.equal a b | _ -> false) let pass msg = E2e.Pass msg let fail msg = E2e.Fail msg let contains pat s = Re.execp (Re.Pcre.re pat |> Re.compile) s (* --------------------------------------------------------------------------- Tests --------------------------------------------------------------------------- *) let test_default_config () = let c = E2e.default_config in Alcotest.(check int) "min_frames" 10 c.min_frames; Alcotest.(check (float 0.1)) "timeout" 60. c.timeout; Alcotest.(check (option string)) "build_file" None c.build_file; Alcotest.(check (option string)) "run_file" None c.run_file; Alcotest.(check (option string)) "kernel" None c.kernel; Alcotest.(check (option string)) "output" None c.output let test_is_pass () = Alcotest.(check bool) "pass is pass" true (E2e.is_pass (pass "ok")); Alcotest.(check bool) "fail is not pass" false (E2e.is_pass (fail "bad")) let test_exit_code_all_pass () = let results = [ pass "a"; pass "b"; pass "c" ] in Alcotest.(check int) "all pass" 0 (E2e.exit_code results) let test_exit_code_one_fail () = let results = [ pass "a"; fail "b"; pass "c" ] in Alcotest.(check int) "one fail" 1 (E2e.exit_code results) let test_exit_code_empty () = Alcotest.(check int) "empty" 0 (E2e.exit_code []) let test_check_frames_pass () = let r = E2e.check_frames ~received:15 ~target:10 in Alcotest.(check bool) "enough frames" true (E2e.is_pass r) let test_check_frames_exact () = let r = E2e.check_frames ~received:10 ~target:10 in Alcotest.(check bool) "exact frames" true (E2e.is_pass r) let test_check_frames_fail () = let r = E2e.check_frames ~received:3 ~target:10 in Alcotest.(check bool) "not enough frames" false (E2e.is_pass r) let test_check_frames_zero () = let r = E2e.check_frames ~received:0 ~target:10 in Alcotest.(check bool) "zero frames" false (E2e.is_pass r) let test_check_exit_code_clean () = let r = E2e.check_exit_code 0 in Alcotest.(check result_testable) "clean" (pass "clean shutdown (exit code 0)") r let test_check_exit_code_crash () = let r = E2e.check_exit_code 1 in Alcotest.(check bool) "crash" false (E2e.is_pass r) let test_check_exit_code_signal () = let r = E2e.check_exit_code 137 in Alcotest.(check bool) "signal" false (E2e.is_pass r) let test_pp_result_pass () = let s = Fmt.str "%a" E2e.pp_result (pass "ok") in Alcotest.(check bool) "has PASS" true (contains "PASS" s) let test_pp_result_fail () = let s = Fmt.str "%a" E2e.pp_result (fail "bad") in Alcotest.(check bool) "has FAIL" true (contains "FAIL" s) let test_report_all_pass () = (* report prints to stdout but returns exit code *) let code = E2e.report [ pass "a"; pass "b" ] in Alcotest.(check int) "exit 0" 0 code let test_report_with_failure () = let code = E2e.report [ pass "a"; fail "b" ] in Alcotest.(check int) "exit 1" 1 code let test_report_empty () = let code = E2e.report [] in Alcotest.(check int) "exit 0" 0 code (* --------------------------------------------------------------------------- Suite --------------------------------------------------------------------------- *) let suite = ( "e2e", [ Alcotest.test_case "config defaults" `Quick test_default_config; Alcotest.test_case "is_pass" `Quick test_is_pass; Alcotest.test_case "exit_code all pass" `Quick test_exit_code_all_pass; Alcotest.test_case "exit_code one fail" `Quick test_exit_code_one_fail; Alcotest.test_case "exit_code empty" `Quick test_exit_code_empty; Alcotest.test_case "check_frames enough" `Quick test_check_frames_pass; Alcotest.test_case "check_frames exact" `Quick test_check_frames_exact; Alcotest.test_case "check_frames not enough" `Quick test_check_frames_fail; Alcotest.test_case "check_frames zero" `Quick test_check_frames_zero; Alcotest.test_case "check_exit clean" `Quick test_check_exit_code_clean; Alcotest.test_case "check_exit crash" `Quick test_check_exit_code_crash; Alcotest.test_case "check_exit signal" `Quick test_check_exit_code_signal; Alcotest.test_case "pp_result pass" `Quick test_pp_result_pass; Alcotest.test_case "pp_result fail" `Quick test_pp_result_fail; Alcotest.test_case "report all pass" `Quick test_report_all_pass; Alcotest.test_case "report with failure" `Quick test_report_with_failure; Alcotest.test_case "report empty" `Quick test_report_empty; ] )