File: shell_utils_test.clj

package info (click to toggle)
shell-utils-clojure 2.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 232 kB
  • sloc: java: 148; sh: 25; makefile: 23
file content (136 lines) | stat: -rw-r--r-- 6,152 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
(ns puppetlabs.puppetserver.shell-utils-test
  (:require [clojure.test :refer :all]
            [puppetlabs.puppetserver.shell-utils :as sh-utils]
            [puppetlabs.kitchensink.core :as ks]
            [puppetlabs.trapperkeeper.testutils.logging :as logging]
            [clojure.string :as str]
            [clojure.set :as set])
  (:import (java.io ByteArrayInputStream)
           (com.puppetlabs.puppetserver ShellUtils ShellUtils$ExecutionOptions)))

(def test-resources
  (ks/absolute-path
   "./dev-resources/puppetlabs/puppetserver/shell_utils_test"))

(defn script-path
  [script-name]
  (str test-resources "/" script-name))

(defn parse-env-output
  [env-output]
  (set (str/split-lines env-output)))

(deftest returns-the-exit-code
  (testing "true should return 0"
    (is (zero? (:exit-code (sh-utils/execute-command (script-path "true"))))))
  (testing "false should return 1"
    (is (= 1 (:exit-code (sh-utils/execute-command (script-path "false")))))))

(deftest returns-stdout-correctly
  (testing "echo should add content to stdout"
    (is (= "foo\n" (:stdout (sh-utils/execute-command
                             (script-path "echo")
                             {:args ["foo"]}))))))

(deftest returns-stderr-correctly
  (testing "echo can add content to stderr as well"
    (logging/with-test-logging
     (is (= "bar\n" (:stderr (sh-utils/execute-command
                              (script-path "warn")
                              {:args ["bar"]})))))))

(deftest combines-stderr-and-stdout-correctly
  (logging/with-test-logging
   (let [options (ShellUtils$ExecutionOptions.)
         _ (.setCombineStdoutStderr options true)
         results (ShellUtils/executeCommand (str (script-path "echo_and_warn")
                                                 " baz")
                                            options)]
     (testing "combined info echoed to stdout and stderr captured as output"
       (let [output (.getOutput results)]
         ;; Allow stdout and stderr messages to come in either order since
         ;; the order in which they are read from the different stream
         ;; consuming threads is not reliable.
         (is (or (= "to out: baz\nto err: baz\n" output)
                 (= "to err: baz\nto out: baz\n" output))
             (format "Output produced, '%s', did not match expected output"
                     output))))
     (testing "only info echoed to stderr captured as error"
       (is (= "to err: baz\n" (.getError results))))
     (testing "only stderr info (and not stdout info) is logged"
       (is (logged?
            "Executed an external process which logged to STDERR: to err: baz\n"
            :warn))))))

(deftest pass-args-correctly
  (testing "passes the expected number of args to cmd"
    (is (= 5 (:exit-code (sh-utils/execute-command
                          (script-path "num-args")
                          {:args ["a" "b" "c" "d" "e"]}))))))

(deftest inherits-env-correctly
  (testing "inherits environment variables if not specified"
    (let [env-output (:stdout (sh-utils/execute-command
                               (script-path "list_env_var_names")))
          env (parse-env-output env-output)]
      (is (< 3 (count env))
          (str "Expected at least 3 environment variables, got:\n" env-output))
      (is (contains? env "PATH"))
      (is (contains? env "PWD"))
      (is (contains? env "HOME")))))

(deftest sets-env-correctly
  (testing "sets environment variables correctly"
    (is (= "foo\n" (:stdout (sh-utils/execute-command
                             (script-path "echo_foo_env_var")
                             {:env {"FOO" "foo"}}))))

    (let [env-output (:stdout (sh-utils/execute-command
                               (script-path "list_env_var_names")
                               {:env {"FOO" "foo\nbar"}}))
          env (parse-env-output env-output)
          ;; it seems that the JVM always includes a PWD env var, no
          ;; matter what, and in certain terminals it may also include a few
          ;; other vars, so we are writing the test to be tolerant of that.
          expected-keys #{"FOO" "PWD" "_" "SHLVL"}
          extra-keys (set/difference env expected-keys)]
      (is (empty? extra-keys)
          (str "Found unexpected environment variables:" extra-keys)))))

(deftest pass-stdin-correctly
  (testing "passes stdin stream to command"
    (is (= "foo" (:stdout (sh-utils/execute-command
                             (script-path "cat")
                             {:in (ByteArrayInputStream.
                                   (.getBytes "foo" "UTF-8"))}))))))

(deftest sets-cwd-correctly
  (testing "sets current working directory correctly"
    (let [tmpdir (System/getProperty "java.io.tmpdir")]
      (is (= (str tmpdir "\n") (:stdout (sh-utils/execute-command
                                         (script-path "echo_cwd")
                                         {:cwd tmpdir})))))))

(deftest throws-exception-for-non-absolute-path
  (testing "Commands must be given using absolute paths"
    (is (thrown? IllegalArgumentException
                 (sh-utils/execute-command "echo")))))

(deftest throws-exception-for-non-existent-file
  (testing "The given command must exist"
    (is (thrown-with-msg? IllegalArgumentException
                          #"command '/usr/bin/footest' does not exist"
                          (sh-utils/execute-command "/usr/bin/footest")))))

(deftest throws-reasonable-error-for-arguments-in-command
  (testing "A meaningful error is raised if arguments are added to the command"
    (is (thrown-with-msg? IllegalArgumentException
                          #"appears to use command-line arguments, but this is not allowed"
                          (sh-utils/execute-command
                           (str (script-path "echo") " foo"))))))

(deftest can-read-more-than-the-pipe-buffer
  (testing "Doesn't deadlock when reading more than the pipe can hold"
    (is (= 128000 (count (:stdout (sh-utils/execute-command
                                   (script-path "gen-output")
                                   {:args ["128000"]})))))))