github.com/darkowlzz/helm@v2.5.1-0.20171213183701-6707fe0468d4+incompatible/pkg/tiller/release_update_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 tiller
    18  
    19  import (
    20  	"strings"
    21  	"testing"
    22  
    23  	"github.com/golang/protobuf/proto"
    24  
    25  	"k8s.io/helm/pkg/helm"
    26  	"k8s.io/helm/pkg/proto/hapi/chart"
    27  	"k8s.io/helm/pkg/proto/hapi/release"
    28  	"k8s.io/helm/pkg/proto/hapi/services"
    29  )
    30  
    31  func TestUpdateRelease(t *testing.T) {
    32  	c := helm.NewContext()
    33  	rs := rsFixture()
    34  	rel := releaseStub()
    35  	rs.env.Releases.Create(rel)
    36  
    37  	req := &services.UpdateReleaseRequest{
    38  		Name: rel.Name,
    39  		Chart: &chart.Chart{
    40  			Metadata: &chart.Metadata{Name: "hello"},
    41  			Templates: []*chart.Template{
    42  				{Name: "templates/hello", Data: []byte("hello: world")},
    43  				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
    44  			},
    45  		},
    46  	}
    47  	res, err := rs.UpdateRelease(c, req)
    48  	if err != nil {
    49  		t.Fatalf("Failed updated: %s", err)
    50  	}
    51  
    52  	if res.Release.Name == "" {
    53  		t.Errorf("Expected release name.")
    54  	}
    55  
    56  	if res.Release.Name != rel.Name {
    57  		t.Errorf("Updated release name does not match previous release name. Expected %s, got %s", rel.Name, res.Release.Name)
    58  	}
    59  
    60  	if res.Release.Namespace != rel.Namespace {
    61  		t.Errorf("Expected release namespace '%s', got '%s'.", rel.Namespace, res.Release.Namespace)
    62  	}
    63  
    64  	updated := compareStoredAndReturnedRelease(t, *rs, *res)
    65  
    66  	if len(updated.Hooks) != 1 {
    67  		t.Fatalf("Expected 1 hook, got %d", len(updated.Hooks))
    68  	}
    69  	if updated.Hooks[0].Manifest != manifestWithUpgradeHooks {
    70  		t.Errorf("Unexpected manifest: %v", updated.Hooks[0].Manifest)
    71  	}
    72  
    73  	if updated.Hooks[0].Events[0] != release.Hook_POST_UPGRADE {
    74  		t.Errorf("Expected event 0 to be post upgrade")
    75  	}
    76  
    77  	if updated.Hooks[0].Events[1] != release.Hook_PRE_UPGRADE {
    78  		t.Errorf("Expected event 0 to be pre upgrade")
    79  	}
    80  
    81  	if len(updated.Manifest) == 0 {
    82  		t.Errorf("Expected manifest in %v", res)
    83  	}
    84  
    85  	if res.Release.Config == nil {
    86  		t.Errorf("Got release without config: %#v", res.Release)
    87  	} else if res.Release.Config.Raw != rel.Config.Raw {
    88  		t.Errorf("Expected release values %q, got %q", rel.Config.Raw, res.Release.Config.Raw)
    89  	}
    90  
    91  	if !strings.Contains(updated.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
    92  		t.Errorf("unexpected output: %s", updated.Manifest)
    93  	}
    94  
    95  	if res.Release.Version != 2 {
    96  		t.Errorf("Expected release version to be %v, got %v", 2, res.Release.Version)
    97  	}
    98  
    99  	edesc := "Upgrade complete"
   100  	if got := res.Release.Info.Description; got != edesc {
   101  		t.Errorf("Expected description %q, got %q", edesc, got)
   102  	}
   103  }
   104  func TestUpdateRelease_ResetValues(t *testing.T) {
   105  	c := helm.NewContext()
   106  	rs := rsFixture()
   107  	rel := releaseStub()
   108  	rs.env.Releases.Create(rel)
   109  
   110  	req := &services.UpdateReleaseRequest{
   111  		Name: rel.Name,
   112  		Chart: &chart.Chart{
   113  			Metadata: &chart.Metadata{Name: "hello"},
   114  			Templates: []*chart.Template{
   115  				{Name: "templates/hello", Data: []byte("hello: world")},
   116  				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
   117  			},
   118  		},
   119  		ResetValues: true,
   120  	}
   121  	res, err := rs.UpdateRelease(c, req)
   122  	if err != nil {
   123  		t.Fatalf("Failed updated: %s", err)
   124  	}
   125  	// This should have been unset. Config:  &chart.Config{Raw: `name: value`},
   126  	if res.Release.Config != nil && res.Release.Config.Raw != "" {
   127  		t.Errorf("Expected chart config to be empty, got %q", res.Release.Config.Raw)
   128  	}
   129  }
   130  
   131  func TestUpdateRelease_ReuseValues(t *testing.T) {
   132  	c := helm.NewContext()
   133  	rs := rsFixture()
   134  	rel := releaseStub()
   135  	rs.env.Releases.Create(rel)
   136  
   137  	req := &services.UpdateReleaseRequest{
   138  		Name: rel.Name,
   139  		Chart: &chart.Chart{
   140  			Metadata: &chart.Metadata{Name: "hello"},
   141  			Templates: []*chart.Template{
   142  				{Name: "templates/hello", Data: []byte("hello: world")},
   143  				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
   144  			},
   145  			// Since reuseValues is set, this should get ignored.
   146  			Values: &chart.Config{Raw: "foo: bar\n"},
   147  		},
   148  		Values:      &chart.Config{Raw: "name2: val2"},
   149  		ReuseValues: true,
   150  	}
   151  	res, err := rs.UpdateRelease(c, req)
   152  	if err != nil {
   153  		t.Fatalf("Failed updated: %s", err)
   154  	}
   155  	// This should have been overwritten with the old value.
   156  	expect := "name: value\n"
   157  	if res.Release.Chart.Values != nil && res.Release.Chart.Values.Raw != expect {
   158  		t.Errorf("Expected chart values to be %q, got %q", expect, res.Release.Chart.Values.Raw)
   159  	}
   160  	// This should have the newly-passed overrides.
   161  	expect = "name2: val2"
   162  	if res.Release.Config != nil && res.Release.Config.Raw != expect {
   163  		t.Errorf("Expected request config to be %q, got %q", expect, res.Release.Config.Raw)
   164  	}
   165  	compareStoredAndReturnedRelease(t, *rs, *res)
   166  }
   167  
   168  func TestUpdateRelease_ResetReuseValues(t *testing.T) {
   169  	// This verifies that when both reset and reuse are set, reset wins.
   170  	c := helm.NewContext()
   171  	rs := rsFixture()
   172  	rel := releaseStub()
   173  	rs.env.Releases.Create(rel)
   174  
   175  	req := &services.UpdateReleaseRequest{
   176  		Name: rel.Name,
   177  		Chart: &chart.Chart{
   178  			Metadata: &chart.Metadata{Name: "hello"},
   179  			Templates: []*chart.Template{
   180  				{Name: "templates/hello", Data: []byte("hello: world")},
   181  				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
   182  			},
   183  		},
   184  		ResetValues: true,
   185  		ReuseValues: true,
   186  	}
   187  	res, err := rs.UpdateRelease(c, req)
   188  	if err != nil {
   189  		t.Fatalf("Failed updated: %s", err)
   190  	}
   191  	// This should have been unset. Config:  &chart.Config{Raw: `name: value`},
   192  	if res.Release.Config != nil && res.Release.Config.Raw != "" {
   193  		t.Errorf("Expected chart config to be empty, got %q", res.Release.Config.Raw)
   194  	}
   195  	compareStoredAndReturnedRelease(t, *rs, *res)
   196  }
   197  
   198  func TestUpdateReleaseFailure(t *testing.T) {
   199  	c := helm.NewContext()
   200  	rs := rsFixture()
   201  	rel := releaseStub()
   202  	rs.env.Releases.Create(rel)
   203  	rs.env.KubeClient = newUpdateFailingKubeClient()
   204  	rs.Log = t.Logf
   205  
   206  	req := &services.UpdateReleaseRequest{
   207  		Name:         rel.Name,
   208  		DisableHooks: true,
   209  		Chart: &chart.Chart{
   210  			Metadata: &chart.Metadata{Name: "hello"},
   211  			Templates: []*chart.Template{
   212  				{Name: "templates/something", Data: []byte("hello: world")},
   213  			},
   214  		},
   215  	}
   216  
   217  	res, err := rs.UpdateRelease(c, req)
   218  	if err == nil {
   219  		t.Error("Expected failed update")
   220  	}
   221  
   222  	if updatedStatus := res.Release.Info.Status.Code; updatedStatus != release.Status_FAILED {
   223  		t.Errorf("Expected FAILED release. Got %d", updatedStatus)
   224  	}
   225  
   226  	compareStoredAndReturnedRelease(t, *rs, *res)
   227  
   228  	edesc := "Upgrade \"angry-panda\" failed: Failed update in kube client"
   229  	if got := res.Release.Info.Description; got != edesc {
   230  		t.Errorf("Expected description %q, got %q", edesc, got)
   231  	}
   232  
   233  	oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version)
   234  	if err != nil {
   235  		t.Errorf("Expected to be able to get previous release")
   236  	}
   237  	if oldStatus := oldRelease.Info.Status.Code; oldStatus != release.Status_DEPLOYED {
   238  		t.Errorf("Expected Deployed status on previous Release version. Got %v", oldStatus)
   239  	}
   240  }
   241  
   242  func TestUpdateReleaseNoHooks(t *testing.T) {
   243  	c := helm.NewContext()
   244  	rs := rsFixture()
   245  	rel := releaseStub()
   246  	rs.env.Releases.Create(rel)
   247  
   248  	req := &services.UpdateReleaseRequest{
   249  		Name:         rel.Name,
   250  		DisableHooks: true,
   251  		Chart: &chart.Chart{
   252  			Metadata: &chart.Metadata{Name: "hello"},
   253  			Templates: []*chart.Template{
   254  				{Name: "templates/hello", Data: []byte("hello: world")},
   255  				{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
   256  			},
   257  		},
   258  	}
   259  
   260  	res, err := rs.UpdateRelease(c, req)
   261  	if err != nil {
   262  		t.Fatalf("Failed updated: %s", err)
   263  	}
   264  
   265  	if hl := res.Release.Hooks[0].LastRun; hl != nil {
   266  		t.Errorf("Expected that no hooks were run. Got %d", hl)
   267  	}
   268  
   269  }
   270  
   271  func TestUpdateReleaseNoChanges(t *testing.T) {
   272  	c := helm.NewContext()
   273  	rs := rsFixture()
   274  	rel := releaseStub()
   275  	rs.env.Releases.Create(rel)
   276  
   277  	req := &services.UpdateReleaseRequest{
   278  		Name:         rel.Name,
   279  		DisableHooks: true,
   280  		Chart:        rel.GetChart(),
   281  	}
   282  
   283  	_, err := rs.UpdateRelease(c, req)
   284  	if err != nil {
   285  		t.Fatalf("Failed updated: %s", err)
   286  	}
   287  }
   288  
   289  func compareStoredAndReturnedRelease(t *testing.T, rs ReleaseServer, res services.UpdateReleaseResponse) *release.Release {
   290  	storedRelease, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
   291  	if err != nil {
   292  		t.Fatalf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
   293  	}
   294  
   295  	if !proto.Equal(storedRelease, res.Release) {
   296  		t.Errorf("Stored release doesn't match returned Release")
   297  	}
   298  
   299  	return storedRelease
   300  }