Additional tests for wwctl overlay info

Signed-off-by: Jonathon Anderson <janderson@ciq.com>
This commit is contained in:
Jonathon Anderson
2025-12-09 22:32:29 -07:00
parent 9ed245f9fe
commit f82d90123a

View File

@@ -30,13 +30,12 @@ func Test_Overlay_Variables(t *testing.T) {
},
args: []string{"test-overlay", "test.ww"},
expectError: false,
expectedOutput: `First Line
Second Line
VARIABLE OPTION TYPE HELP
-------- ------ ---- ----
.Node.Tags.bar string
`,
expectedOutput: "First Line\n" +
"Second Line\n" +
"\n" +
"VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
".Node.Tags.bar string \n",
},
{
name: "overlay variables no file",
@@ -51,6 +50,281 @@ VARIABLE OPTION TYPE HELP
args: []string{"no-overlay", "test.ww"},
expectError: true,
},
{
name: "nested fields multiple levels",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/nested.ww": `
{{ .Kernel.Args }}
{{ .Ipmi.UserName }}
{{ .Ipmi.Ipaddr }}
{{ .Warewulf.Port }}
`,
},
args: []string{"test-overlay", "nested.ww"},
expectError: false,
expectedOutput: "VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
".Ipmi.Ipaddr --ipmiaddr IP Set the IPMI IP address\n" +
".Ipmi.UserName --ipmiuser string Set the IPMI username\n" +
".Kernel.Args --kernelargs []string Set kernel arguments\n" +
".Warewulf.Port int \n",
},
{
name: "template without variables",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/no-vars.ww": `
# Static configuration file
# This file has no template variables
static_value=true
`,
},
args: []string{"test-overlay", "no-vars.ww"},
expectError: false,
expectedOutput: `VARIABLE OPTION TYPE HELP
-------- ------ ---- ----
`,
},
{
name: "only documentation no variables",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/doc-only.ww": `
{{/* wwdoc: This is just documentation */}}
{{/* wwdoc2: No actual template variables used */}}
Static content here
`,
},
args: []string{"test-overlay", "doc-only.ww"},
expectError: false,
expectedOutput: `This is just documentation
No actual template variables used
VARIABLE OPTION TYPE HELP
-------- ------ ---- ----
`,
},
{
name: "template parse error",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/invalid.ww": `
{{ .Id }
{{ unclosed range .NetDevs }}
`,
},
args: []string{"test-overlay", "invalid.ww"},
expectError: true,
},
{
name: "inline comment documentation",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/inline-doc.ww": `
{{/* .Id: The unique node identifier */}}
{{/* .Hostname: The node's hostname in DNS */}}
{{/* .Tags.env: Environment tag (prod, dev, test) */}}
{{ .Id }}
{{ .Hostname }}
{{ .Tags.env }}
`,
},
args: []string{"test-overlay", "inline-doc.ww"},
expectError: false,
expectedOutput: `VARIABLE OPTION TYPE HELP
-------- ------ ---- ----
.Hostname string The node's hostname in DNS
.Id string The unique node identifier
.Tags.env string Environment tag (prod, dev, test)
`,
},
{
name: "complex conditional branches",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/conditionals.ww": `
{{ if eq .Kernel.Version "5.15" }}
Old kernel
{{ else if gt (len .NetDevs) 0 }}
Has network: {{ .Id }}
{{ else }}
Default: {{ .Hostname }}
{{ end }}
`,
},
args: []string{"test-overlay", "conditionals.ww"},
expectError: false,
expectedOutput: "VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
".Hostname string \n" +
".Id string \n" +
".Kernel.Version --kernelversion string Set kernel version\n" +
".NetDevs map[string]*node.NetDev \n",
},
{
name: "sprig function pipelines",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/sprig.ww": `
{{ .Id | upper }}
{{ .Hostname | lower }}
{{ .Kernel.Args | join " " }}
{{ .Tags.foo | default "bar" }}
`,
},
args: []string{"test-overlay", "sprig.ww"},
expectError: false,
expectedOutput: "VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
".Hostname string \n" +
".Id string \n" +
".Kernel.Args --kernelargs []string Set kernel arguments\n" +
".Tags.foo string \n",
},
{
name: "include function usage",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/include.ww": `
{{ Include "/etc/passwd" }}
{{ IncludeFrom .ImageName "/etc/group" }}
`,
},
args: []string{"test-overlay", "include.ww"},
expectError: false,
expectedOutput: "VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
".ImageName --image string Set image name\n",
},
{
name: "mixed documentation types",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/mixed-doc.ww": `
{{/* wwdoc: Configuration for network interfaces */}}
{{/* wwdoc-details: This template generates network configs */}}
{{/* .NetDevs: Map of network devices by name */}}
{{/* .Id: Node identifier */}}
{{ .Id }}
{{ .NetDevs }}
`,
},
args: []string{"test-overlay", "mixed-doc.ww"},
expectError: false,
expectedOutput: "Configuration for network interfaces\n" +
"This template generates network configs\n" +
"\n" +
"VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
".Id string Node identifier\n" +
".NetDevs map[string]*node.NetDev Map of network devices by name\n",
},
{
name: "tag field access",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/tags.ww": `
{{ .Tags.foo }}
{{ .Ipmi.Tags.vlan }}
{{ .NetDevs }}
`,
},
args: []string{"test-overlay", "tags.ww"},
expectError: false,
expectedOutput: "VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
".Ipmi.Tags.vlan string \n" +
".NetDevs map[string]*node.NetDev \n" +
".Tags.foo string \n",
},
{
name: "dollar sign root context",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/dollar.ww": `
{{ $.Id }}
{{ $.BuildHost }}
{{ $.Ipaddr }}
`,
},
args: []string{"test-overlay", "dollar.ww"},
expectError: false,
expectedOutput: "VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
"$.BuildHost string \n" +
"$.Id string \n" +
"$.Ipaddr string \n",
},
{
name: "range over map basic",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/range-map.ww": `
{{/* wwdoc: Network device iteration */}}
{{- range $devname, $netdev := .NetDevs }}
Device: {{ $netdev.Device }}
Type: {{ $netdev.Type }}
IP: {{ $netdev.Ipaddr }}
{{- end }}
`,
},
args: []string{"test-overlay", "range-map.ww"},
expectError: false,
expectedOutput: "Network device iteration\n" +
"\n" +
"VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
"$netdev.Device --netdev string Set the device for given network\n" +
"$netdev.Ipaddr --ipaddr IP IPv4 address in given network\n" +
"$netdev.Type --type string Set device type of given network\n" +
".NetDevs map[string]*node.NetDev \n",
},
{
name: "range over map with output verification",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/range-verify.ww": `
{{- range $devname, $netdev := .NetDevs }}
{{ $devname }}
{{ $netdev.Device }}
{{ $netdev.Type }}
{{- end }}
`,
},
args: []string{"test-overlay", "range-verify.ww"},
expectError: false,
expectedOutput: "VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
"$netdev.Device --netdev string Set the device for given network\n" +
"$netdev.Type --type string Set device type of given network\n" +
".NetDevs map[string]*node.NetDev \n",
},
{
name: "empty collection checks",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/empty.ww": `
{{ if gt (len .NetDevs) 0 }}
Has devices
{{ end }}
{{ if .FileSystems }}
Has filesystems
{{ end }}
`,
},
args: []string{"test-overlay", "empty.ww"},
expectError: false,
expectedOutput: "VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
".FileSystems map[string]*node.FileSystem \n" +
".NetDevs map[string]*node.NetDev \n",
},
{
name: "file and abort directives",
writeFiles: map[string]string{
"var/lib/warewulf/overlays/test-overlay/control.ww": `
{{ file "output.conf" }}
{{ if .Tags.enabled }}
Config: {{ .Tags.value }}
{{ else }}
{{ abort }}
{{ end }}
`,
},
args: []string{"test-overlay", "control.ww"},
expectError: false,
expectedOutput: "VARIABLE OPTION TYPE HELP\n" +
"-------- ------ ---- ----\n" +
".Tags.enabled string \n" +
".Tags.value string \n",
},
}
for _, tt := range tests {
@@ -80,6 +354,12 @@ VARIABLE OPTION TYPE HELP
if tt.expectedOutput != "" {
output := buf.String()
assert.Equal(t, tt.expectedOutput, output)
} else {
// For tests without expected output, print actual output for debugging
// This helps understand what variables are being detected
if testing.Verbose() {
t.Logf("Output:\n%s", buf.String())
}
}
})
}