github.com/werf/3p-helm@v2.8.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  	"k8s.io/api/core/v1"
    31  	"k8s.io/api/extensions/v1beta1"
    32  	apierrors "k8s.io/apimachinery/pkg/api/errors"
    33  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    34  	"k8s.io/apimachinery/pkg/runtime"
    35  	"k8s.io/client-go/kubernetes/fake"
    36  	testcore "k8s.io/client-go/testing"
    37  
    38  	"encoding/json"
    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.Remove(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.Remove(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.Remove(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.Remove(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 formats are unmarshal-able
   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 := []struct {
   324  		expectF    func([]byte, interface{}) error
   325  		expectName string
   326  	}{
   327  		{
   328  			json.Unmarshal,
   329  			"json",
   330  		},
   331  		{
   332  			yaml.Unmarshal,
   333  			"yaml",
   334  		},
   335  	}
   336  	for _, s := range tests {
   337  		var buf bytes.Buffer
   338  		cmd := &initCmd{
   339  			out:        &buf,
   340  			home:       helmpath.Home(home),
   341  			kubeClient: fc,
   342  			opts:       installer.Options{Output: installer.OutputFormat(s.expectName)},
   343  			namespace:  v1.NamespaceDefault,
   344  		}
   345  		if err := cmd.run(); err != nil {
   346  			t.Fatal(err)
   347  		}
   348  		if got := len(fc.Actions()); got != 0 {
   349  			t.Errorf("expected no server calls, got %d", got)
   350  		}
   351  		d := &v1beta1.Deployment{}
   352  		if err = s.expectF(buf.Bytes(), &d); err != nil {
   353  			t.Errorf("error unmarshalling init %s output %s %s", s.expectName, err, buf.String())
   354  		}
   355  	}
   356  
   357  }