github.com/alexellis/go-execute@v0.6.0/pkg/v2/exec_test.go (about) 1 package execute 2 3 import ( 4 "bytes" 5 "context" 6 "errors" 7 "os" 8 "strings" 9 "testing" 10 "time" 11 ) 12 13 func TestExec_ReturnErrorForUnknownCommand(t *testing.T) { 14 ctx := context.Background() 15 16 task := ExecTask{Command: "/bin/go_execute_you_cant_find_me /"} 17 res, err := task.Execute(ctx) 18 if err == nil { 19 t.Fatalf("want error, but got nil") 20 } 21 22 if !strings.Contains(err.Error(), "no such file or directory") { 23 t.Fatalf("want context.Canceled, but got %v", err) 24 } 25 26 // expect and empty default response 27 if res.Cancelled != false { 28 t.Fatalf("want not cancelled, but got true") 29 } 30 if res.ExitCode != 0 { 31 t.Fatalf("want exit code 0, but got %d", res.ExitCode) 32 } 33 if res.Stderr != "" { 34 t.Fatalf("want empty stderr, but got %s", res.Stderr) 35 } 36 if res.Stdout != "" { 37 t.Fatalf("want empty stdout, but got %s", res.Stdout) 38 } 39 } 40 41 func TestExec_ContextAlreadyCancelled(t *testing.T) { 42 ctx, cancel := context.WithCancel(context.Background()) 43 cancel() 44 45 task := ExecTask{Command: "/bin/ls /"} 46 res, err := task.Execute(ctx) 47 if err == nil { 48 t.Fatalf("want error, but got nil") 49 } 50 51 if !errors.Is(err, context.Canceled) { 52 t.Fatalf("want context.Canceled, but got %v", err) 53 } 54 55 if res.Cancelled != true { 56 t.Fatalf("want cancelled, but got false") 57 } 58 59 if res.ExitCode != -1 { 60 t.Fatalf("want exit code -1, but got %d", res.ExitCode) 61 } 62 } 63 64 func TestExec_ContextCancelledDuringExecution(t *testing.T) { 65 ctx, cancel := context.WithCancel(context.Background()) 66 go func() { 67 time.AfterFunc(time.Second, cancel) 68 }() 69 70 task := ExecTask{Command: "sleep 10"} 71 res, err := task.Execute(ctx) 72 if err == nil { 73 t.Fatalf("want error, but got nil") 74 } 75 76 if !errors.Is(err, context.Canceled) { 77 t.Fatalf("want context.Canceled, but got %v", err) 78 } 79 80 if res.Cancelled != true { 81 t.Fatalf("want cancelled, but got false") 82 } 83 84 if res.ExitCode != -1 { 85 t.Fatalf("want exit code -1, but got %d", res.ExitCode) 86 } 87 } 88 89 func TestExecShell_ContextCancelledDuringExecution(t *testing.T) { 90 ctx, cancel := context.WithCancel(context.Background()) 91 go func() { 92 time.AfterFunc(time.Second, cancel) 93 }() 94 95 task := ExecTask{Command: "sleep 10", Shell: true} 96 res, err := task.Execute(ctx) 97 if err == nil { 98 t.Fatalf("want error, but got nil") 99 } 100 101 if !errors.Is(err, context.Canceled) { 102 t.Fatalf("want context.Canceled, but got %v", err) 103 } 104 105 if res.Cancelled != true { 106 t.Fatalf("want cancelled, but got false") 107 } 108 109 if res.ExitCode != -1 { 110 t.Fatalf("want exit code -1, but got %d", res.ExitCode) 111 } 112 } 113 114 func TestExec_WithShell(t *testing.T) { 115 ctx := context.Background() 116 task := ExecTask{Command: "/bin/ls /", Shell: true} 117 res, err := task.Execute(ctx) 118 if err != nil { 119 t.Fatalf(err.Error()) 120 } 121 122 if len(res.Stdout) == 0 { 123 t.Fatalf("want data, but got empty") 124 } 125 126 if len(res.Stderr) != 0 { 127 t.Fatalf("want empty, but got: %s", res.Stderr) 128 } 129 } 130 131 func TestExec_WithShellAndArgs(t *testing.T) { 132 ctx := context.Background() 133 task := ExecTask{Command: "/bin/ls", Args: []string{"/"}, Shell: true} 134 res, err := task.Execute(ctx) 135 if err != nil { 136 t.Fatalf(err.Error()) 137 } 138 139 if len(res.Stdout) == 0 { 140 t.Fatalf("want data, but got empty") 141 } 142 143 if len(res.Stderr) != 0 { 144 t.Fatalf("want empty, but got: %s", res.Stderr) 145 } 146 } 147 148 func TestExec_CatTransformString(t *testing.T) { 149 input := "1 line 1" 150 151 reader := bytes.NewReader([]byte(input)) 152 want := " 1\t1 line 1" 153 154 ctx := context.Background() 155 task := ExecTask{Command: "cat", Shell: false, Args: []string{"-b"}, Stdin: reader} 156 res, err := task.Execute(ctx) 157 if err != nil { 158 t.Fatalf(err.Error()) 159 } 160 161 if res.Stdout != want { 162 t.Fatalf("want %q, got %q", want, res.Stdout) 163 } 164 } 165 166 func TestExec_CatWC(t *testing.T) { 167 input := `this 168 has 169 four 170 lines 171 ` 172 173 reader := bytes.NewReader([]byte(input)) 174 want := "4" 175 176 ctx := context.Background() 177 task := ExecTask{Command: "wc", Shell: false, Args: []string{"-l"}, Stdin: reader} 178 res, err := task.Execute(ctx) 179 if err != nil { 180 t.Fatalf(err.Error()) 181 } 182 183 got := strings.TrimSpace(res.Stdout) 184 if got != want { 185 t.Fatalf("want %q, got %q", want, got) 186 } 187 } 188 189 func TestExec_WithEnvVars(t *testing.T) { 190 ctx := context.Background() 191 task := ExecTask{Command: "env", Shell: false, Env: []string{"GOTEST=1", "GOTEST2=2"}} 192 res, err := task.Execute(ctx) 193 if err != nil { 194 t.Fatalf(err.Error()) 195 } 196 197 if !strings.Contains(res.Stdout, "GOTEST") { 198 t.Fatalf("want env to show GOTEST=1 since we passed that variable") 199 } 200 201 if !strings.Contains(res.Stdout, "GOTEST2") { 202 t.Fatalf("want env to show GOTEST2=2 since we passed that variable") 203 } 204 } 205 206 func TestExec_WithEnvVarsInheritedFromParent(t *testing.T) { 207 os.Setenv("TEST", "value") 208 ctx := context.Background() 209 task := ExecTask{Command: "env", Shell: false, Env: []string{"GOTEST=1"}} 210 res, err := task.Execute(ctx) 211 if err != nil { 212 t.Fatalf(err.Error()) 213 } 214 215 if !strings.Contains(res.Stdout, "TEST") { 216 t.Fatalf("want env to show TEST=value since we passed that variable") 217 } 218 219 if !strings.Contains(res.Stdout, "GOTEST") { 220 t.Fatalf("want env to show GOTEST=1 since we passed that variable") 221 } 222 } 223 224 func TestExec_WithEnvVarsAndShell(t *testing.T) { 225 ctx := context.Background() 226 task := ExecTask{Command: "env", Shell: true, Env: []string{"GOTEST=1"}} 227 res, err := task.Execute(ctx) 228 if err != nil { 229 t.Fatalf(err.Error()) 230 } 231 232 if !strings.Contains(res.Stdout, "GOTEST") { 233 t.Fatalf("want env to show GOTEST=1 since we passed that variable") 234 } 235 } 236 237 func TestExec_CanStreamStdout(t *testing.T) { 238 input := "1 line 1" 239 240 reader := bytes.NewReader([]byte(input)) 241 want := " 1\t1 line 1" 242 243 ctx := context.Background() 244 task := ExecTask{Command: "cat", Shell: false, Args: []string{"-b"}, Stdin: reader, StreamStdio: true} 245 res, err := task.Execute(ctx) 246 if err != nil { 247 t.Fatalf(err.Error()) 248 } 249 250 if res.Stdout != want { 251 t.Fatalf("want %q, got %q", want, res.Stdout) 252 } 253 } 254 255 func TestExec_CanStreamStderr(t *testing.T) { 256 ctx := context.Background() 257 task := ExecTask{Command: "ls /unknown/location/should/fail", StreamStdio: true} 258 res, err := task.Execute(ctx) 259 if err != nil { 260 t.Fatalf(err.Error()) 261 } 262 263 if res.Stdout != "" { 264 t.Fatalf("want empty string Stdout, got %q", res.Stdout) 265 } 266 267 want := "ls: cannot access '/unknown/location/should/fail': No such file or directory\n" 268 if res.Stderr != want { 269 t.Fatalf("want %q Stderr, got %q", want, res.Stderr) 270 } 271 }