github.com/azlyth/helm@v2.8.2+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 expectedDescription := "Upgrade \"angry-panda\" failed: Failed update in kube client" 229 if got := res.Release.Info.Description; got != expectedDescription { 230 t.Errorf("Expected description %q, got %q", expectedDescription, 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 TestUpdateReleaseFailure_Force(t *testing.T) { 243 c := helm.NewContext() 244 rs := rsFixture() 245 rel := namedReleaseStub("forceful-luke", release.Status_FAILED) 246 rs.env.Releases.Create(rel) 247 rs.Log = t.Logf 248 249 req := &services.UpdateReleaseRequest{ 250 Name: rel.Name, 251 DisableHooks: true, 252 Chart: &chart.Chart{ 253 Metadata: &chart.Metadata{Name: "hello"}, 254 Templates: []*chart.Template{ 255 {Name: "templates/something", Data: []byte("text: 'Did you ever hear the tragedy of Darth Plagueis the Wise? I thought not. It’s not a story the Jedi would tell you. It’s a Sith legend. Darth Plagueis was a Dark Lord of the Sith, so powerful and so wise he could use the Force to influence the Midichlorians to create life... He had such a knowledge of the Dark Side that he could even keep the ones he cared about from dying. The Dark Side of the Force is a pathway to many abilities some consider to be unnatural. He became so powerful... The only thing he was afraid of was losing his power, which eventually, of course, he did. Unfortunately, he taught his apprentice everything he knew, then his apprentice killed him in his sleep. Ironic. He could save others from death, but not himself.'")}, 256 }, 257 }, 258 Force: true, 259 } 260 261 res, err := rs.UpdateRelease(c, req) 262 if err != nil { 263 t.Errorf("Expected successful update, got %v", err) 264 } 265 266 if updatedStatus := res.Release.Info.Status.Code; updatedStatus != release.Status_DEPLOYED { 267 t.Errorf("Expected DEPLOYED release. Got %d", updatedStatus) 268 } 269 270 compareStoredAndReturnedRelease(t, *rs, *res) 271 272 expectedDescription := "Upgrade complete" 273 if got := res.Release.Info.Description; got != expectedDescription { 274 t.Errorf("Expected description %q, got %q", expectedDescription, got) 275 } 276 277 oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version) 278 if err != nil { 279 t.Errorf("Expected to be able to get previous release") 280 } 281 if oldStatus := oldRelease.Info.Status.Code; oldStatus != release.Status_DELETED { 282 t.Errorf("Expected Deleted status on previous Release version. Got %v", oldStatus) 283 } 284 } 285 286 func TestUpdateReleaseNoHooks(t *testing.T) { 287 c := helm.NewContext() 288 rs := rsFixture() 289 rel := releaseStub() 290 rs.env.Releases.Create(rel) 291 292 req := &services.UpdateReleaseRequest{ 293 Name: rel.Name, 294 DisableHooks: true, 295 Chart: &chart.Chart{ 296 Metadata: &chart.Metadata{Name: "hello"}, 297 Templates: []*chart.Template{ 298 {Name: "templates/hello", Data: []byte("hello: world")}, 299 {Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)}, 300 }, 301 }, 302 } 303 304 res, err := rs.UpdateRelease(c, req) 305 if err != nil { 306 t.Fatalf("Failed updated: %s", err) 307 } 308 309 if hl := res.Release.Hooks[0].LastRun; hl != nil { 310 t.Errorf("Expected that no hooks were run. Got %d", hl) 311 } 312 313 } 314 315 func TestUpdateReleaseNoChanges(t *testing.T) { 316 c := helm.NewContext() 317 rs := rsFixture() 318 rel := releaseStub() 319 rs.env.Releases.Create(rel) 320 321 req := &services.UpdateReleaseRequest{ 322 Name: rel.Name, 323 DisableHooks: true, 324 Chart: rel.GetChart(), 325 } 326 327 _, err := rs.UpdateRelease(c, req) 328 if err != nil { 329 t.Fatalf("Failed updated: %s", err) 330 } 331 } 332 333 func compareStoredAndReturnedRelease(t *testing.T, rs ReleaseServer, res services.UpdateReleaseResponse) *release.Release { 334 storedRelease, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version) 335 if err != nil { 336 t.Fatalf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases) 337 } 338 339 if !proto.Equal(storedRelease, res.Release) { 340 t.Errorf("Stored release doesn't match returned Release") 341 } 342 343 return storedRelease 344 }