Add Show Widget for library actions with Overview charts from last run output.

This commit is contained in:
2026-07-20 20:48:06 +02:00
parent e047499fed
commit d188ca41b8
20 changed files with 1918 additions and 128 deletions
@@ -0,0 +1,135 @@
package settings
import (
"os"
"path/filepath"
"testing"
"time"
)
func TestEnsureBuiltinActionsAddsMemoryAndUpdatesDisk(t *testing.T) {
now := time.Now().UTC()
store := ActionStore{
Actions: []Action{
{
ID: BuiltinActionUptimeID,
Name: "Uptime",
Kind: ActionKindShell,
Body: "uptime",
Env: []ActionEnvVar{},
Builtin: true,
CreatedAt: now,
UpdatedAt: now,
},
{
ID: BuiltinActionDiskUsageID,
Name: "Disk usage",
Kind: ActionKindShell,
Body: "df -h",
Env: []ActionEnvVar{},
Builtin: true,
CreatedAt: now,
UpdatedAt: now,
},
{
ID: BuiltinActionSysInfoID,
Name: "System info",
Kind: ActionKindScript,
Body: "uname -a",
Env: []ActionEnvVar{},
Builtin: true,
CreatedAt: now,
UpdatedAt: now,
},
{
ID: "custom-1",
Name: "Custom",
Kind: ActionKindShell,
Body: "echo hi",
Env: []ActionEnvVar{},
Builtin: false,
CreatedAt: now,
UpdatedAt: now,
},
},
}
updated, changed := EnsureBuiltinActions(store)
if !changed {
t.Fatal("expected changes")
}
foundMemory := false
foundCustom := false
for _, action := range updated.Actions {
if action.ID == BuiltinActionMemoryID {
foundMemory = true
if !action.ShowWidget || action.WidgetType != ActionWidgetTypeMemory {
t.Fatalf("memory widget = %+v", action)
}
if action.Body != "free -m" {
t.Fatalf("memory body = %q", action.Body)
}
}
if action.ID == BuiltinActionDiskUsageID {
if action.Body != "df -h {{env.MOUNT}}" {
t.Fatalf("disk body = %q", action.Body)
}
if len(action.Env) != 1 || action.Env[0].Name != "MOUNT" || action.Env[0].Value != "/" {
t.Fatalf("disk env = %+v", action.Env)
}
if !action.ShowWidget || action.WidgetType != ActionWidgetTypeDisk {
t.Fatalf("disk widget = %+v", action)
}
}
if action.ID == "custom-1" {
foundCustom = true
}
}
if !foundMemory {
t.Fatal("memory builtin missing")
}
if !foundCustom {
t.Fatal("custom action was dropped")
}
}
func TestUpsertActionWidgetSnapshot(t *testing.T) {
dir := t.TempDir()
first := ActionWidgetSnapshot{
NodeID: "node-1",
ItemID: "item-1",
GroupID: "group-1",
WidgetType: ActionWidgetTypeMemory,
Title: "Memory",
UpdatedAt: time.Now().UTC(),
ExitCode: 0,
RawStdout: "Mem: 1 1 0 0 0 0",
Memory: &MemoryWidgetData{Total: 1, Used: 1},
}
if err := UpsertActionWidgetSnapshot(dir, first); err != nil {
t.Fatalf("upsert: %v", err)
}
second := first
second.Title = "RAM"
second.Memory = &MemoryWidgetData{Total: 2, Used: 1, Free: 1}
if err := UpsertActionWidgetSnapshot(dir, second); err != nil {
t.Fatalf("upsert2: %v", err)
}
store, err := LoadActionWidgets(dir)
if err != nil {
t.Fatalf("load: %v", err)
}
if len(store.Widgets) != 1 {
t.Fatalf("len = %d", len(store.Widgets))
}
if store.Widgets[0].Title != "RAM" || store.Widgets[0].Memory.Total != 2 {
t.Fatalf("widget = %+v", store.Widgets[0])
}
path := filepath.Join(dir, NodeActionWidgetsFileName)
if _, err := os.Stat(path); err != nil {
t.Fatalf("missing file: %v", err)
}
}