github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/chartutil/values_test.go (about) 1 /* 2 Copyright The Helm Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package chartutil 18 19 import ( 20 "bytes" 21 "fmt" 22 "testing" 23 "text/template" 24 25 "github.com/stefanmcshane/helm/pkg/chart" 26 ) 27 28 func TestReadValues(t *testing.T) { 29 doc := `# Test YAML parse 30 poet: "Coleridge" 31 title: "Rime of the Ancient Mariner" 32 stanza: 33 - "at" 34 - "length" 35 - "did" 36 - cross 37 - an 38 - Albatross 39 40 mariner: 41 with: "crossbow" 42 shot: "ALBATROSS" 43 44 water: 45 water: 46 where: "everywhere" 47 nor: "any drop to drink" 48 ` 49 50 data, err := ReadValues([]byte(doc)) 51 if err != nil { 52 t.Fatalf("Error parsing bytes: %s", err) 53 } 54 matchValues(t, data) 55 56 tests := []string{`poet: "Coleridge"`, "# Just a comment", ""} 57 58 for _, tt := range tests { 59 data, err = ReadValues([]byte(tt)) 60 if err != nil { 61 t.Fatalf("Error parsing bytes (%s): %s", tt, err) 62 } 63 if data == nil { 64 t.Errorf(`YAML string "%s" gave a nil map`, tt) 65 } 66 } 67 } 68 69 func TestToRenderValues(t *testing.T) { 70 71 chartValues := map[string]interface{}{ 72 "name": "al Rashid", 73 "where": map[string]interface{}{ 74 "city": "Basrah", 75 "title": "caliph", 76 }, 77 } 78 79 overrideValues := map[string]interface{}{ 80 "name": "Haroun", 81 "where": map[string]interface{}{ 82 "city": "Baghdad", 83 "date": "809 CE", 84 }, 85 } 86 87 c := &chart.Chart{ 88 Metadata: &chart.Metadata{Name: "test"}, 89 Templates: []*chart.File{}, 90 Values: chartValues, 91 Files: []*chart.File{ 92 {Name: "scheherazade/shahryar.txt", Data: []byte("1,001 Nights")}, 93 }, 94 } 95 c.AddDependency(&chart.Chart{ 96 Metadata: &chart.Metadata{Name: "where"}, 97 }) 98 99 o := ReleaseOptions{ 100 Name: "Seven Voyages", 101 Namespace: "default", 102 Revision: 1, 103 IsInstall: true, 104 } 105 106 res, err := ToRenderValues(c, overrideValues, o, nil) 107 if err != nil { 108 t.Fatal(err) 109 } 110 111 // Ensure that the top-level values are all set. 112 if name := res["Chart"].(*chart.Metadata).Name; name != "test" { 113 t.Errorf("Expected chart name 'test', got %q", name) 114 } 115 relmap := res["Release"].(map[string]interface{}) 116 if name := relmap["Name"]; name.(string) != "Seven Voyages" { 117 t.Errorf("Expected release name 'Seven Voyages', got %q", name) 118 } 119 if namespace := relmap["Namespace"]; namespace.(string) != "default" { 120 t.Errorf("Expected namespace 'default', got %q", namespace) 121 } 122 if revision := relmap["Revision"]; revision.(int) != 1 { 123 t.Errorf("Expected revision '1', got %d", revision) 124 } 125 if relmap["IsUpgrade"].(bool) { 126 t.Error("Expected upgrade to be false.") 127 } 128 if !relmap["IsInstall"].(bool) { 129 t.Errorf("Expected install to be true.") 130 } 131 if !res["Capabilities"].(*Capabilities).APIVersions.Has("v1") { 132 t.Error("Expected Capabilities to have v1 as an API") 133 } 134 if res["Capabilities"].(*Capabilities).KubeVersion.Major != "1" { 135 t.Error("Expected Capabilities to have a Kube version") 136 } 137 138 vals := res["Values"].(Values) 139 if vals["name"] != "Haroun" { 140 t.Errorf("Expected 'Haroun', got %q (%v)", vals["name"], vals) 141 } 142 where := vals["where"].(map[string]interface{}) 143 expects := map[string]string{ 144 "city": "Baghdad", 145 "date": "809 CE", 146 "title": "caliph", 147 } 148 for field, expect := range expects { 149 if got := where[field]; got != expect { 150 t.Errorf("Expected %q, got %q (%v)", expect, got, where) 151 } 152 } 153 } 154 155 func TestReadValuesFile(t *testing.T) { 156 data, err := ReadValuesFile("./testdata/coleridge.yaml") 157 if err != nil { 158 t.Fatalf("Error reading YAML file: %s", err) 159 } 160 matchValues(t, data) 161 } 162 163 func ExampleValues() { 164 doc := ` 165 title: "Moby Dick" 166 chapter: 167 one: 168 title: "Loomings" 169 two: 170 title: "The Carpet-Bag" 171 three: 172 title: "The Spouter Inn" 173 ` 174 d, err := ReadValues([]byte(doc)) 175 if err != nil { 176 panic(err) 177 } 178 ch1, err := d.Table("chapter.one") 179 if err != nil { 180 panic("could not find chapter one") 181 } 182 fmt.Print(ch1["title"]) 183 // Output: 184 // Loomings 185 } 186 187 func TestTable(t *testing.T) { 188 doc := ` 189 title: "Moby Dick" 190 chapter: 191 one: 192 title: "Loomings" 193 two: 194 title: "The Carpet-Bag" 195 three: 196 title: "The Spouter Inn" 197 ` 198 d, err := ReadValues([]byte(doc)) 199 if err != nil { 200 t.Fatalf("Failed to parse the White Whale: %s", err) 201 } 202 203 if _, err := d.Table("title"); err == nil { 204 t.Fatalf("Title is not a table.") 205 } 206 207 if _, err := d.Table("chapter"); err != nil { 208 t.Fatalf("Failed to get the chapter table: %s\n%v", err, d) 209 } 210 211 if v, err := d.Table("chapter.one"); err != nil { 212 t.Errorf("Failed to get chapter.one: %s", err) 213 } else if v["title"] != "Loomings" { 214 t.Errorf("Unexpected title: %s", v["title"]) 215 } 216 217 if _, err := d.Table("chapter.three"); err != nil { 218 t.Errorf("Chapter three is missing: %s\n%v", err, d) 219 } 220 221 if _, err := d.Table("chapter.OneHundredThirtySix"); err == nil { 222 t.Errorf("I think you mean 'Epilogue'") 223 } 224 } 225 226 func matchValues(t *testing.T, data map[string]interface{}) { 227 if data["poet"] != "Coleridge" { 228 t.Errorf("Unexpected poet: %s", data["poet"]) 229 } 230 231 if o, err := ttpl("{{len .stanza}}", data); err != nil { 232 t.Errorf("len stanza: %s", err) 233 } else if o != "6" { 234 t.Errorf("Expected 6, got %s", o) 235 } 236 237 if o, err := ttpl("{{.mariner.shot}}", data); err != nil { 238 t.Errorf(".mariner.shot: %s", err) 239 } else if o != "ALBATROSS" { 240 t.Errorf("Expected that mariner shot ALBATROSS") 241 } 242 243 if o, err := ttpl("{{.water.water.where}}", data); err != nil { 244 t.Errorf(".water.water.where: %s", err) 245 } else if o != "everywhere" { 246 t.Errorf("Expected water water everywhere") 247 } 248 } 249 250 func ttpl(tpl string, v map[string]interface{}) (string, error) { 251 var b bytes.Buffer 252 tt := template.Must(template.New("t").Parse(tpl)) 253 err := tt.Execute(&b, v) 254 return b.String(), err 255 } 256 257 func TestPathValue(t *testing.T) { 258 doc := ` 259 title: "Moby Dick" 260 chapter: 261 one: 262 title: "Loomings" 263 two: 264 title: "The Carpet-Bag" 265 three: 266 title: "The Spouter Inn" 267 ` 268 d, err := ReadValues([]byte(doc)) 269 if err != nil { 270 t.Fatalf("Failed to parse the White Whale: %s", err) 271 } 272 273 if v, err := d.PathValue("chapter.one.title"); err != nil { 274 t.Errorf("Got error instead of title: %s\n%v", err, d) 275 } else if v != "Loomings" { 276 t.Errorf("No error but got wrong value for title: %s\n%v", err, d) 277 } 278 if _, err := d.PathValue("chapter.one.doesnotexist"); err == nil { 279 t.Errorf("Non-existent key should return error: %s\n%v", err, d) 280 } 281 if _, err := d.PathValue("chapter.doesnotexist.one"); err == nil { 282 t.Errorf("Non-existent key in middle of path should return error: %s\n%v", err, d) 283 } 284 if _, err := d.PathValue(""); err == nil { 285 t.Error("Asking for the value from an empty path should yield an error") 286 } 287 if v, err := d.PathValue("title"); err == nil { 288 if v != "Moby Dick" { 289 t.Errorf("Failed to return values for root key title") 290 } 291 } 292 }