github.com/wangchanggan/helm@v0.0.0-20211020154240-11b1b7d5406d/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 appsv1 "k8s.io/api/apps/v1" 32 v1 "k8s.io/api/core/v1" 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(&appsv1.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 TestInitCmd_tlsOptions(t *testing.T) { 183 const testDir = "../../testdata" 184 185 // tls certificates in testDir 186 var ( 187 testCaCertFile = filepath.Join(testDir, "ca.pem") 188 testCertFile = filepath.Join(testDir, "crt.pem") 189 testKeyFile = filepath.Join(testDir, "key.pem") 190 ) 191 192 // these tests verify the effects of permuting the "--tls" and "--tls-verify" flags 193 // and the install options yieled as a result of (*initCmd).tlsOptions() 194 // during helm init. 195 var tests = []struct { 196 certFile string 197 keyFile string 198 caFile string 199 enable bool 200 verify bool 201 describe string 202 }{ 203 { // --tls and --tls-verify specified (--tls=true,--tls-verify=true) 204 certFile: testCertFile, 205 keyFile: testKeyFile, 206 caFile: testCaCertFile, 207 enable: true, 208 verify: true, 209 describe: "--tls and --tls-verify specified (--tls=true,--tls-verify=true)", 210 }, 211 { // --tls-verify implies --tls (--tls=false,--tls-verify=true) 212 certFile: testCertFile, 213 keyFile: testKeyFile, 214 caFile: testCaCertFile, 215 enable: false, 216 verify: true, 217 describe: "--tls-verify implies --tls (--tls=false,--tls-verify=true)", 218 }, 219 { // no --tls-verify (--tls=true,--tls-verify=false) 220 certFile: testCertFile, 221 keyFile: testKeyFile, 222 caFile: "", 223 enable: true, 224 verify: false, 225 describe: "no --tls-verify (--tls=true,--tls-verify=false)", 226 }, 227 { // tls is disabled (--tls=false,--tls-verify=false) 228 certFile: "", 229 keyFile: "", 230 caFile: "", 231 enable: false, 232 verify: false, 233 describe: "tls is disabled (--tls=false,--tls-verify=false)", 234 }, 235 } 236 237 for _, tt := range tests { 238 // emulate tls file specific flags 239 tlsCaCertFile, tlsCertFile, tlsKeyFile = tt.caFile, tt.certFile, tt.keyFile 240 241 // emulate tls enable/verify flags 242 tlsEnable, tlsVerify = tt.enable, tt.verify 243 244 cmd := &initCmd{} 245 if err := cmd.tlsOptions(); err != nil { 246 t.Fatalf("unexpected error: %v", err) 247 } 248 249 // expected result options 250 expect := installer.Options{ 251 TLSCaCertFile: tt.caFile, 252 TLSCertFile: tt.certFile, 253 TLSKeyFile: tt.keyFile, 254 VerifyTLS: tt.verify, 255 EnableTLS: tt.enable || tt.verify, 256 } 257 258 if !reflect.DeepEqual(cmd.opts, expect) { 259 t.Errorf("%s: got %#+v, want %#+v", tt.describe, cmd.opts, expect) 260 } 261 } 262 } 263 264 // TestInitCmd_output tests that init -o can be decoded 265 func TestInitCmd_output(t *testing.T) { 266 // This is purely defensive in this case. 267 home, err := ioutil.TempDir("", "helm_home") 268 if err != nil { 269 t.Fatal(err) 270 } 271 dbg := settings.Debug 272 settings.Debug = true 273 defer func() { 274 os.Remove(home) 275 settings.Debug = dbg 276 }() 277 fc := fake.NewSimpleClientset() 278 tests := []string{"json", "yaml"} 279 for _, s := range tests { 280 var buf bytes.Buffer 281 cmd := &initCmd{ 282 out: &buf, 283 home: helmpath.Home(home), 284 kubeClient: fc, 285 opts: installer.Options{Output: installer.OutputFormat(s)}, 286 namespace: v1.NamespaceDefault, 287 } 288 if err := cmd.run(); err != nil { 289 t.Fatal(err) 290 } 291 if got := len(fc.Actions()); got != 0 { 292 t.Errorf("expected no server calls, got %d", got) 293 } 294 295 var obj interface{} 296 decoder := yamlutil.NewYAMLOrJSONDecoder(&buf, 4096) 297 for { 298 err := decoder.Decode(&obj) 299 if err != nil { 300 if err == io.EOF { 301 break 302 } 303 t.Errorf("error decoding init %s output %s %s", s, err, buf.String()) 304 } 305 } 306 } 307 }