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