github.com/tilt-dev/wat@v0.0.2-0.20180626175338-9349b638e250/cli/wat/wat_test.go (about)

     1  package wat
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"os"
     7  	"path/filepath"
     8  	"testing"
     9  	"time"
    10  )
    11  
    12  const testTimeout = time.Second
    13  
    14  var cmdFoo = WatCommand{Command: "echo -n foo; echo ' and foo'"}
    15  var logFoo = CommandLog{Command: cmdFoo.Command, Success: true}
    16  var outputFoo = "foo and foo"
    17  var cmdBar = WatCommand{Command: "echo -n bar; echo ' and bar'"}
    18  var logBar = CommandLog{Command: cmdBar.Command, Success: true}
    19  var outputBar = "bar and bar"
    20  var cmdBaz = WatCommand{Command: "echo -n baz; echo ' and baz'"}
    21  var logBaz = CommandLog{Command: cmdBaz.Command, Success: true}
    22  var outputBaz = "baz and baz"
    23  var cmdFalse = WatCommand{Command: "false"} // will always exit w/ code: 1
    24  var logFalse = CommandLog{Command: cmdFalse.Command, Success: false}
    25  var cmdSleep = WatCommand{Command: "sleep 2"}
    26  
    27  func TestRunCmds(t *testing.T) {
    28  	ctx := context.Background()
    29  	cmds := []WatCommand{cmdFoo, cmdBar, cmdBaz}
    30  	outBuf := bytes.Buffer{}
    31  	errBuf := bytes.Buffer{}
    32  
    33  	logs, err := runCmds(ctx, ".", cmds, testTimeout, &outBuf, &errBuf)
    34  	if err != nil {
    35  		t.Fatal("runCmds:", err)
    36  	}
    37  
    38  	expectedStrs := []string{
    39  		cmdFoo.PrettyCmd(), outputFoo,
    40  		cmdBar.PrettyCmd(), outputBar,
    41  		cmdBaz.PrettyCmd(), outputBaz,
    42  	}
    43  	assertContainsStrings(t, expectedStrs, outBuf.String(), "stdOut")
    44  
    45  	expectedLogs := []CommandLog{logFoo, logBar, logBaz}
    46  	assertCommandLogs(t, expectedLogs, logs)
    47  }
    48  
    49  func TestRunCmdsFailure(t *testing.T) {
    50  	ctx := context.Background()
    51  	cmds := []WatCommand{cmdFoo, cmdFalse, cmdBaz}
    52  	outBuf := bytes.Buffer{}
    53  	errBuf := bytes.Buffer{}
    54  
    55  	logs, err := runCmds(ctx, ".", cmds, testTimeout, &outBuf, &errBuf)
    56  	if err != nil {
    57  		// non-zero exit status should NOT return an err, as this is an expected case
    58  		t.Fatal("runCmds:", err)
    59  	}
    60  
    61  	expectedStrs := []string{cmdFoo.PrettyCmd(), outputFoo, cmdFalse.PrettyCmd()}
    62  	assertContainsStrings(t, expectedStrs, outBuf.String(), "stdOut")
    63  
    64  	expectedLogs := []CommandLog{logFoo, logFalse, logBaz}
    65  	assertCommandLogs(t, expectedLogs, logs)
    66  }
    67  
    68  func TestRunCmdsCapturesStdErr(t *testing.T) {
    69  	ctx := context.Background()
    70  	cmds := []WatCommand{
    71  		WatCommand{Command: "echo 'hello world' > /dev/stderr"},
    72  	}
    73  	outBuf := bytes.Buffer{}
    74  	errBuf := bytes.Buffer{}
    75  
    76  	_, err := runCmds(ctx, ".", cmds, testTimeout, &outBuf, &errBuf)
    77  	if err != nil {
    78  		t.Fatal("runCmds:", err)
    79  	}
    80  
    81  	assertContainsStrings(t, []string{"hello world"}, errBuf.String(), "stdErr")
    82  }
    83  
    84  func TestRunCmdsTimesOut(t *testing.T) {
    85  	ctx := context.Background()
    86  	cmds := []WatCommand{cmdFoo, cmdSleep, cmdBaz}
    87  	outBuf := bytes.Buffer{}
    88  	errBuf := bytes.Buffer{}
    89  
    90  	logs, err := runCmds(ctx, ".", cmds, time.Second, &outBuf, &errBuf)
    91  	if err != context.DeadlineExceeded {
    92  		t.Fatalf("Expected a DeadlineExceeded error. Actual: %v", err)
    93  	}
    94  
    95  	expectedStrs := []string{
    96  		cmdFoo.PrettyCmd(),
    97  		outputFoo,
    98  		cmdSleep.PrettyCmd(),
    99  	}
   100  	assertContainsStrings(t, expectedStrs, outBuf.String(), "stdOut")
   101  
   102  	// We DON'T expect logBaz and logSleep.
   103  	// cmdBaz should not run, b/c in case of timeout we
   104  	// bail on all subsequent commands
   105  	expectedLogs := []CommandLog{logFoo}
   106  	assertCommandLogs(t, expectedLogs, logs)
   107  }
   108  
   109  func TestRunCmdsUnexepctedError(t *testing.T) {
   110  	cmds := []WatCommand{cmdFoo}
   111  
   112  	// Run cmds inside an already-canceled context so we get an error
   113  	ctx := context.Background()
   114  	ctxCancelled, cancelFn := context.WithCancel(ctx)
   115  	cancelFn()
   116  
   117  	logs, err := runCmds(ctxCancelled, ".", cmds, testTimeout, &bytes.Buffer{}, &bytes.Buffer{})
   118  
   119  	if err == nil {
   120  		t.Fatal("Expected an error b/c context has been canceled, but no error returned")
   121  	}
   122  
   123  	if len(logs) != 0 {
   124  		t.Fatalf("Expected 0 logs, got %d", len(logs))
   125  	}
   126  }
   127  
   128  func TestRunCommands(t *testing.T) {
   129  	f := newWatFixture(t)
   130  	defer f.tearDown()
   131  	ws := f.watInit()
   132  
   133  	ctx := context.Background()
   134  	cmds := []WatCommand{cmdFoo, cmdBar, cmdBaz}
   135  	outBuf := bytes.Buffer{}
   136  	errBuf := bytes.Buffer{}
   137  	now := time.Now()
   138  	edits := []string{"a", "b", "c"}
   139  	logContext := LogContext{
   140  		RecentEdits: edits,
   141  		StartTime:   now,
   142  		Source:      LogSourceUser,
   143  	}
   144  
   145  	err := RunCommands(ctx, ws, cmds, testTimeout, &outBuf, &errBuf, logContext)
   146  	if err != nil {
   147  		t.Fatal("RunCommands:", err)
   148  	}
   149  
   150  	expectedLogs := CommandLogGroup{
   151  		Logs:    []CommandLog{logFoo, logBar, logBaz},
   152  		Context: logContext,
   153  	}
   154  
   155  	assertCmdLogFileContents(t, expectedLogs)
   156  }
   157  
   158  func TestRunCommandsRunErr(t *testing.T) {
   159  	f := newWatFixture(t)
   160  	defer f.tearDown()
   161  	ws := f.watInit()
   162  
   163  	ctx := context.Background()
   164  	cmds := []WatCommand{cmdFoo, cmdSleep, cmdBaz}
   165  	err := RunCommands(ctx, ws, cmds, testTimeout, &bytes.Buffer{}, &bytes.Buffer{}, LogContext{})
   166  	if err == nil {
   167  		t.Fatal("Expected an error b/c of bad command, but no error returned")
   168  	}
   169  
   170  	if _, err := os.Stat(filepath.Join(kWatDirName, fnameCmdLog)); err == nil {
   171  		t.Fatal("Log file written, but should not have been, since we encountered an error.")
   172  	}
   173  }