File: command_test.ml

package info (click to toggle)
herdtools7 7.58-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 19,732 kB
  • sloc: ml: 128,583; ansic: 3,827; makefile: 670; python: 407; sh: 212; awk: 14
file content (142 lines) | stat: -rw-r--r-- 5,229 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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
(****************************************************************************)
(*                           the diy toolsuite                              *)
(*                                                                          *)
(* Jade Alglave, University College London, UK.                             *)
(* Luc Maranget, INRIA Paris-Rocquencourt, France.                          *)
(*                                                                          *)
(* Copyright 2010-present Institut National de Recherche en Informatique et *)
(* en Automatique, ARM Ltd and the authors. All rights reserved.            *)
(*                                                                          *)
(* This software is governed by the CeCILL-B license under French law and   *)
(* abiding by the rules of distribution of free software. You can use,      *)
(* modify and/ or redistribute the software under the terms of the CeCILL-B *)
(* license as circulated by CEA, CNRS and INRIA at the following URL        *)
(* "http://www.cecill.info". We also give a copy in LICENSE.txt.            *)
(****************************************************************************)

(** Tests for the Command module. *)

module Option = Base.Option

module StringList = struct
  let compare = Base.List.compare String.compare
  let to_ocaml_string = Base.List.to_ocaml_string Base.String.to_ocaml_string
end

let tests = [
  "Command.command without args", (fun () ->
    let expected = "'foo'" in
    let actual = Command.command "foo" [] in
    if String.compare actual expected <> 0 then
      Test.fail (Printf.sprintf "Expected %s, got %s" expected actual)
  );
  "Command.command with args", (fun () ->
    let expected = "'foo' '-bar' 'baz'" in
    let actual = Command.command "foo" ["-bar"; "baz"] in
    if String.compare actual expected <> 0 then
      Test.fail (Printf.sprintf "Expected %s, got %s" expected actual)
  );
  "Command.command with escaping args", (fun () ->
    let expected = "'/bin/do foo' '-a flag' '~/foo'\\''s files/'" in
    let actual = Command.command "/bin/do foo" ["-a flag"; "~/foo's files/"] in
    if String.compare actual expected <> 0 then
      Test.fail (Printf.sprintf "Expected %s, got %s" expected actual)
  );

  "Command.run runs cleanly", (fun () ->
    (* This test uses `touch`, because it is a command that produces a
     * side-effect, and so can be verified to have run. *)

    (* Create a random file path, by creating a random file and deleting it. *)
    let path = Filename.temp_file "" "" in
    Sys.remove path ;

    (* Recreate it with `touch`. *)
    Command.run "touch" [path] ;

    if not (Sys.file_exists path) then
      Test.fail "File doesn't exist after `touch`"
    else
      (* Cleanup. *)
      Sys.remove path
  );

  "Command.run ~stdout", (fun () ->
    let tests = [
      ("true", [], []);
      ("echo", ["foo"], ["foo"]);
      ("echo", ["foo\nbar"], ["foo"; "bar"]);
    ] in

    List.iter
      (fun (bin, args, expected) ->
        let actual = ref None in
        let read_lines i = actual := Some (Channel.read_lines i) in
        Command.run ~stdout:read_lines bin args ;
        let actual = Option.get !actual in

        if StringList.compare actual expected <> 0 then
          Test.fail (Printf.sprintf "Expected %s, got %s"
            (StringList.to_ocaml_string expected)
            (StringList.to_ocaml_string actual)
          )
      )
      tests
  );
  "Command.run ~stdin ~stdout", (fun () ->
    let echo o =
      Printf.fprintf o "I am a line\n" ;
      Printf.fprintf o "so am I\n" ;
      close_out o
    in
    let expected = [
      "I am a line" ;
      "so am I" ;
    ] in

    let actual = ref None in
    let read_lines i = actual := Some (Channel.read_lines i) in
    Command.run ~stdin:echo ~stdout:read_lines "cat" [] ;
    let actual = Option.get !actual in

    if StringList.compare actual expected <> 0 then
      Test.fail (Printf.sprintf "expected %s, got %s"
        (StringList.to_ocaml_string expected)
        (StringList.to_ocaml_string actual)
      )
  );
  "Command.run ~stdout ~stderr", (fun () ->
    let bin = Lazy.force Shelf.python in
    let args = [
      "-c" ;
      "import sys; sys.stdout.write('mew\\n'); sys.stderr.write('purr\\n')" ;
    ] in

    let expected_stdout = [ "mew" ] in
    let expected_stderr = [ "purr" ] in

    let actual_stdout = ref None in
    let actual_stderr = ref None in
    let read r i = r := Some (Channel.read_lines i) in
    Command.run
      ~stdout:(read actual_stdout)
      ~stderr:(read actual_stderr)
      bin args ;
    let actual_stdout = Option.get !actual_stdout in
    let actual_stderr = Option.get !actual_stderr in

    if StringList.compare actual_stdout expected_stdout <> 0 then
      Test.fail (Printf.sprintf "stdout: expected %s, got %s"
        (StringList.to_ocaml_string expected_stdout)
        (StringList.to_ocaml_string actual_stdout)
      ) ;

    if StringList.compare actual_stderr expected_stderr <> 0 then
      Test.fail (Printf.sprintf "stderr: expected %s, got %s"
        (StringList.to_ocaml_string expected_stderr)
        (StringList.to_ocaml_string actual_stderr)
      )
  );
]

let () = Test.run tests