diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-11-12 23:12:38 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-11-12 23:16:13 +0900 |
| commit | f347d44c2281f507e3786aa498f634bfa4c92d84 (patch) | |
| tree | fe85b41d5f6a5e308b87585f46efd64f90221e2b /internal/helper/helper_test.go | |
| parent | b5630f6883c874d458d9ae3c666cfb7ae5e3121d (diff) | |
internal/helper: relocate from helper
This package is ugly and is pending removal only kept alive by xdg-dbus-proxy.
Its exported symbols are made available until v0.4.0 where it will be removed for #24.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/helper/helper_test.go')
| -rw-r--r-- | internal/helper/helper_test.go | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/internal/helper/helper_test.go b/internal/helper/helper_test.go new file mode 100644 index 00000000..dae098b8 --- /dev/null +++ b/internal/helper/helper_test.go @@ -0,0 +1,139 @@ +package helper_test + +import ( + "context" + "errors" + "fmt" + "io" + "os" + "reflect" + "strconv" + "strings" + "syscall" + "testing" + "time" + + "hakurei.app/internal/helper" +) + +var ( + wantArgs = []string{ + "unix:path=/run/dbus/system_bus_socket", + "/tmp/hakurei.1971/12622d846cc3fe7b4c10359d01f0eb47/system_bus_socket", + "--filter", + "--talk=org.bluez", + "--talk=org.freedesktop.Avahi", + "--talk=org.freedesktop.UPower", + } + + wantPayload = strings.Join(wantArgs, "\x00") + "\x00" + argsWt = helper.MustNewCheckedArgs(wantArgs...) +) + +func argF(argsFd, statFd int) []string { + if argsFd == -1 { + panic("invalid args fd") + } + + return argFChecked(argsFd, statFd) +} + +func argFChecked(argsFd, statFd int) (args []string) { + args = make([]string, 0, 6) + if argsFd > -1 { + args = append(args, "--args", strconv.Itoa(argsFd)) + } + if statFd > -1 { + args = append(args, "--fd", strconv.Itoa(statFd)) + } + return +} + +const ( + containerTimeout = 30 * time.Second +) + +// this function tests an implementation of the helper.Helper interface +func testHelper(t *testing.T, createHelper func(ctx context.Context, setOutput func(stdoutP, stderrP *io.Writer), stat bool) helper.Helper) { + oldWaitDelay := helper.WaitDelay + helper.WaitDelay = 16 * time.Second + t.Cleanup(func() { helper.WaitDelay = oldWaitDelay }) + + t.Run("start helper with status channel and wait", func(t *testing.T) { + ctx, cancel := context.WithTimeout(t.Context(), containerTimeout) + stdout := new(strings.Builder) + h := createHelper(ctx, func(stdoutP, stderrP *io.Writer) { *stdoutP, *stderrP = stdout, os.Stderr }, true) + + t.Run("wait not yet started helper", func(t *testing.T) { + if err := h.Wait(); !reflect.DeepEqual(err, syscall.EINVAL) && + !reflect.DeepEqual(err, errors.New("exec: not started")) { + t.Errorf("Wait: error = %v", err) + } + }) + + t.Log("starting helper stub") + if err := h.Start(); 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 := "helper: already started" + if err := h.Start(); err != nil && err.Error() != wantErr { + t.Errorf("Start: error = %v, wantErr %v", + err, wantErr) + return + } + }) + + t.Log("waiting on helper") + if err := h.Wait(); !errors.Is(err, context.Canceled) { + t.Errorf("Wait: error = %v", + err) + } + + 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: error = %v, wantErr %v", + err, wantErr) + return + } + }) + + if got := trimStdout(stdout); got != wantPayload { + t.Errorf("Start: stdout = %q, want %q", + got, wantPayload) + } + }) + + t.Run("start helper and wait", func(t *testing.T) { + ctx, cancel := context.WithTimeout(t.Context(), containerTimeout) + defer cancel() + stdout := new(strings.Builder) + h := createHelper(ctx, func(stdoutP, stderrP *io.Writer) { *stdoutP, *stderrP = stdout, os.Stderr }, false) + + if err := h.Start(); err != nil { + t.Errorf("Start: error = %v", + err) + return + } + + if err := h.Wait(); err != nil { + t.Errorf("Wait: error = %v stdout = %q", + err, stdout) + } + + if got := trimStdout(stdout); got != wantPayload { + t.Errorf("Start: stdout = %q, want %q", + got, wantPayload) + } + }) +} + +func trimStdout(stdout fmt.Stringer) string { + return strings.TrimPrefix(stdout.String(), "=== RUN TestHelperInit\n") +} |
