package validation import "testing" func TestValidateZFSName(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"valid pool name", "tank", false}, {"valid dataset name", "tank/data", false}, {"valid nested dataset", "tank/data/subdata", false}, {"valid with underscore", "tank_data", false}, {"valid with dash", "tank-data", false}, {"valid with colon", "tank:data", false}, {"empty name", "", true}, {"starts with dash", "-tank", true}, {"starts with dot", ".tank", true}, {"invalid character @", "tank@data", true}, {"too long", string(make([]byte, 257)), true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateZFSName(tt.input) if (err != nil) != tt.wantErr { t.Errorf("ValidateZFSName(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr) } }) } } func TestValidateUsername(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"valid username", "admin", false}, {"valid with underscore", "admin_user", false}, {"valid with dash", "admin-user", false}, {"valid with dot", "admin.user", false}, {"too short", "ab", true}, {"too long", string(make([]byte, 33)), true}, {"empty", "", true}, {"invalid character", "admin@user", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateUsername(tt.input) if (err != nil) != tt.wantErr { t.Errorf("ValidateUsername(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr) } }) } } func TestValidatePassword(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"valid password", "SecurePass123", false}, {"valid with special chars", "Secure!Pass123", false}, {"too short", "Short1", true}, {"no letter", "12345678", true}, {"no number", "SecurePass", true}, {"empty", "", true}, {"too long", string(make([]byte, 129)), true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidatePassword(tt.input) if (err != nil) != tt.wantErr { t.Errorf("ValidatePassword(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr) } }) } } func TestValidateEmail(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"valid email", "user@example.com", false}, {"valid with subdomain", "user@mail.example.com", false}, {"empty (optional)", "", false}, {"invalid format", "notanemail", true}, {"missing @", "user.example.com", true}, {"missing domain", "user@", true}, {"too long", string(make([]byte, 255)), true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateEmail(tt.input) if (err != nil) != tt.wantErr { t.Errorf("ValidateEmail(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr) } }) } } func TestValidateShareName(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"valid share name", "data-share", false}, {"valid with underscore", "data_share", false}, {"reserved name CON", "CON", true}, {"reserved name COM1", "COM1", true}, {"too long", string(make([]byte, 81)), true}, {"empty", "", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateShareName(tt.input) if (err != nil) != tt.wantErr { t.Errorf("ValidateShareName(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr) } }) } } func TestValidateIQN(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"valid IQN", "iqn.2024-12.com.atlas:target1", false}, {"invalid format", "iqn.2024-12", true}, {"missing iqn prefix", "2024-12.com.atlas:target1", true}, {"invalid date format", "iqn.2024-1.com.atlas:target1", true}, {"empty", "", true}, {"too long", string(make([]byte, 224)), true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateIQN(tt.input) if (err != nil) != tt.wantErr { t.Errorf("ValidateIQN(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr) } }) } } func TestValidateSize(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"valid size bytes", "1024", false}, {"valid size KB", "10K", false}, {"valid size MB", "100M", false}, {"valid size GB", "1G", false}, {"valid size TB", "2T", false}, {"lowercase unit", "1g", false}, {"invalid unit", "10X", true}, {"empty", "", true}, {"no number", "G", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateSize(tt.input) if (err != nil) != tt.wantErr { t.Errorf("ValidateSize(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr) } }) } } func TestValidatePath(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"valid absolute path", "/tank/data", false}, {"valid root path", "/", false}, {"empty (optional)", "", false}, {"relative path", "tank/data", true}, {"path traversal", "/tank/../data", true}, {"double slash", "/tank//data", true}, {"too long", "/" + string(make([]byte, 4096)), true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidatePath(tt.input) if (err != nil) != tt.wantErr { t.Errorf("ValidatePath(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr) } }) } } func TestValidateCIDR(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"valid CIDR", "192.168.1.0/24", false}, {"valid IP", "192.168.1.1", false}, {"wildcard", "*", false}, {"valid hostname", "server.example.com", false}, {"invalid format", "not@a@valid@format", true}, {"empty", "", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateCIDR(tt.input) if (err != nil) != tt.wantErr { t.Errorf("ValidateCIDR(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr) } }) } } func TestSanitizeString(t *testing.T) { tests := []struct { name string input string expected string }{ {"normal string", "hello world", "hello world"}, {"with null byte", "hello\x00world", "helloworld"}, {"with control chars", "hello\x01\x02world", "helloworld"}, {"with whitespace", " hello world ", "hello world"}, {"empty", "", ""}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := SanitizeString(tt.input) if result != tt.expected { t.Errorf("SanitizeString(%q) = %q, want %q", tt.input, result, tt.expected) } }) } } func TestSanitizePath(t *testing.T) { tests := []struct { name string input string expected string }{ {"normal path", "/tank/data", "/tank/data"}, {"with backslash", "/tank\\data", "/tank/data"}, {"with double slash", "/tank//data", "/tank/data"}, {"with whitespace", " /tank/data ", "/tank/data"}, {"multiple slashes", "/tank///data", "/tank/data"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := SanitizePath(tt.input) if result != tt.expected { t.Errorf("SanitizePath(%q) = %q, want %q", tt.input, result, tt.expected) } }) } }