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  }