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 }