790109ea24
- node capacity set: partial updates (only set dimensions passed; read-modify-write on existing row) - node capacity auto [percentage]: SSH to node, discover CPU (nproc), memory (/proc/meminfo), disk (df), multiply by percentage (default 75) - ACL check --verbose: prints resolved ACLPath + all entries + identity - job list UX: short 8-char IDs, NODE column, conditional EXIT (- for non-terminal statuses) ---ci--- project: orca milestone: v0.12.18 phase: D status: complete requirements: covered: [168, 169] ---/ci---
197 lines
5.5 KiB
Go
197 lines
5.5 KiB
Go
package cli
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.cloudinit.dev/coreci/orca/internal/certpaths"
|
|
"git.cloudinit.dev/coreci/orca/internal/store"
|
|
)
|
|
|
|
func TestNodeCapacitySetPartialUpdate(t *testing.T) {
|
|
_, cleanup := initTestEnv(t)
|
|
defer cleanup()
|
|
resetRootFlags(t)
|
|
var buf bytes.Buffer
|
|
rootCmd.SetOut(&buf)
|
|
rootCmd.SetErr(&buf)
|
|
// REQ-168: partial updates are now allowed. Setting only --cpu
|
|
// should succeed (memory/disk default to 0 or existing values).
|
|
rootCmd.SetArgs([]string{"node", "capacity", "set", "--cpu", "1000"})
|
|
if err := rootCmd.Execute(); err != nil {
|
|
t.Fatalf("expected success for partial capacity set, got: %v", err)
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|