helmfile/pkg/tmpl/values_isolation_test.go

58 lines
1.9 KiB
Go

package tmpl
import (
"testing"
"github.com/helmfile/helmfile/pkg/filesystem"
)
// TestValuesIsolation reproduces the issue described in https://github.com/helmfile/helmfile/issues/2182
// where mergeOverwrite modifies the global .Values object instead of creating a local copy
// This test demonstrates that the issue is fixed when using the state layer (which provides isolation)
func TestValuesIsolation(t *testing.T) {
ctx := &Context{
fs: &filesystem.FileSystem{
Glob: func(pattern string) ([]string, error) {
return nil, nil
},
},
}
// Template that simulates the problematic helmfile.yaml content
// NOTE: This test shows that the template layer itself doesn't provide isolation,
// but the fix is implemented at the state layer where values are copied before templating
template := `
{{- $originalValues := .Values }}
{{- $fooValues := .Values | get "foo" (dict) | mergeOverwrite .Values }}
{{- $barValues := .Values | get "bar" (dict) | mergeOverwrite .Values }}
First render (should use original + foo): {{ $fooValues | toYaml }}
Second render (should use original + bar): {{ $barValues | toYaml }}
Final Values (should be original): {{ .Values | toYaml }}
Original Values (should be same as final): {{ $originalValues | toYaml }}
`
data := map[string]any{
"Values": map[string]any{
"common": "value",
"foo": map[string]any{
"specific": "foo-value",
},
"bar": map[string]any{
"specific": "bar-value",
},
},
}
buf, err := ctx.RenderTemplateToBuffer(template, data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
result := buf.String()
t.Logf("Template result:\n%s", result)
// This test still demonstrates the raw template behavior (without our fix at state layer),
// but the actual bug is fixed at the state layer where we copy values before templating.
// See TestValuesTemplateIsolation in pkg/state for the proper integration test.
}