File: run_test.ml

package info (click to toggle)
liquidsoap 2.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 12,372 kB
  • sloc: ml: 71,806; javascript: 27,320; ansic: 398; xml: 114; sh: 99; lisp: 96; makefile: 26
file content (123 lines) | stat: -rw-r--r-- 3,759 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
let timeout = 10 * 60
let test = Sys.argv.(1)
let cmd = Sys.argv.(2)
let args = try Array.sub Sys.argv 2 (Array.length Sys.argv - 2) with _ -> [||]
let stdin_file = Filename.null
let log_files = ref []

let cleanup () =
  List.iter (fun logfile -> try Unix.unlink logfile with _ -> ()) !log_files

let warning_prefix, error_prefix =
  if Sys.getenv_opt "GITHUB_ACTIONS" <> None then
    ( Printf.sprintf "::warning file=%s,title=Test skipped::" test,
      Printf.sprintf "::error file=%s,title=Test failed::" test )
  else ("", "")

let () = Console.color_conf := `Always
let colorized_test = Console.colorize [`white; `bold] test
let colorized_timeout = Console.colorize [`magenta; `bold] "[timeout]"
let colorized_ok = Console.colorize [`green; `bold] "[ok]"
let colorized_skipped = Console.colorize [`yellow; `bold] "[skipped]"
let colorized_failed = Console.colorize [`red; `bold] "[failed]"

let run_process ~action cmd args =
  let start_time = Unix.time () in
  let logfile = Filename.temp_file "test" test in
  log_files := logfile :: !log_files;
  let stdin = Unix.openfile stdin_file [Unix.O_RDWR] 0o644 in
  let stdout = Unix.openfile logfile [Unix.O_RDWR; Unix.O_TRUNC] 0o644 in

  let print_log () =
    try
      Unix.close stdout;
      let buffer_size = 1024 in
      let buffer = Bytes.create buffer_size in
      let fd = Unix.openfile logfile [Unix.O_RDONLY] 0 in
      let rec loop () =
        match Unix.read fd buffer 0 buffer_size with
          | 0 -> ()
          | _ ->
              Printf.eprintf "%s" (Bytes.unsafe_to_string buffer);
              loop ()
      in
      loop ();
      print_newline ();
      Unix.close fd
    with _ -> ()
  in

  let runtime () =
    let runtime = Unix.time () -. start_time in
    let min = int_of_float (runtime /. 60.) in
    let sec = runtime -. (float min *. 60.) in
    (min, int_of_float sec)
  in

  let pid_ref = ref None in
  let running = ref false in

  let on_timeout () =
    if !running then (
      let min, sec = runtime () in
      Printf.eprintf "%s%s test %s: %s (time: %02dm:%02ds)\n" error_prefix
        action colorized_test colorized_timeout min sec;
      (match !pid_ref with Some p -> Unix.kill p Sys.sigkill | None -> ());
      print_log ();
      cleanup ();
      exit 1)
  in

  ignore
    (Thread.create
       (fun () ->
         Unix.sleep timeout;
         on_timeout ())
       ());

  let pid = Unix.create_process cmd args stdin stdout stdout in
  running := true;
  pid_ref := Some pid;

  match Unix.waitpid [] pid with
    | _, Unix.WEXITED 0 ->
        running := false;
        let min, sec = runtime () in
        Printf.eprintf "%s test %s: %s (time: %02dm:%02ds)\n" action
          colorized_test colorized_ok min sec;
        if Sys.getenv_opt "LIQ_VERBOSE_TEST" <> None then print_log ();
        cleanup ()
    | _, Unix.WEXITED 123 ->
        running := false;
        Printf.eprintf "%s%s test %s: %s\n" warning_prefix action colorized_test
          colorized_skipped;
        exit 0
    | _ ->
        running := false;
        let min, sec = runtime () in
        Printf.eprintf "%s%s test %s: %s (time: %02dm:%02ds)\n" action
          error_prefix colorized_test colorized_failed min sec;
        print_log ();
        exit 1

let run () =
  (*
  Unix.putenv "MEMTRACE" (Printf.sprintf "%s.trace" test);
*)
  if String.starts_with ~prefix:"liquidsoap" cmd then
    run_process ~action:"Cached" cmd
      (Array.concat
         [
           [| args.(0) |];
           [| "--cache-only" |];
           Array.sub args 1 (Array.length args - 1);
         ]);

  run_process ~action:"Ran" cmd args

let () =
  try run ()
  with exn ->
    let bt = Printexc.get_raw_backtrace () in
    cleanup ();
    Printexc.raise_with_backtrace exn bt