github.com/haraldrudell/parl@v0.4.176/pexec/exec-stream_test.go (about) 1 /* 2 © 2021–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package pexec 7 8 import ( 9 "context" 10 "errors" 11 "io" 12 "os" 13 "os/exec" 14 "strings" 15 "testing" 16 17 "github.com/haraldrudell/parl" 18 "github.com/haraldrudell/parl/perrors" 19 "github.com/haraldrudell/parl/pio" 20 "golang.org/x/sys/unix" 21 ) 22 23 func TestExecStream(t *testing.T) { 24 messageNotFound := "executable file not found" 25 var stdout = pio.NewCloserBuffer() 26 var stderr = pio.NewCloserBuffer() 27 ctx := context.Background() 28 setCommand := []string{"set"} 29 sleepCommand := []string{"sleep", "1"} 30 31 var err error 32 var isCancel bool 33 var statusCode int 34 35 // empty args list 36 _, _, err = ExecStream(pio.EofReader, stdout, stderr, ctx) 37 if err == nil { 38 t.Error("ExecStream missing err") 39 } else if !errors.Is(err, ErrArgsListEmpty) { 40 t.Errorf("ExecStream bad err: %q exp: %q", perrors.Short(err), ErrArgsListEmpty) 41 } 42 43 // bash built-in: error 44 _, _, err = ExecStream(pio.EofReader, stdout, stderr, ctx, setCommand...) 45 if err == nil { 46 t.Error("ExecStream missing err") 47 } else if !strings.Contains(err.Error(), messageNotFound) { 48 t.Errorf("ExecStream bad err: %q exp: %q", perrors.Short(err), messageNotFound) 49 } 50 51 // terminate using context 52 ctxCancel := parl.NewCancelContext(context.Background()) 53 startCallback := func(execCmd *exec.Cmd, err error) { 54 if err == nil { 55 t.Log("startCallback invoking cancel") 56 parl.InvokeCancel(ctxCancel) 57 } else { 58 t.Errorf("startCallback had error: %s", perrors.Short(err)) 59 } 60 } 61 statusCode, isCancel, err = ExecStreamFull(pio.EofReader, stdout, stderr, nil, ctxCancel, startCallback, nil, sleepCommand...) 62 t.Logf("ExecStreamFull returned values on context cancel: status code: %d isCancel: %t, err: %s", statusCode, isCancel, perrors.Short(err)) 63 if err != nil { 64 t.Errorf("ExecStream canceled context produced error: %s", perrors.Long(err)) 65 } else if !isCancel { 66 t.Error("ExecStream canceled context returned isCancel false") 67 } 68 //t.Fail() 69 } 70 71 // ITEST= go test ./pexec 72 func TestExecStreamGoodExit(t *testing.T) { 73 if _, ok := os.LookupEnv("ITEST"); !ok { 74 t.Skip("skip because ITEST not set") 75 } 76 var args []string = []string{"sleep", "0"} 77 78 var stdout, stderr io.WriteCloser 79 var err error 80 var isCancel bool 81 var statusCode int 82 var ctx context.Context = context.Background() 83 var startCallback func(execCmd *exec.Cmd, err error) 84 85 statusCode, isCancel, err = ExecStreamFull(pio.EofReader, stdout, stderr, nil, ctx, startCallback, nil, args...) 86 87 // Success: status code: 0 isCancel: false, err: OK 88 t.Logf("Success: status code: %d isCancel: %t, err: %s", statusCode, isCancel, perrors.Short(err)) 89 } 90 91 func SIGTERMstartCallback(execCmd *exec.Cmd, err error) { 92 execCmd.Process.Signal(unix.SIGTERM) 93 } 94 95 // ITEST= go test -v -run ^TestExecStreamSIGTERM$ github.com/haraldrudell/parl/pexec 96 // 97 // exec-stream_test.go:112: Success: status code: -1 isCancel: false, err: pexec.ExecStreamFull execCmd.Wait signal: terminated at pexec.ExecStreamFull()-exec-stream-full.go:168 98 func TestExecStreamSIGTERM(t *testing.T) { 99 100 if _, ok := os.LookupEnv("ITEST"); !ok { 101 t.Skip("skip because ITEST not set") 102 } 103 var args []string = []string{"sleep", "10"} 104 105 var stdout, stderr io.WriteCloser 106 var err error 107 var isCancel bool 108 var statusCode int 109 var ctx context.Context = context.Background() 110 111 statusCode, isCancel, err = ExecStreamFull(pio.EofReader, stdout, stderr, nil, ctx, SIGTERMstartCallback, nil, args...) 112 113 // Success: status code: 0 isCancel: false, err: OK 114 t.Logf("Success: status code: %d isCancel: %t, err: %s", statusCode, isCancel, perrors.Short(err)) 115 } 116 117 func TestExecStreamControlBreak(t *testing.T) { 118 }