github.com/Beeketing/helm@v2.12.1+incompatible/cmd/helm/init_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 main 18 19 import ( 20 "bytes" 21 "io" 22 "io/ioutil" 23 "os" 24 "path/filepath" 25 "reflect" 26 "strings" 27 "testing" 28 29 "github.com/ghodss/yaml" 30 31 "k8s.io/api/core/v1" 32 "k8s.io/api/extensions/v1beta1" 33 apierrors "k8s.io/apimachinery/pkg/api/errors" 34 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 35 "k8s.io/apimachinery/pkg/runtime" 36 yamlutil "k8s.io/apimachinery/pkg/util/yaml" 37 "k8s.io/client-go/kubernetes/fake" 38 testcore "k8s.io/client-go/testing" 39 40 "k8s.io/helm/cmd/helm/installer" 41 "k8s.io/helm/pkg/helm/helmpath" 42 ) 43 44 func TestInitCmd(t *testing.T) { 45 home, err := ioutil.TempDir("", "helm_home") 46 if err != nil { 47 t.Fatal(err) 48 } 49 defer os.RemoveAll(home) 50 51 var buf bytes.Buffer 52 fc := fake.NewSimpleClientset() 53 cmd := &initCmd{ 54 out: &buf, 55 home: helmpath.Home(home), 56 kubeClient: fc, 57 namespace: v1.NamespaceDefault, 58 } 59 if err := cmd.run(); err != nil { 60 t.Errorf("expected error: %v", err) 61 } 62 actions := fc.Actions() 63 if len(actions) != 2 { 64 t.Errorf("Expected 2 actions, got %d", len(actions)) 65 } 66 if !actions[0].Matches("create", "deployments") { 67 t.Errorf("unexpected action: %v, expected create deployment", actions[0]) 68 } 69 if !actions[1].Matches("create", "services") { 70 t.Errorf("unexpected action: %v, expected create service", actions[1]) 71 } 72 expected := "Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster." 73 if !strings.Contains(buf.String(), expected) { 74 t.Errorf("expected %q, got %q", expected, buf.String()) 75 } 76 } 77 78 func TestInitCmd_exists(t *testing.T) { 79 home, err := ioutil.TempDir("", "helm_home") 80 if err != nil { 81 t.Fatal(err) 82 } 83 defer os.RemoveAll(home) 84 85 var buf bytes.Buffer 86 fc := fake.NewSimpleClientset(&v1beta1.Deployment{ 87 ObjectMeta: metav1.ObjectMeta{ 88 Namespace: v1.NamespaceDefault, 89 Name: "tiller-deploy", 90 }, 91 }) 92 fc.PrependReactor("*", "*", func(action testcore.Action) (bool, runtime.Object, error) { 93 return true, nil, apierrors.NewAlreadyExists(v1.Resource("deployments"), "1") 94 }) 95 cmd := &initCmd{ 96 out: &buf, 97 home: helmpath.Home(home), 98 kubeClient: fc, 99 namespace: v1.NamespaceDefault, 100 } 101 if err := cmd.run(); err != nil { 102 t.Errorf("expected error: %v", err) 103 } 104 expected := "Warning: Tiller is already installed in the cluster.\n" + 105 "(Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)" 106 if !strings.Contains(buf.String(), expected) { 107 t.Errorf("expected %q, got %q", expected, buf.String()) 108 } 109 } 110 111 func TestInitCmd_clientOnly(t *testing.T) { 112 home, err := ioutil.TempDir("", "helm_home") 113 if err != nil { 114 t.Fatal(err) 115 } 116 defer os.RemoveAll(home) 117 118 var buf bytes.Buffer 119 fc := fake.NewSimpleClientset() 120 cmd := &initCmd{ 121 out: &buf, 122 home: helmpath.Home(home), 123 kubeClient: fc, 124 clientOnly: true, 125 namespace: v1.NamespaceDefault, 126 } 127 if err := cmd.run(); err != nil { 128 t.Errorf("unexpected error: %v", err) 129 } 130 if len(fc.Actions()) != 0 { 131 t.Error("expected client call") 132 } 133 expected := "Not installing Tiller due to 'client-only' flag having been set" 134 if !strings.Contains(buf.String(), expected) { 135 t.Errorf("expected %q, got %q", expected, buf.String()) 136 } 137 } 138 139 func TestInitCmd_dryRun(t *testing.T) { 140 // This is purely defensive in this case. 141 home, err := ioutil.TempDir("", "helm_home") 142 if err != nil { 143 t.Fatal(err) 144 } 145 cleanup := resetEnv() 146 defer func() { 147 os.Remove(home) 148 cleanup() 149 }() 150 151 settings.Debug = true 152 153 var buf bytes.Buffer 154 fc := fake.NewSimpleClientset() 155 cmd := &initCmd{ 156 out: &buf, 157 home: helmpath.Home(home), 158 kubeClient: fc, 159 clientOnly: true, 160 dryRun: true, 161 namespace: v1.NamespaceDefault, 162 } 163 if err := cmd.run(); err != nil { 164 t.Fatal(err) 165 } 166 if got := len(fc.Actions()); got != 0 { 167 t.Errorf("expected no server calls, got %d", got) 168 } 169 170 docs := bytes.Split(buf.Bytes(), []byte("\n---")) 171 if got, want := len(docs), 2; got != want { 172 t.Fatalf("Expected document count of %d, got %d", want, got) 173 } 174 for _, doc := range docs { 175 var y map[string]interface{} 176 if err := yaml.Unmarshal(doc, &y); err != nil { 177 t.Errorf("Expected parseable YAML, got %q\n\t%s", doc, err) 178 } 179 } 180 } 181 182 func TestEnsureHome(t *testing.T) { 183 home, err := ioutil.TempDir("", "helm_home") 184 if err != nil { 185 t.Fatal(err) 186 } 187 defer os.RemoveAll(home) 188 189 b := bytes.NewBuffer(nil) 190 hh := helmpath.Home(home) 191 settings.Home = hh 192 if err := ensureDirectories(hh, b); err != nil { 193 t.Error(err) 194 } 195 if err := ensureDefaultRepos(hh, b, false); err != nil { 196 t.Error(err) 197 } 198 if err := ensureDefaultRepos(hh, b, true); err != nil { 199 t.Error(err) 200 } 201 if err := ensureRepoFileFormat(hh.RepositoryFile(), b); err != nil { 202 t.Error(err) 203 } 204 205 expectedDirs := []string{hh.String(), hh.Repository(), hh.Cache(), hh.LocalRepository()} 206 for _, dir := range expectedDirs { 207 if fi, err := os.Stat(dir); err != nil { 208 t.Errorf("%s", err) 209 } else if !fi.IsDir() { 210 t.Errorf("%s is not a directory", fi) 211 } 212 } 213 214 if fi, err := os.Stat(hh.RepositoryFile()); err != nil { 215 t.Error(err) 216 } else if fi.IsDir() { 217 t.Errorf("%s should not be a directory", fi) 218 } 219 220 if fi, err := os.Stat(hh.LocalRepository(localRepositoryIndexFile)); err != nil { 221 t.Errorf("%s", err) 222 } else if fi.IsDir() { 223 t.Errorf("%s should not be a directory", fi) 224 } 225 } 226 227 func TestInitCmd_tlsOptions(t *testing.T) { 228 const testDir = "../../testdata" 229 230 // tls certificates in testDir 231 var ( 232 testCaCertFile = filepath.Join(testDir, "ca.pem") 233 testCertFile = filepath.Join(testDir, "crt.pem") 234 testKeyFile = filepath.Join(testDir, "key.pem") 235 ) 236 237 // these tests verify the effects of permuting the "--tls" and "--tls-verify" flags 238 // and the install options yieled as a result of (*initCmd).tlsOptions() 239 // during helm init. 240 var tests = []struct { 241 certFile string 242 keyFile string 243 caFile string 244 enable bool 245 verify bool 246 describe string 247 }{ 248 { // --tls and --tls-verify specified (--tls=true,--tls-verify=true) 249 certFile: testCertFile, 250 keyFile: testKeyFile, 251 caFile: testCaCertFile, 252 enable: true, 253 verify: true, 254 describe: "--tls and --tls-verify specified (--tls=true,--tls-verify=true)", 255 }, 256 { // --tls-verify implies --tls (--tls=false,--tls-verify=true) 257 certFile: testCertFile, 258 keyFile: testKeyFile, 259 caFile: testCaCertFile, 260 enable: false, 261 verify: true, 262 describe: "--tls-verify implies --tls (--tls=false,--tls-verify=true)", 263 }, 264 { // no --tls-verify (--tls=true,--tls-verify=false) 265 certFile: testCertFile, 266 keyFile: testKeyFile, 267 caFile: "", 268 enable: true, 269 verify: false, 270 describe: "no --tls-verify (--tls=true,--tls-verify=false)", 271 }, 272 { // tls is disabled (--tls=false,--tls-verify=false) 273 certFile: "", 274 keyFile: "", 275 caFile: "", 276 enable: false, 277 verify: false, 278 describe: "tls is disabled (--tls=false,--tls-verify=false)", 279 }, 280 } 281 282 for _, tt := range tests { 283 // emulate tls file specific flags 284 tlsCaCertFile, tlsCertFile, tlsKeyFile = tt.caFile, tt.certFile, tt.keyFile 285 286 // emulate tls enable/verify flags 287 tlsEnable, tlsVerify = tt.enable, tt.verify 288 289 cmd := &initCmd{} 290 if err := cmd.tlsOptions(); err != nil { 291 t.Fatalf("unexpected error: %v", err) 292 } 293 294 // expected result options 295 expect := installer.Options{ 296 TLSCaCertFile: tt.caFile, 297 TLSCertFile: tt.certFile, 298 TLSKeyFile: tt.keyFile, 299 VerifyTLS: tt.verify, 300 EnableTLS: tt.enable || tt.verify, 301 } 302 303 if !reflect.DeepEqual(cmd.opts, expect) { 304 t.Errorf("%s: got %#+v, want %#+v", tt.describe, cmd.opts, expect) 305 } 306 } 307 } 308 309 // TestInitCmd_output tests that init -o can be decoded 310 func TestInitCmd_output(t *testing.T) { 311 // This is purely defensive in this case. 312 home, err := ioutil.TempDir("", "helm_home") 313 if err != nil { 314 t.Fatal(err) 315 } 316 dbg := settings.Debug 317 settings.Debug = true 318 defer func() { 319 os.Remove(home) 320 settings.Debug = dbg 321 }() 322 fc := fake.NewSimpleClientset() 323 tests := []string{"json", "yaml"} 324 for _, s := range tests { 325 var buf bytes.Buffer 326 cmd := &initCmd{ 327 out: &buf, 328 home: helmpath.Home(home), 329 kubeClient: fc, 330 opts: installer.Options{Output: installer.OutputFormat(s)}, 331 namespace: v1.NamespaceDefault, 332 } 333 if err := cmd.run(); err != nil { 334 t.Fatal(err) 335 } 336 if got := len(fc.Actions()); got != 0 { 337 t.Errorf("expected no server calls, got %d", got) 338 } 339 340 var obj interface{} 341 decoder := yamlutil.NewYAMLOrJSONDecoder(&buf, 4096) 342 for { 343 err := decoder.Decode(&obj) 344 if err != nil { 345 if err == io.EOF { 346 break 347 } 348 t.Errorf("error decoding init %s output %s %s", s, err, buf.String()) 349 } 350 } 351 } 352 }