github.com/windmilleng/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 }