mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-15 10:12:07 -04:00
260
core/internal/server/brightness/udev_test.go
Normal file
260
core/internal/server/brightness/udev_test.go
Normal file
@@ -0,0 +1,260 @@
|
||||
package brightness
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pilebones/go-udev/netlink"
|
||||
)
|
||||
|
||||
func setupTestManager(t *testing.T) (*Manager, string) {
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
backlightDir := filepath.Join(tmpDir, "backlight", "intel_backlight")
|
||||
if err := os.MkdirAll(backlightDir, 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(backlightDir, "max_brightness"), []byte("1000\n"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(backlightDir, "brightness"), []byte("500\n"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
sysfs := &SysfsBackend{
|
||||
basePath: tmpDir,
|
||||
classes: []string{"backlight"},
|
||||
}
|
||||
if err := sysfs.scanDevices(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m := &Manager{
|
||||
sysfsBackend: sysfs,
|
||||
sysfsReady: true,
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
m.state = State{
|
||||
Devices: []Device{
|
||||
{
|
||||
Class: ClassBacklight,
|
||||
ID: "backlight:intel_backlight",
|
||||
Name: "intel_backlight",
|
||||
Current: 500,
|
||||
Max: 1000,
|
||||
CurrentPercent: 50,
|
||||
Backend: "sysfs",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return m, tmpDir
|
||||
}
|
||||
|
||||
func TestHandleUdevBrightnessChange_UpdatesState(t *testing.T) {
|
||||
m, _ := setupTestManager(t)
|
||||
|
||||
m.handleUdevBrightnessChange("backlight:intel_backlight", 750)
|
||||
|
||||
state := m.GetState()
|
||||
if len(state.Devices) != 1 {
|
||||
t.Fatalf("expected 1 device, got %d", len(state.Devices))
|
||||
}
|
||||
|
||||
dev := state.Devices[0]
|
||||
if dev.Current != 750 {
|
||||
t.Errorf("expected Current=750, got %d", dev.Current)
|
||||
}
|
||||
if dev.CurrentPercent != 75 {
|
||||
t.Errorf("expected CurrentPercent=75, got %d", dev.CurrentPercent)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleUdevBrightnessChange_NoChangeWhenSameValue(t *testing.T) {
|
||||
m, _ := setupTestManager(t)
|
||||
|
||||
updateCh := m.SubscribeUpdates("test")
|
||||
defer m.UnsubscribeUpdates("test")
|
||||
|
||||
m.handleUdevBrightnessChange("backlight:intel_backlight", 500)
|
||||
|
||||
select {
|
||||
case <-updateCh:
|
||||
t.Error("should not broadcast when brightness unchanged")
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleUdevBrightnessChange_BroadcastsOnChange(t *testing.T) {
|
||||
m, _ := setupTestManager(t)
|
||||
|
||||
updateCh := m.SubscribeUpdates("test")
|
||||
defer m.UnsubscribeUpdates("test")
|
||||
|
||||
m.handleUdevBrightnessChange("backlight:intel_backlight", 750)
|
||||
|
||||
select {
|
||||
case update := <-updateCh:
|
||||
if update.Device.Current != 750 {
|
||||
t.Errorf("broadcast had wrong Current: got %d, want 750", update.Device.Current)
|
||||
}
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
t.Error("expected broadcast on brightness change")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleUdevBrightnessChange_UnknownDevice(t *testing.T) {
|
||||
m, _ := setupTestManager(t)
|
||||
|
||||
m.handleUdevBrightnessChange("backlight:unknown_device", 500)
|
||||
|
||||
state := m.GetState()
|
||||
if len(state.Devices) != 1 {
|
||||
t.Errorf("state should be unchanged, got %d devices", len(state.Devices))
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleUdevBrightnessChange_NilSysfsBackend(t *testing.T) {
|
||||
m := &Manager{
|
||||
sysfsBackend: nil,
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
m.handleUdevBrightnessChange("backlight:test", 500)
|
||||
}
|
||||
|
||||
func TestHandleUdevBrightnessChange_DeviceNotInState(t *testing.T) {
|
||||
m, _ := setupTestManager(t)
|
||||
|
||||
m.sysfsBackend.deviceCache.Store("backlight:other_device", &sysfsDevice{
|
||||
class: ClassBacklight,
|
||||
id: "backlight:other_device",
|
||||
name: "other_device",
|
||||
maxBrightness: 100,
|
||||
minValue: 1,
|
||||
})
|
||||
|
||||
m.handleUdevBrightnessChange("backlight:other_device", 50)
|
||||
|
||||
state := m.GetState()
|
||||
for _, d := range state.Devices {
|
||||
if d.ID == "backlight:other_device" {
|
||||
t.Error("device should not be added to state via udev change event")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleEvent_ChangeAction(t *testing.T) {
|
||||
m, tmpDir := setupTestManager(t)
|
||||
um := &UdevMonitor{stop: make(chan struct{})}
|
||||
|
||||
brightnessPath := filepath.Join(tmpDir, "backlight", "intel_backlight", "brightness")
|
||||
if err := os.WriteFile(brightnessPath, []byte("800\n"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
event := netlink.UEvent{
|
||||
Action: netlink.CHANGE,
|
||||
Env: map[string]string{
|
||||
"SUBSYSTEM": "backlight",
|
||||
"DEVPATH": "/devices/pci0000:00/0000:00:02.0/drm/card0/card0-eDP-1/intel_backlight",
|
||||
},
|
||||
}
|
||||
|
||||
um.handleEvent(m, event)
|
||||
|
||||
state := m.GetState()
|
||||
if state.Devices[0].Current != 800 {
|
||||
t.Errorf("expected Current=800 after change event, got %d", state.Devices[0].Current)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleEvent_MissingEnvVars(t *testing.T) {
|
||||
m, _ := setupTestManager(t)
|
||||
um := &UdevMonitor{stop: make(chan struct{})}
|
||||
|
||||
event := netlink.UEvent{
|
||||
Action: netlink.CHANGE,
|
||||
Env: map[string]string{},
|
||||
}
|
||||
|
||||
um.handleEvent(m, event)
|
||||
|
||||
state := m.GetState()
|
||||
if state.Devices[0].Current != 500 {
|
||||
t.Error("state should be unchanged with missing env vars")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleEvent_MissingSubsystem(t *testing.T) {
|
||||
m, _ := setupTestManager(t)
|
||||
um := &UdevMonitor{stop: make(chan struct{})}
|
||||
|
||||
event := netlink.UEvent{
|
||||
Action: netlink.CHANGE,
|
||||
Env: map[string]string{
|
||||
"DEVPATH": "/devices/foo/bar",
|
||||
},
|
||||
}
|
||||
|
||||
um.handleEvent(m, event)
|
||||
|
||||
state := m.GetState()
|
||||
if state.Devices[0].Current != 500 {
|
||||
t.Error("state should be unchanged with missing SUBSYSTEM")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleChange_BrightnessFileNotFound(t *testing.T) {
|
||||
m, _ := setupTestManager(t)
|
||||
um := &UdevMonitor{stop: make(chan struct{})}
|
||||
|
||||
um.handleChange(m, "backlight", "nonexistent_device")
|
||||
|
||||
state := m.GetState()
|
||||
if state.Devices[0].Current != 500 {
|
||||
t.Error("state should be unchanged when brightness file not found")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleChange_InvalidBrightnessValue(t *testing.T) {
|
||||
m, tmpDir := setupTestManager(t)
|
||||
um := &UdevMonitor{stop: make(chan struct{})}
|
||||
|
||||
brightnessPath := filepath.Join(tmpDir, "backlight", "intel_backlight", "brightness")
|
||||
if err := os.WriteFile(brightnessPath, []byte("not_a_number\n"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
um.handleChange(m, "backlight", "intel_backlight")
|
||||
|
||||
state := m.GetState()
|
||||
if state.Devices[0].Current != 500 {
|
||||
t.Error("state should be unchanged with invalid brightness value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUdevMonitor_Close(t *testing.T) {
|
||||
um := &UdevMonitor{stop: make(chan struct{})}
|
||||
|
||||
um.Close()
|
||||
|
||||
select {
|
||||
case <-um.stop:
|
||||
default:
|
||||
t.Error("stop channel should be closed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleChange_NilSysfsBackend(t *testing.T) {
|
||||
m := &Manager{
|
||||
sysfsBackend: nil,
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
um := &UdevMonitor{stop: make(chan struct{})}
|
||||
|
||||
um.handleChange(m, "backlight", "test_device")
|
||||
}
|
||||
Reference in New Issue
Block a user