github.com/Beeketing/helm@v2.12.1+incompatible/pkg/tiller/release_install_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 "fmt" 21 "strings" 22 "testing" 23 24 "k8s.io/helm/pkg/helm" 25 "k8s.io/helm/pkg/proto/hapi/chart" 26 "k8s.io/helm/pkg/proto/hapi/release" 27 "k8s.io/helm/pkg/proto/hapi/services" 28 "k8s.io/helm/pkg/version" 29 ) 30 31 func TestHasCRDHook(t *testing.T) { 32 tests := []struct { 33 hooks []*release.Hook 34 expect bool 35 }{ 36 { 37 hooks: []*release.Hook{ 38 {Events: []release.Hook_Event{release.Hook_PRE_DELETE}}, 39 }, 40 expect: false, 41 }, 42 { 43 hooks: []*release.Hook{ 44 {Events: []release.Hook_Event{release.Hook_CRD_INSTALL}}, 45 }, 46 expect: true, 47 }, 48 { 49 hooks: []*release.Hook{ 50 {Events: []release.Hook_Event{release.Hook_PRE_UPGRADE, release.Hook_CRD_INSTALL}}, 51 }, 52 expect: true, 53 }, 54 } 55 56 for i, tt := range tests { 57 if tt.expect != hasCRDHook(tt.hooks) { 58 t.Errorf("test %d: expected %t, got %t", i, tt.expect, !tt.expect) 59 } 60 } 61 } 62 63 func TestInstallRelease(t *testing.T) { 64 c := helm.NewContext() 65 rs := rsFixture() 66 67 req := installRequest() 68 res, err := rs.InstallRelease(c, req) 69 if err != nil { 70 t.Fatalf("Failed install: %s", err) 71 } 72 if res.Release.Name == "" { 73 t.Errorf("Expected release name.") 74 } 75 if res.Release.Namespace != "spaced" { 76 t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace) 77 } 78 79 rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version) 80 if err != nil { 81 t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases) 82 } 83 84 t.Logf("rel: %v", rel) 85 86 if len(rel.Hooks) != 1 { 87 t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks)) 88 } 89 if rel.Hooks[0].Manifest != manifestWithHook { 90 t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest) 91 } 92 93 if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL { 94 t.Errorf("Expected event 0 is post install") 95 } 96 if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE { 97 t.Errorf("Expected event 0 is pre-delete") 98 } 99 100 if len(res.Release.Manifest) == 0 { 101 t.Errorf("No manifest returned: %v", res.Release) 102 } 103 104 if len(rel.Manifest) == 0 { 105 t.Errorf("Expected manifest in %v", res) 106 } 107 108 if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") { 109 t.Errorf("unexpected output: %s", rel.Manifest) 110 } 111 112 if rel.Info.Description != "Install complete" { 113 t.Errorf("unexpected description: %s", rel.Info.Description) 114 } 115 } 116 117 func TestInstallRelease_WithNotes(t *testing.T) { 118 c := helm.NewContext() 119 rs := rsFixture() 120 121 req := installRequest( 122 withChart(withNotes(notesText)), 123 ) 124 res, err := rs.InstallRelease(c, req) 125 if err != nil { 126 t.Fatalf("Failed install: %s", err) 127 } 128 if res.Release.Name == "" { 129 t.Errorf("Expected release name.") 130 } 131 if res.Release.Namespace != "spaced" { 132 t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace) 133 } 134 135 rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version) 136 if err != nil { 137 t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases) 138 } 139 140 t.Logf("rel: %v", rel) 141 142 if len(rel.Hooks) != 1 { 143 t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks)) 144 } 145 if rel.Hooks[0].Manifest != manifestWithHook { 146 t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest) 147 } 148 149 if rel.Info.Status.Notes != notesText { 150 t.Fatalf("Expected '%s', got '%s'", notesText, rel.Info.Status.Notes) 151 } 152 153 if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL { 154 t.Errorf("Expected event 0 is post install") 155 } 156 if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE { 157 t.Errorf("Expected event 0 is pre-delete") 158 } 159 160 if len(res.Release.Manifest) == 0 { 161 t.Errorf("No manifest returned: %v", res.Release) 162 } 163 164 if len(rel.Manifest) == 0 { 165 t.Errorf("Expected manifest in %v", res) 166 } 167 168 if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") { 169 t.Errorf("unexpected output: %s", rel.Manifest) 170 } 171 172 if rel.Info.Description != "Install complete" { 173 t.Errorf("unexpected description: %s", rel.Info.Description) 174 } 175 } 176 177 func TestInstallRelease_WithNotesRendered(t *testing.T) { 178 c := helm.NewContext() 179 rs := rsFixture() 180 181 req := installRequest( 182 withChart(withNotes(notesText + " {{.Release.Name}}")), 183 ) 184 res, err := rs.InstallRelease(c, req) 185 if err != nil { 186 t.Fatalf("Failed install: %s", err) 187 } 188 if res.Release.Name == "" { 189 t.Errorf("Expected release name.") 190 } 191 if res.Release.Namespace != "spaced" { 192 t.Errorf("Expected release namespace 'spaced', got '%s'.", res.Release.Namespace) 193 } 194 195 rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version) 196 if err != nil { 197 t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases) 198 } 199 200 t.Logf("rel: %v", rel) 201 202 if len(rel.Hooks) != 1 { 203 t.Fatalf("Expected 1 hook, got %d", len(rel.Hooks)) 204 } 205 if rel.Hooks[0].Manifest != manifestWithHook { 206 t.Errorf("Unexpected manifest: %v", rel.Hooks[0].Manifest) 207 } 208 209 expectedNotes := fmt.Sprintf("%s %s", notesText, res.Release.Name) 210 if rel.Info.Status.Notes != expectedNotes { 211 t.Fatalf("Expected '%s', got '%s'", expectedNotes, rel.Info.Status.Notes) 212 } 213 214 if rel.Hooks[0].Events[0] != release.Hook_POST_INSTALL { 215 t.Errorf("Expected event 0 is post install") 216 } 217 if rel.Hooks[0].Events[1] != release.Hook_PRE_DELETE { 218 t.Errorf("Expected event 0 is pre-delete") 219 } 220 221 if len(res.Release.Manifest) == 0 { 222 t.Errorf("No manifest returned: %v", res.Release) 223 } 224 225 if len(rel.Manifest) == 0 { 226 t.Errorf("Expected manifest in %v", res) 227 } 228 229 if !strings.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world") { 230 t.Errorf("unexpected output: %s", rel.Manifest) 231 } 232 233 if rel.Info.Description != "Install complete" { 234 t.Errorf("unexpected description: %s", rel.Info.Description) 235 } 236 } 237 238 func TestInstallRelease_TillerVersion(t *testing.T) { 239 version.Version = "2.2.0" 240 c := helm.NewContext() 241 rs := rsFixture() 242 243 req := installRequest( 244 withChart(withTiller(">=2.2.0")), 245 ) 246 _, err := rs.InstallRelease(c, req) 247 if err != nil { 248 t.Fatalf("Expected valid range. Got %q", err) 249 } 250 } 251 252 func TestInstallRelease_WrongTillerVersion(t *testing.T) { 253 version.Version = "2.2.0" 254 c := helm.NewContext() 255 rs := rsFixture() 256 257 req := installRequest( 258 withChart(withTiller("<2.0.0")), 259 ) 260 _, err := rs.InstallRelease(c, req) 261 if err == nil { 262 t.Fatalf("Expected to fail because of wrong version") 263 } 264 265 expect := "Chart incompatible with Tiller" 266 if !strings.Contains(err.Error(), expect) { 267 t.Errorf("Expected %q to contain %q", err.Error(), expect) 268 } 269 } 270 271 func TestInstallRelease_WithChartAndDependencyNotes(t *testing.T) { 272 c := helm.NewContext() 273 rs := rsFixture() 274 275 req := installRequest(withChart( 276 withNotes(notesText), 277 withDependency(withNotes(notesText+" child")), 278 )) 279 res, err := rs.InstallRelease(c, req) 280 if err != nil { 281 t.Fatalf("Failed install: %s", err) 282 } 283 if res.Release.Name == "" { 284 t.Errorf("Expected release name.") 285 } 286 287 rel, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version) 288 if err != nil { 289 t.Errorf("Expected release for %s (%v).", res.Release.Name, rs.env.Releases) 290 } 291 292 t.Logf("rel: %v", rel) 293 294 if rel.Info.Status.Notes != notesText { 295 t.Fatalf("Expected '%s', got '%s'", notesText, rel.Info.Status.Notes) 296 } 297 298 if rel.Info.Description != "Install complete" { 299 t.Errorf("unexpected description: %s", rel.Info.Description) 300 } 301 } 302 303 func TestInstallRelease_DryRun(t *testing.T) { 304 c := helm.NewContext() 305 rs := rsFixture() 306 307 req := installRequest(withDryRun(), 308 withChart(withSampleTemplates()), 309 ) 310 res, err := rs.InstallRelease(c, req) 311 if err != nil { 312 t.Errorf("Failed install: %s", err) 313 } 314 if res.Release.Name == "" { 315 t.Errorf("Expected release name.") 316 } 317 318 if !strings.Contains(res.Release.Manifest, "---\n# Source: hello/templates/hello\nhello: world") { 319 t.Errorf("unexpected output: %s", res.Release.Manifest) 320 } 321 322 if !strings.Contains(res.Release.Manifest, "---\n# Source: hello/templates/goodbye\ngoodbye: world") { 323 t.Errorf("unexpected output: %s", res.Release.Manifest) 324 } 325 326 if !strings.Contains(res.Release.Manifest, "hello: Earth") { 327 t.Errorf("Should contain partial content. %s", res.Release.Manifest) 328 } 329 330 if strings.Contains(res.Release.Manifest, "hello: {{ template \"_planet\" . }}") { 331 t.Errorf("Should not contain partial templates itself. %s", res.Release.Manifest) 332 } 333 334 if strings.Contains(res.Release.Manifest, "empty") { 335 t.Errorf("Should not contain template data for an empty file. %s", res.Release.Manifest) 336 } 337 338 if _, err := rs.env.Releases.Get(res.Release.Name, res.Release.Version); err == nil { 339 t.Errorf("Expected no stored release.") 340 } 341 342 if l := len(res.Release.Hooks); l != 1 { 343 t.Fatalf("Expected 1 hook, got %d", l) 344 } 345 346 if res.Release.Hooks[0].LastRun != nil { 347 t.Error("Expected hook to not be marked as run.") 348 } 349 350 if res.Release.Info.Description != "Dry run complete" { 351 t.Errorf("unexpected description: %s", res.Release.Info.Description) 352 } 353 } 354 355 func TestInstallRelease_NoHooks(t *testing.T) { 356 c := helm.NewContext() 357 rs := rsFixture() 358 rs.env.Releases.Create(releaseStub()) 359 360 req := installRequest(withDisabledHooks()) 361 res, err := rs.InstallRelease(c, req) 362 if err != nil { 363 t.Errorf("Failed install: %s", err) 364 } 365 366 if hl := res.Release.Hooks[0].LastRun; hl != nil { 367 t.Errorf("Expected that no hooks were run. Got %d", hl) 368 } 369 } 370 371 func TestInstallRelease_CRDInstallHook(t *testing.T) { 372 c := helm.NewContext() 373 rs := rsFixture() 374 rs.env.Releases.Create(releaseStub()) 375 376 req := installRequest() 377 req.Chart.Templates = append(req.Chart.Templates, &chart.Template{ 378 Name: "templates/crdhook", 379 Data: []byte(manifestWithCRDHook), 380 }) 381 382 res, err := rs.InstallRelease(c, req) 383 if err != nil { 384 t.Errorf("Failed install: %s", err) 385 } 386 387 // The new hook should have been pulled from the manifest. 388 if l := len(res.Release.Hooks); l != 2 { 389 t.Fatalf("expected 2 hooks, got %d", l) 390 } 391 392 expect := "Install complete" 393 if got := res.Release.Info.Description; got != expect { 394 t.Errorf("Expected Description to be %q, got %q", expect, got) 395 } 396 } 397 398 func TestInstallRelease_DryRunCRDInstallHook(t *testing.T) { 399 c := helm.NewContext() 400 rs := rsFixture() 401 rs.env.Releases.Create(releaseStub()) 402 403 req := installRequest(withDryRun()) 404 req.Chart.Templates = append(req.Chart.Templates, &chart.Template{ 405 Name: "templates/crdhook", 406 Data: []byte(manifestWithCRDHook), 407 }) 408 409 res, err := rs.InstallRelease(c, req) 410 if err != nil { 411 t.Errorf("Failed install: %s", err) 412 } 413 414 expect := "Validation skipped because CRDs are not installed" 415 if res.Release.Info.Description != expect { 416 t.Errorf("Expected Description %q, got %q", expect, res.Release.Info.Description) 417 } 418 } 419 420 func TestInstallRelease_FailedHooks(t *testing.T) { 421 c := helm.NewContext() 422 rs := rsFixture() 423 rs.env.Releases.Create(releaseStub()) 424 rs.env.KubeClient = newHookFailingKubeClient() 425 426 req := installRequest() 427 res, err := rs.InstallRelease(c, req) 428 if err == nil { 429 t.Error("Expected failed install") 430 } 431 432 if hl := res.Release.Info.Status.Code; hl != release.Status_FAILED { 433 t.Errorf("Expected FAILED release. Got %d", hl) 434 } 435 } 436 437 func TestInstallRelease_ReuseName(t *testing.T) { 438 c := helm.NewContext() 439 rs := rsFixture() 440 rel := releaseStub() 441 rel.Info.Status.Code = release.Status_DELETED 442 rs.env.Releases.Create(rel) 443 444 req := installRequest( 445 withReuseName(), 446 withName(rel.Name), 447 ) 448 res, err := rs.InstallRelease(c, req) 449 if err != nil { 450 t.Fatalf("Failed install: %s", err) 451 } 452 453 if res.Release.Name != rel.Name { 454 t.Errorf("expected %q, got %q", rel.Name, res.Release.Name) 455 } 456 457 getreq := &services.GetReleaseStatusRequest{Name: rel.Name, Version: 0} 458 getres, err := rs.GetReleaseStatus(c, getreq) 459 if err != nil { 460 t.Errorf("Failed to retrieve release: %s", err) 461 } 462 if getres.Info.Status.Code != release.Status_DEPLOYED { 463 t.Errorf("Release status is %q", getres.Info.Status.Code) 464 } 465 } 466 467 func TestInstallRelease_KubeVersion(t *testing.T) { 468 c := helm.NewContext() 469 rs := rsFixture() 470 471 req := installRequest( 472 withChart(withKube(">=0.0.0")), 473 ) 474 _, err := rs.InstallRelease(c, req) 475 if err != nil { 476 t.Fatalf("Expected valid range. Got %q", err) 477 } 478 } 479 480 func TestInstallRelease_WrongKubeVersion(t *testing.T) { 481 c := helm.NewContext() 482 rs := rsFixture() 483 484 req := installRequest( 485 withChart(withKube(">=5.0.0")), 486 ) 487 488 _, err := rs.InstallRelease(c, req) 489 if err == nil { 490 t.Fatalf("Expected to fail because of wrong version") 491 } 492 493 expect := "Chart requires kubernetesVersion" 494 if !strings.Contains(err.Error(), expect) { 495 t.Errorf("Expected %q to contain %q", err.Error(), expect) 496 } 497 } 498 499 func TestInstallRelease_Description(t *testing.T) { 500 c := helm.NewContext() 501 rs := rsFixture() 502 rs.env.Releases.Create(releaseStub()) 503 504 customDescription := "foo" 505 req := &services.InstallReleaseRequest{ 506 Chart: chartStub(), 507 Description: customDescription, 508 } 509 res, err := rs.InstallRelease(c, req) 510 if err != nil { 511 t.Errorf("Failed install: %s", err) 512 } 513 514 if desc := res.Release.Info.Description; desc != customDescription { 515 t.Errorf("Expected description %q. Got %q", customDescription, desc) 516 } 517 }