aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/internal/testsuite/testsuite.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/internal/testsuite/testsuite.go')
-rw-r--r--test/internal/testsuite/testsuite.go134
1 files changed, 74 insertions, 60 deletions
diff --git a/test/internal/testsuite/testsuite.go b/test/internal/testsuite/testsuite.go
index 00eb2f92..456c36b4 100644
--- a/test/internal/testsuite/testsuite.go
+++ b/test/internal/testsuite/testsuite.go
@@ -13,8 +13,6 @@ import (
"os"
"os/exec"
"os/signal"
- "os/user"
- "strconv"
"sync"
"syscall"
"time"
@@ -27,20 +25,17 @@ func ReceiveSignals() {
log.Fatalf("terminating on signal %s", <-s)
}
-// GetUser returns the [user.User] structure describing the user with uid 1000.
-func GetUser() *user.User {
- if u, err := user.LookupId("1000"); err != nil {
- log.Fatal(err)
- return nil
- } else {
- return u
- }
-}
-
// MustRun runs command and terminates the testsuite on error.
-func MustRun(command ...string) {
+func MustRun(cred *syscall.Credential, extraEnv []string, command ...string) {
cmd := exec.Command(command[0], command[1:]...)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Pdeathsig: syscall.SIGKILL,
+ Credential: cred,
+ }
+ if len(extraEnv) != 0 {
+ cmd.Env = append(cmd.Environ(), extraEnv...)
+ }
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
@@ -52,9 +47,16 @@ var ErrUnexpectedSuccess = errors.New("process unexpectedly exited with code 0")
// MustFail runs command and terminates the testsuite if the program fails to
// start or exits with code 0.
-func MustFail(command ...string) {
+func MustFail(cred *syscall.Credential, extraEnv []string, command ...string) {
cmd := exec.Command(command[0], command[1:]...)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Pdeathsig: syscall.SIGKILL,
+ Credential: cred,
+ }
+ if len(extraEnv) != 0 {
+ cmd.Env = append(cmd.Environ(), extraEnv...)
+ }
if err := cmd.Run(); err == nil {
log.Fatal(ErrUnexpectedSuccess)
} else if e, ok := errors.AsType[*exec.ExitError](err); !ok {
@@ -64,16 +66,6 @@ func MustFail(command ...string) {
}
}
-// MustRunAs wraps [MustRun] for sudo.
-func MustRunAs(username string, command ...string) {
- MustRun(append([]string{"sudo", "-u", username}, command...)...)
-}
-
-// MustFailAs wraps [MustFail] for sudo.
-func MustFailAs(username string, command ...string) {
- MustFail(append([]string{"sudo", "-u", username}, command...)...)
-}
-
// MustStart starts cmd and returns a channel delivering its wait error.
func MustStart(cmd *exec.Cmd) (done <-chan error) {
if err := cmd.Start(); err != nil {
@@ -84,24 +76,24 @@ func MustStart(cmd *exec.Cmd) (done <-chan error) {
return d
}
-// MustStartAs wraps [MustStart] for sudo.
-func MustStartAs(
+// MustStartWith wraps [MustStart] and creates the [exec.Cmd] object internally.
+func MustStartWith(
ctx context.Context,
- username string,
+ cred *syscall.Credential,
+ extraEnv []string,
files []*os.File,
command ...string,
) (proc *os.Process, done <-chan error) {
- sudoArgs := []string{
- "-u", username,
- }
- if len(files) != 0 {
- sudoArgs = append(sudoArgs, "-C", strconv.Itoa(len(files)+4))
- }
- sudoArgs = append(sudoArgs, "--")
- cmd := exec.CommandContext(ctx, "sudo", append(sudoArgs, command...)...)
+ cmd := exec.CommandContext(ctx, command[0], command[1:]...)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
cmd.ExtraFiles = files
- cmd.SysProcAttr = &syscall.SysProcAttr{Pdeathsig: syscall.SIGTERM}
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Pdeathsig: syscall.SIGTERM,
+ Credential: cred,
+ }
+ if len(extraEnv) != 0 {
+ cmd.Env = append(cmd.Environ(), extraEnv...)
+ }
return cmd.Process, MustStart(cmd)
}
@@ -136,9 +128,21 @@ func FilterTerminated(err error) error {
}
// Poll repeatedly runs command until it succeeds.
-func Poll(d time.Duration, command ...string) {
+func Poll(
+ d time.Duration,
+ cred *syscall.Credential,
+ extraEnv []string,
+ command ...string,
+) {
for range time.NewTicker(d).C {
cmd := exec.Command(command[0], command[1:]...)
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Pdeathsig: syscall.SIGKILL,
+ Credential: cred,
+ }
+ if len(extraEnv) != 0 {
+ cmd.Env = append(cmd.Environ(), extraEnv...)
+ }
if err := cmd.Run(); err != nil {
if e, ok := errors.AsType[*exec.ExitError](err); ok && e.Exited() {
continue
@@ -160,15 +164,15 @@ const (
// MustStartSessionBus starts a session bus that is never explicitly terminated.
// The test suite is terminated if the session bus daemon terminates.
-func MustStartSessionBus(username string) (dbusEnv string) {
+func MustStartSessionBus(cred *syscall.Credential) (dbusEnv string) {
r, w, err := os.Pipe()
if err != nil {
log.Fatal(err)
}
// this is never explicitly terminated
- _, done := MustStartAs(
- context.Background(), username, []*os.File{w},
+ _, done := MustStartWith(
+ context.Background(), cred, nil, []*os.File{w},
"dbus-daemon",
"--print-address=3",
"--address=unix:path="+XDGRuntimeDir+"/dbus",
@@ -209,16 +213,18 @@ const (
// by calling [TerminateSway].
func MustStartSway(
wg *sync.WaitGroup,
- username, dbusEnv string,
+ cred *syscall.Credential,
+ dbusEnv string,
) {
wg.Go(func() {
// this is terminated via swaymsg
- _, done := MustStartAs(
- context.Background(), username, nil, "env",
- "WLR_BACKENDS=headless",
- XDGRuntimeEnv,
- SwayEnv,
- dbusEnv,
+ _, done := MustStartWith(
+ context.Background(), cred, []string{
+ "WLR_BACKENDS=headless",
+ XDGRuntimeEnv,
+ SwayEnv,
+ dbusEnv,
+ }, nil,
"sway",
)
if err := <-done; err != nil {
@@ -226,23 +232,29 @@ func MustStartSway(
}
})
- Poll(50*time.Millisecond, "sudo", "-u", username, SwayEnv, "swaymsg")
+ Poll(
+ 50*time.Millisecond,
+ cred,
+ []string{SwayEnv},
+ "swaymsg",
+ )
log.Printf("sway available via %s", SwayEnv)
}
// TerminateSway requests for the sway server to terminate via sway IPC.
-func TerminateSway(username string) {
- MustFailAs(username, SwayEnv, "swaymsg", "exit")
+func TerminateSway(cred *syscall.Credential) {
+ MustFail(cred, []string{SwayEnv}, "swaymsg", "exit")
}
// MustStartPipeWire starts a PipeWire server that is never explicitly
// terminated. The test suite is terminated if the PipeWire server terminates.
-func MustStartPipeWire(username, dbusEnv string) {
+func MustStartPipeWire(cred *syscall.Credential, dbusEnv string) {
// this is never explicitly terminated
- _, done := MustStartAs(
- context.Background(), username, nil, "env",
- XDGRuntimeEnv,
- dbusEnv,
+ _, done := MustStartWith(
+ context.Background(), cred, []string{
+ XDGRuntimeEnv,
+ dbusEnv,
+ }, nil,
"pipewire",
)
@@ -253,17 +265,19 @@ func MustStartPipeWire(username, dbusEnv string) {
log.Fatal("pipewire terminated unexpectedly")
}()
- Poll(50*time.Millisecond, "sudo", "-u", username,
+ Poll(50*time.Millisecond, cred, []string{
XDGRuntimeEnv,
dbusEnv,
+ },
"wpctl",
"status",
)
- _, _done := MustStartAs(
- context.Background(), username, nil, "env",
- XDGRuntimeEnv,
- dbusEnv,
+ _, _done := MustStartWith(
+ context.Background(), cred, []string{
+ XDGRuntimeEnv,
+ dbusEnv,
+ }, nil,
"wireplumber",
)