package utils import "testing" func TestValidateVMID(t *testing.T) { tests := []struct { name string vmid int wantErr bool }{ {"valid minimum", 100, false}, {"valid maximum", 999999999, false}, {"valid middle", 1000, false}, {"too small", 99, true}, {"zero", 0, true}, {"negative", -1, true}, {"too large", 1000000000, true}, {"very large", 2000000000, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateVMID(tt.vmid) if (err != nil) != tt.wantErr { t.Errorf("ValidateVMID(%d) error = %v, wantErr %v", tt.vmid, err, tt.wantErr) } }) } } func TestValidateVMName(t *testing.T) { tests := []struct { name string vmName string wantErr bool }{ // Valid names {"simple name", "vm-001", false}, {"with underscore", "vm_001", false}, {"with dot", "vm.001", false}, {"with spaces", "my vm", false}, {"alphanumeric", "vm001", false}, {"mixed case", "MyVM", false}, {"max length", string(make([]byte, 100)), false}, // 100 chars // Invalid names {"empty", "", true}, {"too long", string(make([]byte, 101)), true}, // 101 chars {"starts with space", " vm", true}, {"ends with space", "vm ", true}, {"invalid char @", "vm@001", true}, {"invalid char #", "vm#001", true}, {"invalid char $", "vm$001", true}, {"invalid char %", "vm%001", true}, {"only spaces", " ", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateVMName(tt.vmName) if (err != nil) != tt.wantErr { t.Errorf("ValidateVMName(%q) error = %v, wantErr %v", tt.vmName, err, tt.wantErr) } }) } } func TestValidateMemory(t *testing.T) { tests := []struct { name string memory string wantErr bool }{ // Valid memory {"minimum", "128Mi", false}, {"128MB", "128M", false}, {"1Gi", "1Gi", false}, {"4Gi", "4Gi", false}, {"8Gi", "8Gi", false}, {"16Gi", "16Gi", false}, {"maximum", "2097152Mi", false}, // 2TB in MiB {"2TB in GiB", "2048Gi", false}, // Invalid memory {"empty", "", true}, {"too small", "127Mi", true}, {"too small MB", "127M", true}, {"zero", "0", true}, {"too large", "2097153Mi", true}, // Over 2TB {"too large GiB", "2049Gi", true}, {"invalid format", "invalid", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateMemory(tt.memory) if (err != nil) != tt.wantErr { t.Errorf("ValidateMemory(%q) error = %v, wantErr %v", tt.memory, err, tt.wantErr) } }) } } func TestValidateDisk(t *testing.T) { tests := []struct { name string disk string wantErr bool }{ // Valid disk {"minimum", "1Gi", false}, {"1GB", "1G", false}, {"10Gi", "10Gi", false}, {"50Gi", "50Gi", false}, {"100Gi", "100Gi", false}, {"1Ti", "1Ti", false}, {"maximum", "102400Gi", false}, // 100TB in GiB {"100TB in TiB", "100Ti", false}, // Invalid disk {"empty", "", true}, {"too small", "0.5Gi", true}, // Less than 1GB {"zero", "0", true}, {"too large", "102401Gi", true}, // Over 100TB {"too large TiB", "101Ti", true}, {"invalid format", "invalid", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateDisk(tt.disk) if (err != nil) != tt.wantErr { t.Errorf("ValidateDisk(%q) error = %v, wantErr %v", tt.disk, err, tt.wantErr) } }) } } func TestValidateCPU(t *testing.T) { tests := []struct { name string cpu int wantErr bool }{ {"minimum", 1, false}, {"valid", 2, false}, {"valid", 4, false}, {"valid", 8, false}, {"maximum", 1024, false}, {"zero", 0, true}, {"negative", -1, true}, {"too large", 1025, true}, {"very large", 2048, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateCPU(tt.cpu) if (err != nil) != tt.wantErr { t.Errorf("ValidateCPU(%d) error = %v, wantErr %v", tt.cpu, err, tt.wantErr) } }) } } func TestValidateNetworkBridge(t *testing.T) { tests := []struct { name string network string wantErr bool }{ // Valid networks {"vmbr0", "vmbr0", false}, {"vmbr1", "vmbr1", false}, {"custom-bridge", "custom-bridge", false}, {"custom_bridge", "custom_bridge", false}, {"bridge01", "bridge01", false}, {"BRIDGE", "BRIDGE", false}, // Invalid networks {"empty", "", true}, {"with space", "vmbr 0", true}, {"with @", "vmbr@0", true}, {"with #", "vmbr#0", true}, {"with $", "vmbr$0", true}, {"with dot", "vmbr.0", true}, // Dots are typically not used in bridge names } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateNetworkBridge(tt.network) if (err != nil) != tt.wantErr { t.Errorf("ValidateNetworkBridge(%q) error = %v, wantErr %v", tt.network, err, tt.wantErr) } }) } } func TestValidateImageSpec(t *testing.T) { tests := []struct { name string image string wantErr bool }{ // Valid template IDs {"valid template ID min", "100", false}, {"valid template ID", "1000", false}, {"valid template ID max", "999999999", false}, // Valid volid format {"valid volid", "local:iso/ubuntu-22.04.iso", false}, {"valid volid with path", "storage:path/to/image.qcow2", false}, // Valid image names {"simple name", "ubuntu-22.04-cloud", false}, {"with dots", "ubuntu.22.04.cloud", false}, {"with hyphens", "ubuntu-22-04-cloud", false}, {"with underscores", "ubuntu_22_04_cloud", false}, {"max length", string(make([]byte, 255)), false}, // 255 chars // Invalid {"empty", "", true}, {"invalid template ID too small", "99", true}, {"invalid template ID too large", "1000000000", true}, {"invalid volid no storage", ":path", true}, {"invalid volid no path", "storage:", true}, {"too long name", string(make([]byte, 256)), true}, // 256 chars } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateImageSpec(tt.image) if (err != nil) != tt.wantErr { t.Errorf("ValidateImageSpec(%q) error = %v, wantErr %v", tt.image, err, tt.wantErr) } }) } }