mirror of
https://github.com/helm/helm.git
synced 2026-03-22 02:20:42 -04:00
This provides support for "global" variables. It does this by declaring "global" to be a special namespace. It then copies this namespace into every subchart, coalescing it into any "global" namespace found there. The net result is that if "global.foo" is set in the YAML file, it will be available to every chart/subchart as ".global.foo" regardless of where that chart is in the subchart tree.
264 lines
5.7 KiB
Go
264 lines
5.7 KiB
Go
package chartutil
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"testing"
|
|
"text/template"
|
|
|
|
"k8s.io/helm/pkg/proto/hapi/chart"
|
|
)
|
|
|
|
func TestReadValues(t *testing.T) {
|
|
doc := `# Test YAML parse
|
|
poet: "Coleridge"
|
|
title: "Rime of the Ancient Mariner"
|
|
stanza:
|
|
- "at"
|
|
- "length"
|
|
- "did"
|
|
- cross
|
|
- an
|
|
- Albatross
|
|
|
|
mariner:
|
|
with: "crossbow"
|
|
shot: "ALBATROSS"
|
|
|
|
water:
|
|
water:
|
|
where: "everywhere"
|
|
nor: "any drop to drink"
|
|
`
|
|
|
|
data, err := ReadValues([]byte(doc))
|
|
if err != nil {
|
|
t.Fatalf("Error parsing bytes: %s", err)
|
|
}
|
|
matchValues(t, data)
|
|
}
|
|
|
|
func TestReadValuesFile(t *testing.T) {
|
|
data, err := ReadValuesFile("./testdata/coleridge.yaml")
|
|
if err != nil {
|
|
t.Fatalf("Error reading YAML file: %s", err)
|
|
}
|
|
matchValues(t, data)
|
|
}
|
|
|
|
func ExampleValues() {
|
|
doc := `
|
|
title: "Moby Dick"
|
|
chapter:
|
|
one:
|
|
title: "Loomings"
|
|
two:
|
|
title: "The Carpet-Bag"
|
|
three:
|
|
title: "The Spouter Inn"
|
|
`
|
|
d, err := ReadValues([]byte(doc))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
ch1, err := d.Table("chapter.one")
|
|
if err != nil {
|
|
panic("could not find chapter one")
|
|
}
|
|
fmt.Print(ch1["title"])
|
|
// Output:
|
|
// Loomings
|
|
}
|
|
|
|
func TestTable(t *testing.T) {
|
|
doc := `
|
|
title: "Moby Dick"
|
|
chapter:
|
|
one:
|
|
title: "Loomings"
|
|
two:
|
|
title: "The Carpet-Bag"
|
|
three:
|
|
title: "The Spouter Inn"
|
|
`
|
|
d, err := ReadValues([]byte(doc))
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse the White Whale: %s", err)
|
|
}
|
|
|
|
if _, err := d.Table("title"); err == nil {
|
|
t.Fatalf("Title is not a table.")
|
|
}
|
|
|
|
if _, err := d.Table("chapter"); err != nil {
|
|
t.Fatalf("Failed to get the chapter table: %s\n%v", err, d)
|
|
}
|
|
|
|
if v, err := d.Table("chapter.one"); err != nil {
|
|
t.Errorf("Failed to get chapter.one: %s", err)
|
|
} else if v["title"] != "Loomings" {
|
|
t.Errorf("Unexpected title: %s", v["title"])
|
|
}
|
|
|
|
if _, err := d.Table("chapter.three"); err != nil {
|
|
t.Errorf("Chapter three is missing: %s\n%v", err, d)
|
|
}
|
|
|
|
if _, err := d.Table("chapter.OneHundredThirtySix"); err == nil {
|
|
t.Errorf("I think you mean 'Epilogue'")
|
|
}
|
|
}
|
|
|
|
func matchValues(t *testing.T, data map[string]interface{}) {
|
|
if data["poet"] != "Coleridge" {
|
|
t.Errorf("Unexpected poet: %s", data["poet"])
|
|
}
|
|
|
|
if o, err := ttpl("{{len .stanza}}", data); err != nil {
|
|
t.Errorf("len stanza: %s", err)
|
|
} else if o != "6" {
|
|
t.Errorf("Expected 6, got %s", o)
|
|
}
|
|
|
|
if o, err := ttpl("{{.mariner.shot}}", data); err != nil {
|
|
t.Errorf(".mariner.shot: %s", err)
|
|
} else if o != "ALBATROSS" {
|
|
t.Errorf("Expected that mariner shot ALBATROSS")
|
|
}
|
|
|
|
if o, err := ttpl("{{.water.water.where}}", data); err != nil {
|
|
t.Errorf(".water.water.where: %s", err)
|
|
} else if o != "everywhere" {
|
|
t.Errorf("Expected water water everywhere")
|
|
}
|
|
}
|
|
|
|
func ttpl(tpl string, v map[string]interface{}) (string, error) {
|
|
var b bytes.Buffer
|
|
tt := template.Must(template.New("t").Parse(tpl))
|
|
if err := tt.Execute(&b, v); err != nil {
|
|
return "", err
|
|
}
|
|
return b.String(), nil
|
|
}
|
|
|
|
var testCoalesceValuesYaml = `
|
|
top: yup
|
|
|
|
global:
|
|
name: Ishmael
|
|
subject: Queequeg
|
|
|
|
pequod:
|
|
global:
|
|
name: Stinky
|
|
harpooner: Tashtego
|
|
ahab:
|
|
scope: whale
|
|
`
|
|
|
|
func TestCoalesceValues(t *testing.T) {
|
|
tchart := "testdata/moby"
|
|
overrides := map[string]interface{}{
|
|
"override": "good",
|
|
}
|
|
c, err := LoadDir(tchart)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
tvals := &chart.Config{Raw: testCoalesceValuesYaml}
|
|
|
|
v, err := CoalesceValues(c, tvals, overrides)
|
|
j, _ := json.MarshalIndent(v, "", " ")
|
|
t.Logf("Coalesced Values: %s", string(j))
|
|
|
|
tests := []struct {
|
|
tpl string
|
|
expect string
|
|
}{
|
|
{"{{.top}}", "yup"},
|
|
{"{{.override}}", "good"},
|
|
{"{{.name}}", "moby"},
|
|
{"{{.global.name}}", "Ishmael"},
|
|
{"{{.global.subject}}", "Queequeg"},
|
|
{"{{.global.harpooner}}", "<no value>"},
|
|
{"{{.pequod.name}}", "pequod"},
|
|
{"{{.pequod.ahab.name}}", "ahab"},
|
|
{"{{.pequod.ahab.scope}}", "whale"},
|
|
{"{{.pequod.ahab.global.name}}", "Ishmael"},
|
|
{"{{.pequod.ahab.global.subject}}", "Queequeg"},
|
|
{"{{.pequod.ahab.global.harpooner}}", "Tashtego"},
|
|
{"{{.pequod.global.name}}", "Ishmael"},
|
|
{"{{.pequod.global.subject}}", "Queequeg"},
|
|
{"{{.spouter.global.name}}", "Ishmael"},
|
|
{"{{.spouter.global.harpooner}}", "<no value>"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
if o, err := ttpl(tt.tpl, v); err != nil || o != tt.expect {
|
|
t.Errorf("Expected %q to expand to %q, got %q", tt.tpl, tt.expect, o)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCoalesceTables(t *testing.T) {
|
|
dst := map[string]interface{}{
|
|
"name": "Ishmael",
|
|
"address": map[string]interface{}{
|
|
"street": "123 Spouter Inn Ct.",
|
|
"city": "Nantucket",
|
|
},
|
|
"details": map[string]interface{}{
|
|
"friends": []string{"Tashtego"},
|
|
},
|
|
"boat": "pequod",
|
|
}
|
|
src := map[string]interface{}{
|
|
"occupation": "whaler",
|
|
"address": map[string]interface{}{
|
|
"state": "MA",
|
|
"street": "234 Spouter Inn Ct.",
|
|
},
|
|
"details": "empty",
|
|
"boat": map[string]interface{}{
|
|
"mast": true,
|
|
},
|
|
}
|
|
coalesceTables(dst, src)
|
|
|
|
if dst["name"] != "Ishmael" {
|
|
t.Errorf("Unexpected name: %s", dst["name"])
|
|
}
|
|
if dst["occupation"] != "whaler" {
|
|
t.Errorf("Unexpected occupation: %s", dst["occupation"])
|
|
}
|
|
|
|
addr, ok := dst["address"].(map[string]interface{})
|
|
if !ok {
|
|
t.Fatal("Address went away.")
|
|
}
|
|
|
|
if addr["street"].(string) != "234 Spouter Inn Ct." {
|
|
t.Errorf("Unexpected address: %v", addr["street"])
|
|
}
|
|
|
|
if addr["city"].(string) != "Nantucket" {
|
|
t.Errorf("Unexpected city: %v", addr["city"])
|
|
}
|
|
|
|
if addr["state"].(string) != "MA" {
|
|
t.Errorf("Unexpected state: %v", addr["state"])
|
|
}
|
|
|
|
if det, ok := dst["details"].(map[string]interface{}); !ok {
|
|
t.Fatalf("Details is the wrong type: %v", dst["details"])
|
|
} else if _, ok := det["friends"]; !ok {
|
|
t.Error("Could not find your friends. Maybe you don't have any. :-(")
|
|
}
|
|
|
|
if dst["boat"].(string) != "pequod" {
|
|
t.Errorf("Expected boat string, got %v", dst["boat"])
|
|
}
|
|
}
|