github.com/mponton/terratest@v0.44.0/modules/shell/command_test.go (about) 1 package shell 2 3 import ( 4 "bytes" 5 "fmt" 6 "regexp" 7 "strings" 8 "testing" 9 10 "github.com/stretchr/testify/assert" 11 12 "github.com/mponton/terratest/modules/logger" 13 "github.com/mponton/terratest/modules/random" 14 ) 15 16 func TestRunCommandAndGetOutput(t *testing.T) { 17 t.Parallel() 18 19 text := "Hello, World" 20 cmd := Command{ 21 Command: "echo", 22 Args: []string{text}, 23 } 24 25 out := RunCommandAndGetOutput(t, cmd) 26 assert.Equal(t, text, strings.TrimSpace(out)) 27 } 28 29 func TestRunCommandAndGetOutputOrder(t *testing.T) { 30 t.Parallel() 31 32 stderrText := "Hello, Error" 33 stdoutText := "Hello, World" 34 expectedText := "Hello, Error\nHello, World\nHello, Error\nHello, World\nHello, Error\nHello, Error" 35 bashCode := fmt.Sprintf(` 36 echo_stderr(){ 37 (>&2 echo "%s") 38 # Add sleep to stabilize the test 39 sleep .01s 40 } 41 echo_stdout(){ 42 echo "%s" 43 # Add sleep to stabilize the test 44 sleep .01s 45 } 46 echo_stderr 47 echo_stdout 48 echo_stderr 49 echo_stdout 50 echo_stderr 51 echo_stderr 52 `, 53 stderrText, 54 stdoutText, 55 ) 56 cmd := Command{ 57 Command: "bash", 58 Args: []string{"-c", bashCode}, 59 } 60 61 out := RunCommandAndGetOutput(t, cmd) 62 assert.Equal(t, expectedText, strings.TrimSpace(out)) 63 } 64 65 func TestRunCommandGetExitCode(t *testing.T) { 66 t.Parallel() 67 68 cmd := Command{ 69 Command: "bash", 70 Args: []string{"-c", "exit 42"}, 71 Logger: logger.Discard, 72 } 73 74 out, err := RunCommandAndGetOutputE(t, cmd) 75 assert.Equal(t, "", out) 76 assert.NotNil(t, err) 77 code, err := GetExitCodeForRunCommandError(err) 78 assert.Nil(t, err) 79 assert.Equal(t, code, 42) 80 } 81 82 func TestRunCommandAndGetOutputConcurrency(t *testing.T) { 83 t.Parallel() 84 85 uniqueStderr := random.UniqueId() 86 uniqueStdout := random.UniqueId() 87 88 bashCode := fmt.Sprintf(` 89 echo_stderr(){ 90 sleep .0$[ ( $RANDOM %% 10 ) + 1 ]s 91 (>&2 echo "%s") 92 } 93 echo_stdout(){ 94 sleep .0$[ ( $RANDOM %% 10 ) + 1 ]s 95 echo "%s" 96 } 97 for i in {1..500} 98 do 99 echo_stderr & 100 echo_stdout & 101 done 102 wait 103 `, 104 uniqueStderr, 105 uniqueStdout, 106 ) 107 cmd := Command{ 108 Command: "bash", 109 Args: []string{"-c", bashCode}, 110 Logger: logger.Discard, 111 } 112 113 out := RunCommandAndGetOutput(t, cmd) 114 stdoutReg := regexp.MustCompile(uniqueStdout) 115 stderrReg := regexp.MustCompile(uniqueStderr) 116 assert.Equal(t, 500, len(stdoutReg.FindAllString(out, -1))) 117 assert.Equal(t, 500, len(stderrReg.FindAllString(out, -1))) 118 } 119 120 func TestRunCommandWithHugeLineOutput(t *testing.T) { 121 t.Parallel() 122 123 // generate a ~100KB line 124 bashCode := fmt.Sprintf(` 125 for i in {0..35000} 126 do 127 echo -n foo 128 done 129 echo 130 `) 131 132 cmd := Command{ 133 Command: "bash", 134 Args: []string{"-c", bashCode}, 135 Logger: logger.Discard, // don't print that line to stdout 136 } 137 138 out, err := RunCommandAndGetOutputE(t, cmd) 139 assert.NoError(t, err) 140 141 var buffer bytes.Buffer 142 for i := 0; i <= 35000; i++ { 143 buffer.WriteString("foo") 144 } 145 146 assert.Equal(t, out, buffer.String()) 147 } 148 149 // TestRunCommandOutputError ensures that getting the output never panics, even if no command was ever run. 150 func TestRunCommandOutputError(t *testing.T) { 151 t.Parallel() 152 153 cmd := Command{ 154 Command: "thisbinarydoesnotexistbecausenobodyusesnamesthatlong", 155 Args: []string{"-no-flag"}, 156 Logger: logger.Discard, 157 } 158 159 out, err := RunCommandAndGetOutputE(t, cmd) 160 assert.Equal(t, "", out) 161 assert.NotNil(t, err) 162 } 163 164 func TestCommandOutputType(t *testing.T) { 165 t.Parallel() 166 167 stdout := "hello world" 168 stderr := "this command has failed" 169 170 _, err := RunCommandAndGetOutputE(t, Command{ 171 Command: "sh", 172 Args: []string{"-c", `echo "` + stdout + `" && echo "` + stderr + `" >&2 && exit 1`}, 173 Logger: logger.Discard, 174 }) 175 176 if err != nil { 177 o, ok := err.(*ErrWithCmdOutput) 178 if !ok { 179 t.Fatalf("did not get correct type. got=%T", err) 180 } 181 assert.Len(t, o.Output.Stdout(), len(stdout)) 182 assert.Len(t, o.Output.Stderr(), len(stderr)) 183 assert.Len(t, o.Output.Combined(), len(stdout)+len(stderr)+1) // +1 for newline 184 } 185 }