package virtualmachine import "testing" func TestCategorizeError(t *testing.T) { tests := []struct { name string errorStr string wantType string wantReason string }{ // API not supported errors { name: "501 error", errorStr: "501 Not Implemented", wantType: "APINotSupported", wantReason: "ImportDiskAPINotImplemented", }, { name: "not implemented", errorStr: "importdisk API is not implemented", wantType: "APINotSupported", wantReason: "ImportDiskAPINotImplemented", }, { name: "importdisk error", errorStr: "failed to use importdisk", wantType: "APINotSupported", wantReason: "ImportDiskAPINotImplemented", }, // Configuration errors { name: "cannot get provider config", errorStr: "cannot get provider config", wantType: "ConfigurationError", wantReason: "InvalidConfiguration", }, { name: "cannot get credentials", errorStr: "cannot get credentials", wantType: "ConfigurationError", wantReason: "InvalidConfiguration", }, { name: "cannot find site", errorStr: "cannot find site", wantType: "ConfigurationError", wantReason: "InvalidConfiguration", }, { name: "cannot create proxmox client", errorStr: "cannot create Proxmox client", wantType: "ConfigurationError", wantReason: "InvalidConfiguration", }, // Quota errors { name: "quota exceeded", errorStr: "quota exceeded", wantType: "QuotaExceeded", wantReason: "ResourceQuotaExceeded", }, { name: "resource exceeded", errorStr: "resource exceeded", wantType: "QuotaExceeded", wantReason: "ResourceQuotaExceeded", }, // Node health errors { name: "node unhealthy", errorStr: "node is unhealthy", wantType: "NodeUnhealthy", wantReason: "NodeHealthCheckFailed", }, { name: "node not reachable", errorStr: "node is not reachable", wantType: "NodeUnhealthy", wantReason: "NodeHealthCheckFailed", }, { name: "node offline", errorStr: "node is offline", wantType: "NodeUnhealthy", wantReason: "NodeHealthCheckFailed", }, // Image errors { name: "image not found", errorStr: "image not found in storage", wantType: "ImageNotFound", wantReason: "ImageNotFoundInStorage", }, { name: "cannot find image", errorStr: "cannot find image", wantType: "ImageNotFound", wantReason: "ImageNotFoundInStorage", }, // Lock errors { name: "lock file error", errorStr: "lock file timeout", wantType: "LockError", wantReason: "LockFileTimeout", }, { name: "timeout error", errorStr: "operation timeout", wantType: "LockError", wantReason: "LockFileTimeout", }, // Authentication errors { name: "authentication error", errorStr: "authentication failed", wantType: "AuthenticationError", wantReason: "AuthenticationFailed", }, { name: "unauthorized", errorStr: "unauthorized access", wantType: "AuthenticationError", wantReason: "AuthenticationFailed", }, { name: "401 error", errorStr: "401 Unauthorized", wantType: "AuthenticationError", wantReason: "AuthenticationFailed", }, { name: "invalid credentials", errorStr: "invalid credentials", wantType: "AuthenticationError", wantReason: "AuthenticationFailed", }, { name: "forbidden", errorStr: "forbidden", wantType: "AuthenticationError", wantReason: "AuthenticationFailed", }, { name: "403 error", errorStr: "403 Forbidden", wantType: "AuthenticationError", wantReason: "AuthenticationFailed", }, // Network errors { name: "network error", errorStr: "network connection failed", wantType: "NetworkError", wantReason: "TransientNetworkFailure", }, { name: "connection error", errorStr: "connection refused", wantType: "NetworkError", wantReason: "TransientNetworkFailure", }, { name: "connection reset", errorStr: "connection reset", wantType: "NetworkError", wantReason: "TransientNetworkFailure", }, { name: "502 error", errorStr: "502 Bad Gateway", wantType: "NetworkError", wantReason: "TransientNetworkFailure", }, { name: "503 error", errorStr: "503 Service Unavailable", wantType: "NetworkError", wantReason: "TransientNetworkFailure", }, // Creation failures { name: "cannot create vm", errorStr: "cannot create VM", wantType: "CreationFailed", wantReason: "VMCreationFailed", }, { name: "failed to create", errorStr: "failed to create VM", wantType: "CreationFailed", wantReason: "VMCreationFailed", }, // Unknown errors { name: "unknown error", errorStr: "something went wrong", wantType: "Failed", wantReason: "UnknownError", }, { name: "empty error", errorStr: "", wantType: "Failed", wantReason: "UnknownError", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := categorizeError(tt.errorStr) if result.Type != tt.wantType { t.Errorf("categorizeError(%q).Type = %q, want %q", tt.errorStr, result.Type, tt.wantType) } if result.Reason != tt.wantReason { t.Errorf("categorizeError(%q).Reason = %q, want %q", tt.errorStr, result.Reason, tt.wantReason) } }) } } func TestCategorizeError_CaseInsensitive(t *testing.T) { tests := []struct { name string errorStr string wantType string }{ {"uppercase", "AUTHENTICATION FAILED", "AuthenticationError"}, {"mixed case", "AuThEnTiCaTiOn FaIlEd", "AuthenticationError"}, {"lowercase", "authentication failed", "AuthenticationError"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := categorizeError(tt.errorStr) if result.Type != tt.wantType { t.Errorf("categorizeError(%q).Type = %q, want %q", tt.errorStr, result.Type, tt.wantType) } }) } }