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