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  }