aboutsummaryrefslogtreecommitdiffhomepage
path: root/helper/helper_test.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-02-13 23:15:34 +0900
committerOphestra <cat@gensokyo.uk>2025-02-13 23:34:15 +0900
commitfe7d208cf76fa6f24bb9d12ba29b5ed61d837ce3 (patch)
treecac02af50a13b2078739a8f5a74d219f3b60833d /helper/helper_test.go
parent60c287375048b21eab2bd82f1e7d43e36dcfb3a2 (diff)
helper: use generic extra files interface
This replaces the pipes object and integrates context into helper process lifecycle. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'helper/helper_test.go')
-rw-r--r--helper/helper_test.go114
1 files changed, 40 insertions, 74 deletions
diff --git a/helper/helper_test.go b/helper/helper_test.go
index 92a8c55c..69be474e 100644
--- a/helper/helper_test.go
+++ b/helper/helper_test.go
@@ -1,6 +1,9 @@
package helper_test
import (
+ "context"
+ "errors"
+ "fmt"
"strconv"
"strings"
"testing"
@@ -23,20 +26,23 @@ var (
argsWt = helper.MustNewCheckedArgs(wantArgs)
)
-func argF(argsFD, statFD int) []string {
- if argsFD == -1 {
+func argF(argsFd, statFd int) []string {
+ if argsFd == -1 {
panic("invalid args fd")
}
- return argFChecked(argsFD, statFD)
+ return argFChecked(argsFd, statFd)
}
-func argFChecked(argsFD, statFD int) []string {
- if statFD == -1 {
- return []string{"--args", strconv.Itoa(argsFD)}
- } else {
- return []string{"--args", strconv.Itoa(argsFD), "--fd", strconv.Itoa(statFD)}
+func argFChecked(argsFd, statFd int) (args []string) {
+ args = make([]string, 0, 4)
+ if argsFd > -1 {
+ args = append(args, "--args", strconv.Itoa(argsFd))
}
+ if statFd > -1 {
+ args = append(args, "--fd", strconv.Itoa(statFd))
+ }
+ return
}
// this function tests an implementation of the helper.Helper interface
@@ -45,66 +51,42 @@ func testHelper(t *testing.T, createHelper func() helper.Helper) {
t.Run("start helper with status channel and wait", func(t *testing.T) {
h := createHelper()
- ready := make(chan error, 1)
- cmd := h.Unwrap()
stdout, stderr := new(strings.Builder), new(strings.Builder)
- cmd.Stdout, cmd.Stderr = stdout, stderr
+ h.Stdout(stdout).Stderr(stderr)
t.Run("wait not yet started helper", func(t *testing.T) {
- wantErr := "exec: not started"
- if err := h.Wait(); err != nil && err.Error() != wantErr {
- t.Errorf("Wait(%v) error = %v, wantErr %v",
- ready,
- err, wantErr)
- return
- }
+ defer func() {
+ r := recover()
+ if r == nil {
+ t.Fatalf("Wait did not panic")
+ }
+ }()
+ panic(fmt.Sprintf("unreachable: %v", h.Wait()))
})
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+
t.Log("starting helper stub")
- if err := h.StartNotify(ready); err != nil {
- t.Errorf("StartNotify(%v) error = %v",
- ready,
- err)
+ if err := h.Start(ctx, true); err != nil {
+ t.Errorf("Start: error = %v", err)
+ cancel()
return
}
+ t.Log("cancelling context")
+ cancel()
t.Run("start already started helper", func(t *testing.T) {
wantErr := "exec: already started"
- if err := h.StartNotify(ready); err != nil && err.Error() != wantErr {
- t.Errorf("StartNotify(%v) error = %v, wantErr %v",
- ready,
+ if err := h.Start(ctx, true); err != nil && err.Error() != wantErr {
+ t.Errorf("Start: error = %v, wantErr %v",
err, wantErr)
return
}
})
- t.Log("waiting on status channel with timeout")
- select {
- case <-time.NewTimer(5 * time.Second).C:
- t.Errorf("never got a ready response")
- t.Errorf("stdout:\n%s", stdout.String())
- t.Errorf("stderr:\n%s", stderr.String())
- if err := cmd.Process.Kill(); err != nil {
- panic(err.Error())
- }
- return
- case err := <-ready:
- if err != nil {
- t.Errorf("StartNotify(%v) latent error = %v",
- ready,
- err)
- }
- }
-
- t.Log("closing status pipe")
- if err := h.Close(); err != nil {
- t.Errorf("Close() error = %v",
- err)
- }
-
t.Log("waiting on helper")
- if err := h.Wait(); err != nil {
+ if err := h.Wait(); !errors.Is(err, context.Canceled) {
t.Errorf("Wait() err = %v stderr = %s",
err, stderr)
}
@@ -112,51 +94,35 @@ func testHelper(t *testing.T, createHelper func() helper.Helper) {
t.Run("wait already finalised helper", func(t *testing.T) {
wantErr := "exec: Wait was already called"
if err := h.Wait(); err != nil && err.Error() != wantErr {
- t.Errorf("Wait(%v) error = %v, wantErr %v",
- ready,
+ t.Errorf("Wait: error = %v, wantErr %v",
err, wantErr)
return
}
})
if got := stdout.String(); !strings.HasPrefix(got, wantPayload) {
- t.Errorf("StartNotify(%v) stdout = %v, want %v",
- ready,
+ t.Errorf("Start: stdout = %v, want %v",
got, wantPayload)
}
})
t.Run("start helper and wait", func(t *testing.T) {
h := createHelper()
- cmd := h.Unwrap()
stdout, stderr := new(strings.Builder), new(strings.Builder)
- cmd.Stdout, cmd.Stderr = stdout, stderr
+ h.Stdout(stdout).Stderr(stderr)
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
- if err := h.Start(); err != nil {
+ if err := h.Start(ctx, false); err != nil {
t.Errorf("Start() error = %v",
err)
return
}
- t.Run("close helper without status pipe", func(t *testing.T) {
- defer func() {
- wantPanic := "attempted to close helper with no status pipe"
- if r := recover(); r != wantPanic {
- t.Errorf("Close() panic = %v, wantPanic %v",
- r, wantPanic)
- }
- }()
- if err := h.Close(); err != nil {
- t.Errorf("Close() error = %v",
- err)
- return
- }
- })
-
if err := h.Wait(); err != nil {
- t.Errorf("Wait() err = %v stderr = %s",
- err, stderr)
+ t.Errorf("Wait() err = %v stdout = %s stderr = %s",
+ err, stdout, stderr)
}
if got := stdout.String(); !strings.HasPrefix(got, wantPayload) {