github.com/Beeketing/helm@v2.12.1+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_WithChartAndDependencyNotes(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_DryRun(t *testing.T) {
   304  	c := helm.NewContext()
   305  	rs := rsFixture()
   306  
   307  	req := installRequest(withDryRun(),
   308  		withChart(withSampleTemplates()),
   309  	)
   310  	res, err := rs.InstallRelease(c, req)
   311  	if err != nil {
   312  		t.Errorf("Failed install: %s", err)
   313  	}
   314  	if res.Release.Name == "" {
   315  		t.Errorf("Expected release name.")
   316  	}
   317  
   318  	if !strings.Contains(res.Release.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
   319  		t.Errorf("unexpected output: %s", res.Release.Manifest)
   320  	}
   321  
   322  	if !strings.Contains(res.Release.Manifest, "---\n# Source: hello/templates/goodbye\ngoodbye: world") {
   323  		t.Errorf("unexpected output: %s", res.Release.Manifest)
   324  	}
   325  
   326  	if !strings.Contains(res.Release.Manifest, "hello: Earth") {
   327  		t.Errorf("Should contain partial content. %s", res.Release.Manifest)
   328  	}
   329  
   330  	if strings.Contains(res.Release.Manifest, "hello: {{ template \"_planet\" . }}") {
   331  		t.Errorf("Should not contain partial templates itself. %s", res.Release.Manifest)
   332  	}
   333  
   334  	if strings.Contains(res.Release.Manifest, "empty") {
   335  		t.Errorf("Should not contain template data for an empty file. %s", res.Release.Manifest)
   336  	}
   337  
   338  	if _, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version); err == nil {
   339  		t.Errorf("Expected no stored release.")
   340  	}
   341  
   342  	if l := len(res.Release.Hooks); l != 1 {
   343  		t.Fatalf("Expected 1 hook, got %d", l)
   344  	}
   345  
   346  	if res.Release.Hooks[0].LastRun != nil {
   347  		t.Error("Expected hook to not be marked as run.")
   348  	}
   349  
   350  	if res.Release.Info.Description != "Dry run complete" {
   351  		t.Errorf("unexpected description: %s", res.Release.Info.Description)
   352  	}
   353  }
   354  
   355  func TestInstallRelease_NoHooks(t *testing.T) {
   356  	c := helm.NewContext()
   357  	rs := rsFixture()
   358  	rs.env.Releases.Create(releaseStub())
   359  
   360  	req := installRequest(withDisabledHooks())
   361  	res, err := rs.InstallRelease(c, req)
   362  	if err != nil {
   363  		t.Errorf("Failed install: %s", err)
   364  	}
   365  
   366  	if hl := res.Release.Hooks[0].LastRun; hl != nil {
   367  		t.Errorf("Expected that no hooks were run. Got %d", hl)
   368  	}
   369  }
   370  
   371  func TestInstallRelease_CRDInstallHook(t *testing.T) {
   372  	c := helm.NewContext()
   373  	rs := rsFixture()
   374  	rs.env.Releases.Create(releaseStub())
   375  
   376  	req := installRequest()
   377  	req.Chart.Templates = append(req.Chart.Templates, &chart.Template{
   378  		Name: "templates/crdhook",
   379  		Data: []byte(manifestWithCRDHook),
   380  	})
   381  
   382  	res, err := rs.InstallRelease(c, req)
   383  	if err != nil {
   384  		t.Errorf("Failed install: %s", err)
   385  	}
   386  
   387  	// The new hook should have been pulled from the manifest.
   388  	if l := len(res.Release.Hooks); l != 2 {
   389  		t.Fatalf("expected 2 hooks, got %d", l)
   390  	}
   391  
   392  	expect := "Install complete"
   393  	if got := res.Release.Info.Description; got != expect {
   394  		t.Errorf("Expected Description to be %q, got %q", expect, got)
   395  	}
   396  }
   397  
   398  func TestInstallRelease_DryRunCRDInstallHook(t *testing.T) {
   399  	c := helm.NewContext()
   400  	rs := rsFixture()
   401  	rs.env.Releases.Create(releaseStub())
   402  
   403  	req := installRequest(withDryRun())
   404  	req.Chart.Templates = append(req.Chart.Templates, &chart.Template{
   405  		Name: "templates/crdhook",
   406  		Data: []byte(manifestWithCRDHook),
   407  	})
   408  
   409  	res, err := rs.InstallRelease(c, req)
   410  	if err != nil {
   411  		t.Errorf("Failed install: %s", err)
   412  	}
   413  
   414  	expect := "Validation skipped because CRDs are not installed"
   415  	if res.Release.Info.Description != expect {
   416  		t.Errorf("Expected Description %q, got %q", expect, res.Release.Info.Description)
   417  	}
   418  }
   419  
   420  func TestInstallRelease_FailedHooks(t *testing.T) {
   421  	c := helm.NewContext()
   422  	rs := rsFixture()
   423  	rs.env.Releases.Create(releaseStub())
   424  	rs.env.KubeClient = newHookFailingKubeClient()
   425  
   426  	req := installRequest()
   427  	res, err := rs.InstallRelease(c, req)
   428  	if err == nil {
   429  		t.Error("Expected failed install")
   430  	}
   431  
   432  	if hl := res.Release.Info.Status.Code; hl != release.Status_FAILED {
   433  		t.Errorf("Expected FAILED release. Got %d", hl)
   434  	}
   435  }
   436  
   437  func TestInstallRelease_ReuseName(t *testing.T) {
   438  	c := helm.NewContext()
   439  	rs := rsFixture()
   440  	rel := releaseStub()
   441  	rel.Info.Status.Code = release.Status_DELETED
   442  	rs.env.Releases.Create(rel)
   443  
   444  	req := installRequest(
   445  		withReuseName(),
   446  		withName(rel.Name),
   447  	)
   448  	res, err := rs.InstallRelease(c, req)
   449  	if err != nil {
   450  		t.Fatalf("Failed install: %s", err)
   451  	}
   452  
   453  	if res.Release.Name != rel.Name {
   454  		t.Errorf("expected %q, got %q", rel.Name, res.Release.Name)
   455  	}
   456  
   457  	getreq := &services.GetReleaseStatusRequest{Name: rel.Name, Version: 0}
   458  	getres, err := rs.GetReleaseStatus(c, getreq)
   459  	if err != nil {
   460  		t.Errorf("Failed to retrieve release: %s", err)
   461  	}
   462  	if getres.Info.Status.Code != release.Status_DEPLOYED {
   463  		t.Errorf("Release status is %q", getres.Info.Status.Code)
   464  	}
   465  }
   466  
   467  func TestInstallRelease_KubeVersion(t *testing.T) {
   468  	c := helm.NewContext()
   469  	rs := rsFixture()
   470  
   471  	req := installRequest(
   472  		withChart(withKube(">=0.0.0")),
   473  	)
   474  	_, err := rs.InstallRelease(c, req)
   475  	if err != nil {
   476  		t.Fatalf("Expected valid range. Got %q", err)
   477  	}
   478  }
   479  
   480  func TestInstallRelease_WrongKubeVersion(t *testing.T) {
   481  	c := helm.NewContext()
   482  	rs := rsFixture()
   483  
   484  	req := installRequest(
   485  		withChart(withKube(">=5.0.0")),
   486  	)
   487  
   488  	_, err := rs.InstallRelease(c, req)
   489  	if err == nil {
   490  		t.Fatalf("Expected to fail because of wrong version")
   491  	}
   492  
   493  	expect := "Chart requires kubernetesVersion"
   494  	if !strings.Contains(err.Error(), expect) {
   495  		t.Errorf("Expected %q to contain %q", err.Error(), expect)
   496  	}
   497  }
   498  
   499  func TestInstallRelease_Description(t *testing.T) {
   500  	c := helm.NewContext()
   501  	rs := rsFixture()
   502  	rs.env.Releases.Create(releaseStub())
   503  
   504  	customDescription := "foo"
   505  	req := &services.InstallReleaseRequest{
   506  		Chart:       chartStub(),
   507  		Description: customDescription,
   508  	}
   509  	res, err := rs.InstallRelease(c, req)
   510  	if err != nil {
   511  		t.Errorf("Failed install: %s", err)
   512  	}
   513  
   514  	if desc := res.Release.Info.Description; desc != customDescription {
   515  		t.Errorf("Expected description %q. Got %q", customDescription, desc)
   516  	}
   517  }