| 
									
										
										
										
											2016-06-23 02:28:45 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2018-08-25 03:03:55 +08:00
										 |  |  | Copyright The Helm Authors. | 
					
						
							| 
									
										
										
										
											2016-06-23 02:28:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  | you may not use this file except in compliance with the License. | 
					
						
							|  |  |  | You may obtain a copy of the License at | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  | distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  | See the License for the specific language governing permissions and | 
					
						
							|  |  |  | limitations under the License. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | package engine | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | 	"sync" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-04 02:27:05 +08:00
										 |  |  | 	"helm.sh/helm/v3/pkg/chart" | 
					
						
							|  |  |  | 	"helm.sh/helm/v3/pkg/chartutil" | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-27 07:06:41 +08:00
										 |  |  | func TestSortTemplates(t *testing.T) { | 
					
						
							|  |  |  | 	tpls := map[string]renderable{ | 
					
						
							|  |  |  | 		"/mychart/templates/foo.tpl":                                 {}, | 
					
						
							|  |  |  | 		"/mychart/templates/charts/foo/charts/bar/templates/foo.tpl": {}, | 
					
						
							|  |  |  | 		"/mychart/templates/bar.tpl":                                 {}, | 
					
						
							|  |  |  | 		"/mychart/templates/charts/foo/templates/bar.tpl":            {}, | 
					
						
							|  |  |  | 		"/mychart/templates/_foo.tpl":                                {}, | 
					
						
							|  |  |  | 		"/mychart/templates/charts/foo/templates/foo.tpl":            {}, | 
					
						
							|  |  |  | 		"/mychart/templates/charts/bar/templates/foo.tpl":            {}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	got := sortTemplates(tpls) | 
					
						
							|  |  |  | 	if len(got) != len(tpls) { | 
					
						
							|  |  |  | 		t.Fatal("Sorted results are missing templates") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expect := []string{ | 
					
						
							|  |  |  | 		"/mychart/templates/charts/foo/charts/bar/templates/foo.tpl", | 
					
						
							|  |  |  | 		"/mychart/templates/charts/foo/templates/foo.tpl", | 
					
						
							|  |  |  | 		"/mychart/templates/charts/foo/templates/bar.tpl", | 
					
						
							|  |  |  | 		"/mychart/templates/charts/bar/templates/foo.tpl", | 
					
						
							|  |  |  | 		"/mychart/templates/foo.tpl", | 
					
						
							|  |  |  | 		"/mychart/templates/bar.tpl", | 
					
						
							|  |  |  | 		"/mychart/templates/_foo.tpl", | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for i, e := range expect { | 
					
						
							|  |  |  | 		if got[i] != e { | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 			t.Fatalf("\n\tExp:\n%s\n\tGot:\n%s", | 
					
						
							|  |  |  | 				strings.Join(expect, "\n"), | 
					
						
							|  |  |  | 				strings.Join(got, "\n"), | 
					
						
							|  |  |  | 			) | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-15 06:28:43 +08:00
										 |  |  | func TestFuncMap(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	fns := funcMap() | 
					
						
							| 
									
										
										
										
											2016-10-15 06:28:43 +08:00
										 |  |  | 	forbidden := []string{"env", "expandenv"} | 
					
						
							|  |  |  | 	for _, f := range forbidden { | 
					
						
							|  |  |  | 		if _, ok := fns[f]; ok { | 
					
						
							|  |  |  | 			t.Errorf("Forbidden function %s exists in FuncMap.", f) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Test for Engine-specific template functions.
 | 
					
						
							| 
									
										
										
										
											2020-04-23 00:09:34 +08:00
										 |  |  | 	expect := []string{"include", "required", "tpl", "toYaml", "fromYaml", "toToml", "toJson", "fromJson", "lookup"} | 
					
						
							| 
									
										
										
										
											2016-10-15 06:28:43 +08:00
										 |  |  | 	for _, f := range expect { | 
					
						
							|  |  |  | 		if _, ok := fns[f]; !ok { | 
					
						
							|  |  |  | 			t.Errorf("Expected add-on function %q", f) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | func TestRender(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-05-05 07:27:00 +08:00
										 |  |  | 	c := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{ | 
					
						
							|  |  |  | 			Name:    "moby", | 
					
						
							|  |  |  | 			Version: "1.2.3", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 			{Name: "templates/test1", Data: []byte("{{.Values.outer | title }} {{.Values.inner | title}}")}, | 
					
						
							|  |  |  | 			{Name: "templates/test2", Data: []byte("{{.Values.global.callme | lower }}")}, | 
					
						
							| 
									
										
										
										
											2016-10-22 07:12:41 +08:00
										 |  |  | 			{Name: "templates/test3", Data: []byte("{{.noValue}}")}, | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 			{Name: "templates/test4", Data: []byte("{{toJson .Values}}")}, | 
					
						
							| 
									
										
										
										
											2016-05-05 07:27:00 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-08-30 00:56:19 +08:00
										 |  |  | 		Values: map[string]interface{}{"outer": "DEFAULT", "inner": "DEFAULT"}, | 
					
						
							| 
									
										
										
										
											2016-05-05 07:27:00 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-05 07:57:24 +08:00
										 |  |  | 	vals := map[string]interface{}{ | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 		"Values": map[string]interface{}{ | 
					
						
							|  |  |  | 			"outer": "spouter", | 
					
						
							|  |  |  | 			"inner": "inn", | 
					
						
							|  |  |  | 			"global": map[string]interface{}{ | 
					
						
							|  |  |  | 				"callme": "Ishmael", | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2018-12-05 07:57:24 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-05-05 07:27:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-22 05:55:35 +08:00
										 |  |  | 	v, err := chartutil.CoalesceValues(c, vals) | 
					
						
							| 
									
										
										
										
											2016-06-14 03:11:39 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("Failed to coalesce values: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	out, err := Render(c, v) | 
					
						
							| 
									
										
										
										
											2016-05-05 07:27:00 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("Failed to render templates: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	expect := map[string]string{ | 
					
						
							|  |  |  | 		"moby/templates/test1": "Spouter Inn", | 
					
						
							|  |  |  | 		"moby/templates/test2": "ishmael", | 
					
						
							|  |  |  | 		"moby/templates/test3": "", | 
					
						
							|  |  |  | 		"moby/templates/test4": `{"global":{"callme":"Ishmael"},"inner":"inn","outer":"spouter"}`, | 
					
						
							| 
									
										
										
										
											2016-06-25 06:25:43 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-15 01:10:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	for name, data := range expect { | 
					
						
							|  |  |  | 		if out[name] != data { | 
					
						
							|  |  |  | 			t.Errorf("Expected %q, got %q", data, out[name]) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-10 02:09:00 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-22 03:16:55 +08:00
										 |  |  | func TestRenderRefsOrdering(t *testing.T) { | 
					
						
							|  |  |  | 	parentChart := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{ | 
					
						
							|  |  |  | 			Name:    "parent", | 
					
						
							|  |  |  | 			Version: "1.2.3", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		Templates: []*chart.File{ | 
					
						
							|  |  |  | 			{Name: "templates/_helpers.tpl", Data: []byte(`{{- define "test" -}}parent value{{- end -}}`)}, | 
					
						
							|  |  |  | 			{Name: "templates/test.yaml", Data: []byte(`{{ tpl "{{ include \"test\" . }}" . }}`)}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	childChart := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{ | 
					
						
							|  |  |  | 			Name:    "child", | 
					
						
							|  |  |  | 			Version: "1.2.3", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		Templates: []*chart.File{ | 
					
						
							|  |  |  | 			{Name: "templates/_helpers.tpl", Data: []byte(`{{- define "test" -}}child value{{- end -}}`)}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	parentChart.AddDependency(childChart) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expect := map[string]string{ | 
					
						
							|  |  |  | 		"parent/templates/test.yaml": "parent value", | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < 100; i++ { | 
					
						
							|  |  |  | 		out, err := Render(parentChart, chartutil.Values{}) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Failed to render templates: %s", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for name, data := range expect { | 
					
						
							|  |  |  | 			if out[name] != data { | 
					
						
							| 
									
										
										
										
											2021-03-16 09:11:57 +08:00
										 |  |  | 				t.Fatalf("Expected %q, got %q (iteration %d)", data, out[name], i+1) | 
					
						
							| 
									
										
										
										
											2020-04-22 03:16:55 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | func TestRenderInternals(t *testing.T) { | 
					
						
							|  |  |  | 	// Test the internals of the rendering tool.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 	vals := chartutil.Values{"Name": "one", "Value": "two"} | 
					
						
							|  |  |  | 	tpls := map[string]renderable{ | 
					
						
							|  |  |  | 		"one": {tpl: `Hello {{title .Name}}`, vals: vals}, | 
					
						
							|  |  |  | 		"two": {tpl: `Goodbye {{upper .Value}}`, vals: vals}, | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | 		// Test whether a template can reliably reference another template
 | 
					
						
							|  |  |  | 		// without regard for ordering.
 | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 		"three": {tpl: `{{template "two" dict "Value" "three"}}`, vals: vals}, | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	out, err := new(Engine).render(tpls) | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("Failed template rendering: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(out) != 3 { | 
					
						
							|  |  |  | 		t.Fatalf("Expected 3 templates, got %d", len(out)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if out["one"] != "Hello One" { | 
					
						
							|  |  |  | 		t.Errorf("Expected 'Hello One', got %q", out["one"]) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if out["two"] != "Goodbye TWO" { | 
					
						
							|  |  |  | 		t.Errorf("Expected 'Goodbye TWO'. got %q", out["two"]) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if out["three"] != "Goodbye THREE" { | 
					
						
							|  |  |  | 		t.Errorf("Expected 'Goodbye THREE'. got %q", out["two"]) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestParallelRenderInternals(t *testing.T) { | 
					
						
							|  |  |  | 	// Make sure that we can use one Engine to run parallel template renders.
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	e := new(Engine) | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | 	var wg sync.WaitGroup | 
					
						
							|  |  |  | 	for i := 0; i < 20; i++ { | 
					
						
							|  |  |  | 		wg.Add(1) | 
					
						
							|  |  |  | 		go func(i int) { | 
					
						
							|  |  |  | 			tt := fmt.Sprintf("expect-%d", i) | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 			tpls := map[string]renderable{ | 
					
						
							|  |  |  | 				"t": { | 
					
						
							|  |  |  | 					tpl:  `{{.val}}`, | 
					
						
							|  |  |  | 					vals: map[string]interface{}{"val": tt}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-03-03 13:09:03 +08:00
										 |  |  | 			out, err := e.render(tpls) | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				t.Errorf("Failed to render %s: %s", tt, err) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 			if out["t"] != tt { | 
					
						
							|  |  |  | 				t.Errorf("Expected %q, got %q", tt, out["t"]) | 
					
						
							| 
									
										
										
										
											2016-04-13 06:18:42 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			wg.Done() | 
					
						
							|  |  |  | 		}(i) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	wg.Wait() | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-24 00:33:03 +08:00
										 |  |  | func TestParseErrors(t *testing.T) { | 
					
						
							|  |  |  | 	vals := chartutil.Values{"Values": map[string]interface{}{}} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tplsUndefinedFunction := map[string]renderable{ | 
					
						
							|  |  |  | 		"undefined_function": {tpl: `{{foo}}`, vals: vals}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, err := new(Engine).render(tplsUndefinedFunction) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatalf("Expected failures while rendering: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expected := `parse error at (undefined_function:1): function "foo" not defined` | 
					
						
							|  |  |  | 	if err.Error() != expected { | 
					
						
							|  |  |  | 		t.Errorf("Expected '%s', got %q", expected, err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestExecErrors(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2019-04-09 05:45:29 +08:00
										 |  |  | 	vals := chartutil.Values{"Values": map[string]interface{}{}} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tplsMissingRequired := map[string]renderable{ | 
					
						
							|  |  |  | 		"missing_required": {tpl: `{{required "foo is required" .Values.foo}}`, vals: vals}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, err := new(Engine).render(tplsMissingRequired) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatalf("Expected failures while rendering: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-07-24 00:33:03 +08:00
										 |  |  | 	expected := `execution error at (missing_required:1:2): foo is required` | 
					
						
							| 
									
										
										
										
											2019-04-09 05:45:29 +08:00
										 |  |  | 	if err.Error() != expected { | 
					
						
							|  |  |  | 		t.Errorf("Expected '%s', got %q", expected, err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-24 00:33:03 +08:00
										 |  |  | 	tplsMissingRequired = map[string]renderable{ | 
					
						
							|  |  |  | 		"missing_required_with_colons": {tpl: `{{required ":this: message: has many: colons:" .Values.foo}}`, vals: vals}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, err = new(Engine).render(tplsMissingRequired) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatalf("Expected failures while rendering: %s", err) | 
					
						
							| 
									
										
										
										
											2019-04-09 05:45:29 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-07-24 00:33:03 +08:00
										 |  |  | 	expected = `execution error at (missing_required_with_colons:1:2): :this: message: has many: colons:` | 
					
						
							|  |  |  | 	if err.Error() != expected { | 
					
						
							|  |  |  | 		t.Errorf("Expected '%s', got %q", expected, err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	issue6044tpl := `{{ $someEmptyValue := "" }} | 
					
						
							|  |  |  | {{ $myvar := "abc" }} | 
					
						
							|  |  |  | {{- required (printf "%s: something is missing" $myvar) $someEmptyValue | repeat 0 }}` | 
					
						
							|  |  |  | 	tplsMissingRequired = map[string]renderable{ | 
					
						
							|  |  |  | 		"issue6044": {tpl: issue6044tpl, vals: vals}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, err = new(Engine).render(tplsMissingRequired) | 
					
						
							| 
									
										
										
										
											2019-04-09 05:45:29 +08:00
										 |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatalf("Expected failures while rendering: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-07-24 00:33:03 +08:00
										 |  |  | 	expected = `execution error at (issue6044:3:4): abc: something is missing` | 
					
						
							| 
									
										
										
										
											2019-04-09 05:45:29 +08:00
										 |  |  | 	if err.Error() != expected { | 
					
						
							|  |  |  | 		t.Errorf("Expected '%s', got %q", expected, err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-07-24 00:33:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-18 17:45:45 +08:00
										 |  |  | func TestFailErrors(t *testing.T) { | 
					
						
							|  |  |  | 	vals := chartutil.Values{"Values": map[string]interface{}{}} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 02:23:17 +08:00
										 |  |  | 	failtpl := `All your base are belong to us{{ fail "This is an error" }}` | 
					
						
							| 
									
										
										
										
											2020-11-18 17:45:45 +08:00
										 |  |  | 	tplsFailed := map[string]renderable{ | 
					
						
							|  |  |  | 		"failtpl": {tpl: failtpl, vals: vals}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, err := new(Engine).render(tplsFailed) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatalf("Expected failures while rendering: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-12-07 22:58:30 +08:00
										 |  |  | 	expected := `execution error at (failtpl:1:33): This is an error` | 
					
						
							| 
									
										
										
										
											2020-11-18 17:45:45 +08:00
										 |  |  | 	if err.Error() != expected { | 
					
						
							|  |  |  | 		t.Errorf("Expected '%s', got %q", expected, err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-12-03 02:23:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var e Engine | 
					
						
							|  |  |  | 	e.LintMode = true | 
					
						
							|  |  |  | 	out, err := e.render(tplsFailed) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectStr := "All your base are belong to us" | 
					
						
							|  |  |  | 	if gotStr := out["failtpl"]; gotStr != expectStr { | 
					
						
							|  |  |  | 		t.Errorf("Expected %q, got %q (%v)", expectStr, gotStr, out) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-18 17:45:45 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | func TestAllTemplates(t *testing.T) { | 
					
						
							|  |  |  | 	ch1 := &chart.Chart{ | 
					
						
							| 
									
										
										
										
											2016-06-29 01:57:47 +08:00
										 |  |  | 		Metadata: &chart.Metadata{Name: "ch1"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2016-10-22 07:12:41 +08:00
										 |  |  | 			{Name: "templates/foo", Data: []byte("foo")}, | 
					
						
							|  |  |  | 			{Name: "templates/bar", Data: []byte("bar")}, | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	dep1 := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "laboratory mice"}, | 
					
						
							|  |  |  | 		Templates: []*chart.File{ | 
					
						
							|  |  |  | 			{Name: "templates/pinky", Data: []byte("pinky")}, | 
					
						
							|  |  |  | 			{Name: "templates/brain", Data: []byte("brain")}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ch1.AddDependency(dep1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dep2 := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "same thing we do every night"}, | 
					
						
							|  |  |  | 		Templates: []*chart.File{ | 
					
						
							|  |  |  | 			{Name: "templates/innermost", Data: []byte("innermost")}, | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	dep1.AddDependency(dep2) | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	tpls := allTemplates(ch1, chartutil.Values{}) | 
					
						
							| 
									
										
										
										
											2016-04-22 05:52:16 +08:00
										 |  |  | 	if len(tpls) != 5 { | 
					
						
							|  |  |  | 		t.Errorf("Expected 5 charts, got %d", len(tpls)) | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-24 02:06:52 +08:00
										 |  |  | func TestChartValuesContainsIsRoot(t *testing.T) { | 
					
						
							|  |  |  | 	ch1 := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "parent"}, | 
					
						
							|  |  |  | 		Templates: []*chart.File{ | 
					
						
							|  |  |  | 			{Name: "templates/isroot", Data: []byte("{{.Chart.IsRoot}}")}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	dep1 := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "child"}, | 
					
						
							|  |  |  | 		Templates: []*chart.File{ | 
					
						
							|  |  |  | 			{Name: "templates/isroot", Data: []byte("{{.Chart.IsRoot}}")}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ch1.AddDependency(dep1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	out, err := Render(ch1, chartutil.Values{}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to render templates: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expects := map[string]string{ | 
					
						
							|  |  |  | 		"parent/charts/child/templates/isroot": "false", | 
					
						
							|  |  |  | 		"parent/templates/isroot":              "true", | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for file, expect := range expects { | 
					
						
							|  |  |  | 		if out[file] != expect { | 
					
						
							|  |  |  | 			t.Errorf("Expected %q, got %q", expect, out[file]) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | func TestRenderDependency(t *testing.T) { | 
					
						
							|  |  |  | 	deptpl := `{{define "myblock"}}World{{end}}` | 
					
						
							|  |  |  | 	toptpl := `Hello {{template "myblock"}}` | 
					
						
							|  |  |  | 	ch := &chart.Chart{ | 
					
						
							| 
									
										
										
										
											2016-07-07 05:31:12 +08:00
										 |  |  | 		Metadata: &chart.Metadata{Name: "outerchart"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2016-10-22 07:12:41 +08:00
										 |  |  | 			{Name: "templates/outer", Data: []byte(toptpl)}, | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	ch.AddDependency(&chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "innerchart"}, | 
					
						
							|  |  |  | 		Templates: []*chart.File{ | 
					
						
							|  |  |  | 			{Name: "templates/inner", Data: []byte(deptpl)}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	out, err := Render(ch, map[string]interface{}{}) | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to render chart: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(out) != 2 { | 
					
						
							|  |  |  | 		t.Errorf("Expected 2, got %d", len(out)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expect := "Hello World" | 
					
						
							| 
									
										
										
										
											2016-10-22 07:12:41 +08:00
										 |  |  | 	if out["outerchart/templates/outer"] != expect { | 
					
						
							| 
									
										
										
										
											2016-04-22 04:50:16 +08:00
										 |  |  | 		t.Errorf("Expected %q, got %q", expect, out["outer"]) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestRenderNestedValues(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-07-07 05:31:12 +08:00
										 |  |  | 	innerpath := "templates/inner.tpl" | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 	outerpath := "templates/outer.tpl" | 
					
						
							| 
									
										
										
										
											2016-07-07 05:31:12 +08:00
										 |  |  | 	// Ensure namespacing rules are working.
 | 
					
						
							|  |  |  | 	deepestpath := "templates/inner.tpl" | 
					
						
							|  |  |  | 	checkrelease := "templates/release.tpl" | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	deepest := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "deepest"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2016-06-23 11:24:34 +08:00
										 |  |  | 			{Name: deepestpath, Data: []byte(`And this same {{.Values.what}} that smiles {{.Values.global.when}}`)}, | 
					
						
							| 
									
										
										
										
											2016-06-24 06:06:53 +08:00
										 |  |  | 			{Name: checkrelease, Data: []byte(`Tomorrow will be {{default "happy" .Release.Name }}`)}, | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-08-30 00:56:19 +08:00
										 |  |  | 		Values: map[string]interface{}{"what": "milkshake"}, | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	inner := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "herrick"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2016-06-23 11:24:34 +08:00
										 |  |  | 			{Name: innerpath, Data: []byte(`Old {{.Values.who}} is still a-flyin'`)}, | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-08-30 00:56:19 +08:00
										 |  |  | 		Values: map[string]interface{}{"who": "Robert"}, | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	inner.AddDependency(deepest) | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	outer := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "top"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2016-06-23 11:24:34 +08:00
										 |  |  | 			{Name: outerpath, Data: []byte(`Gather ye {{.Values.what}} while ye may`)}, | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-08-30 00:56:19 +08:00
										 |  |  | 		Values: map[string]interface{}{ | 
					
						
							|  |  |  | 			"what": "stinkweed", | 
					
						
							|  |  |  | 			"who":  "me", | 
					
						
							|  |  |  | 			"herrick": map[string]interface{}{ | 
					
						
							|  |  |  | 				"who": "time", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	outer.AddDependency(inner) | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-05 07:57:24 +08:00
										 |  |  | 	injValues := map[string]interface{}{ | 
					
						
							|  |  |  | 		"what": "rosebuds", | 
					
						
							|  |  |  | 		"herrick": map[string]interface{}{ | 
					
						
							|  |  |  | 			"deepest": map[string]interface{}{ | 
					
						
							|  |  |  | 				"what": "flower", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		"global": map[string]interface{}{ | 
					
						
							|  |  |  | 			"when": "to-day", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-20 15:13:19 +08:00
										 |  |  | 	tmp, err := chartutil.CoalesceValues(outer, injValues) | 
					
						
							| 
									
										
										
										
											2016-06-14 03:11:39 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("Failed to coalesce values: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-23 11:24:34 +08:00
										 |  |  | 	inject := chartutil.Values{ | 
					
						
							|  |  |  | 		"Values": tmp, | 
					
						
							|  |  |  | 		"Chart":  outer.Metadata, | 
					
						
							|  |  |  | 		"Release": chartutil.Values{ | 
					
						
							| 
									
										
										
										
											2016-06-24 06:06:53 +08:00
										 |  |  | 			"Name": "dyin", | 
					
						
							| 
									
										
										
										
											2016-06-23 11:24:34 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-14 03:11:39 +08:00
										 |  |  | 	t.Logf("Calculated values: %v", inject) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	out, err := Render(outer, inject) | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to render templates: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 00:13:34 +08:00
										 |  |  | 	fullouterpath := "top/" + outerpath | 
					
						
							|  |  |  | 	if out[fullouterpath] != "Gather ye rosebuds while ye may" { | 
					
						
							|  |  |  | 		t.Errorf("Unexpected outer: %q", out[fullouterpath]) | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 00:13:34 +08:00
										 |  |  | 	fullinnerpath := "top/charts/herrick/" + innerpath | 
					
						
							|  |  |  | 	if out[fullinnerpath] != "Old time is still a-flyin'" { | 
					
						
							|  |  |  | 		t.Errorf("Unexpected inner: %q", out[fullinnerpath]) | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 00:13:34 +08:00
										 |  |  | 	fulldeepestpath := "top/charts/herrick/charts/deepest/" + deepestpath | 
					
						
							|  |  |  | 	if out[fulldeepestpath] != "And this same flower that smiles to-day" { | 
					
						
							|  |  |  | 		t.Errorf("Unexpected deepest: %q", out[fulldeepestpath]) | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-24 06:06:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 00:13:34 +08:00
										 |  |  | 	fullcheckrelease := "top/charts/herrick/charts/deepest/" + checkrelease | 
					
						
							|  |  |  | 	if out[fullcheckrelease] != "Tomorrow will be dyin" { | 
					
						
							|  |  |  | 		t.Errorf("Unexpected release: %q", out[fullcheckrelease]) | 
					
						
							| 
									
										
										
										
											2016-06-24 06:06:53 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-22 06:45:42 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-06-29 01:57:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestRenderBuiltinValues(t *testing.T) { | 
					
						
							|  |  |  | 	inner := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "Latium"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2016-10-22 07:12:41 +08:00
										 |  |  | 			{Name: "templates/Lavinia", Data: []byte(`{{.Template.Name}}{{.Chart.Name}}{{.Release.Name}}`)}, | 
					
						
							|  |  |  | 			{Name: "templates/From", Data: []byte(`{{.Files.author | printf "%s"}} {{.Files.Get "book/title.txt"}}`)}, | 
					
						
							| 
									
										
										
										
											2016-06-29 01:57:47 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Files: []*chart.File{ | 
					
						
							|  |  |  | 			{Name: "author", Data: []byte("Virgil")}, | 
					
						
							|  |  |  | 			{Name: "book/title.txt", Data: []byte("Aeneid")}, | 
					
						
							| 
									
										
										
										
											2016-07-28 02:04:11 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-06-29 01:57:47 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	outer := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "Troy"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2016-10-22 07:12:41 +08:00
										 |  |  | 			{Name: "templates/Aeneas", Data: []byte(`{{.Template.Name}}{{.Chart.Name}}{{.Release.Name}}`)}, | 
					
						
							| 
									
										
										
										
											2016-06-29 01:57:47 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	outer.AddDependency(inner) | 
					
						
							| 
									
										
										
										
											2016-06-29 01:57:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	inject := chartutil.Values{ | 
					
						
							| 
									
										
										
										
											2018-04-20 15:13:19 +08:00
										 |  |  | 		"Values": "", | 
					
						
							| 
									
										
										
										
											2016-06-29 01:57:47 +08:00
										 |  |  | 		"Chart":  outer.Metadata, | 
					
						
							|  |  |  | 		"Release": chartutil.Values{ | 
					
						
							|  |  |  | 			"Name": "Aeneid", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Logf("Calculated values: %v", outer) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	out, err := Render(outer, inject) | 
					
						
							| 
									
										
										
										
											2016-06-29 01:57:47 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to render templates: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expects := map[string]string{ | 
					
						
							| 
									
										
										
										
											2016-10-22 07:12:41 +08:00
										 |  |  | 		"Troy/charts/Latium/templates/Lavinia": "Troy/charts/Latium/templates/LaviniaLatiumAeneid", | 
					
						
							|  |  |  | 		"Troy/templates/Aeneas":                "Troy/templates/AeneasTroyAeneid", | 
					
						
							|  |  |  | 		"Troy/charts/Latium/templates/From":    "Virgil Aeneid", | 
					
						
							| 
									
										
										
										
											2016-06-29 01:57:47 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for file, expect := range expects { | 
					
						
							|  |  |  | 		if out[file] != expect { | 
					
						
							|  |  |  | 			t.Errorf("Expected %q, got %q", expect, out[file]) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-07-30 07:06:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | func TestAlterFuncMap_include(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-07-30 07:06:09 +08:00
										 |  |  | 	c := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "conrad"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2016-10-22 07:12:41 +08:00
										 |  |  | 			{Name: "templates/quote", Data: []byte(`{{include "conrad/templates/_partial" . | indent 2}} dead.`)}, | 
					
						
							|  |  |  | 			{Name: "templates/_partial", Data: []byte(`{{.Release.Name}} - he`)}, | 
					
						
							| 
									
										
										
										
											2016-07-30 07:06:09 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 22:57:51 +08:00
										 |  |  | 	// Check nested reference in include FuncMap
 | 
					
						
							|  |  |  | 	d := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "nested"}, | 
					
						
							|  |  |  | 		Templates: []*chart.File{ | 
					
						
							|  |  |  | 			{Name: "templates/quote", Data: []byte(`{{include "nested/templates/quote" . | indent 2}} dead.`)}, | 
					
						
							|  |  |  | 			{Name: "templates/_partial", Data: []byte(`{{.Release.Name}} - he`)}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-30 07:06:09 +08:00
										 |  |  | 	v := chartutil.Values{ | 
					
						
							| 
									
										
										
										
											2018-04-20 15:13:19 +08:00
										 |  |  | 		"Values": "", | 
					
						
							| 
									
										
										
										
											2016-07-30 07:06:09 +08:00
										 |  |  | 		"Chart":  c.Metadata, | 
					
						
							|  |  |  | 		"Release": chartutil.Values{ | 
					
						
							|  |  |  | 			"Name": "Mistah Kurtz", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	out, err := Render(c, v) | 
					
						
							| 
									
										
										
										
											2016-07-30 07:06:09 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expect := "  Mistah Kurtz - he dead." | 
					
						
							| 
									
										
										
										
											2016-10-22 07:12:41 +08:00
										 |  |  | 	if got := out["conrad/templates/quote"]; got != expect { | 
					
						
							| 
									
										
										
										
											2016-07-30 07:06:09 +08:00
										 |  |  | 		t.Errorf("Expected %q, got %q (%v)", expect, got, out) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-12-02 22:57:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	_, err = Render(d, v) | 
					
						
							|  |  |  | 	expectErrName := "nested/templates/quote" | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Errorf("Expected err of nested reference name: %v", expectErrName) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-02 23:37:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | func TestAlterFuncMap_require(t *testing.T) { | 
					
						
							|  |  |  | 	c := &chart.Chart{ | 
					
						
							| 
									
										
										
										
											2017-03-02 23:37:14 +08:00
										 |  |  | 		Metadata: &chart.Metadata{Name: "conan"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2017-03-02 23:37:14 +08:00
										 |  |  | 			{Name: "templates/quote", Data: []byte(`All your base are belong to {{ required "A valid 'who' is required" .Values.who }}`)}, | 
					
						
							|  |  |  | 			{Name: "templates/bases", Data: []byte(`All {{ required "A valid 'bases' is required" .Values.bases }} of them!`)}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	v := chartutil.Values{ | 
					
						
							| 
									
										
										
										
											2017-03-02 23:37:14 +08:00
										 |  |  | 		"Values": chartutil.Values{ | 
					
						
							|  |  |  | 			"who":   "us", | 
					
						
							|  |  |  | 			"bases": 2, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 		"Chart": c.Metadata, | 
					
						
							| 
									
										
										
										
											2017-03-02 23:37:14 +08:00
										 |  |  | 		"Release": chartutil.Values{ | 
					
						
							|  |  |  | 			"Name": "That 90s meme", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	out, err := Render(c, v) | 
					
						
							| 
									
										
										
										
											2017-03-02 23:37:14 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectStr := "All your base are belong to us" | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	if gotStr := out["conan/templates/quote"]; gotStr != expectStr { | 
					
						
							|  |  |  | 		t.Errorf("Expected %q, got %q (%v)", expectStr, gotStr, out) | 
					
						
							| 
									
										
										
										
											2017-03-02 23:37:14 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	expectNum := "All 2 of them!" | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	if gotNum := out["conan/templates/bases"]; gotNum != expectNum { | 
					
						
							|  |  |  | 		t.Errorf("Expected %q, got %q (%v)", expectNum, gotNum, out) | 
					
						
							| 
									
										
										
										
											2017-03-02 23:37:14 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-06-14 01:52:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// test required without passing in needed values with lint mode on
 | 
					
						
							|  |  |  | 	// verifies lint replaces required with an empty string (should not fail)
 | 
					
						
							|  |  |  | 	lintValues := chartutil.Values{ | 
					
						
							|  |  |  | 		"Values": chartutil.Values{ | 
					
						
							|  |  |  | 			"who": "us", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		"Chart": c.Metadata, | 
					
						
							|  |  |  | 		"Release": chartutil.Values{ | 
					
						
							|  |  |  | 			"Name": "That 90s meme", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var e Engine | 
					
						
							|  |  |  | 	e.LintMode = true | 
					
						
							|  |  |  | 	out, err = e.Render(c, lintValues) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectStr = "All your base are belong to us" | 
					
						
							|  |  |  | 	if gotStr := out["conan/templates/quote"]; gotStr != expectStr { | 
					
						
							|  |  |  | 		t.Errorf("Expected %q, got %q (%v)", expectStr, gotStr, out) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expectNum = "All  of them!" | 
					
						
							|  |  |  | 	if gotNum := out["conan/templates/bases"]; gotNum != expectNum { | 
					
						
							|  |  |  | 		t.Errorf("Expected %q, got %q (%v)", expectNum, gotNum, out) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-02 23:37:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | func TestAlterFuncMap_tpl(t *testing.T) { | 
					
						
							|  |  |  | 	c := &chart.Chart{ | 
					
						
							| 
									
										
										
										
											2017-04-29 00:21:42 +08:00
										 |  |  | 		Metadata: &chart.Metadata{Name: "TplFunction"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2017-04-29 00:21:42 +08:00
										 |  |  | 			{Name: "templates/base", Data: []byte(`Evaluate tpl {{tpl "Value: {{ .Values.value}}" .}}`)}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	v := chartutil.Values{ | 
					
						
							| 
									
										
										
										
											2017-04-29 00:21:42 +08:00
										 |  |  | 		"Values": chartutil.Values{ | 
					
						
							|  |  |  | 			"value": "myvalue", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 		"Chart": c.Metadata, | 
					
						
							| 
									
										
										
										
											2017-04-29 00:21:42 +08:00
										 |  |  | 		"Release": chartutil.Values{ | 
					
						
							|  |  |  | 			"Name": "TestRelease", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	out, err := Render(c, v) | 
					
						
							| 
									
										
										
										
											2017-04-29 00:21:42 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	expect := "Evaluate tpl Value: myvalue" | 
					
						
							|  |  |  | 	if got := out["TplFunction/templates/base"]; got != expect { | 
					
						
							|  |  |  | 		t.Errorf("Expected %q, got %q (%v)", expect, got, out) | 
					
						
							| 
									
										
										
										
											2017-04-29 00:21:42 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-04-29 00:21:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | func TestAlterFuncMap_tplfunc(t *testing.T) { | 
					
						
							|  |  |  | 	c := &chart.Chart{ | 
					
						
							| 
									
										
										
										
											2017-05-02 15:41:58 +08:00
										 |  |  | 		Metadata: &chart.Metadata{Name: "TplFunction"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2017-05-02 15:41:58 +08:00
										 |  |  | 			{Name: "templates/base", Data: []byte(`Evaluate tpl {{tpl "Value: {{ .Values.value | quote}}" .}}`)}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	v := chartutil.Values{ | 
					
						
							| 
									
										
										
										
											2017-05-02 15:41:58 +08:00
										 |  |  | 		"Values": chartutil.Values{ | 
					
						
							|  |  |  | 			"value": "myvalue", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 		"Chart": c.Metadata, | 
					
						
							| 
									
										
										
										
											2017-05-02 15:41:58 +08:00
										 |  |  | 		"Release": chartutil.Values{ | 
					
						
							|  |  |  | 			"Name": "TestRelease", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	out, err := Render(c, v) | 
					
						
							| 
									
										
										
										
											2017-05-02 15:41:58 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	expect := "Evaluate tpl Value: \"myvalue\"" | 
					
						
							|  |  |  | 	if got := out["TplFunction/templates/base"]; got != expect { | 
					
						
							|  |  |  | 		t.Errorf("Expected %q, got %q (%v)", expect, got, out) | 
					
						
							| 
									
										
										
										
											2017-05-02 15:41:58 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-05-02 15:41:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | func TestAlterFuncMap_tplinclude(t *testing.T) { | 
					
						
							|  |  |  | 	c := &chart.Chart{ | 
					
						
							| 
									
										
										
										
											2017-05-28 16:55:15 +08:00
										 |  |  | 		Metadata: &chart.Metadata{Name: "TplFunction"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:28:50 +08:00
										 |  |  | 		Templates: []*chart.File{ | 
					
						
							| 
									
										
										
										
											2017-05-28 16:55:15 +08:00
										 |  |  | 			{Name: "templates/base", Data: []byte(`{{ tpl "{{include ` + "`" + `TplFunction/templates/_partial` + "`" + ` .  | quote }}" .}}`)}, | 
					
						
							| 
									
										
										
										
											2017-12-04 00:39:34 +08:00
										 |  |  | 			{Name: "templates/_partial", Data: []byte(`{{.Template.Name}}`)}, | 
					
						
							| 
									
										
										
										
											2017-05-28 16:55:15 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	v := chartutil.Values{ | 
					
						
							| 
									
										
										
										
											2017-05-28 16:55:15 +08:00
										 |  |  | 		"Values": chartutil.Values{ | 
					
						
							|  |  |  | 			"value": "myvalue", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 		"Chart": c.Metadata, | 
					
						
							| 
									
										
										
										
											2017-05-28 16:55:15 +08:00
										 |  |  | 		"Release": chartutil.Values{ | 
					
						
							|  |  |  | 			"Name": "TestRelease", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 07:45:52 +08:00
										 |  |  | 	out, err := Render(c, v) | 
					
						
							| 
									
										
										
										
											2017-05-28 16:55:15 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-25 02:28:29 +08:00
										 |  |  | 	expect := "\"TplFunction/templates/base\"" | 
					
						
							|  |  |  | 	if got := out["TplFunction/templates/base"]; got != expect { | 
					
						
							|  |  |  | 		t.Errorf("Expected %q, got %q (%v)", expect, got, out) | 
					
						
							| 
									
										
										
										
											2017-05-28 16:55:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-30 07:06:09 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-02-11 01:25:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestRenderRecursionLimit(t *testing.T) { | 
					
						
							|  |  |  | 	// endless recursion should produce an error
 | 
					
						
							|  |  |  | 	c := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "bad"}, | 
					
						
							|  |  |  | 		Templates: []*chart.File{ | 
					
						
							|  |  |  | 			{Name: "templates/base", Data: []byte(`{{include "recursion" . }}`)}, | 
					
						
							|  |  |  | 			{Name: "templates/recursion", Data: []byte(`{{define "recursion"}}{{include "recursion" . }}{{end}}`)}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	v := chartutil.Values{ | 
					
						
							|  |  |  | 		"Values": "", | 
					
						
							|  |  |  | 		"Chart":  c.Metadata, | 
					
						
							|  |  |  | 		"Release": chartutil.Values{ | 
					
						
							|  |  |  | 			"Name": "TestRelease", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expectErr := "rendering template has a nested reference name: recursion: unable to execute template" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, err := Render(c, v) | 
					
						
							|  |  |  | 	if err == nil || !strings.HasSuffix(err.Error(), expectErr) { | 
					
						
							|  |  |  | 		t.Errorf("Expected err with suffix: %s", expectErr) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// calling the same function many times is ok
 | 
					
						
							|  |  |  | 	times := 4000 | 
					
						
							|  |  |  | 	phrase := "All work and no play makes Jack a dull boy" | 
					
						
							|  |  |  | 	printFunc := `{{define "overlook"}}{{printf "` + phrase + `\n"}}{{end}}` | 
					
						
							|  |  |  | 	var repeatedIncl string | 
					
						
							|  |  |  | 	for i := 0; i < times; i++ { | 
					
						
							|  |  |  | 		repeatedIncl += `{{include "overlook" . }}` | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	d := &chart.Chart{ | 
					
						
							|  |  |  | 		Metadata: &chart.Metadata{Name: "overlook"}, | 
					
						
							|  |  |  | 		Templates: []*chart.File{ | 
					
						
							|  |  |  | 			{Name: "templates/quote", Data: []byte(repeatedIncl)}, | 
					
						
							|  |  |  | 			{Name: "templates/_function", Data: []byte(printFunc)}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	out, err := Render(d, v) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var expect string | 
					
						
							|  |  |  | 	for i := 0; i < times; i++ { | 
					
						
							|  |  |  | 		expect += phrase + "\n" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if got := out["overlook/templates/quote"]; got != expect { | 
					
						
							|  |  |  | 		t.Errorf("Expected %q, got %q (%v)", expect, got, out) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |