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 }