End-to-end test harness for the SpaceOS pipeline
at main 126 lines 5.1 kB view raw
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6(** Unit tests for {!E2e} — pure logic only, no VMs. *) 7 8(* --------------------------------------------------------------------------- 9 Helpers 10 --------------------------------------------------------------------------- *) 11 12let result_testable = 13 Alcotest.testable E2e.pp_result (fun a b -> 14 match (a, b) with 15 | E2e.Pass a, E2e.Pass b -> String.equal a b 16 | Fail a, Fail b -> String.equal a b 17 | _ -> false) 18 19let pass msg = E2e.Pass msg 20let fail msg = E2e.Fail msg 21let contains pat s = Re.execp (Re.Pcre.re pat |> Re.compile) s 22 23(* --------------------------------------------------------------------------- 24 Tests 25 --------------------------------------------------------------------------- *) 26 27let test_default_config () = 28 let c = E2e.default_config in 29 Alcotest.(check int) "min_frames" 10 c.min_frames; 30 Alcotest.(check (float 0.1)) "timeout" 60. c.timeout; 31 Alcotest.(check (option string)) "build_file" None c.build_file; 32 Alcotest.(check (option string)) "run_file" None c.run_file; 33 Alcotest.(check (option string)) "kernel" None c.kernel; 34 Alcotest.(check (option string)) "output" None c.output 35 36let test_is_pass () = 37 Alcotest.(check bool) "pass is pass" true (E2e.is_pass (pass "ok")); 38 Alcotest.(check bool) "fail is not pass" false (E2e.is_pass (fail "bad")) 39 40let test_exit_code_all_pass () = 41 let results = [ pass "a"; pass "b"; pass "c" ] in 42 Alcotest.(check int) "all pass" 0 (E2e.exit_code results) 43 44let test_exit_code_one_fail () = 45 let results = [ pass "a"; fail "b"; pass "c" ] in 46 Alcotest.(check int) "one fail" 1 (E2e.exit_code results) 47 48let test_exit_code_empty () = Alcotest.(check int) "empty" 0 (E2e.exit_code []) 49 50let test_check_frames_pass () = 51 let r = E2e.check_frames ~received:15 ~target:10 in 52 Alcotest.(check bool) "enough frames" true (E2e.is_pass r) 53 54let test_check_frames_exact () = 55 let r = E2e.check_frames ~received:10 ~target:10 in 56 Alcotest.(check bool) "exact frames" true (E2e.is_pass r) 57 58let test_check_frames_fail () = 59 let r = E2e.check_frames ~received:3 ~target:10 in 60 Alcotest.(check bool) "not enough frames" false (E2e.is_pass r) 61 62let test_check_frames_zero () = 63 let r = E2e.check_frames ~received:0 ~target:10 in 64 Alcotest.(check bool) "zero frames" false (E2e.is_pass r) 65 66let test_check_exit_code_clean () = 67 let r = E2e.check_exit_code 0 in 68 Alcotest.(check result_testable) 69 "clean" 70 (pass "clean shutdown (exit code 0)") 71 r 72 73let test_check_exit_code_crash () = 74 let r = E2e.check_exit_code 1 in 75 Alcotest.(check bool) "crash" false (E2e.is_pass r) 76 77let test_check_exit_code_signal () = 78 let r = E2e.check_exit_code 137 in 79 Alcotest.(check bool) "signal" false (E2e.is_pass r) 80 81let test_pp_result_pass () = 82 let s = Fmt.str "%a" E2e.pp_result (pass "ok") in 83 Alcotest.(check bool) "has PASS" true (contains "PASS" s) 84 85let test_pp_result_fail () = 86 let s = Fmt.str "%a" E2e.pp_result (fail "bad") in 87 Alcotest.(check bool) "has FAIL" true (contains "FAIL" s) 88 89let test_report_all_pass () = 90 (* report prints to stdout but returns exit code *) 91 let code = E2e.report [ pass "a"; pass "b" ] in 92 Alcotest.(check int) "exit 0" 0 code 93 94let test_report_with_failure () = 95 let code = E2e.report [ pass "a"; fail "b" ] in 96 Alcotest.(check int) "exit 1" 1 code 97 98let test_report_empty () = 99 let code = E2e.report [] in 100 Alcotest.(check int) "exit 0" 0 code 101 102(* --------------------------------------------------------------------------- 103 Suite 104 --------------------------------------------------------------------------- *) 105 106let suite = 107 ( "e2e", 108 [ 109 Alcotest.test_case "config defaults" `Quick test_default_config; 110 Alcotest.test_case "is_pass" `Quick test_is_pass; 111 Alcotest.test_case "exit_code all pass" `Quick test_exit_code_all_pass; 112 Alcotest.test_case "exit_code one fail" `Quick test_exit_code_one_fail; 113 Alcotest.test_case "exit_code empty" `Quick test_exit_code_empty; 114 Alcotest.test_case "check_frames enough" `Quick test_check_frames_pass; 115 Alcotest.test_case "check_frames exact" `Quick test_check_frames_exact; 116 Alcotest.test_case "check_frames not enough" `Quick test_check_frames_fail; 117 Alcotest.test_case "check_frames zero" `Quick test_check_frames_zero; 118 Alcotest.test_case "check_exit clean" `Quick test_check_exit_code_clean; 119 Alcotest.test_case "check_exit crash" `Quick test_check_exit_code_crash; 120 Alcotest.test_case "check_exit signal" `Quick test_check_exit_code_signal; 121 Alcotest.test_case "pp_result pass" `Quick test_pp_result_pass; 122 Alcotest.test_case "pp_result fail" `Quick test_pp_result_fail; 123 Alcotest.test_case "report all pass" `Quick test_report_all_pass; 124 Alcotest.test_case "report with failure" `Quick test_report_with_failure; 125 Alcotest.test_case "report empty" `Quick test_report_empty; 126 ] )