diff options
| author | Ophestra <cat@gensokyo.uk> | 2026-10-06 23:11:29 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2026-10-06 23:11:29 +0900 |
| commit | a6334d4ff69ce0c02128256f2032617096882ee5 (patch) | |
| tree | fa3b1d49a6315166bfa5f4e7e2ed616db0e9622b | |
| parent | a9e2749f6654d0aa07b274a45c9177d10323f80a (diff) | |
internal/testsuite: add additional environment
This improves compatibility. This change also improves error messages.
Signed-off-by: Ophestra <cat@gensokyo.uk>
| -rw-r--r-- | cmd/hakurei/testsuite/sandbox/main.go | 12 | ||||
| -rw-r--r-- | internal/testsuite/testsuite.go | 81 |
2 files changed, 67 insertions, 26 deletions
diff --git a/cmd/hakurei/testsuite/sandbox/main.go b/cmd/hakurei/testsuite/sandbox/main.go index 1d3d4516..820b7e2f 100644 --- a/cmd/hakurei/testsuite/sandbox/main.go +++ b/cmd/hakurei/testsuite/sandbox/main.go @@ -65,9 +65,9 @@ func mustStart( select { case err := <-done: if err == nil { - log.Fatal("test process terminated unexpectedly") + log.Fatalf("test process %d terminated unexpectedly", serial) } - log.Fatal(err) + log.Fatalf("test process %d terminated unexpectedly: %v", serial, err) default: break } @@ -117,7 +117,7 @@ func main() { log.Fatal(err) } - var testToolDone <-chan error + var testHelperDone <-chan error { cmd := exec.Command( "go", "build", @@ -127,7 +127,7 @@ func main() { "./cmd/hakurei/testsuite/sandbox/tester", ) cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr - testToolDone = testsuite.MustStart(cmd) + testHelperDone = testsuite.MustStart(cmd) } var wg sync.WaitGroup @@ -232,8 +232,8 @@ func main() { defer testsuite.TerminateSway(&cred) testsuite.MustStartPipeWire(&cred, dbusEnv) - if err := <-testToolDone; err != nil { - log.Fatal(err) + if err := <-testHelperDone; err != nil { + log.Fatalf("cannot compile test helper: %v", err) } log.Println("created test helper") diff --git a/internal/testsuite/testsuite.go b/internal/testsuite/testsuite.go index 456c36b4..6e48eca1 100644 --- a/internal/testsuite/testsuite.go +++ b/internal/testsuite/testsuite.go @@ -13,6 +13,9 @@ import ( "os" "os/exec" "os/signal" + "os/user" + "strconv" + "strings" "sync" "syscall" "time" @@ -25,6 +28,52 @@ func ReceiveSignals() { log.Fatalf("terminating on signal %s", <-s) } +var ( + // users caches [user.LookupId] calls. + users = make(map[string]*user.User) + // usersMu synchronises access to users. + usersMu sync.RWMutex +) + +// mustLookupId is like [user.LookupId], but the first result is cached. +func mustLookupId(uid string) *user.User { + usersMu.RLock() + v, ok := users[uid] + usersMu.RUnlock() + if ok { + return v + } + + u, err := user.LookupId(uid) + if err != nil { + log.Fatal(err) + } + + usersMu.Lock() + users[uid] = u + usersMu.Unlock() + return u +} + +// MustAppendEnv adds extra environment variables to cmd. +func MustAppendEnv(cmd *exec.Cmd, env ...string) { + if len(cmd.Env) == 0 { + var cred syscall.Credential + if cmd.SysProcAttr != nil && cmd.SysProcAttr.Credential != nil { + cred = *cmd.SysProcAttr.Credential + } + u := mustLookupId(strconv.Itoa(int(cred.Uid))) + + cmd.Env = append(cmd.Env, + "PATH="+os.Getenv("PATH"), + "HOME="+u.HomeDir, + "USER="+u.Username, + "USERNAME="+u.Username, + ) + } + cmd.Env = append(cmd.Env, env...) +} + // MustRun runs command and terminates the testsuite on error. func MustRun(cred *syscall.Credential, extraEnv []string, command ...string) { cmd := exec.Command(command[0], command[1:]...) @@ -33,11 +82,9 @@ func MustRun(cred *syscall.Credential, extraEnv []string, command ...string) { Pdeathsig: syscall.SIGKILL, Credential: cred, } - if len(extraEnv) != 0 { - cmd.Env = append(cmd.Environ(), extraEnv...) - } + MustAppendEnv(cmd, extraEnv...) if err := cmd.Run(); err != nil { - log.Fatal(err) + log.Fatalf("must run %s: %v", strings.Join(command, " "), err) } } @@ -54,15 +101,13 @@ func MustFail(cred *syscall.Credential, extraEnv []string, command ...string) { Pdeathsig: syscall.SIGKILL, Credential: cred, } - if len(extraEnv) != 0 { - cmd.Env = append(cmd.Environ(), extraEnv...) - } + MustAppendEnv(cmd, extraEnv...) if err := cmd.Run(); err == nil { log.Fatal(ErrUnexpectedSuccess) } else if e, ok := errors.AsType[*exec.ExitError](err); !ok { - log.Fatal(err) + log.Fatalf("must fail %s: %v", strings.Join(command, " "), err) } else if !e.Exited() { - log.Fatal(e) + log.Fatalf("must fail %s: %v", strings.Join(command, " "), e) } } @@ -91,9 +136,7 @@ func MustStartWith( Pdeathsig: syscall.SIGTERM, Credential: cred, } - if len(extraEnv) != 0 { - cmd.Env = append(cmd.Environ(), extraEnv...) - } + MustAppendEnv(cmd, extraEnv...) return cmd.Process, MustStart(cmd) } @@ -140,14 +183,12 @@ func Poll( Pdeathsig: syscall.SIGKILL, Credential: cred, } - if len(extraEnv) != 0 { - cmd.Env = append(cmd.Environ(), extraEnv...) - } + MustAppendEnv(cmd, extraEnv...) if err := cmd.Run(); err != nil { if e, ok := errors.AsType[*exec.ExitError](err); ok && e.Exited() { continue } - log.Fatal(err) + log.Fatalf("poll %s: %v", strings.Join(command, " "), err) } break } @@ -183,7 +224,7 @@ func MustStartSessionBus(cred *syscall.Credential) (dbusEnv string) { go func() { if _err := <-done; _err != nil { - log.Fatal(_err) + log.Fatalf("session bus terminated unexpectedly: %v", _err) } log.Fatal("session bus terminated unexpectedly") }() @@ -228,7 +269,7 @@ func MustStartSway( "sway", ) if err := <-done; err != nil { - log.Fatal(err) + log.Fatalf("sway terminated unexpectedly: %v", err) } }) @@ -260,7 +301,7 @@ func MustStartPipeWire(cred *syscall.Credential, dbusEnv string) { go func() { if _err := <-done; _err != nil { - log.Fatal(_err) + log.Fatalf("pipewire terminated unexpectedly: %v", _err) } log.Fatal("pipewire terminated unexpectedly") }() @@ -283,7 +324,7 @@ func MustStartPipeWire(cred *syscall.Credential, dbusEnv string) { go func() { if _err := <-_done; _err != nil { - log.Fatal(_err) + log.Fatalf("wireplumber terminated unexpectedly: %v", _err) } log.Fatal("wireplumber terminated unexpectedly") }() |
