package cli import ( "bytes" "encoding/json" "strings" "testing" "git.cloudinit.dev/coreci/orca/internal/certpaths" "git.cloudinit.dev/coreci/orca/internal/store" ) func TestNodeCapacitySetMissingArgs(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"node", "capacity", "set", "--cpu", "1000"}) if err := rootCmd.Execute(); err == nil { t.Fatal("expected error for capacity set missing memory/disk, got nil") } } func TestNodeCapacitySet(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"node", "capacity", "set", "--cpu", "2000", "--memory", "4096", "--disk", "51200"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("capacity set: %v", err) } if !strings.Contains(buf.String(), "Capacity set") { t.Errorf("capacity set output unexpected: %s", buf.String()) } } func TestNodeCapacitySetJSON(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"node", "capacity", "set", "--cpu", "3000", "--memory", "8192", "--disk", "102400", "--json"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("capacity set --json: %v", err) } var c map[string]any if err := json.Unmarshal(bytes.TrimSpace(buf.Bytes()), &c); err != nil { t.Fatalf("unmarshal capacity set json: %v\n%s", err, buf.String()) } if c["NodeID"] != "self" { t.Errorf("capacity set --json NodeID = %v, want self", c["NodeID"]) } } func TestNodeCapacityShowNotFound(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"node", "capacity", "show", "missing-node"}) if err := rootCmd.Execute(); err == nil { t.Fatal("expected error for capacity show missing node, got nil") } } func TestNodeCapacityShowAfterSet(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() seedCapacity(t, "show-node", 4000, 4096, 51200) resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"node", "capacity", "show", "show-node"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("capacity show: %v", err) } out := buf.String() if !strings.Contains(out, "show-node") { t.Errorf("capacity show missing node id: %s", out) } if !strings.Contains(out, "4000") { t.Errorf("capacity show missing cpu: %s", out) } } func TestNodeCapacityShowJSON(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() seedCapacity(t, "jsonshow-node", 4000, 4096, 51200) resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"node", "capacity", "show", "jsonshow-node", "--json"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("capacity show --json: %v", err) } var c map[string]any if err := json.Unmarshal(bytes.TrimSpace(buf.Bytes()), &c); err != nil { t.Fatalf("unmarshal capacity show json: %v\n%s", err, buf.String()) } if c["NodeID"] != "jsonshow-node" { t.Errorf("capacity show --json NodeID = %v, want jsonshow-node", c["NodeID"]) } } func TestNodeCapacityListEmpty(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"node", "capacity", "list"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("capacity list: %v", err) } if !strings.Contains(buf.String(), "No capacity") { t.Errorf("capacity list empty output unexpected: %s", buf.String()) } } func TestNodeCapacityListAfterSet(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() seedCapacity(t, "list-node", 5000, 4096, 51200) resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"node", "capacity", "list"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("capacity list: %v", err) } if !strings.Contains(buf.String(), "list-node") { t.Errorf("capacity list missing node: %s", buf.String()) } } func TestNodeCapacityListJSON(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() seedCapacity(t, "jsonlist-node", 5000, 4096, 51200) resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"node", "capacity", "list", "--json"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("capacity list --json: %v", err) } var rows []map[string]any if err := json.Unmarshal(bytes.TrimSpace(buf.Bytes()), &rows); err != nil { t.Fatalf("unmarshal capacity list json: %v\n%s", err, buf.String()) } found := false for _, r := range rows { if r["NodeID"] == "jsonlist-node" { found = true } } if !found { t.Errorf("capacity list --json missing jsonlist-node: %s", buf.String()) } } func seedCapacity(t *testing.T, nodeID string, cpu, mem, disk int64) { t.Helper() db, err := store.Open(certpaths.DBPath()) if err != nil { t.Fatalf("open db: %v", err) } defer db.Close() repo := store.NewCapacityRepo(db) c := &store.NodeCapacity{ NodeID: nodeID, CPUMillicores: cpu, MemoryMiB: mem, DiskMiB: disk, } if err := repo.Upsert(t.Context(), c); err != nil { t.Fatalf("upsert capacity: %v", err) } }