257 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
package app
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"strings"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/roboll/helmfile/helmexec"
 | 
						|
	"github.com/roboll/helmfile/state"
 | 
						|
	"gopkg.in/yaml.v2"
 | 
						|
)
 | 
						|
 | 
						|
func makeRenderer(readFile func(string) ([]byte, error), env string) *twoPassRenderer {
 | 
						|
	return &twoPassRenderer{
 | 
						|
		reader:    readFile,
 | 
						|
		env:       env,
 | 
						|
		namespace: "namespace",
 | 
						|
		filename:  "",
 | 
						|
		logger:    helmexec.NewLogger(os.Stdout, "debug"),
 | 
						|
		abs:       filepath.Abs,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestReadFromYaml_MakeEnvironmentHasNoSideEffects(t *testing.T) {
 | 
						|
 | 
						|
	yamlContent := []byte(`
 | 
						|
environments:
 | 
						|
  staging:
 | 
						|
    values:
 | 
						|
    - default/values.yaml
 | 
						|
  production:
 | 
						|
 | 
						|
releases:
 | 
						|
- name: {{ readFile "other/default/values.yaml" }}
 | 
						|
  chart: mychart1
 | 
						|
`)
 | 
						|
 | 
						|
	fileReaderCalls := 0
 | 
						|
	// make a reader that returns a simulated context
 | 
						|
	fileReader := func(filename string) ([]byte, error) {
 | 
						|
		expectedFilename := filepath.Clean("default/values.yaml")
 | 
						|
		if !strings.HasSuffix(filename, expectedFilename) {
 | 
						|
			return nil, fmt.Errorf("unexpected filename: expected=%s, actual=%s", expectedFilename, filename)
 | 
						|
		}
 | 
						|
		fileReaderCalls++
 | 
						|
		if fileReaderCalls == 2 {
 | 
						|
			return []byte("SecondPass"), nil
 | 
						|
		}
 | 
						|
		return []byte(""), nil
 | 
						|
	}
 | 
						|
 | 
						|
	r := makeRenderer(fileReader, "staging")
 | 
						|
	yamlBuf, err := r.renderTemplate(yamlContent)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("unexpected error: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	var state state.HelmState
 | 
						|
	err = yaml.Unmarshal(yamlBuf.Bytes(), &state)
 | 
						|
 | 
						|
	if fileReaderCalls > 2 {
 | 
						|
		t.Error("reader should be called only twice")
 | 
						|
	}
 | 
						|
 | 
						|
	if state.Releases[0].Name != "SecondPass" {
 | 
						|
		t.Errorf("release name should have ben set as SecondPass")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestReadFromYaml_RenderTemplate(t *testing.T) {
 | 
						|
 | 
						|
	defaultValuesYaml := []byte(`
 | 
						|
releaseName: "hello"
 | 
						|
conditionalReleaseTag: "yes"
 | 
						|
`)
 | 
						|
 | 
						|
	yamlContent := []byte(`
 | 
						|
environments:
 | 
						|
  staging:
 | 
						|
    values:
 | 
						|
    - default/values.yaml
 | 
						|
  production:
 | 
						|
 | 
						|
releases:
 | 
						|
- name: {{ .Environment.Values.releaseName }}
 | 
						|
  chart: mychart1
 | 
						|
 | 
						|
{{ if (eq .Environment.Values.conditionalReleaseTag "yes") }}
 | 
						|
- name: conditionalRelease
 | 
						|
{{ end }}
 | 
						|
 | 
						|
`)
 | 
						|
 | 
						|
	// make a reader that returns a simulated context
 | 
						|
	fileReader := func(filename string) ([]byte, error) {
 | 
						|
		expectedFilename := filepath.Clean("default/values.yaml")
 | 
						|
		if !strings.HasSuffix(filename, expectedFilename) {
 | 
						|
			return nil, fmt.Errorf("unexpected filename: expected=%s, actual=%s", expectedFilename, filename)
 | 
						|
		}
 | 
						|
		return defaultValuesYaml, nil
 | 
						|
	}
 | 
						|
 | 
						|
	r := makeRenderer(fileReader, "staging")
 | 
						|
	// test the double rendering
 | 
						|
	yamlBuf, err := r.renderTemplate(yamlContent)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("unexpected error: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	var state state.HelmState
 | 
						|
	err = yaml.Unmarshal(yamlBuf.Bytes(), &state)
 | 
						|
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("unexpected error: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	if len(state.Releases) != 2 {
 | 
						|
		t.Fatal("there should be 2 releases")
 | 
						|
	}
 | 
						|
 | 
						|
	if state.Releases[0].Name != "hello" {
 | 
						|
		t.Errorf("release name should be hello")
 | 
						|
	}
 | 
						|
 | 
						|
	if state.Releases[1].Name != "conditionalRelease" {
 | 
						|
		t.Error("conditional release should have been present")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestReadFromYaml_RenderTemplateWithValuesReferenceError(t *testing.T) {
 | 
						|
	defaultValuesYaml := []byte("")
 | 
						|
 | 
						|
	yamlContent := []byte(`
 | 
						|
environments:
 | 
						|
  staging:
 | 
						|
    values:
 | 
						|
    - default/values.yaml
 | 
						|
  production:
 | 
						|
 | 
						|
{{ if (eq .Environment.Values.releaseName "a") }} # line 8
 | 
						|
releases:
 | 
						|
- name: a
 | 
						|
	chart: mychart1
 | 
						|
{{ end }}
 | 
						|
`)
 | 
						|
 | 
						|
	// make a reader that returns a simulated context
 | 
						|
	fileReader := func(filename string) ([]byte, error) {
 | 
						|
		return defaultValuesYaml, nil
 | 
						|
	}
 | 
						|
 | 
						|
	r := makeRenderer(fileReader, "staging")
 | 
						|
	// test the double rendering
 | 
						|
	_, err := r.renderTemplate(yamlContent)
 | 
						|
 | 
						|
	if !strings.Contains(err.Error(), "stringTemplate:8") {
 | 
						|
		t.Fatalf("error should contain a stringTemplate error (reference to unknow key) %v", err)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// This test shows that a gotmpl reference will get rendered correctly
 | 
						|
// even if the pre-render disables the readFile and exec functions.
 | 
						|
// This does not apply to .gotmpl files, which is a nice side-effect.
 | 
						|
func TestReadFromYaml_RenderTemplateWithGotmpl(t *testing.T) {
 | 
						|
 | 
						|
	defaultValuesYamlGotmpl := []byte(`
 | 
						|
releaseName: {{ readFile "nonIgnoredFile" }}
 | 
						|
`)
 | 
						|
 | 
						|
	yamlContent := []byte(`
 | 
						|
environments:
 | 
						|
  staging:
 | 
						|
    values:
 | 
						|
    - values.yaml.gotmpl
 | 
						|
  production:
 | 
						|
 | 
						|
{{ if (eq .Environment.Values.releaseName "release-a") }} # line 8
 | 
						|
releases:
 | 
						|
- name: a
 | 
						|
  chart: mychart1
 | 
						|
{{ end }}
 | 
						|
`)
 | 
						|
 | 
						|
	fileReader := func(filename string) ([]byte, error) {
 | 
						|
		if strings.HasSuffix(filename, "nonIgnoredFile") {
 | 
						|
			return []byte("release-a"), nil
 | 
						|
		}
 | 
						|
		return defaultValuesYamlGotmpl, nil
 | 
						|
	}
 | 
						|
 | 
						|
	r := makeRenderer(fileReader, "staging")
 | 
						|
	rendered, _ := r.renderTemplate(yamlContent)
 | 
						|
 | 
						|
	var state state.HelmState
 | 
						|
	yaml.Unmarshal(rendered.Bytes(), &state)
 | 
						|
 | 
						|
	if len(state.Releases) != 1 {
 | 
						|
		t.Fatal("there should be 1 release")
 | 
						|
	}
 | 
						|
 | 
						|
	if state.Releases[0].Name != "a" {
 | 
						|
		t.Fatal("release should have been declared")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestReadFromYaml_RenderTemplateWithNamespace(t *testing.T) {
 | 
						|
	defaultValuesYaml := []byte(``)
 | 
						|
	yamlContent := []byte(`releases:
 | 
						|
- name: {{ .Namespace }}-myrelease
 | 
						|
  chart: mychart
 | 
						|
`)
 | 
						|
 | 
						|
	// make a reader that returns a simulated context
 | 
						|
	fileReader := func(filename string) ([]byte, error) {
 | 
						|
		return defaultValuesYaml, nil
 | 
						|
	}
 | 
						|
 | 
						|
	r := makeRenderer(fileReader, "staging")
 | 
						|
	yamlBuf, err := r.renderTemplate(yamlContent)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("unexpected error: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	var state state.HelmState
 | 
						|
	err = yaml.Unmarshal(yamlBuf.Bytes(), &state)
 | 
						|
 | 
						|
	if state.Releases[0].Name != "namespace-myrelease" {
 | 
						|
		t.Errorf("release name should be namespace-myrelease")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestReadFromYaml_HelfileShouldBeResilentToTemplateErrors(t *testing.T) {
 | 
						|
	yamlContent := []byte(`environments:
 | 
						|
  staging:
 | 
						|
	production:
 | 
						|
 | 
						|
releases:
 | 
						|
{{ if (eq .Environment.Name "production" }}  # notice syntax error: unclosed left paren
 | 
						|
- name: prod-myrelease
 | 
						|
{{ else }}
 | 
						|
- name: myapp
 | 
						|
{{ end }}
 | 
						|
  chart: mychart
 | 
						|
`)
 | 
						|
	fileReader := func(filename string) ([]byte, error) {
 | 
						|
		return yamlContent, nil
 | 
						|
	}
 | 
						|
 | 
						|
	r := makeRenderer(fileReader, "staging")
 | 
						|
	_, err := r.renderTemplate(yamlContent)
 | 
						|
	if err == nil {
 | 
						|
		t.Fatalf("wanted error, none returned")
 | 
						|
	}
 | 
						|
}
 |