You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.3 KiB
92 lines
2.3 KiB
|
2 months ago
|
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())
|
||
|
|
}
|
||
|
|
}
|