diff --git a/helpers_test.go b/helpers_test.go index a468d8c..006e173 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -21,6 +21,7 @@ func TestGetStartTime(t *testing.T) { if testing.Short() { t.Skip("skipping in short mode") } + readOnlySystemUnit := systemTestUnit(t) testCases := []struct { unit string err error @@ -33,16 +34,16 @@ func TestGetStartTime(t *testing.T) { // try existing unit in user mode as user {"syncthing", ErrUnitNotActive, Options{UserMode: true}, true}, // try existing unit in system mode as user - {"nginx", nil, Options{UserMode: false}, true}, + {readOnlySystemUnit, nil, Options{UserMode: false}, true}, // Run these tests only as a superuser // try nonexistant unit in system mode as system {"nonexistant", ErrUnitNotActive, Options{UserMode: false}, false}, // try existing unit in system mode as system - {"nginx", ErrBusFailure, Options{UserMode: true}, false}, + {readOnlySystemUnit, ErrBusFailure, Options{UserMode: true}, false}, // try existing unit in system mode as system - {"nginx", nil, Options{UserMode: false}, false}, + {readOnlySystemUnit, nil, Options{UserMode: false}, false}, } ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() @@ -94,6 +95,7 @@ func TestGetStartTime(t *testing.T) { } func TestGetNumRestarts(t *testing.T) { + readOnlySystemUnit := systemTestUnit(t) type testCase struct { unit string err error @@ -108,16 +110,16 @@ func TestGetNumRestarts(t *testing.T) { // try existing unit in user mode as user (loaded, so NRestarts=0 is valid) {"syncthing", nil, Options{UserMode: true}, true}, // try existing unit in system mode as user - {"nginx", nil, Options{UserMode: false}, true}, + {readOnlySystemUnit, nil, Options{UserMode: false}, true}, // Run these tests only as a superuser // try nonexistant unit in system mode as system {"nonexistant", ErrValueNotSet, Options{UserMode: false}, false}, // try existing unit in system mode as system - {"nginx", ErrBusFailure, Options{UserMode: true}, false}, + {readOnlySystemUnit, ErrBusFailure, Options{UserMode: true}, false}, // try existing unit in system mode as system - {"nginx", nil, Options{UserMode: false}, false}, + {readOnlySystemUnit, nil, Options{UserMode: false}, false}, } for _, tc := range testCases { func(tc testCase) { @@ -177,6 +179,7 @@ func TestGetNumRestarts(t *testing.T) { } func TestGetMemoryUsage(t *testing.T) { + readOnlySystemUnit := systemTestUnit(t) type testCase struct { unit string err error @@ -191,16 +194,16 @@ func TestGetMemoryUsage(t *testing.T) { // try existing unit in user mode as user {"syncthing", ErrValueNotSet, Options{UserMode: true}, true}, // try existing unit in system mode as user - {"nginx", nil, Options{UserMode: false}, true}, + {readOnlySystemUnit, nil, Options{UserMode: false}, true}, // Run these tests only as a superuser // try nonexistant unit in system mode as system {"nonexistant", ErrValueNotSet, Options{UserMode: false}, false}, // try existing unit in system mode as system - {"nginx", ErrBusFailure, Options{UserMode: true}, false}, + {readOnlySystemUnit, ErrBusFailure, Options{UserMode: true}, false}, // try existing unit in system mode as system - {"nginx", nil, Options{UserMode: false}, false}, + {readOnlySystemUnit, nil, Options{UserMode: false}, false}, } for _, tc := range testCases { func(tc testCase) { @@ -224,9 +227,9 @@ func TestGetMemoryUsage(t *testing.T) { t.Run("prove memory usage values change across services", func(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() - bytes, err := GetMemoryUsage(ctx, "nginx", Options{UserMode: false}) + bytes, err := GetMemoryUsage(ctx, readOnlySystemUnit, Options{UserMode: false}) if err != nil { - t.Errorf("issue getting memory usage of nginx: %v", err) + t.Errorf("issue getting memory usage of %s: %v", readOnlySystemUnit, err) } secondBytes, err := GetMemoryUsage(ctx, "user.slice", Options{UserMode: false}) if err != nil { diff --git a/systemctl_test.go b/systemctl_test.go index af8817a..c72d566 100644 --- a/systemctl_test.go +++ b/systemctl_test.go @@ -367,6 +367,7 @@ func TestRestart(t *testing.T) { unit := "nginx" userMode := false if userString != "root" && userString != "system" { + t.Skip("skipping non-root lifecycle test without a portable controllable user unit") userMode = true unit = "syncthing" } @@ -406,7 +407,7 @@ func TestShow(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } - unit := "nginx" + unit := systemTestUnit(t) opts := Options{ UserMode: false, } @@ -429,6 +430,7 @@ func TestStart(t *testing.T) { unit := "nginx" userMode := false if userString != "root" && userString != "system" { + t.Skip("skipping non-root lifecycle test without a portable controllable user unit") userMode = true unit = "syncthing" } @@ -461,7 +463,7 @@ func TestStart(t *testing.T) { } func TestStatus(t *testing.T) { - unit := "nginx" + unit := systemTestUnit(t) userMode := false opts := Options{UserMode: userMode} ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) @@ -476,6 +478,7 @@ func TestStop(t *testing.T) { unit := "nginx" userMode := false if userString != "root" && userString != "system" { + t.Skip("skipping non-root lifecycle test without a portable controllable user unit") userMode = true unit = "syncthing" } diff --git a/test_units_test.go b/test_units_test.go new file mode 100644 index 0000000..85eabf3 --- /dev/null +++ b/test_units_test.go @@ -0,0 +1,43 @@ +package systemctl + +import ( + "context" + "strings" + "testing" + "time" + + "github.com/taigrr/systemctl/properties" +) + +func systemTestUnit(t *testing.T) string { + t.Helper() + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + units, err := GetUnits(ctx, Options{UserMode: false}) + if err != nil { + t.Fatalf("get system units: %v", err) + } + for _, unit := range units { + if unit.Active != "active" || unit.Sub != "running" || !strings.HasSuffix(unit.Name, ".service") { + continue + } + name := strings.TrimSuffix(unit.Name, ".service") + startTime, err := Show(ctx, name, properties.ExecMainStartTimestamp, Options{UserMode: false}) + if err != nil || startTime == "" { + continue + } + restarts, err := Show(ctx, name, properties.NRestarts, Options{UserMode: false}) + if err != nil || restarts == "" || restarts == "[not set]" { + continue + } + memory, err := Show(ctx, name, properties.MemoryCurrent, Options{UserMode: false}) + if err != nil || memory == "" || memory == "[not set]" { + continue + } + return name + } + + t.Skip("no readable active system service found for read-only tests") + return "" +}