banger/internal/cli/tui_test.go
Thales Maciel 6e00fa690d Reject invalid VM CPU and memory values
VM create and vm set accepted zero or negative CPU and memory values, which either got stored directly or silently fell back to defaults and only surfaced as failures later. This tightens validation so bad settings are rejected at the user boundary and again in the daemon before any VM record is persisted.

Change vm.create CPU and memory request fields to optional pointers so omitted values still mean defaults, while explicit non-positive values can be distinguished and rejected. Update Cobra create/set parsing, keep the TUI aligned with the new API shape, and add regression tests for CLI parsing, daemon-side validation, and the create-defaults path.

Validation: go test ./... and make build. Left my-rootfs.ext4 untracked.
2026-03-16 16:28:17 -03:00

89 lines
2.7 KiB
Go

package cli
import (
"testing"
"banger/internal/model"
)
func TestCreateVMFormSubmit(t *testing.T) {
form := newCreateVMForm([]model.Image{{Name: "default"}}, model.DaemonConfig{DefaultImageName: "default"})
form.fields[0].input.SetValue("devbox")
form.fields[2].input.SetValue("4")
form.fields[3].input.SetValue("2048")
form.fields[4].input.SetValue("12G")
form.fields[5].input.SetValue("24G")
form.fields[6].index = 1
action, err := form.submit()
if err != nil {
t.Fatalf("submit: %v", err)
}
if action.kind != actionCreate {
t.Fatalf("kind = %s, want %s", action.kind, actionCreate)
}
if action.create.Name != "devbox" || action.create.ImageName != "default" {
t.Fatalf("unexpected create params: %+v", action.create)
}
if action.create.VCPUCount == nil || *action.create.VCPUCount != 4 || action.create.MemoryMiB == nil || *action.create.MemoryMiB != 2048 {
t.Fatalf("unexpected cpu/memory: %+v", action.create)
}
if action.create.SystemOverlaySize != "12G" || action.create.WorkDiskSize != "24G" {
t.Fatalf("unexpected disk sizes: %+v", action.create)
}
if !action.create.NATEnabled {
t.Fatalf("expected NAT enabled: %+v", action.create)
}
}
func TestEditVMFormSubmit(t *testing.T) {
form := newEditVMForm(model.VMRecord{
ID: "vm-1",
Spec: model.VMSpec{
VCPUCount: 2,
MemoryMiB: 1024,
WorkDiskSizeBytes: 16 * 1024 * 1024 * 1024,
NATEnabled: false,
},
})
form.fields[0].input.SetValue("6")
form.fields[1].input.SetValue("4096")
form.fields[2].input.SetValue("32G")
form.fields[3].index = 1
action, err := form.submit()
if err != nil {
t.Fatalf("submit: %v", err)
}
if action.kind != actionEdit {
t.Fatalf("kind = %s, want %s", action.kind, actionEdit)
}
if action.set.IDOrName != "vm-1" {
t.Fatalf("unexpected vm id: %+v", action.set)
}
if action.set.VCPUCount == nil || *action.set.VCPUCount != 6 {
t.Fatalf("unexpected vcpu: %+v", action.set)
}
if action.set.MemoryMiB == nil || *action.set.MemoryMiB != 4096 {
t.Fatalf("unexpected memory: %+v", action.set)
}
if action.set.WorkDiskSize != "32G" {
t.Fatalf("unexpected disk size: %+v", action.set)
}
if action.set.NATEnabled == nil || !*action.set.NATEnabled {
t.Fatalf("expected nat enabled: %+v", action.set)
}
}
func TestResolveSelectedID(t *testing.T) {
vms := []model.VMRecord{{ID: "one"}, {ID: "two"}}
if got := resolveSelectedID("two", vms); got != "two" {
t.Fatalf("resolveSelectedID existing = %q, want %q", got, "two")
}
if got := resolveSelectedID("missing", vms); got != "one" {
t.Fatalf("resolveSelectedID fallback = %q, want %q", got, "one")
}
if got := resolveSelectedID("anything", nil); got != "" {
t.Fatalf("resolveSelectedID empty = %q, want empty", got)
}
}