Skip to content

Commit 2fe6c49

Browse files
committed
addressed review comments
1 parent f0b3d3e commit 2fe6c49

16 files changed

Lines changed: 229 additions & 248 deletions

internal/config/config.go

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func parseYAMLTemplate(data []byte) (*ImageTemplate, error) {
9999
}
100100

101101
// Validate against image template schema
102-
if err := validate.ValidateImageJSON(jsonData); err != nil {
102+
if err := validate.ValidateImageTemplateJSON(jsonData); err != nil {
103103
return nil, fmt.Errorf("template validation error: %w", err)
104104
}
105105

@@ -109,36 +109,9 @@ func parseYAMLTemplate(data []byte) (*ImageTemplate, error) {
109109
return nil, fmt.Errorf("parsing template: %w", err)
110110
}
111111

112-
// Validate template has required content
113-
if err := validateTemplateContent(&template); err != nil {
114-
return nil, fmt.Errorf("template content validation: %w", err)
115-
}
116-
117112
return &template, nil
118113
}
119114

120-
// validateTemplateContent validates the template has required content
121-
func validateTemplateContent(template *ImageTemplate) error {
122-
if len(template.SystemConfigs) == 0 {
123-
return fmt.Errorf("no system configurations found in template")
124-
}
125-
126-
// Validate supported OS combinations
127-
validCombinations := map[string]map[string]bool{
128-
"azure-linux": {"azl3": true},
129-
"emt": {"emt3": true},
130-
"elxr": {"elxr12": true},
131-
}
132-
133-
if validDists, ok := validCombinations[template.Target.OS]; !ok {
134-
return fmt.Errorf("unsupported OS: %s", template.Target.OS)
135-
} else if !validDists[template.Target.Dist] {
136-
return fmt.Errorf("unsupported distribution %s for OS %s", template.Target.Dist, template.Target.OS)
137-
}
138-
139-
return nil
140-
}
141-
142115
// GetProviderName returns the provider name for the given template
143116
func (t *ImageTemplate) GetProviderName() string {
144117
// Map OS/dist combinations to provider names
@@ -197,7 +170,7 @@ func DefaultGlobalConfig() *GlobalConfig {
197170
Workers: 8,
198171
CacheDir: "./cache",
199172
WorkDir: "./workspace",
200-
TempDir: "",
173+
TempDir: "./tmp",
201174

202175
Logging: LoggingConfig{
203176
Level: "info",

internal/config/config_test.go

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -158,56 +158,51 @@ func TestUnsupportedFileFormat(t *testing.T) {
158158
}
159159

160160
func TestUnsupportedDistribution(t *testing.T) {
161-
template := &ImageTemplate{
162-
Target: struct {
163-
OS string `yaml:"os"`
164-
Dist string `yaml:"dist"`
165-
Arch string `yaml:"arch"`
166-
ImageType string `yaml:"imageType"`
167-
}{
168-
OS: "unknown-os",
169-
Dist: "unknown-dist",
170-
Arch: "x86_64",
171-
ImageType: "iso",
172-
},
173-
SystemConfigs: []SystemConfig{
174-
{
175-
Name: "test-config",
176-
Description: "Test configuration",
177-
Packages: []string{"package1"},
178-
Kernel: KernelConfig{
179-
Version: "6.12",
180-
Cmdline: "quiet",
181-
},
182-
},
183-
},
184-
}
161+
// This test verifies that schema validation catches invalid OS/dist combinations
185162

186-
err := validateTemplateContent(template)
163+
invalidYaml := `image:
164+
name: test
165+
version: "1.0.0"
166+
target:
167+
os: azure-linux
168+
dist: emt3 # Invalid: azure-linux should only use azl3
169+
arch: x86_64
170+
imageType: raw
171+
systemConfigs:
172+
- name: test
173+
packages: ["test"]
174+
kernel:
175+
version: "6.12"
176+
`
177+
178+
// This should fail during schema validation
179+
_, err := parseYAMLTemplate([]byte(invalidYaml))
187180
if err == nil {
188-
t.Errorf("expected error for unsupported OS")
181+
t.Errorf("expected schema validation error for invalid OS/dist combination")
182+
}
183+
if !strings.Contains(err.Error(), "template validation error") {
184+
t.Errorf("expected schema validation error, got: %v", err)
189185
}
190186
}
191187

192188
func TestEmptySystemConfigs(t *testing.T) {
193-
template := &ImageTemplate{
194-
Target: struct {
195-
OS string `yaml:"os"`
196-
Dist string `yaml:"dist"`
197-
Arch string `yaml:"arch"`
198-
ImageType string `yaml:"imageType"`
199-
}{
200-
OS: "azure-linux",
201-
Dist: "azl3",
202-
Arch: "x86_64",
203-
ImageType: "iso",
204-
},
205-
SystemConfigs: []SystemConfig{}, // Empty
206-
}
189+
// This test verifies that schema validation catches empty systemConfigs
207190

208-
err := validateTemplateContent(template)
191+
invalidYaml := `image:
192+
name: test
193+
version: "1.0.0"
194+
target:
195+
os: azure-linux
196+
dist: azl3
197+
arch: x86_64
198+
imageType: raw
199+
systemConfigs: [] # Invalid: minItems is 1
200+
`
201+
202+
// This should fail during schema validation
203+
_, err := parseYAMLTemplate([]byte(invalidYaml))
209204
if err == nil {
210-
t.Errorf("expected error for empty system configurations")
205+
t.Errorf("expected schema validation error for empty systemConfigs")
211206
}
212207
}
213208

@@ -256,11 +251,5 @@ func TestAllSupportedProviders(t *testing.T) {
256251
if version != tc.version {
257252
t.Errorf("for %s/%s expected version '%s', got '%s'", tc.os, tc.dist, tc.version, version)
258253
}
259-
260-
// Test validation
261-
err := validateTemplateContent(template)
262-
if err != nil {
263-
t.Errorf("validation failed for %s/%s: %v", tc.os, tc.dist, err)
264-
}
265254
}
266255
}

internal/validate/validate.go

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,11 @@ func ValidateAgainstSchema(name string, schemaBytes, data []byte) error {
3333
return nil
3434
}
3535

36-
// ValidateComposerJSON runs the composer schema against data
37-
func ValidateComposerJSON(data []byte) error {
38-
return ValidateAgainstSchema(
39-
"os-image-composer.schema.json",
40-
schema_pkg.ComposerSchema,
41-
data,
42-
)
43-
}
44-
45-
// ValidateTemplateJSON runs the template schema against data
46-
func ValidateImageJSON(data []byte) error {
36+
// ValidateImageTemplateJSON runs the template schema against data
37+
func ValidateImageTemplateJSON(data []byte) error {
4738
return ValidateAgainstSchema(
4839
"os-image-template.schema.json",
49-
schema_pkg.ImageSchema,
40+
schema_pkg.ImageTemplateSchema,
5041
data,
5142
)
5243
}

internal/validate/validate_test.go

Lines changed: 73 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,6 @@ func loadFile(t *testing.T, relPath string) []byte {
2222
return data
2323
}
2424

25-
// Test legacy JSON composer format (for backward compatibility)
26-
func TestValidComposerJSON(t *testing.T) {
27-
v := loadFile(t, "testdata/valid.json")
28-
if err := ValidateComposerJSON(v); err != nil {
29-
t.Errorf("expected valid.json to pass, but got: %v", err)
30-
}
31-
}
32-
33-
func TestInvalidComposerJSON(t *testing.T) {
34-
v := loadFile(t, "testdata/invalid.json")
35-
if err := ValidateComposerJSON(v); err == nil {
36-
t.Errorf("expected invalid.json to fail validation")
37-
}
38-
}
39-
4025
// Test new YAML image template format
4126
func TestValidImageTemplate(t *testing.T) {
4227
v := loadFile(t, "image-templates/azl3-x86_64-edge-raw.yml")
@@ -54,7 +39,7 @@ func TestValidImageTemplate(t *testing.T) {
5439
t.Errorf("json marshaling error: %v", err)
5540
return
5641
}
57-
if err := ValidateImageJSON(dataJSON); err != nil {
42+
if err := ValidateImageTemplateJSON(dataJSON); err != nil {
5843
t.Errorf("expected image-templates/azl3-x86_64-edge-raw.yml to pass, but got: %v", err)
5944
}
6045
}
@@ -76,7 +61,7 @@ func TestInvalidImageTemplate(t *testing.T) {
7661
return
7762
}
7863

79-
if err := ValidateImageJSON(dataJSON); err == nil {
64+
if err := ValidateImageTemplateJSON(dataJSON); err == nil {
8065
t.Errorf("expected testdata/invalid-image.yml to pass, but got: %v", err)
8166
}
8267
}
@@ -117,36 +102,15 @@ func TestInvalidConfig(t *testing.T) {
117102

118103
if err := ValidateConfigJSON(dataJSON); err == nil {
119104
t.Errorf("expected invalid-config.json to fail validation: %v", err)
120-
} else {
121-
t.Logf("expected validation error: %v", err)
122105
}
123106
}
124107

125-
// Test validation of template structure
108+
// Test validation of template structure using external test files
126109
func TestImageTemplateStructure(t *testing.T) {
127-
// Test a minimal valid template
128-
minimalTemplate := `image:
129-
name: test-image
130-
version: "1.0.0"
131-
132-
target:
133-
os: azure-linux
134-
dist: azl3
135-
arch: x86_64
136-
imageType: raw
137-
138-
systemConfigs:
139-
- name: minimal
140-
description: Minimal test configuration
141-
packages:
142-
- openssh-server
143-
kernel:
144-
version: "6.12"
145-
cmdline: "quiet"
146-
`
110+
v := loadFile(t, "testdata/complete-valid-template.yml")
147111

148112
var raw interface{}
149-
if err := yaml.Unmarshal([]byte(minimalTemplate), &raw); err != nil {
113+
if err := yaml.Unmarshal(v, &raw); err != nil {
150114
t.Fatalf("failed to parse minimal template: %v", err)
151115
}
152116

@@ -155,29 +119,16 @@ systemConfigs:
155119
t.Fatalf("failed to marshal to JSON: %v", err)
156120
}
157121

158-
if err := ValidateImageJSON(dataJSON); err != nil {
122+
if err := ValidateImageTemplateJSON(dataJSON); err != nil {
159123
t.Errorf("minimal template should be valid, but got: %v", err)
160124
}
161125
}
162126

163127
func TestImageTemplateMissingFields(t *testing.T) {
164-
// Test template missing required fields
165-
invalidTemplate := `image:
166-
name: test-image
167-
168-
target:
169-
os: azure-linux
170-
dist: azl3
171-
arch: x86_64
172-
173-
systemConfigs:
174-
- name: incomplete
175-
packages:
176-
- openssh-server
177-
`
128+
v := loadFile(t, "testdata/incomplete-template.yml")
178129

179130
var raw interface{}
180-
if err := yaml.Unmarshal([]byte(invalidTemplate), &raw); err != nil {
131+
if err := yaml.Unmarshal(v, &raw); err != nil {
181132
t.Fatalf("failed to parse invalid template: %v", err)
182133
}
183134

@@ -186,7 +137,71 @@ systemConfigs:
186137
t.Fatalf("failed to marshal to JSON: %v", err)
187138
}
188139

189-
if err := ValidateImageJSON(dataJSON); err == nil {
140+
if err := ValidateImageTemplateJSON(dataJSON); err == nil {
190141
t.Errorf("incomplete template should fail validation")
191142
}
192143
}
144+
145+
// Table-driven test for multiple template validation scenarios
146+
func TestImageTemplateValidation(t *testing.T) {
147+
tests := []struct {
148+
name string
149+
file string
150+
shouldPass bool
151+
description string
152+
}{
153+
{
154+
name: "ValidComplete",
155+
file: "testdata/complete-valid-template.yml",
156+
shouldPass: true,
157+
description: "complete template with all optional fields",
158+
},
159+
{
160+
name: "InvalidMissingImage",
161+
file: "testdata/missing-image-section.yml",
162+
shouldPass: false,
163+
description: "template missing image section",
164+
},
165+
{
166+
name: "InvalidMissingTarget",
167+
file: "testdata/missing-target-section.yml",
168+
shouldPass: false,
169+
description: "template missing target section",
170+
},
171+
{
172+
name: "InvalidMissingSystemConfigs",
173+
file: "testdata/missing-systemconfigs.yml",
174+
shouldPass: false,
175+
description: "template missing systemConfigs section",
176+
},
177+
{
178+
name: "InvalidWrongTypes",
179+
file: "testdata/wrong-field-types.yml",
180+
shouldPass: false,
181+
description: "template with incorrect field types",
182+
},
183+
}
184+
185+
for _, tt := range tests {
186+
t.Run(tt.name, func(t *testing.T) {
187+
v := loadFile(t, tt.file)
188+
189+
var raw interface{}
190+
if err := yaml.Unmarshal(v, &raw); err != nil {
191+
t.Fatalf("failed to parse template %s: %v", tt.file, err)
192+
}
193+
194+
dataJSON, err := json.Marshal(raw)
195+
if err != nil {
196+
t.Fatalf("failed to marshal to JSON: %v", err)
197+
}
198+
199+
err = ValidateImageTemplateJSON(dataJSON)
200+
if tt.shouldPass && err != nil {
201+
t.Errorf("expected %s to pass validation (%s), but got error: %v", tt.file, tt.description, err)
202+
} else if !tt.shouldPass && err == nil {
203+
t.Errorf("expected %s to fail validation (%s), but it passed", tt.file, tt.description)
204+
}
205+
})
206+
}
207+
}

schema/embed.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ package schema
22

33
import _ "embed"
44

5-
//go:embed os-image-composer.schema.json
6-
var ComposerSchema []byte
7-
85
//go:embed os-image-template.schema.json
9-
var ImageSchema []byte
6+
var ImageTemplateSchema []byte
107

118
//go:embed os-image-composer-config.schema.json
129
var ConfigSchema []byte

0 commit comments

Comments
 (0)