github.com/defensepoint-snyk-test/helm-new@v0.0.0-20211130153739-c57ea64d6603/cmd/helm/install_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  	"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  		{
    65  			name:     "install with multiple unordered list values",
    66  			args:     []string{"testdata/testcharts/alpine"},
    67  			flags:    strings.Split("--name virgil --set foo[1].bar=baz,foo[0].baz=bar", " "),
    68  			resp:     helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}),
    69  			expected: "virgil",
    70  		},
    71  		{
    72  			name:     "install with values",
    73  			args:     []string{"testdata/testcharts/alpine"},
    74  			flags:    strings.Split("--name virgil -f testdata/testcharts/alpine/extra_values.yaml", " "),
    75  			resp:     helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}),
    76  			expected: "virgil",
    77  		},
    78  		// Install, values from multiple yaml
    79  		{
    80  			name:     "install with values",
    81  			args:     []string{"testdata/testcharts/alpine"},
    82  			flags:    strings.Split("--name virgil -f testdata/testcharts/alpine/extra_values.yaml -f testdata/testcharts/alpine/more_values.yaml", " "),
    83  			resp:     helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}),
    84  			expected: "virgil",
    85  		},
    86  		// Install, no charts
    87  		{
    88  			name: "install with no chart specified",
    89  			args: []string{},
    90  			err:  true,
    91  		},
    92  		// Install, re-use name
    93  		{
    94  			name:     "install and replace release",
    95  			args:     []string{"testdata/testcharts/alpine"},
    96  			flags:    strings.Split("--name aeneas --replace", " "),
    97  			expected: "aeneas",
    98  			resp:     helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}),
    99  		},
   100  		// Install, with timeout
   101  		{
   102  			name:     "install with a timeout",
   103  			args:     []string{"testdata/testcharts/alpine"},
   104  			flags:    strings.Split("--name foobar --timeout 120", " "),
   105  			expected: "foobar",
   106  			resp:     helm.ReleaseMock(&helm.MockReleaseOptions{Name: "foobar"}),
   107  		},
   108  		// Install, with wait
   109  		{
   110  			name:     "install with a wait",
   111  			args:     []string{"testdata/testcharts/alpine"},
   112  			flags:    strings.Split("--name apollo --wait", " "),
   113  			expected: "apollo",
   114  			resp:     helm.ReleaseMock(&helm.MockReleaseOptions{Name: "apollo"}),
   115  		},
   116  		// Install, using the name-template
   117  		{
   118  			name:     "install with name-template",
   119  			args:     []string{"testdata/testcharts/alpine"},
   120  			flags:    []string{"--name-template", "{{lower \"FOOBAR\"}}"},
   121  			expected: "foobar",
   122  			resp:     helm.ReleaseMock(&helm.MockReleaseOptions{Name: "foobar"}),
   123  		},
   124  		{
   125  			name:     "install with custom description",
   126  			args:     []string{"testdata/testcharts/alpine"},
   127  			flags:    []string{"--name", "virgil", "--description", "foobar"},
   128  			expected: "virgil",
   129  			resp:     helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil", Description: "foobar"}),
   130  		},
   131  		// Install, perform chart verification along the way.
   132  		{
   133  			name:  "install with verification, missing provenance",
   134  			args:  []string{"testdata/testcharts/compressedchart-0.1.0.tgz"},
   135  			flags: strings.Split("--verify --keyring testdata/helm-test-key.pub", " "),
   136  			err:   true,
   137  		},
   138  		{
   139  			name:  "install with verification, directory instead of file",
   140  			args:  []string{"testdata/testcharts/signtest"},
   141  			flags: strings.Split("--verify --keyring testdata/helm-test-key.pub", " "),
   142  			err:   true,
   143  		},
   144  		{
   145  			name:  "install with verification, valid",
   146  			args:  []string{"testdata/testcharts/signtest-0.1.0.tgz"},
   147  			flags: strings.Split("--verify --keyring testdata/helm-test-key.pub", " "),
   148  		},
   149  		// Install, chart with missing dependencies in /charts
   150  		{
   151  			name: "install chart with missing dependencies",
   152  			args: []string{"testdata/testcharts/chart-missing-deps"},
   153  			err:  true,
   154  		},
   155  		// Install, chart with bad requirements.yaml in /charts
   156  		{
   157  			name: "install chart with bad requirements.yaml",
   158  			args: []string{"testdata/testcharts/chart-bad-requirements"},
   159  			err:  true,
   160  		},
   161  		// Install, using a bad release name
   162  		{
   163  			name:  "install chart with release name using capitals",
   164  			args:  []string{"testdata/testcharts/alpine"},
   165  			flags: []string{"--name", "FOO"},
   166  			err:   true,
   167  		},
   168  		{
   169  			name:  "install chart with release name using periods",
   170  			args:  []string{"testdata/testcharts/alpine"},
   171  			flags: []string{"--name", "foo.bar"},
   172  			err:   true,
   173  		},
   174  		{
   175  			name:  "install chart with release name using underscores",
   176  			args:  []string{"testdata/testcharts/alpine"},
   177  			flags: []string{"--name", "foo_bar"},
   178  			err:   true,
   179  		},
   180  		// Install, using a bad name-template
   181  		{
   182  			name:  "install with name-template",
   183  			args:  []string{"testdata/testcharts/alpine"},
   184  			flags: []string{"--name-template", "{{UPPER \"foobar\"}}"},
   185  			err:   true,
   186  		},
   187  	}
   188  
   189  	runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command {
   190  		return newInstallCmd(c, out)
   191  	})
   192  }
   193  
   194  type nameTemplateTestCase struct {
   195  	tpl              string
   196  	expected         string
   197  	expectedErrorStr string
   198  }
   199  
   200  func TestNameTemplate(t *testing.T) {
   201  	testCases := []nameTemplateTestCase{
   202  		// Just a straight up nop please
   203  		{
   204  			tpl:              "foobar",
   205  			expected:         "foobar",
   206  			expectedErrorStr: "",
   207  		},
   208  		// Random numbers at the end for fun & profit
   209  		{
   210  			tpl:              "foobar-{{randNumeric 6}}",
   211  			expected:         "foobar-[0-9]{6}$",
   212  			expectedErrorStr: "",
   213  		},
   214  		// Random numbers in the middle for fun & profit
   215  		{
   216  			tpl:              "foobar-{{randNumeric 4}}-baz",
   217  			expected:         "foobar-[0-9]{4}-baz$",
   218  			expectedErrorStr: "",
   219  		},
   220  		// No such function
   221  		{
   222  			tpl:              "foobar-{{randInt}}",
   223  			expected:         "",
   224  			expectedErrorStr: "function \"randInt\" not defined",
   225  		},
   226  		// Invalid template
   227  		{
   228  			tpl:              "foobar-{{",
   229  			expected:         "",
   230  			expectedErrorStr: "unexpected unclosed action",
   231  		},
   232  	}
   233  
   234  	for _, tc := range testCases {
   235  
   236  		n, err := generateName(tc.tpl)
   237  		if err != nil {
   238  			if tc.expectedErrorStr == "" {
   239  				t.Errorf("Was not expecting error, but got: %v", err)
   240  				continue
   241  			}
   242  			re, compErr := regexp.Compile(tc.expectedErrorStr)
   243  			if compErr != nil {
   244  				t.Errorf("Expected error string failed to compile: %v", compErr)
   245  				continue
   246  			}
   247  			if !re.MatchString(err.Error()) {
   248  				t.Errorf("Error didn't match for %s expected %s but got %v", tc.tpl, tc.expectedErrorStr, err)
   249  				continue
   250  			}
   251  		}
   252  		if err == nil && tc.expectedErrorStr != "" {
   253  			t.Errorf("Was expecting error %s but didn't get an error back", tc.expectedErrorStr)
   254  		}
   255  
   256  		if tc.expected != "" {
   257  			re, err := regexp.Compile(tc.expected)
   258  			if err != nil {
   259  				t.Errorf("Expected string failed to compile: %v", err)
   260  				continue
   261  			}
   262  			if !re.MatchString(n) {
   263  				t.Errorf("Returned name didn't match for %s expected %s but got %s", tc.tpl, tc.expected, n)
   264  			}
   265  		}
   266  	}
   267  }
   268  
   269  func TestMergeValues(t *testing.T) {
   270  	nestedMap := map[string]interface{}{
   271  		"foo": "bar",
   272  		"baz": map[string]string{
   273  			"cool": "stuff",
   274  		},
   275  	}
   276  	anotherNestedMap := map[string]interface{}{
   277  		"foo": "bar",
   278  		"baz": map[string]string{
   279  			"cool":    "things",
   280  			"awesome": "stuff",
   281  		},
   282  	}
   283  	flatMap := map[string]interface{}{
   284  		"foo": "bar",
   285  		"baz": "stuff",
   286  	}
   287  	anotherFlatMap := map[string]interface{}{
   288  		"testing": "fun",
   289  	}
   290  
   291  	testMap := mergeValues(flatMap, nestedMap)
   292  	equal := reflect.DeepEqual(testMap, nestedMap)
   293  	if !equal {
   294  		t.Errorf("Expected a nested map to overwrite a flat value. Expected: %v, got %v", nestedMap, testMap)
   295  	}
   296  
   297  	testMap = mergeValues(nestedMap, flatMap)
   298  	equal = reflect.DeepEqual(testMap, flatMap)
   299  	if !equal {
   300  		t.Errorf("Expected a flat value to overwrite a map. Expected: %v, got %v", flatMap, testMap)
   301  	}
   302  
   303  	testMap = mergeValues(nestedMap, anotherNestedMap)
   304  	equal = reflect.DeepEqual(testMap, anotherNestedMap)
   305  	if !equal {
   306  		t.Errorf("Expected a nested map to overwrite another nested map. Expected: %v, got %v", anotherNestedMap, testMap)
   307  	}
   308  
   309  	testMap = mergeValues(anotherFlatMap, anotherNestedMap)
   310  	expectedMap := map[string]interface{}{
   311  		"testing": "fun",
   312  		"foo":     "bar",
   313  		"baz": map[string]string{
   314  			"cool":    "things",
   315  			"awesome": "stuff",
   316  		},
   317  	}
   318  	equal = reflect.DeepEqual(testMap, expectedMap)
   319  	if !equal {
   320  		t.Errorf("Expected a map with different keys to merge properly with another map. Expected: %v, got %v", expectedMap, testMap)
   321  	}
   322  }