The laptop model's hardware module and a memory-pressure module for any machine (hq research 027/03, 026/05, to-be 42 phase 3). The predecessor's polling auto-profile and mem-guard user scripts become each module's own Go code launched by the node runtime (ADR 0198): a profile switcher woken by the kernel's power-supply uevents, and a guard that warns on RAM, swap or PSI before systemd-oomd acts, on the desktop over the account's bus and always as an event. supergfxctl and triggerhappy are kept as found (research 027 Q1).
74 lines
2.7 KiB
Go
74 lines
2.7 KiB
Go
package main
|
|
|
|
import "testing"
|
|
|
|
func on(b bool) *bool { return &b }
|
|
|
|
func TestADischargingBatteryWinsOverAnAdapterThatSaysOnline(t *testing.T) {
|
|
got := PowerSource([]Supply{
|
|
{Name: "BAT1", Type: "Battery", Status: "Discharging"},
|
|
{Name: "ucsi-source-psy-USBC000:001", Type: "USB", Scope: "System", Online: on(true)},
|
|
})
|
|
if got.OnAC {
|
|
t.Fatalf("a USB-C port reporting online while the battery discharges was read as mains: %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestMainsOnlineIsAC(t *testing.T) {
|
|
got := PowerSource([]Supply{
|
|
{Name: "ACAD", Type: "Mains", Online: on(true)},
|
|
{Name: "BAT1", Type: "Battery", Status: "Not charging"},
|
|
})
|
|
if !got.OnAC || got.Reason != "ACAD (Mains) is online" {
|
|
t.Fatalf("%+v", got)
|
|
}
|
|
}
|
|
|
|
func TestAPeripheralsBatteryDecidesNothing(t *testing.T) {
|
|
got := PowerSource([]Supply{
|
|
{Name: "hidpp_battery_0", Type: "Battery", Scope: "Device", Status: "Discharging"},
|
|
{Name: "ACAD", Type: "Mains", Online: on(true)},
|
|
{Name: "BAT1", Type: "Battery", Status: "Charging"},
|
|
})
|
|
if !got.OnAC {
|
|
t.Fatalf("a mouse's discharging battery put the laptop on battery: %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestNoSupplyOnlineWithABatteryIsBatteryAndNoBatteryIsMains(t *testing.T) {
|
|
if got := PowerSource([]Supply{{Name: "ACAD", Type: "Mains", Online: on(false)}, {Name: "BAT1", Type: "Battery", Status: "Unknown"}}); got.OnAC {
|
|
t.Fatalf("%+v", got)
|
|
}
|
|
if got := PowerSource(nil); !got.OnAC {
|
|
t.Fatalf("a machine with no battery is on mains: %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestTheBatteryIsReadInWattHoursFromChargeAndHealthAgainstDesign(t *testing.T) {
|
|
f := newFake(t)
|
|
// The laptop's own battery, as measured: charge_* in µAh, no energy_* and no power_now.
|
|
f.supply("BAT1", map[string]string{
|
|
"type": "Battery", "status": "Discharging", "capacity": "80",
|
|
"charge_now": "3073000", "charge_full": "3865000", "charge_full_design": "4580000",
|
|
"voltage_min_design": "15939000", "current_now": "1000000", "voltage_now": "16000000",
|
|
"cycle_count": "0", "charge_control_end_threshold": "80", "manufacturer": "ASUS ",
|
|
})
|
|
bs := f.machine().Batteries()
|
|
if len(bs) != 1 {
|
|
t.Fatalf("%+v", bs)
|
|
}
|
|
b := bs[0]
|
|
if *b.EnergyWh != 49 || *b.FullWh != 61.6 || *b.DesignWh != 73 || *b.HealthPercent != 84.4 {
|
|
t.Fatalf("energy %v full %v design %v health %v", *b.EnergyWh, *b.FullWh, *b.DesignWh, *b.HealthPercent)
|
|
}
|
|
if b.Cycles != nil || b.CyclesNote == "" {
|
|
t.Fatal("a cycle count of 0 is the firmware not reporting one, and said so")
|
|
}
|
|
if *b.LimitPercent != 80 || *b.PowerW != 16 || b.HoursRemaining == nil || *b.HoursRemaining != 3.1 {
|
|
t.Fatalf("limit %v power %v hours %v", *b.LimitPercent, *b.PowerW, b.HoursRemaining)
|
|
}
|
|
if b.Manufacturer != "ASUS" {
|
|
t.Fatalf("manufacturer %q", b.Manufacturer)
|
|
}
|
|
}
|