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