github.com/koderover/helm@v2.17.0+incompatible/pkg/tiller/release_rollback_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  	"strings"
    21  	"testing"
    22  
    23  	"k8s.io/helm/pkg/helm"
    24  	"k8s.io/helm/pkg/proto/hapi/release"
    25  	"k8s.io/helm/pkg/proto/hapi/services"
    26  )
    27  
    28  func TestRollbackRelease(t *testing.T) {
    29  	c := helm.NewContext()
    30  	rs := rsFixture()
    31  	rel := releaseStub()
    32  	rs.env.Releases.Create(rel)
    33  	upgradedRel := upgradeReleaseVersion(rel)
    34  	upgradedRel.Hooks = []*release.Hook{
    35  		{
    36  			Name:     "test-cm",
    37  			Kind:     "ConfigMap",
    38  			Path:     "test-cm",
    39  			Manifest: manifestWithRollbackHooks,
    40  			Events: []release.Hook_Event{
    41  				release.Hook_PRE_ROLLBACK,
    42  				release.Hook_POST_ROLLBACK,
    43  			},
    44  		},
    45  	}
    46  
    47  	upgradedRel.Manifest = "hello world"
    48  	rs.env.Releases.Update(rel)
    49  	rs.env.Releases.Create(upgradedRel)
    50  
    51  	req := &services.RollbackReleaseRequest{
    52  		Name: rel.Name,
    53  	}
    54  	res, err := rs.RollbackRelease(c, req)
    55  	if err != nil {
    56  		t.Fatalf("Failed rollback: %s", err)
    57  	}
    58  
    59  	if res.Release.Name == "" {
    60  		t.Errorf("Expected release name.")
    61  	}
    62  
    63  	if res.Release.Name != rel.Name {
    64  		t.Errorf("Updated release name does not match previous release name. Expected %s, got %s", rel.Name, res.Release.Name)
    65  	}
    66  
    67  	if res.Release.Namespace != rel.Namespace {
    68  		t.Errorf("Expected release namespace '%s', got '%s'.", rel.Namespace, res.Release.Namespace)
    69  	}
    70  
    71  	if res.Release.Version != 3 {
    72  		t.Errorf("Expected release version to be %v, got %v", 3, res.Release.Version)
    73  	}
    74  
    75  	updated, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version)
    76  	if err != nil {
    77  		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
    78  	}
    79  
    80  	if len(updated.Hooks) != 2 {
    81  		t.Fatalf("Expected 2 hooks, got %d", len(updated.Hooks))
    82  	}
    83  
    84  	if updated.Hooks[0].Manifest != manifestWithHook {
    85  		t.Errorf("Unexpected manifest: %v", updated.Hooks[0].Manifest)
    86  	}
    87  
    88  	anotherUpgradedRelease := upgradeReleaseVersion(upgradedRel)
    89  	rs.env.Releases.Update(upgradedRel)
    90  	rs.env.Releases.Create(anotherUpgradedRelease)
    91  
    92  	res, err = rs.RollbackRelease(c, req)
    93  	if err != nil {
    94  		t.Fatalf("Failed rollback: %s", err)
    95  	}
    96  
    97  	updated, err = rs.env.Releases.Get(res.Release.Name, res.Release.Version)
    98  	if err != nil {
    99  		t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases)
   100  	}
   101  
   102  	if len(updated.Hooks) != 1 {
   103  		t.Fatalf("Expected 1 hook, got %d", len(updated.Hooks))
   104  	}
   105  
   106  	if updated.Hooks[0].Manifest != manifestWithRollbackHooks {
   107  		t.Errorf("Unexpected manifest: %v", updated.Hooks[0].Manifest)
   108  	}
   109  
   110  	if res.Release.Version != 4 {
   111  		t.Errorf("Expected release version to be %v, got %v", 3, res.Release.Version)
   112  	}
   113  
   114  	if updated.Hooks[0].Events[0] != release.Hook_PRE_ROLLBACK {
   115  		t.Errorf("Expected event 0 to be pre rollback")
   116  	}
   117  
   118  	if updated.Hooks[0].Events[1] != release.Hook_POST_ROLLBACK {
   119  		t.Errorf("Expected event 1 to be post rollback")
   120  	}
   121  
   122  	if len(res.Release.Manifest) == 0 {
   123  		t.Errorf("No manifest returned: %v", res.Release)
   124  	}
   125  
   126  	if len(updated.Manifest) == 0 {
   127  		t.Errorf("Expected manifest in %v", res)
   128  	}
   129  
   130  	if !strings.Contains(updated.Manifest, "hello world") {
   131  		t.Errorf("unexpected output: %s", rel.Manifest)
   132  	}
   133  
   134  	if res.Release.Info.Description != "Rollback to 2" {
   135  		t.Errorf("Expected rollback to 2, got %q", res.Release.Info.Description)
   136  	}
   137  }
   138  
   139  func TestRollbackWithReleaseVersion(t *testing.T) {
   140  	c := helm.NewContext()
   141  	rs := rsFixture()
   142  	rs.Log = t.Logf
   143  	rs.env.Releases.Log = t.Logf
   144  	rel2 := releaseStub()
   145  	rel2.Name = "other"
   146  	rs.env.Releases.Create(rel2)
   147  	rel := releaseStub()
   148  	rs.env.Releases.Create(rel)
   149  	v2 := upgradeReleaseVersion(rel)
   150  	rs.env.Releases.Update(rel)
   151  	rs.env.Releases.Create(v2)
   152  	v3 := upgradeReleaseVersion(v2)
   153  	// retain the original release as DEPLOYED while the update should fail
   154  	v2.Info.Status.Code = release.Status_DEPLOYED
   155  	v3.Info.Status.Code = release.Status_FAILED
   156  	rs.env.Releases.Update(v2)
   157  	rs.env.Releases.Create(v3)
   158  
   159  	req := &services.RollbackReleaseRequest{
   160  		Name:         rel.Name,
   161  		DisableHooks: true,
   162  		Version:      1,
   163  	}
   164  
   165  	_, err := rs.RollbackRelease(c, req)
   166  	if err != nil {
   167  		t.Fatalf("Failed rollback: %s", err)
   168  	}
   169  	// check that v2 is now in a SUPERSEDED state
   170  	oldRel, err := rs.env.Releases.Get(rel.Name, 2)
   171  	if err != nil {
   172  		t.Fatalf("Failed to retrieve v2: %s", err)
   173  	}
   174  	if oldRel.Info.Status.Code != release.Status_SUPERSEDED {
   175  		t.Errorf("Expected v2 to be in a SUPERSEDED state, got %q", oldRel.Info.Status.Code)
   176  	}
   177  	// make sure we didn't update some other deployments.
   178  	otherRel, err := rs.env.Releases.Get(rel2.Name, 1)
   179  	if err != nil {
   180  		t.Fatalf("Failed to retrieve other v1: %s", err)
   181  	}
   182  	if otherRel.Info.Status.Code != release.Status_DEPLOYED {
   183  		t.Errorf("Expected other deployed release to stay untouched, got %q", otherRel.Info.Status.Code)
   184  	}
   185  }
   186  
   187  func TestRollbackDeleted(t *testing.T) {
   188  	c := helm.NewContext()
   189  	rs := rsFixture()
   190  	rs.Log = t.Logf
   191  	rs.env.Releases.Log = t.Logf
   192  	rel2 := releaseStub()
   193  	rel2.Name = "other"
   194  	rs.env.Releases.Create(rel2)
   195  	rel := releaseStub()
   196  	rs.env.Releases.Create(rel)
   197  	v2 := upgradeReleaseVersion(rel)
   198  	rs.env.Releases.Update(rel)
   199  	rs.env.Releases.Create(v2)
   200  	v3 := upgradeReleaseVersion(v2)
   201  	// retain the original release as DEPLOYED while the update should fail
   202  	v2.Info.Status.Code = release.Status_DEPLOYED
   203  	v3.Info.Status.Code = release.Status_FAILED
   204  	rs.env.Releases.Update(v2)
   205  	rs.env.Releases.Create(v3)
   206  
   207  	req1 := &services.UninstallReleaseRequest{
   208  		Name:         rel.Name,
   209  		DisableHooks: true,
   210  	}
   211  
   212  	_, err := rs.UninstallRelease(c, req1)
   213  	if err != nil {
   214  		t.Fatalf("Failed uninstall: %s", err)
   215  	}
   216  
   217  	oldRel, err := rs.env.Releases.Get(rel.Name, 3)
   218  	if err != nil {
   219  		t.Fatalf("Failed to retrieve v3: %s", err)
   220  	}
   221  	if oldRel.Info.Status.Code != release.Status_DELETED {
   222  		t.Errorf("Expected v3 to be in a DELETED state, got %q", oldRel.Info.Status.Code)
   223  	}
   224  
   225  	req2 := &services.RollbackReleaseRequest{
   226  		Name:         rel.Name,
   227  		DisableHooks: true,
   228  		Version:      2,
   229  	}
   230  
   231  	_, err = rs.RollbackRelease(c, req2)
   232  	if err != nil {
   233  		t.Fatalf("Failed rollback: %s", err)
   234  	}
   235  	// check that v3 is now in a SUPERSEDED state
   236  	oldRel, err = rs.env.Releases.Get(rel.Name, 3)
   237  	if err != nil {
   238  		t.Fatalf("Failed to retrieve v3: %s", err)
   239  	}
   240  	if oldRel.Info.Status.Code != release.Status_SUPERSEDED {
   241  		t.Errorf("Expected v3 to be in a SUPERSEDED state, got %q", oldRel.Info.Status.Code)
   242  	}
   243  	// make sure we didn't update some other deployments.
   244  	otherRel, err := rs.env.Releases.Get(rel2.Name, 1)
   245  	if err != nil {
   246  		t.Fatalf("Failed to retrieve other v1: %s", err)
   247  	}
   248  	if otherRel.Info.Status.Code != release.Status_DEPLOYED {
   249  		t.Errorf("Expected other deployed release to stay untouched, got %q", otherRel.Info.Status.Code)
   250  	}
   251  }
   252  
   253  func TestRollbackReleaseNoHooks(t *testing.T) {
   254  	c := helm.NewContext()
   255  	rs := rsFixture()
   256  	rel := releaseStub()
   257  	rel.Hooks = []*release.Hook{
   258  		{
   259  			Name:     "test-cm",
   260  			Kind:     "ConfigMap",
   261  			Path:     "test-cm",
   262  			Manifest: manifestWithRollbackHooks,
   263  			Events: []release.Hook_Event{
   264  				release.Hook_PRE_ROLLBACK,
   265  				release.Hook_POST_ROLLBACK,
   266  			},
   267  		},
   268  	}
   269  	rs.env.Releases.Create(rel)
   270  	upgradedRel := upgradeReleaseVersion(rel)
   271  	rs.env.Releases.Update(rel)
   272  	rs.env.Releases.Create(upgradedRel)
   273  
   274  	req := &services.RollbackReleaseRequest{
   275  		Name:         rel.Name,
   276  		DisableHooks: true,
   277  	}
   278  
   279  	res, err := rs.RollbackRelease(c, req)
   280  	if err != nil {
   281  		t.Fatalf("Failed rollback: %s", err)
   282  	}
   283  
   284  	if hl := res.Release.Hooks[0].LastRun; hl != nil {
   285  		t.Errorf("Expected that no hooks were run. Got %d", hl)
   286  	}
   287  }
   288  
   289  func TestRollbackReleaseFailure(t *testing.T) {
   290  	c := helm.NewContext()
   291  	rs := rsFixture()
   292  	rel := releaseStub()
   293  	rs.env.Releases.Create(rel)
   294  	upgradedRel := upgradeReleaseVersion(rel)
   295  	rs.env.Releases.Update(rel)
   296  	rs.env.Releases.Create(upgradedRel)
   297  
   298  	req := &services.RollbackReleaseRequest{
   299  		Name:         rel.Name,
   300  		DisableHooks: true,
   301  	}
   302  
   303  	rs.env.KubeClient = newUpdateFailingKubeClient()
   304  	res, err := rs.RollbackRelease(c, req)
   305  	if err == nil {
   306  		t.Error("Expected failed rollback")
   307  	}
   308  
   309  	if targetStatus := res.Release.Info.Status.Code; targetStatus != release.Status_FAILED {
   310  		t.Errorf("Expected FAILED release. Got %v", targetStatus)
   311  	}
   312  
   313  	oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version)
   314  	if err != nil {
   315  		t.Errorf("Expected to be able to get previous release")
   316  	}
   317  	if oldStatus := oldRelease.Info.Status.Code; oldStatus != release.Status_SUPERSEDED {
   318  		t.Errorf("Expected SUPERSEDED status on previous Release version. Got %v", oldStatus)
   319  	}
   320  }
   321  
   322  func TestRollbackReleaseWithCustomDescription(t *testing.T) {
   323  	c := helm.NewContext()
   324  	rs := rsFixture()
   325  	rel := releaseStub()
   326  	rs.env.Releases.Create(rel)
   327  	upgradedRel := upgradeReleaseVersion(rel)
   328  	rs.env.Releases.Update(rel)
   329  	rs.env.Releases.Create(upgradedRel)
   330  
   331  	customDescription := "foo"
   332  	req := &services.RollbackReleaseRequest{
   333  		Name:        rel.Name,
   334  		Description: customDescription,
   335  	}
   336  	res, err := rs.RollbackRelease(c, req)
   337  	if err != nil {
   338  		t.Fatalf("Failed rollback: %s", err)
   339  	}
   340  
   341  	if res.Release.Name == "" {
   342  		t.Errorf("Expected release name.")
   343  	}
   344  
   345  	if res.Release.Name != rel.Name {
   346  		t.Errorf("Updated release name does not match previous release name. Expected %s, got %s", rel.Name, res.Release.Name)
   347  	}
   348  
   349  	if res.Release.Info.Description != customDescription {
   350  		t.Errorf("Expected Description to be %q, got %q", customDescription, res.Release.Info.Description)
   351  	}
   352  }