github.com/Beeketing/helm@v2.12.1+incompatible/cmd/helm/template_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  	"bufio"
    21  	"bytes"
    22  	"fmt"
    23  	"io"
    24  	"os"
    25  	"path/filepath"
    26  	"strings"
    27  	"testing"
    28  )
    29  
    30  var (
    31  	subchart1ChartPath = "./../../pkg/chartutil/testdata/subpop/charts/subchart1"
    32  	frobnitzChartPath  = "./../../pkg/chartutil/testdata/frobnitz"
    33  )
    34  
    35  func TestTemplateCmd(t *testing.T) {
    36  	subchart1AbsChartPath, err := filepath.Abs(subchart1ChartPath)
    37  	if err != nil {
    38  		t.Fatal(err)
    39  	}
    40  	tests := []struct {
    41  		name        string
    42  		desc        string
    43  		args        []string
    44  		expectKey   string
    45  		expectValue string
    46  		expectError string
    47  	}{
    48  		{
    49  			name:        "check_name",
    50  			desc:        "check for a known name in chart",
    51  			args:        []string{subchart1ChartPath},
    52  			expectKey:   "subchart1/templates/service.yaml",
    53  			expectValue: "protocol: TCP\n    name: nginx",
    54  		},
    55  		{
    56  			name:        "check_set_name",
    57  			desc:        "verify --set values exist",
    58  			args:        []string{subchart1ChartPath, "-x", "templates/service.yaml", "--set", "service.name=apache"},
    59  			expectKey:   "subchart1/templates/service.yaml",
    60  			expectValue: "protocol: TCP\n    name: apache",
    61  		},
    62  		{
    63  			name:        "check_execute",
    64  			desc:        "verify --execute single template",
    65  			args:        []string{subchart1ChartPath, "-x", "templates/service.yaml", "--set", "service.name=apache"},
    66  			expectKey:   "subchart1/templates/service.yaml",
    67  			expectValue: "protocol: TCP\n    name: apache",
    68  		},
    69  		{
    70  			name:        "check_execute_non_existent",
    71  			desc:        "verify --execute fails on a template that doesn't exist",
    72  			args:        []string{subchart1ChartPath, "-x", "templates/thisdoesn'texist.yaml"},
    73  			expectError: "could not find template",
    74  		},
    75  		{
    76  			name:        "check_execute_absolute",
    77  			desc:        "verify --execute single template",
    78  			args:        []string{subchart1ChartPath, "-x", filepath.Join(subchart1AbsChartPath, "templates", "service.yaml"), "--set", "service.name=apache"},
    79  			expectKey:   "subchart1/templates/service.yaml",
    80  			expectValue: "protocol: TCP\n    name: apache",
    81  		},
    82  		{
    83  			name:        "check_execute_subchart_template",
    84  			desc:        "verify --execute single template on a subchart template",
    85  			args:        []string{subchart1ChartPath, "-x", "charts/subcharta/templates/service.yaml", "--set", "subcharta.service.name=foobar"},
    86  			expectKey:   "subchart1/charts/subcharta/templates/service.yaml",
    87  			expectValue: "protocol: TCP\n    name: foobar",
    88  		},
    89  		{
    90  			name:        "check_execute_subchart_template_for_tgz_subchart",
    91  			desc:        "verify --execute single template on a subchart template where the subchart is a .tgz in the chart directory",
    92  			args:        []string{frobnitzChartPath, "-x", "charts/mariner/templates/placeholder.tpl", "--set", "mariner.name=moon"},
    93  			expectKey:   "frobnitz/charts/mariner/templates/placeholder.tpl",
    94  			expectValue: "Goodbye moon",
    95  		},
    96  		{
    97  			name:        "check_namespace",
    98  			desc:        "verify --namespace",
    99  			args:        []string{subchart1ChartPath, "--namespace", "test"},
   100  			expectKey:   "subchart1/templates/service.yaml",
   101  			expectValue: "namespace: \"test\"",
   102  		},
   103  		{
   104  			name:        "check_release_name",
   105  			desc:        "verify --release exists",
   106  			args:        []string{subchart1ChartPath, "--name", "test"},
   107  			expectKey:   "subchart1/templates/service.yaml",
   108  			expectValue: "release-name: \"test\"",
   109  		},
   110  		{
   111  			name:        "check_invalid_name_uppercase",
   112  			desc:        "verify the release name using capitals is invalid",
   113  			args:        []string{subchart1ChartPath, "--name", "FOO"},
   114  			expectKey:   "subchart1/templates/service.yaml",
   115  			expectError: "is not a valid DNS label",
   116  		},
   117  		{
   118  			name:        "check_invalid_name_uppercase",
   119  			desc:        "verify the release name using periods is invalid",
   120  			args:        []string{subchart1ChartPath, "--name", "foo.bar"},
   121  			expectKey:   "subchart1/templates/service.yaml",
   122  			expectError: "is not a valid DNS label",
   123  		},
   124  		{
   125  			name:        "check_invalid_name_uppercase",
   126  			desc:        "verify the release name using underscores is invalid",
   127  			args:        []string{subchart1ChartPath, "--name", "foo_bar"},
   128  			expectKey:   "subchart1/templates/service.yaml",
   129  			expectError: "is not a valid DNS label",
   130  		},
   131  		{
   132  			name:        "check_release_is_install",
   133  			desc:        "verify --is-upgrade toggles .Release.IsInstall",
   134  			args:        []string{subchart1ChartPath, "--is-upgrade=false"},
   135  			expectKey:   "subchart1/templates/service.yaml",
   136  			expectValue: "release-is-install: \"true\"",
   137  		},
   138  		{
   139  			name:        "check_release_is_upgrade",
   140  			desc:        "verify --is-upgrade toggles .Release.IsUpgrade",
   141  			args:        []string{subchart1ChartPath, "--is-upgrade", "true"},
   142  			expectKey:   "subchart1/templates/service.yaml",
   143  			expectValue: "release-is-upgrade: \"true\"",
   144  		},
   145  		{
   146  			name:        "check_notes",
   147  			desc:        "verify --notes shows notes",
   148  			args:        []string{subchart1ChartPath, "--notes", "true"},
   149  			expectKey:   "subchart1/templates/NOTES.txt",
   150  			expectValue: "Sample notes for subchart1",
   151  		},
   152  		{
   153  			name:        "check_values_files",
   154  			desc:        "verify --values files values exist",
   155  			args:        []string{subchart1ChartPath, "--values", subchart1ChartPath + "/charts/subchartA/values.yaml"},
   156  			expectKey:   "subchart1/templates/service.yaml",
   157  			expectValue: "name: apache",
   158  		},
   159  		{
   160  			name:        "check_invalid_name_template",
   161  			desc:        "verify the relase name generate by template is invalid",
   162  			args:        []string{subchart1ChartPath, "--name-template", "foobar-{{ b64enc \"abc\" }}-baz"},
   163  			expectError: "is not a valid DNS label",
   164  		},
   165  		{
   166  			name:        "check_name_template",
   167  			desc:        "verify --name-template result exists",
   168  			args:        []string{subchart1ChartPath, "--name-template", "foobar-{{ lower \"ABC\" }}-baz"},
   169  			expectKey:   "subchart1/templates/service.yaml",
   170  			expectValue: "release-name: \"foobar-abc-baz\"",
   171  		},
   172  		{
   173  			name:        "check_kube_version",
   174  			desc:        "verify --kube-version overrides the kubernetes version",
   175  			args:        []string{subchart1ChartPath, "--kube-version", "1.6"},
   176  			expectKey:   "subchart1/templates/service.yaml",
   177  			expectValue: "kube-version/major: \"1\"\n    kube-version/minor: \"6\"\n    kube-version/gitversion: \"v1.6.0\"",
   178  		},
   179  	}
   180  
   181  	var buf bytes.Buffer
   182  	for _, tt := range tests {
   183  		tt := tt
   184  		t.Run(tt.name, func(t *testing.T) {
   185  			// capture stdout
   186  			old := os.Stdout
   187  			r, w, _ := os.Pipe()
   188  			os.Stdout = w
   189  			// execute template command
   190  			out := bytes.NewBuffer(nil)
   191  			cmd := newTemplateCmd(out)
   192  			cmd.SetArgs(tt.args)
   193  			err := cmd.Execute()
   194  
   195  			if tt.expectError != "" {
   196  				if err == nil {
   197  					t.Errorf("expected err: %s, but no error occurred", tt.expectError)
   198  				}
   199  				// non nil error, check if it contains the expected error
   200  				if strings.Contains(err.Error(), tt.expectError) {
   201  					// had the error we were looking for, this test case is
   202  					// done
   203  					return
   204  				}
   205  				t.Fatalf("expected err: %q, got: %q", tt.expectError, err)
   206  			} else if err != nil {
   207  				t.Errorf("expected no error, got %v", err)
   208  			}
   209  			// restore stdout
   210  			w.Close()
   211  			os.Stdout = old
   212  			var b bytes.Buffer
   213  			io.Copy(&b, r)
   214  			r.Close()
   215  			// scan yaml into map[<path>]yaml
   216  			scanner := bufio.NewScanner(&b)
   217  			next := false
   218  			lastKey := ""
   219  			m := map[string]string{}
   220  			for scanner.Scan() {
   221  				if scanner.Text() == "---" {
   222  					next = true
   223  				} else if next {
   224  					// remove '# Source: '
   225  					head := "# Source: "
   226  					lastKey = scanner.Text()[len(head):]
   227  					next = false
   228  				} else {
   229  					m[lastKey] = m[lastKey] + scanner.Text() + "\n"
   230  				}
   231  			}
   232  			if err := scanner.Err(); err != nil {
   233  				fmt.Fprintln(os.Stderr, "reading standard input:", err)
   234  			}
   235  			if v, ok := m[tt.expectKey]; ok {
   236  				if !strings.Contains(v, tt.expectValue) {
   237  					t.Errorf("failed to match expected value %s in %s", tt.expectValue, v)
   238  				}
   239  			} else {
   240  				t.Errorf("could not find key %s", tt.expectKey)
   241  			}
   242  			buf.Reset()
   243  		})
   244  	}
   245  }