package systemcontrol import ( "context" "net" "os" "path/filepath" "sync/atomic" "testing" "time" ) func TestSysfsResetButtonActiveLow(t *testing.T) { path := filepath.Join(t.TempDir(), "value") if err := os.WriteFile(path, []byte("0\n"), 0o600); err != nil { t.Fatal(err) } pressed, err := (SysfsResetButton{ValuePath: path, ActiveLow: true}).ResetButtonPressed(context.Background()) if err != nil { t.Fatal(err) } if !pressed { t.Fatal("active-low reset button was not reported pressed") } } type countingController struct{ calls atomic.Int32 } func (c *countingController) Reboot(context.Context) error { c.calls.Add(1) return nil } func TestClientReadsResetButtonState(t *testing.T) { path := filepath.Join(t.TempDir(), "system.sock") valuePath := filepath.Join(t.TempDir(), "value") if err := os.WriteFile(valuePath, []byte("0\n"), 0o600); err != nil { t.Fatal(err) } listener, err := net.Listen("unix", path) if err != nil { t.Skipf("Unix sockets unavailable: %v", err) } defer listener.Close() server := &Server{ Controller: MockController{}, ResetButton: SysfsResetButton{ValuePath: valuePath, ActiveLow: true}, } done := make(chan error, 1) go func() { done <- server.Serve(listener) }() defer func() { _ = listener.Close() <-done }() pressed, err := NewClient(path).ResetButtonPressed(context.Background()) if err != nil { t.Fatal(err) } if !pressed { t.Fatal("reset button was not reported pressed") } } func TestClientSchedulesOnePrivilegedReboot(t *testing.T) { path := filepath.Join(t.TempDir(), "system.sock") listener, err := net.Listen("unix", path) if err != nil { t.Skipf("Unix sockets unavailable: %v", err) } defer listener.Close() controller := &countingController{} server := &Server{Controller: controller, RebootDelay: time.Millisecond} done := make(chan error, 1) go func() { done <- server.Serve(listener) }() defer func() { _ = listener.Close() <-done }() if err := NewClient(path).Reboot(context.Background()); err != nil { t.Fatal(err) } deadline := time.Now().Add(time.Second) for controller.calls.Load() == 0 && time.Now().Before(deadline) { time.Sleep(time.Millisecond) } if controller.calls.Load() != 1 { t.Fatalf("reboot calls = %d, want 1", controller.calls.Load()) } }