| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package execution |
| |
| import ( |
| "bytes" |
| "context" |
| "errors" |
| "io" |
| "os/exec" |
| "testing" |
| |
| "github.com/google/go-cmp/cmp" |
| ) |
| |
| func TestExecAll(t *testing.T) { |
| echo, err := exec.LookPath("echo") |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| helloCmd := Command{Args: []string{echo, "hello"}} |
| byeCmd := Command{Args: []string{echo, "bye"}} |
| unknownCmd := Command{Args: []string{"unknownCmd"}} |
| userCmd := Command{Args: []string{"false"}, UserCausedError: true} |
| tests := []struct { |
| name string |
| cmds []Command |
| expectErr bool |
| expectUserErr bool |
| expectedStdout string |
| }{ |
| { |
| name: "all pass", |
| cmds: []Command{helloCmd, byeCmd}, |
| expectedStdout: "hello\nbye\n", |
| }, |
| { |
| name: "middle command fails", |
| cmds: []Command{helloCmd, unknownCmd, byeCmd}, |
| expectErr: true, |
| expectedStdout: "hello\n", |
| }, |
| { |
| name: "last command fails", |
| cmds: []Command{helloCmd, byeCmd, unknownCmd}, |
| expectErr: true, |
| expectedStdout: "hello\nbye\n", |
| }, |
| { |
| name: "user command fails", |
| cmds: []Command{userCmd}, |
| expectErr: true, |
| expectUserErr: true, |
| }, |
| } |
| |
| for _, test := range tests { |
| t.Run(test.name, func(t *testing.T) { |
| ctx := context.Background() |
| var stdout bytes.Buffer |
| executor := NewExecutor(&stdout, io.Discard, "") |
| if err := executor.ExecAll(ctx, test.cmds); err != nil { |
| if !test.expectErr { |
| t.Errorf("Failed with error: %s", err) |
| } |
| var userErr userError |
| if errors.As(err, &userErr) { |
| if !test.expectUserErr { |
| t.Errorf("Got user error unexpectedly: %s", userErr) |
| } |
| } else if test.expectUserErr { |
| t.Errorf("Got non-user error unexpectedly: %s", err) |
| } |
| } else if test.expectErr { |
| t.Errorf("Expected an error but didn't get one") |
| } |
| |
| if diff := cmp.Diff(test.expectedStdout, stdout.String()); diff != "" { |
| t.Errorf("Unexpected stdout diff: %s", diff) |
| } |
| }) |
| } |
| |
| t.Run("context canceled", func(t *testing.T) { |
| executor := NewExecutor(io.Discard, io.Discard, t.TempDir()) |
| ctx, cancel := context.WithCancel(context.Background()) |
| go cancel() |
| if err := executor.Exec(ctx, "sleep", "2"); !errors.Is(err, context.Canceled) { |
| t.Fatalf("Expected Exec to return context.Canceled after context cancelation but got: %s", err) |
| } |
| }) |
| } |