Skip to content

Commit 0ba16af

Browse files
ensure uts are parseable
1 parent 286b30a commit 0ba16af

1 file changed

Lines changed: 172 additions & 0 deletions

File tree

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package memberagentarc
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"strings"
7+
"testing"
8+
"text/template"
9+
10+
. "github.com/onsi/gomega"
11+
12+
"sigs.k8s.io/yaml"
13+
)
14+
15+
// TestHelmChartTemplatesRenderValidYAML tests that Helm chart templates render
16+
// to valid YAML with maximal configuration values that activate all conditional paths.
17+
func TestHelmChartTemplatesRenderValidYAML(t *testing.T) {
18+
g := NewWithT(t)
19+
// Maximal configuration to activate all conditional template paths
20+
values := map[string]interface{}{
21+
"memberagent": map[string]interface{}{
22+
"repository": "mcr.microsoft.com/aks/fleet/member-agent",
23+
"tag": "v1.0.0",
24+
},
25+
"mcscontrollermanager": map[string]interface{}{
26+
"repository": "mcr.microsoft.com/aks/fleet/mcs-controller-manager",
27+
"tag": "v1.0.0",
28+
},
29+
"membernetcontrollermanager": map[string]interface{}{
30+
"repository": "mcr.microsoft.com/aks/fleet/member-net-controller-manager",
31+
"tag": "v1.0.0",
32+
},
33+
"refreshtoken": map[string]interface{}{
34+
"repository": "mcr.microsoft.com/aks/fleet/refresh-token",
35+
"tag": "v1.0.0",
36+
},
37+
"crdinstaller": map[string]interface{}{
38+
"enabled": true,
39+
"repository": "mcr.microsoft.com/aks/fleet/crd-installer",
40+
"tag": "v1.0.0",
41+
"logVerbosity": 2,
42+
},
43+
"logVerbosity": 5,
44+
"namespace": "fleet-system",
45+
"config": map[string]interface{}{
46+
"scope": "https://test.scope",
47+
"hubURL": "https://hub.example.com",
48+
"memberClusterName": "test-cluster",
49+
"hubCA": "test-ca-cert",
50+
},
51+
"enableV1Beta1APIs": true,
52+
"enableTrafficManagerFeature": true,
53+
"enableNetworkingFeatures": true,
54+
"propertyProvider": "azure",
55+
"Azure": map[string]interface{}{
56+
"proxySettings": map[string]interface{}{
57+
"isProxyEnabled": true,
58+
"httpProxy": "http://proxy.example.com:8080",
59+
"httpsProxy": "https://proxy.example.com:8443",
60+
"noProxy": "localhost,127.0.0.1",
61+
"proxyCert": "test-proxy-cert",
62+
},
63+
"Identity": map[string]interface{}{
64+
"MSIAdapterYaml": "image: mcr.microsoft.com/aks/msi-adapter:v1.0.0\nresources:\n limits:\n cpu: 100m",
65+
},
66+
"Extension": map[string]interface{}{
67+
"Name": "fleet-member-extension",
68+
},
69+
},
70+
}
71+
72+
// Template context matching Helm's structure
73+
context := map[string]interface{}{
74+
"Values": values,
75+
"Release": map[string]interface{}{
76+
"Name": "test-release",
77+
"Namespace": "fleet-system",
78+
},
79+
"Chart": map[string]interface{}{
80+
"Name": "arc-member-cluster-agents",
81+
"Version": "1.0.0",
82+
},
83+
}
84+
85+
templatesDir := "templates"
86+
entries, err := os.ReadDir(templatesDir)
87+
g.Expect(err).ToNot(HaveOccurred(), "Failed to read templates directory")
88+
89+
validatedCount := 0
90+
for _, entry := range entries {
91+
// Skip directories and helper templates
92+
if entry.IsDir() || strings.HasPrefix(entry.Name(), "_") {
93+
continue
94+
}
95+
96+
templatePath := filepath.Join(templatesDir, entry.Name())
97+
templateBytes, err := os.ReadFile(templatePath)
98+
g.Expect(err).ToNot(HaveOccurred(), "Failed to read template %s", entry.Name())
99+
100+
// Parse and render the Go template
101+
tmpl := template.New(entry.Name()).Funcs(helmFuncMap())
102+
tmpl, err = tmpl.Parse(string(templateBytes))
103+
g.Expect(err).ToNot(HaveOccurred(), "Failed to parse template %s", entry.Name())
104+
105+
var rendered strings.Builder
106+
err = tmpl.Execute(&rendered, context)
107+
g.Expect(err).ToNot(HaveOccurred(), "Failed to render template %s. Err :s", entry.Name(), err)
108+
109+
renderedContent := strings.TrimSpace(rendered.String())
110+
g.Expect(renderedContent).ToNot(BeEmpty(), "Rendered template %s is empty", entry.Name())
111+
112+
// Validate each YAML document in multi-doc files
113+
docs := strings.Split(renderedContent, "\n---\n")
114+
validDocsCount := 0
115+
for i, doc := range docs {
116+
doc = strings.TrimSpace(doc)
117+
if doc == "" {
118+
continue
119+
}
120+
121+
var obj interface{}
122+
err := yaml.Unmarshal([]byte(doc), &obj)
123+
g.Expect(err).ToNot(HaveOccurred(), "Template %s doc %d is invalid YAML: %v\nContent:\n%s",
124+
entry.Name(), i+1, err, doc)
125+
validDocsCount++
126+
}
127+
128+
validatedCount++
129+
}
130+
131+
g.Expect(validatedCount).ToNot(BeZero(), "No templates were validated")
132+
}
133+
134+
// helmFuncMap returns template functions that mimic Helm's template functions
135+
func helmFuncMap() template.FuncMap {
136+
return template.FuncMap{
137+
"nindent": func(spaces int, s string) string {
138+
indent := strings.Repeat(" ", spaces)
139+
lines := strings.Split(s, "\n")
140+
var result []string
141+
for i, line := range lines {
142+
if i == 0 {
143+
result = append(result, "\n"+indent+line)
144+
} else {
145+
result = append(result, indent+line)
146+
}
147+
}
148+
return strings.Join(result, "\n")
149+
},
150+
"quote": func(s interface{}) string {
151+
return `"` + toString(s) + `"`
152+
},
153+
"b64enc": func(s string) string {
154+
// Simple mock - just return the string for testing purposes
155+
return s
156+
},
157+
"include": func(name string, data interface{}) string {
158+
// Simple mock - return empty string for testing
159+
return ""
160+
},
161+
}
162+
}
163+
164+
func toString(v interface{}) string {
165+
if v == nil {
166+
return ""
167+
}
168+
if s, ok := v.(string); ok {
169+
return s
170+
}
171+
return ""
172+
}

0 commit comments

Comments
 (0)