github.com/koderover/helm@v2.17.0+incompatible/pkg/tiller/release_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 tiller
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  	"testing"
    23  
    24  	"k8s.io/helm/pkg/helm"
    25  	"k8s.io/helm/pkg/proto/hapi/chart"
    26  	"k8s.io/helm/pkg/proto/hapi/release"
    27  	"k8s.io/helm/pkg/proto/hapi/services"
    28  	"k8s.io/helm/pkg/version"
    29  )
    30  
    31  func TestHasCRDHook(t *testing.T) {
    32  	tests := []struct {
    33  		hooks  []*release.Hook
    34  		expect bool
    35  	}{
    36  		{
    37  			hooks: []*release.Hook{
    38  				{Events: []release.Hook_Event{release.Hook_PRE_DELETE}},
    39  			},
    40  			expect: false,
    41  		},
    42  		{
    43  			hooks: []*release.Hook{
    44  				{Events: []release.Hook_Event{release.Hook_CRD_INSTALL}},
    45  			},
    46  			expect: true,
    47  		},
    48  		{
    49  			hooks: []*release.Hook{
    50  				{Events: []release.Hook_Event{release.Hook_PRE_UPGRADE, release.Hook_CRD_INSTALL}},
    51  			},
    52  			expect: true,
    53  		},
    54  	}
    55  
    56  	for i, tt := range tests {
    57  		if tt.expect != hasCRDHook(tt.hooks) {
    58  			t.Errorf("test %d: expected %t, got %t", i, tt.expect, !tt.expect)
    59  		}
    60  	}
    61  }
    62  
    63  func TestInstallRelease(t *testing.T) {
    64  	c := helm.NewContext()
    65  	rs := rsFixture()
    66  
    67  	req := installRequest()
    68  	res, err := rs.InstallRelease(c, req)
    69  	if err != nil {
    70  		t.Fatalf("Failed install: %s", err)
    71  	}
    72  	if res.Release.Name == "" {
    73  		t.Errorf("Expected release name.")
    74  	}
    75  	if res.Release.Namespace != "spaced" {
    76  		t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace)
    77  	}
    78  
    79  	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
    80  	if err != nil {
    81  		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
    82  	}
    83  
    84  	t.Logf("rel: %v", rel)
    85  
    86  	if len(rel.Hooks) != 1 {
    87  		t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks))
    88  	}
    89  	if rel.Hooks[0].Manifest != manifestWithHook {
    90  		t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest)
    91  	}
    92  
    93  	if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL {
    94  		t.Errorf("Expected event 0 is post install")
    95  	}
    96  	if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE {
    97  		t.Errorf("Expected event 0 is pre-delete")
    98  	}
    99  
   100  	if len(res.Release.Manifest) == 0 {
   101  		t.Errorf("No manifest returned: %v", res.Release)
   102  	}
   103  
   104  	if len(rel.Manifest) == 0 {
   105  		t.Errorf("Expected manifest in %v", res)
   106  	}
   107  
   108  	if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
   109  		t.Errorf("unexpected output: %s", rel.Manifest)
   110  	}
   111  
   112  	if rel.Info.Description != "Install complete" {
   113  		t.Errorf("unexpected description: %s", rel.Info.Description)
   114  	}
   115  }
   116  
   117  func TestInstallRelease_WithNotes(t *testing.T) {
   118  	c := helm.NewContext()
   119  	rs := rsFixture()
   120  
   121  	req := installRequest(
   122  		withChart(withNotes(notesText)),
   123  	)
   124  	res, err := rs.InstallRelease(c, req)
   125  	if err != nil {
   126  		t.Fatalf("Failed install: %s", err)
   127  	}
   128  	if res.Release.Name == "" {
   129  		t.Errorf("Expected release name.")
   130  	}
   131  	if res.Release.Namespace != "spaced" {
   132  		t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace)
   133  	}
   134  
   135  	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
   136  	if err != nil {
   137  		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
   138  	}
   139  
   140  	t.Logf("rel: %v", rel)
   141  
   142  	if len(rel.Hooks) != 1 {
   143  		t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks))
   144  	}
   145  	if rel.Hooks[0].Manifest != manifestWithHook {
   146  		t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest)
   147  	}
   148  
   149  	if rel.Info.Status.Notes != notesText {
   150  		t.Fatalf("Expected '%s', got '%s'", notesText, rel.Info.Status.Notes)
   151  	}
   152  
   153  	if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL {
   154  		t.Errorf("Expected event 0 is post install")
   155  	}
   156  	if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE {
   157  		t.Errorf("Expected event 0 is pre-delete")
   158  	}
   159  
   160  	if len(res.Release.Manifest) == 0 {
   161  		t.Errorf("No manifest returned: %v", res.Release)
   162  	}
   163  
   164  	if len(rel.Manifest) == 0 {
   165  		t.Errorf("Expected manifest in %v", res)
   166  	}
   167  
   168  	if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
   169  		t.Errorf("unexpected output: %s", rel.Manifest)
   170  	}
   171  
   172  	if rel.Info.Description != "Install complete" {
   173  		t.Errorf("unexpected description: %s", rel.Info.Description)
   174  	}
   175  }
   176  
   177  func TestInstallRelease_WithNotesRendered(t *testing.T) {
   178  	c := helm.NewContext()
   179  	rs := rsFixture()
   180  
   181  	req := installRequest(
   182  		withChart(withNotes(notesText + " {{.Release.Name}}")),
   183  	)
   184  	res, err := rs.InstallRelease(c, req)
   185  	if err != nil {
   186  		t.Fatalf("Failed install: %s", err)
   187  	}
   188  	if res.Release.Name == "" {
   189  		t.Errorf("Expected release name.")
   190  	}
   191  	if res.Release.Namespace != "spaced" {
   192  		t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace)
   193  	}
   194  
   195  	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
   196  	if err != nil {
   197  		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
   198  	}
   199  
   200  	t.Logf("rel: %v", rel)
   201  
   202  	if len(rel.Hooks) != 1 {
   203  		t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks))
   204  	}
   205  	if rel.Hooks[0].Manifest != manifestWithHook {
   206  		t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest)
   207  	}
   208  
   209  	expectedNotes := fmt.Sprintf("%s %s", notesText, res.Release.Name)
   210  	if rel.Info.Status.Notes != expectedNotes {
   211  		t.Fatalf("Expected '%s', got '%s'", expectedNotes, rel.Info.Status.Notes)
   212  	}
   213  
   214  	if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL {
   215  		t.Errorf("Expected event 0 is post install")
   216  	}
   217  	if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE {
   218  		t.Errorf("Expected event 0 is pre-delete")
   219  	}
   220  
   221  	if len(res.Release.Manifest) == 0 {
   222  		t.Errorf("No manifest returned: %v", res.Release)
   223  	}
   224  
   225  	if len(rel.Manifest) == 0 {
   226  		t.Errorf("Expected manifest in %v", res)
   227  	}
   228  
   229  	if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
   230  		t.Errorf("unexpected output: %s", rel.Manifest)
   231  	}
   232  
   233  	if rel.Info.Description != "Install complete" {
   234  		t.Errorf("unexpected description: %s", rel.Info.Description)
   235  	}
   236  }
   237  
   238  func TestInstallRelease_TillerVersion(t *testing.T) {
   239  	version.Version = "2.2.0"
   240  	c := helm.NewContext()
   241  	rs := rsFixture()
   242  
   243  	req := installRequest(
   244  		withChart(withTiller(">=2.2.0")),
   245  	)
   246  	_, err := rs.InstallRelease(c, req)
   247  	if err != nil {
   248  		t.Fatalf("Expected valid range. Got %q", err)
   249  	}
   250  }
   251  
   252  func TestInstallRelease_WrongTillerVersion(t *testing.T) {
   253  	version.Version = "2.2.0"
   254  	c := helm.NewContext()
   255  	rs := rsFixture()
   256  
   257  	req := installRequest(
   258  		withChart(withTiller("<2.0.0")),
   259  	)
   260  	_, err := rs.InstallRelease(c, req)
   261  	if err == nil {
   262  		t.Fatalf("Expected to fail because of wrong version")
   263  	}
   264  
   265  	expect := "Chart incompatible with Tiller"
   266  	if !strings.Contains(err.Error(), expect) {
   267  		t.Errorf("Expected %q to contain %q", err.Error(), expect)
   268  	}
   269  }
   270  
   271  func TestInstallRelease_WithChartAndDependencyParentNotes(t *testing.T) {
   272  	c := helm.NewContext()
   273  	rs := rsFixture()
   274  
   275  	req := installRequest(withChart(
   276  		withNotes(notesText),
   277  		withDependency(withNotes(notesText+" child")),
   278  	))
   279  	res, err := rs.InstallRelease(c, req)
   280  	if err != nil {
   281  		t.Fatalf("Failed install: %s", err)
   282  	}
   283  	if res.Release.Name == "" {
   284  		t.Errorf("Expected release name.")
   285  	}
   286  
   287  	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
   288  	if err != nil {
   289  		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
   290  	}
   291  
   292  	t.Logf("rel: %v", rel)
   293  
   294  	if rel.Info.Status.Notes != notesText {
   295  		t.Fatalf("Expected '%s', got '%s'", notesText, rel.Info.Status.Notes)
   296  	}
   297  
   298  	if rel.Info.Description != "Install complete" {
   299  		t.Errorf("unexpected description: %s", rel.Info.Description)
   300  	}
   301  }
   302  
   303  func TestInstallRelease_WithChartAndDependencyAllNotes(t *testing.T) {
   304  	c := helm.NewContext()
   305  	rs := rsFixture()
   306  
   307  	req := installRequest(withSubNotes(),
   308  		withChart(
   309  			withNotes(notesText),
   310  			withDependency(withNotes(notesText+" child")),
   311  		))
   312  	res, err := rs.InstallRelease(c, req)
   313  	if err != nil {
   314  		t.Fatalf("Failed install: %s", err)
   315  	}
   316  	if res.Release.Name == "" {
   317  		t.Errorf("Expected release name.")
   318  	}
   319  
   320  	rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
   321  	if err != nil {
   322  		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
   323  	}
   324  
   325  	t.Logf("rel: %v", rel)
   326  
   327  	if !strings.Contains(rel.Info.Status.Notes, notesText) || !strings.Contains(rel.Info.Status.Notes, notesText+" child") {
   328  		t.Fatalf("Expected '%s', got '%s'", notesText+"\n"+notesText+" child", rel.Info.Status.Notes)
   329  	}
   330  
   331  	if rel.Info.Description != "Install complete" {
   332  		t.Errorf("unexpected description: %s", rel.Info.Description)
   333  	}
   334  }
   335  
   336  func TestInstallRelease_DryRun(t *testing.T) {
   337  	c := helm.NewContext()
   338  	rs := rsFixture()
   339  
   340  	req := installRequest(withDryRun(),
   341  		withChart(withSampleTemplates()),
   342  	)
   343  	res, err := rs.InstallRelease(c, req)
   344  	if err != nil {
   345  		t.Errorf("Failed install: %s", err)
   346  	}
   347  	if res.Release.Name == "" {
   348  		t.Errorf("Expected release name.")
   349  	}
   350  
   351  	if !strings.Contains(res.Release.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
   352  		t.Errorf("unexpected output: %s", res.Release.Manifest)
   353  	}
   354  
   355  	if !strings.Contains(res.Release.Manifest, "---\n# Source: hello/templates/goodbye\ngoodbye: world") {
   356  		t.Errorf("unexpected output: %s", res.Release.Manifest)
   357  	}
   358  
   359  	if !strings.Contains(res.Release.Manifest, "hello: Earth") {
   360  		t.Errorf("Should contain partial content. %s", res.Release.Manifest)
   361  	}
   362  
   363  	if strings.Contains(res.Release.Manifest, "hello: {{ template \"_planet\" . }}") {
   364  		t.Errorf("Should not contain partial templates itself. %s", res.Release.Manifest)
   365  	}
   366  
   367  	if strings.Contains(res.Release.Manifest, "empty") {
   368  		t.Errorf("Should not contain template data for an empty file. %s", res.Release.Manifest)
   369  	}
   370  
   371  	if _, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version); err == nil {
   372  		t.Errorf("Expected no stored release.")
   373  	}
   374  
   375  	if l := len(res.Release.Hooks); l != 1 {
   376  		t.Fatalf("Expected 1 hook, got %d", l)
   377  	}
   378  
   379  	if res.Release.Hooks[0].LastRun != nil {
   380  		t.Error("Expected hook to not be marked as run.")
   381  	}
   382  
   383  	if res.Release.Info.Description != "Dry run complete" {
   384  		t.Errorf("unexpected description: %s", res.Release.Info.Description)
   385  	}
   386  }
   387  
   388  func TestInstallRelease_NoHooks(t *testing.T) {
   389  	c := helm.NewContext()
   390  	rs := rsFixture()
   391  	rs.env.Releases.Create(releaseStub())
   392  
   393  	req := installRequest(withDisabledHooks())
   394  	res, err := rs.InstallRelease(c, req)
   395  	if err != nil {
   396  		t.Errorf("Failed install: %s", err)
   397  	}
   398  
   399  	if hl := res.Release.Hooks[0].LastRun; hl != nil {
   400  		t.Errorf("Expected that no hooks were run. Got %d", hl)
   401  	}
   402  }
   403  
   404  func TestInstallRelease_CRDInstallHook(t *testing.T) {
   405  	c := helm.NewContext()
   406  	rs := rsFixture()
   407  	rs.env.Releases.Create(releaseStub())
   408  
   409  	req := installRequest()
   410  	req.Chart.Templates = append(req.Chart.Templates, &chart.Template{
   411  		Name: "templates/crdhook",
   412  		Data: []byte(manifestWithCRDHook),
   413  	})
   414  
   415  	res, err := rs.InstallRelease(c, req)
   416  	if err != nil {
   417  		t.Errorf("Failed install: %s", err)
   418  	}
   419  
   420  	// The new hook should have been pulled from the manifest.
   421  	if l := len(res.Release.Hooks); l != 2 {
   422  		t.Fatalf("expected 2 hooks, got %d", l)
   423  	}
   424  
   425  	expect := "Install complete"
   426  	if got := res.Release.Info.Description; got != expect {
   427  		t.Errorf("Expected Description to be %q, got %q", expect, got)
   428  	}
   429  }
   430  
   431  func TestInstallRelease_DryRunCRDInstallHook(t *testing.T) {
   432  	c := helm.NewContext()
   433  	rs := rsFixture()
   434  	rs.env.Releases.Create(releaseStub())
   435  
   436  	req := installRequest(withDryRun())
   437  	req.Chart.Templates = append(req.Chart.Templates, &chart.Template{
   438  		Name: "templates/crdhook",
   439  		Data: []byte(manifestWithCRDHook),
   440  	})
   441  
   442  	res, err := rs.InstallRelease(c, req)
   443  	if err != nil {
   444  		t.Errorf("Failed install: %s", err)
   445  	}
   446  
   447  	expect := "Validation skipped because CRDs are not installed"
   448  	if res.Release.Info.Description != expect {
   449  		t.Errorf("Expected Description %q, got %q", expect, res.Release.Info.Description)
   450  	}
   451  }
   452  
   453  func TestInstallRelease_FailedHooks(t *testing.T) {
   454  	c := helm.NewContext()
   455  	rs := rsFixture()
   456  	rs.env.Releases.Create(releaseStub())
   457  	rs.env.KubeClient = newHookFailingKubeClient()
   458  
   459  	req := installRequest()
   460  	res, err := rs.InstallRelease(c, req)
   461  	if err == nil {
   462  		t.Error("Expected failed install")
   463  	}
   464  
   465  	if hl := res.Release.Info.Status.Code; hl != release.Status_FAILED {
   466  		t.Errorf("Expected FAILED release. Got %d", hl)
   467  	}
   468  }
   469  
   470  func TestInstallRelease_ReuseName(t *testing.T) {
   471  	c := helm.NewContext()
   472  	rs := rsFixture()
   473  	rel := releaseStub()
   474  	rel.Info.Status.Code = release.Status_DELETED
   475  	rs.env.Releases.Create(rel)
   476  
   477  	req := installRequest(
   478  		withReuseName(),
   479  		withName(rel.Name),
   480  	)
   481  	res, err := rs.InstallRelease(c, req)
   482  	if err != nil {
   483  		t.Fatalf("Failed install: %s", err)
   484  	}
   485  
   486  	if res.Release.Name != rel.Name {
   487  		t.Errorf("expected %q, got %q", rel.Name, res.Release.Name)
   488  	}
   489  
   490  	getreq := &services.GetReleaseStatusRequest{Name: rel.Name, Version: 0}
   491  	getres, err := rs.GetReleaseStatus(c, getreq)
   492  	if err != nil {
   493  		t.Errorf("Failed to retrieve release: %s", err)
   494  	}
   495  	if getres.Info.Status.Code != release.Status_DEPLOYED {
   496  		t.Errorf("Release status is %q", getres.Info.Status.Code)
   497  	}
   498  }
   499  
   500  func TestInstallRelease_KubeVersion(t *testing.T) {
   501  	c := helm.NewContext()
   502  	rs := rsFixture()
   503  
   504  	req := installRequest(
   505  		withChart(withKube(">=0.0.0-0")),
   506  	)
   507  	_, err := rs.InstallRelease(c, req)
   508  	if err != nil {
   509  		t.Fatalf("Expected valid range. Got %q", err)
   510  	}
   511  }
   512  
   513  func TestInstallRelease_WrongKubeVersion(t *testing.T) {
   514  	c := helm.NewContext()
   515  	rs := rsFixture()
   516  
   517  	req := installRequest(
   518  		withChart(withKube(">=5.0.0")),
   519  	)
   520  
   521  	_, err := rs.InstallRelease(c, req)
   522  	if err == nil {
   523  		t.Fatalf("Expected to fail because of wrong version")
   524  	}
   525  
   526  	expect := "Chart requires kubernetesVersion"
   527  	if !strings.Contains(err.Error(), expect) {
   528  		t.Errorf("Expected %q to contain %q", err.Error(), expect)
   529  	}
   530  }
   531  
   532  func TestInstallRelease_Description(t *testing.T) {
   533  	c := helm.NewContext()
   534  	rs := rsFixture()
   535  	rs.env.Releases.Create(releaseStub())
   536  
   537  	customDescription := "foo"
   538  	req := &services.InstallReleaseRequest{
   539  		Chart:       chartStub(),
   540  		Description: customDescription,
   541  	}
   542  	res, err := rs.InstallRelease(c, req)
   543  	if err != nil {
   544  		t.Errorf("Failed install: %s", err)
   545  	}
   546  
   547  	if desc := res.Release.Info.Description; desc != customDescription {
   548  		t.Errorf("Expected description %q. Got %q", customDescription, desc)
   549  	}
   550  }