Files
Mitchell-JohnsonandClaude Fable 5.1 8ee2a2d293 Bug bash 2026-09-19: 17 bugs fixed and verified (BUGS.md)
Widgets: a bad pattern no longer silences every widget; malformed layouts load.
Shell: lost session returns to login at once; tab titles; Escape closes menus and dialogs.
Files: names are one path segment; unsaved edits ask before page/machine/tab changes;
only folders that opened are remembered. Terminals: unique default names; 64-char names.
API: queries capped at 10 000 values; 32 streams per client, 512 in all; only
/embed/widget is frameable. ZFS sensors: one unprivileged zpool list, no sudo journal spam.
Phone: 36 px inputs; dataset rows as wide as their cells. Machines: valid name pattern.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-19 10:18:23 -07:00

96 lines
3.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package sensors
import (
"encoding/json"
"reflect"
"strings"
"testing"
)
type fake []Sensor
func (f fake) Sensors() []Sensor { return f }
func TestSeg(t *testing.T) {
for in, want := range map[string]string{"/": "root", "/mnt/tank": "mnt_tank", "Package id 0": "package_id_0", "enp3s0": "enp3s0", " ": "unnamed", "Tctl+": "tctl", "nvme0n1": "nvme0n1"} {
if got := Seg(in); got != want {
t.Errorf("Seg(%q) = %q, want %q", in, got, want)
}
}
}
func TestRegistryDedupes(t *testing.T) {
r := NewRegistry(fake{{ID: "temp.nvme.composite", Value: 40.0}}, fake{{ID: "temp.nvme.composite", Value: 50.0}})
all := r.All()
if len(all) != 2 || all[0].ID != "temp.nvme.composite" || all[1].ID != "temp.nvme.composite_2" {
t.Fatalf("got %+v", all)
}
}
func TestShape(t *testing.T) {
all := []Sensor{{ID: "cpu.usage", Value: 12.5, Unit: "%"}, {ID: "fan.a.fan1", Value: 800.0}, {ID: "fan.a.fan2", Value: 900.0}, {ID: "net.eth0.up", Value: true}}
got, err := Shape(all, json.RawMessage(`{"cpu":"cpu.usage","fans":"fan.*","box":{"link":"net.eth0.up","gone":"ups.battery"},"list":["cpu.usage"]}`), false)
if err != nil {
t.Fatal(err)
}
want := map[string]any{
"cpu": 12.5,
"fans": map[string]any{"fan.a.fan1": 800.0, "fan.a.fan2": 900.0},
"box": map[string]any{"link": true, "gone": nil},
"list": []any{12.5},
}
if !reflect.DeepEqual(got, want) {
t.Fatalf("got %#v\nwant %#v", got, want)
}
full, _ := Shape(all, json.RawMessage(`"cpu.usage"`), true)
if s, ok := full.(Sensor); !ok || s.Unit != "%" {
t.Fatalf("full: got %#v", full)
}
for _, bad := range []string{`{"x": 5}`, `{"x": "fan.["}`, `not json`} {
if _, err := Shape(all, json.RawMessage(bad), false); err == nil {
t.Errorf("Shape(%s) should fail", bad)
}
}
}
func TestWriteProm(t *testing.T) {
var b strings.Builder
WriteProm(&b, []Sensor{
{ID: "cpu.usage", Kind: "usage", Unit: "%", Value: 12.5},
{ID: "ups.runtime", Kind: "duration", Unit: "min", Value: 2.0},
{ID: "net.eth0.up", Kind: "state", Value: true, Labels: map[string]string{"iface": "eth0"}},
{ID: "ups.state", Kind: "state", Value: `Nor"mal`},
{ID: "updates.pending", Kind: "count", Value: 3.0},
})
got := b.String()
for _, want := range []string{
"# TYPE hamlab_usage_percent gauge\n" + `hamlab_usage_percent{id="cpu.usage"} 12.5`,
`hamlab_duration_seconds{id="ups.runtime"} 120`,
`hamlab_state{id="net.eth0.up",iface="eth0"} 1`,
`hamlab_state{id="ups.state",value="Nor\"mal"} 1`,
`hamlab_updates_pending{id="updates.pending"} 3`,
} {
if !strings.Contains(got, want) {
t.Errorf("missing %q in:\n%s", want, got)
}
}
}
func TestShapeBudget(t *testing.T) {
all := make([]Sensor, 300)
for i := range all {
all[i] = Sensor{ID: "s." + strings.Repeat("x", i%7) + string(rune('a'+i%26)) + strings.Repeat("y", i/26), Value: 1.0}
}
q := map[string]string{}
for i := 0; i < 40; i++ { // 40 × 300 = 12 000 values
q["k"+strings.Repeat("z", i)] = "*"
}
b, _ := json.Marshal(q)
if _, err := Shape(all, b, false); err == nil {
t.Fatal("a query returning more than MaxValues must be refused")
}
if _, err := Shape(all, json.RawMessage(`{"a":"*","b":"*"}`), false); err != nil {
t.Fatalf("an ordinary query must pass: %v", err)
}
}