github.com/canthefason/helm@v2.2.1-0.20170221172616-16b043b8d505+incompatible/cmd/helm/install_test.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors All rights reserved. 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 main 18 19 import ( 20 "io" 21 "reflect" 22 "regexp" 23 "strings" 24 "testing" 25 26 "github.com/spf13/cobra" 27 ) 28 29 func TestInstall(t *testing.T) { 30 tests := []releaseCase{ 31 // Install, base case 32 { 33 name: "basic install", 34 args: []string{"testdata/testcharts/alpine"}, 35 flags: strings.Split("--name aeneas", " "), 36 expected: "aeneas", 37 resp: releaseMock(&releaseOptions{name: "aeneas"}), 38 }, 39 // Install, no hooks 40 { 41 name: "install without hooks", 42 args: []string{"testdata/testcharts/alpine"}, 43 flags: strings.Split("--name aeneas --no-hooks", " "), 44 expected: "juno", 45 resp: releaseMock(&releaseOptions{name: "juno"}), 46 }, 47 // Install, values from cli 48 { 49 name: "install with values", 50 args: []string{"testdata/testcharts/alpine"}, 51 flags: strings.Split("--set foo=bar", " "), 52 resp: releaseMock(&releaseOptions{name: "virgil"}), 53 expected: "virgil", 54 }, 55 // Install, values from cli via multiple --set 56 { 57 name: "install with multiple values", 58 args: []string{"testdata/testcharts/alpine"}, 59 flags: strings.Split("--set foo=bar", "--set bar=foo"), 60 resp: releaseMock(&releaseOptions{name: "virgil"}), 61 expected: "virgil", 62 }, 63 // Install, values from yaml 64 { 65 name: "install with values", 66 args: []string{"testdata/testcharts/alpine"}, 67 flags: strings.Split("-f testdata/testcharts/alpine/extra_values.yaml", " "), 68 resp: releaseMock(&releaseOptions{name: "virgil"}), 69 expected: "virgil", 70 }, 71 // Install, values from multiple yaml 72 { 73 name: "install with values", 74 args: []string{"testdata/testcharts/alpine"}, 75 flags: strings.Split("-f testdata/testcharts/alpine/extra_values.yaml -f testdata/testcharts/alpine/more_values.yaml", " "), 76 resp: releaseMock(&releaseOptions{name: "virgil"}), 77 expected: "virgil", 78 }, 79 // Install, no charts 80 { 81 name: "install with no chart specified", 82 args: []string{}, 83 err: true, 84 }, 85 // Install, re-use name 86 { 87 name: "install and replace release", 88 args: []string{"testdata/testcharts/alpine"}, 89 flags: strings.Split("--name aeneas --replace", " "), 90 expected: "aeneas", 91 resp: releaseMock(&releaseOptions{name: "aeneas"}), 92 }, 93 // Install, with timeout 94 { 95 name: "install with a timeout", 96 args: []string{"testdata/testcharts/alpine"}, 97 flags: strings.Split("--timeout 120", " "), 98 expected: "foobar", 99 resp: releaseMock(&releaseOptions{name: "foobar"}), 100 }, 101 // Install, with wait 102 { 103 name: "install with a wait", 104 args: []string{"testdata/testcharts/alpine"}, 105 flags: strings.Split("--wait", " "), 106 expected: "apollo", 107 resp: releaseMock(&releaseOptions{name: "apollo"}), 108 }, 109 // Install, using the name-template 110 { 111 name: "install with name-template", 112 args: []string{"testdata/testcharts/alpine"}, 113 flags: []string{"--name-template", "{{upper \"foobar\"}}"}, 114 expected: "FOOBAR", 115 resp: releaseMock(&releaseOptions{name: "FOOBAR"}), 116 }, 117 // Install, perform chart verification along the way. 118 { 119 name: "install with verification, missing provenance", 120 args: []string{"testdata/testcharts/compressedchart-0.1.0.tgz"}, 121 flags: strings.Split("--verify --keyring testdata/helm-test-key.pub", " "), 122 err: true, 123 }, 124 { 125 name: "install with verification, directory instead of file", 126 args: []string{"testdata/testcharts/signtest"}, 127 flags: strings.Split("--verify --keyring testdata/helm-test-key.pub", " "), 128 err: true, 129 }, 130 { 131 name: "install with verification, valid", 132 args: []string{"testdata/testcharts/signtest-0.1.0.tgz"}, 133 flags: strings.Split("--verify --keyring testdata/helm-test-key.pub", " "), 134 }, 135 // Install, chart with missing dependencies in /charts 136 { 137 name: "install chart with missing dependencies", 138 args: []string{"testdata/testcharts/chart-missing-deps"}, 139 expected: "Warning: reqsubchart2 is in requirements.yaml but not in the charts/ directory!", 140 }, 141 } 142 143 runReleaseCases(t, tests, func(c *fakeReleaseClient, out io.Writer) *cobra.Command { 144 return newInstallCmd(c, out) 145 }) 146 } 147 148 type nameTemplateTestCase struct { 149 tpl string 150 expected string 151 expectedErrorStr string 152 } 153 154 func TestNameTemplate(t *testing.T) { 155 testCases := []nameTemplateTestCase{ 156 // Just a straight up nop please 157 { 158 tpl: "foobar", 159 expected: "foobar", 160 expectedErrorStr: "", 161 }, 162 // Random numbers at the end for fun & profit 163 { 164 tpl: "foobar-{{randNumeric 6}}", 165 expected: "foobar-[0-9]{6}$", 166 expectedErrorStr: "", 167 }, 168 // Random numbers in the middle for fun & profit 169 { 170 tpl: "foobar-{{randNumeric 4}}-baz", 171 expected: "foobar-[0-9]{4}-baz$", 172 expectedErrorStr: "", 173 }, 174 // No such function 175 { 176 tpl: "foobar-{{randInt}}", 177 expected: "", 178 expectedErrorStr: "function \"randInt\" not defined", 179 }, 180 // Invalid template 181 { 182 tpl: "foobar-{{", 183 expected: "", 184 expectedErrorStr: "unexpected unclosed action", 185 }, 186 } 187 188 for _, tc := range testCases { 189 190 n, err := generateName(tc.tpl) 191 if err != nil { 192 if tc.expectedErrorStr == "" { 193 t.Errorf("Was not expecting error, but got: %v", err) 194 continue 195 } 196 re, compErr := regexp.Compile(tc.expectedErrorStr) 197 if compErr != nil { 198 t.Errorf("Expected error string failed to compile: %v", compErr) 199 continue 200 } 201 if !re.MatchString(err.Error()) { 202 t.Errorf("Error didn't match for %s expected %s but got %v", tc.tpl, tc.expectedErrorStr, err) 203 continue 204 } 205 } 206 if err == nil && tc.expectedErrorStr != "" { 207 t.Errorf("Was expecting error %s but didn't get an error back", tc.expectedErrorStr) 208 } 209 210 if tc.expected != "" { 211 re, err := regexp.Compile(tc.expected) 212 if err != nil { 213 t.Errorf("Expected string failed to compile: %v", err) 214 continue 215 } 216 if !re.MatchString(n) { 217 t.Errorf("Returned name didn't match for %s expected %s but got %s", tc.tpl, tc.expected, n) 218 } 219 } 220 } 221 } 222 223 func TestMergeValues(t *testing.T) { 224 nestedMap := map[string]interface{}{ 225 "foo": "bar", 226 "baz": map[string]string{ 227 "cool": "stuff", 228 }, 229 } 230 anotherNestedMap := map[string]interface{}{ 231 "foo": "bar", 232 "baz": map[string]string{ 233 "cool": "things", 234 "awesome": "stuff", 235 }, 236 } 237 flatMap := map[string]interface{}{ 238 "foo": "bar", 239 "baz": "stuff", 240 } 241 anotherFlatMap := map[string]interface{}{ 242 "testing": "fun", 243 } 244 245 testMap := mergeValues(flatMap, nestedMap) 246 equal := reflect.DeepEqual(testMap, nestedMap) 247 if !equal { 248 t.Errorf("Expected a nested map to overwrite a flat value. Expected: %v, got %v", nestedMap, testMap) 249 } 250 251 testMap = mergeValues(nestedMap, flatMap) 252 equal = reflect.DeepEqual(testMap, flatMap) 253 if !equal { 254 t.Errorf("Expected a flat value to overwrite a map. Expected: %v, got %v", flatMap, testMap) 255 } 256 257 testMap = mergeValues(nestedMap, anotherNestedMap) 258 equal = reflect.DeepEqual(testMap, anotherNestedMap) 259 if !equal { 260 t.Errorf("Expected a nested map to overwrite another nested map. Expected: %v, got %v", anotherNestedMap, testMap) 261 } 262 263 testMap = mergeValues(anotherFlatMap, anotherNestedMap) 264 expectedMap := map[string]interface{}{ 265 "testing": "fun", 266 "foo": "bar", 267 "baz": map[string]string{ 268 "cool": "things", 269 "awesome": "stuff", 270 }, 271 } 272 equal = reflect.DeepEqual(testMap, expectedMap) 273 if !equal { 274 t.Errorf("Expected a map with different keys to merge properly with another map. Expected: %v, got %v", expectedMap, testMap) 275 } 276 }