github.com/deis/deis@v1.13.5-0.20170519182049-1d9e59fbdbfc/deisctl/cmd/cmd_test.go (about) 1 package cmd 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "net/http" 9 "net/http/httptest" 10 "reflect" 11 "strings" 12 "sync" 13 "testing" 14 15 "github.com/deis/deis/deisctl/backend" 16 "github.com/deis/deis/deisctl/config" 17 "github.com/deis/deis/deisctl/config/model" 18 "github.com/deis/deis/deisctl/test/mock" 19 "github.com/deis/deis/deisctl/units" 20 ) 21 22 type backendStub struct { 23 startedUnits []string 24 stoppedUnits []string 25 installedUnits []string 26 uninstalledUnits []string 27 restartedUnits []string 28 expected bool 29 } 30 31 func (backend *backendStub) Create(targets []string, wg *sync.WaitGroup, out, ew io.Writer) { 32 backend.installedUnits = append(backend.installedUnits, targets...) 33 } 34 func (backend *backendStub) Destroy(targets []string, wg *sync.WaitGroup, out, ew io.Writer) { 35 backend.uninstalledUnits = append(backend.uninstalledUnits, targets...) 36 } 37 func (backend *backendStub) Start(targets []string, wg *sync.WaitGroup, out, ew io.Writer) { 38 backend.startedUnits = append(backend.startedUnits, targets...) 39 } 40 func (backend *backendStub) Stop(targets []string, wg *sync.WaitGroup, out, ew io.Writer) { 41 backend.stoppedUnits = append(backend.stoppedUnits, targets...) 42 } 43 func (backend *backendStub) Scale(component string, num int, wg *sync.WaitGroup, out, ew io.Writer) { 44 switch { 45 case component == "router" && num == 3: 46 backend.expected = true 47 case component == "registry" && num == 4: 48 backend.expected = true 49 default: 50 backend.expected = false 51 } 52 } 53 func (backend *backendStub) RollingRestart(target string, wg *sync.WaitGroup, out, ew io.Writer) { 54 backend.restartedUnits = append(backend.restartedUnits, target) 55 } 56 57 func (backend *backendStub) ListMachines() error { 58 return nil 59 } 60 61 func (backend *backendStub) ListUnits() error { 62 return nil 63 } 64 func (backend *backendStub) ListUnitFiles() error { 65 return nil 66 } 67 func (backend *backendStub) Status(target string) error { 68 if target == "controller" || target == "builder" { 69 return nil 70 } 71 return errors.New("Test Error") 72 } 73 func (backend *backendStub) Journal(target string) error { 74 if target == "controller" || target == "builder" { 75 return nil 76 } 77 return errors.New("Test Error") 78 } 79 func (backend *backendStub) SSH(target string) error { 80 if target == "controller" { 81 return nil 82 } 83 return errors.New("Error") 84 } 85 func (backend *backendStub) SSHExec(target, command string) error { 86 if target == "controller" && command == "sh" { 87 return nil 88 } 89 return errors.New("Error") 90 } 91 92 func (backend *backendStub) Dock(target string, command []string) error { 93 return nil 94 } 95 96 var _ backend.Backend = &backendStub{} 97 98 func fakeCheckKeys(cb config.Backend) error { 99 return nil 100 } 101 102 type fakeHTTPServer struct{} 103 104 func (fakeHTTPServer) ServeHTTP(res http.ResponseWriter, req *http.Request) { 105 106 if strings.Split(req.URL.Path, "/")[1] != "v1.7.2" { 107 res.WriteHeader(http.StatusNotFound) 108 } 109 110 res.Write([]byte("test")) 111 } 112 113 func TestRefreshUnits(t *testing.T) { 114 t.Parallel() 115 116 name, err := ioutil.TempDir("", "deisctl") 117 118 if err != nil { 119 t.Error(err) 120 } 121 122 handler := fakeHTTPServer{} 123 server := httptest.NewServer(handler) 124 defer server.Close() 125 126 err = RefreshUnits(name, "v1.7.2", server.URL+"/") 127 128 if err != nil { 129 t.Error(err) 130 } 131 132 files, err := ioutil.ReadDir(name) 133 134 // There will be a "decorators" subdirectory and that shouldn't be 135 // counted as a unit when making the upcoming assertion. 136 numFiles := len(files) - 1 137 138 if len(units.Names) != numFiles { 139 t.Error(fmt.Errorf("Expected %d units, Got %d", len(units.Names), numFiles)) 140 } 141 142 for _, unit := range units.Names { 143 found := false 144 145 for _, file := range files { 146 if unit+".service" == file.Name() { 147 found = true 148 } 149 } 150 151 if found == false { 152 t.Error(fmt.Errorf("Expected to find %s in %v", unit, files)) 153 } 154 } 155 } 156 157 func TestRefreshUnitsError(t *testing.T) { 158 t.Parallel() 159 160 name, err := ioutil.TempDir("", "deisctl") 161 162 if err != nil { 163 t.Error(err) 164 } 165 166 handler := fakeHTTPServer{} 167 server := httptest.NewServer(handler) 168 defer server.Close() 169 170 err = RefreshUnits(name, "foo", server.URL+"/") 171 result := err.Error() 172 expected := "404 Not Found" 173 174 if result != expected { 175 t.Error(fmt.Errorf("Expected %s, Got %s", expected, result)) 176 } 177 } 178 179 func TestListUnits(t *testing.T) { 180 t.Parallel() 181 182 b := backendStub{installedUnits: []string{"router@1", "router@2"}} 183 184 if ListUnits(&b) != nil { 185 t.Error("unexpected error") 186 } 187 } 188 189 func TestListUnitFiles(t *testing.T) { 190 t.Parallel() 191 192 b := backendStub{} 193 194 if ListUnitFiles(&b) != nil { 195 t.Error("unexpected error") 196 } 197 } 198 199 func TestScaling(t *testing.T) { 200 t.Parallel() 201 202 b := backendStub{expected: false} 203 scale := []string{"registry=4", "router=3"} 204 205 Scale(scale, &b) 206 207 if b.expected == false { 208 t.Error("b.Scale called with unexpected arguements") 209 } 210 } 211 212 func TestScalingNonScalableComponent(t *testing.T) { 213 t.Parallel() 214 215 b := backendStub{} 216 expected := "cannot scale controller component" 217 err := Scale([]string{"controller=2"}, &b).Error() 218 219 if err != expected { 220 t.Error(fmt.Errorf("Expected '%v', Got '%v'", expected, err)) 221 } 222 } 223 224 func TestScalingInvalidFormat(t *testing.T) { 225 t.Parallel() 226 227 b := backendStub{} 228 expected := "Could not parse: controller2" 229 err := Scale([]string{"controller2"}, &b).Error() 230 231 if err != expected { 232 t.Error(fmt.Errorf("Expected '%v', Got '%v'", expected, err)) 233 } 234 } 235 236 func TestStart(t *testing.T) { 237 t.Parallel() 238 239 b := backendStub{} 240 expected := []string{"router@1", "router@2"} 241 242 Start(expected, &b) 243 244 if !reflect.DeepEqual(b.startedUnits, expected) { 245 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.startedUnits)) 246 } 247 } 248 249 func TestStartPlatform(t *testing.T) { 250 t.Parallel() 251 252 b := backendStub{} 253 expected := []string{"store-monitor", "store-daemon", "store-metadata", "store-gateway@*", 254 "store-volume", "logger", "logspout", "database", "registry@*", "controller", 255 "builder", "publisher", "router@*", "database", "registry@*", "controller", 256 "builder", "publisher", "router@*"} 257 258 Start([]string{"platform"}, &b) 259 260 if !reflect.DeepEqual(b.startedUnits, expected) { 261 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.startedUnits)) 262 } 263 } 264 265 func TestStartStatelessPlatform(t *testing.T) { 266 t.Parallel() 267 268 b := backendStub{} 269 expected := []string{"logger", "logspout", "registry@*", "controller", 270 "builder", "publisher", "router@*", "registry@*", "controller", 271 "builder", "publisher", "router@*"} 272 273 Start([]string{"stateless-platform"}, &b) 274 275 if !reflect.DeepEqual(b.startedUnits, expected) { 276 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.startedUnits)) 277 } 278 } 279 280 func TestRollingRestart(t *testing.T) { 281 t.Parallel() 282 283 b := backendStub{} 284 expected := []string{"router"} 285 286 RollingRestart("router", &b) 287 288 if !reflect.DeepEqual(b.restartedUnits, expected) { 289 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.restartedUnits)) 290 } 291 } 292 293 func TestUpgradePrep(t *testing.T) { 294 t.Parallel() 295 296 b := backendStub{} 297 expected := []string{"database", "registry@*", "controller", "builder", "logger", "logspout", "store-volume", 298 "store-gateway@*", "store-metadata", "store-daemon", "store-monitor"} 299 300 UpgradePrep(false, &b) 301 302 if !reflect.DeepEqual(b.stoppedUnits, expected) { 303 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits)) 304 } 305 } 306 307 func TestStatelessUpgradePrep(t *testing.T) { 308 t.Parallel() 309 310 b := backendStub{} 311 expected := []string{"database", "registry@*", "controller", "builder", "logger", "logspout"} 312 313 UpgradePrep(true, &b) 314 315 if !reflect.DeepEqual(b.stoppedUnits, expected) { 316 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits)) 317 } 318 } 319 320 func TestUpgradeTakeover(t *testing.T) { 321 t.Parallel() 322 testMock := mock.ConfigBackend{Expected: []*model.ConfigNode{{Key: "/deis/services/app1", Value: "foo", TTL: 10}, 323 {Key: "/deis/services/app2", Value: "8000", TTL: 10}}} 324 325 b := backendStub{} 326 expectedRestarted := []string{"router"} 327 expectedStarted := []string{"publisher", "store-monitor", "store-daemon", "store-metadata", 328 "store-gateway@*", "store-volume", "logger", "logspout", "database", "registry@*", 329 "controller", "builder", "publisher", "database", "registry@*", 330 "controller", "builder", "publisher"} 331 332 if err := doUpgradeTakeOver(false, &b, testMock); err != nil { 333 t.Error(fmt.Errorf("Takeover failed: %v", err)) 334 } 335 336 if !reflect.DeepEqual(b.restartedUnits, expectedRestarted) { 337 t.Error(fmt.Errorf("Expected %v, Got %v", expectedRestarted, b.restartedUnits)) 338 } 339 if !reflect.DeepEqual(b.startedUnits, expectedStarted) { 340 t.Error(fmt.Errorf("Expected %v, Got %v", expectedStarted, b.startedUnits)) 341 } 342 } 343 344 func TestStatelessUpgradeTakeover(t *testing.T) { 345 t.Parallel() 346 testMock := mock.ConfigBackend{Expected: []*model.ConfigNode{{Key: "/deis/services/app1", Value: "foo", TTL: 10}, 347 {Key: "/deis/services/app2", Value: "8000", TTL: 10}}} 348 349 b := backendStub{} 350 expectedRestarted := []string{"router"} 351 expectedStarted := []string{"publisher", "logspout", "registry@*", 352 "controller", "builder", "publisher", "router@*", "registry@*", 353 "controller", "builder", "publisher"} 354 355 if err := doUpgradeTakeOver(true, &b, testMock); err != nil { 356 t.Error(fmt.Errorf("Takeover failed: %v", err)) 357 } 358 359 if !reflect.DeepEqual(b.restartedUnits, expectedRestarted) { 360 t.Error(fmt.Errorf("Expected %v, Got %v", expectedRestarted, b.restartedUnits)) 361 } 362 if !reflect.DeepEqual(b.startedUnits, expectedStarted) { 363 t.Error(fmt.Errorf("Expected %v, Got %v", expectedStarted, b.startedUnits)) 364 } 365 } 366 367 func TestStop(t *testing.T) { 368 t.Parallel() 369 370 b := backendStub{} 371 expected := []string{"router@1", "router@2"} 372 Stop(expected, &b) 373 374 if !reflect.DeepEqual(b.stoppedUnits, expected) { 375 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits)) 376 } 377 } 378 379 func TestStopPlatform(t *testing.T) { 380 t.Parallel() 381 382 b := backendStub{} 383 expected := []string{"router@*", "publisher", "controller", "builder", "database", 384 "registry@*", "logger", "logspout", "store-volume", "store-gateway@*", 385 "store-metadata", "store-daemon", "store-monitor"} 386 Stop([]string{"platform"}, &b) 387 388 if !reflect.DeepEqual(b.stoppedUnits, expected) { 389 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits)) 390 } 391 } 392 393 func TestStopStatelessPlatform(t *testing.T) { 394 t.Parallel() 395 396 b := backendStub{} 397 expected := []string{"router@*", "publisher", "controller", "builder", 398 "registry@*", "logspout"} 399 Stop([]string{"stateless-platform"}, &b) 400 401 if !reflect.DeepEqual(b.stoppedUnits, expected) { 402 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits)) 403 } 404 } 405 406 func TestRestart(t *testing.T) { 407 t.Parallel() 408 409 b := backendStub{} 410 expected := []string{"router@4", "router@5"} 411 412 Restart(expected, &b) 413 414 if !reflect.DeepEqual(b.stoppedUnits, expected) { 415 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits)) 416 } 417 if !reflect.DeepEqual(b.startedUnits, expected) { 418 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.startedUnits)) 419 } 420 } 421 422 func TestSSH(t *testing.T) { 423 t.Parallel() 424 425 b := backendStub{} 426 err := SSH("controller", []string{}, &b) 427 428 if err != nil { 429 t.Error(err) 430 } 431 } 432 func TestSSHExec(t *testing.T) { 433 t.Parallel() 434 435 b := backendStub{} 436 err := SSH("controller", []string{"sh"}, &b) 437 438 if err != nil { 439 t.Error(err) 440 } 441 } 442 443 func TestSSHError(t *testing.T) { 444 t.Parallel() 445 446 b := backendStub{} 447 err := SSH("registry", []string{}, &b) 448 449 if err == nil { 450 t.Error("Error expected") 451 } 452 } 453 454 func TestStatus(t *testing.T) { 455 t.Parallel() 456 457 b := backendStub{} 458 459 if Status([]string{"controller", "builder"}, &b) != nil { 460 t.Error("Unexpected Error") 461 } 462 } 463 464 func TestStatusError(t *testing.T) { 465 t.Parallel() 466 467 b := backendStub{} 468 469 expected := "Test Error" 470 err := Status([]string{"blah"}, &b).Error() 471 472 if err != expected { 473 t.Error(fmt.Errorf("Expected '%v', Got '%v'", expected, err)) 474 } 475 } 476 477 func TestJournal(t *testing.T) { 478 t.Parallel() 479 480 b := backendStub{} 481 482 if Journal([]string{"controller", "builder"}, &b) != nil { 483 t.Error("Unexpected Error") 484 } 485 } 486 487 func TestJournalError(t *testing.T) { 488 t.Parallel() 489 490 b := backendStub{} 491 492 expected := "Test Error" 493 err := Journal([]string{"blah"}, &b).Error() 494 495 if err != expected { 496 t.Error(fmt.Errorf("Expected '%v', Got '%v'", expected, err)) 497 } 498 } 499 500 func TestInstall(t *testing.T) { 501 t.Parallel() 502 503 b := backendStub{} 504 cb := mock.ConfigBackend{} 505 506 expected := []string{"router@1", "router@2"} 507 508 Install(expected, &b, &cb, fakeCheckKeys) 509 510 if !reflect.DeepEqual(b.installedUnits, expected) { 511 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits)) 512 } 513 } 514 515 func TestInstallPlatform(t *testing.T) { 516 t.Parallel() 517 518 b := backendStub{} 519 cb := mock.ConfigBackend{} 520 521 expected := []string{"store-daemon", "store-monitor", "store-metadata", "store-volume", 522 "store-gateway@1", "logger", "logspout", "database", "registry@1", 523 "controller", "builder", "publisher", "router@1", "router@2", "router@3"} 524 525 Install([]string{"platform"}, &b, &cb, fakeCheckKeys) 526 527 if !reflect.DeepEqual(b.installedUnits, expected) { 528 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits)) 529 } 530 } 531 532 func TestInstallPlatformWithCustomRouterMeshSize(t *testing.T) { 533 t.Parallel() 534 535 b := backendStub{} 536 cb := mock.ConfigBackend{} 537 538 expected := []string{"store-daemon", "store-monitor", "store-metadata", "store-volume", 539 "store-gateway@1", "logger", "logspout", "database", "registry@1", 540 "controller", "builder", "publisher", "router@1", "router@2", "router@3", "router@4", "router@5"} 541 RouterMeshSize = 5 542 543 Install([]string{"platform"}, &b, &cb, fakeCheckKeys) 544 RouterMeshSize = DefaultRouterMeshSize 545 546 if !reflect.DeepEqual(b.installedUnits, expected) { 547 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits)) 548 } 549 } 550 551 func TestInstallStatelessPlatform(t *testing.T) { 552 t.Parallel() 553 554 b := backendStub{} 555 cb := mock.ConfigBackend{} 556 557 expected := []string{"logger", "logspout", "registry@1", 558 "controller", "builder", "publisher", "router@1", "router@2", "router@3"} 559 560 Install([]string{"stateless-platform"}, &b, &cb, fakeCheckKeys) 561 562 if !reflect.DeepEqual(b.installedUnits, expected) { 563 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits)) 564 } 565 } 566 567 func TestUninstall(t *testing.T) { 568 t.Parallel() 569 570 b := backendStub{} 571 expected := []string{"router@3", "router@4"} 572 573 Uninstall(expected, &b) 574 575 if !reflect.DeepEqual(b.uninstalledUnits, expected) { 576 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.uninstalledUnits)) 577 } 578 } 579 580 func TestUninstallPlatform(t *testing.T) { 581 t.Parallel() 582 583 b := backendStub{} 584 expected := []string{"router@*", "publisher", "controller", "builder", "database", 585 "registry@*", "logger", "logspout", "store-volume", "store-gateway@*", 586 "store-metadata", "store-daemon", "store-monitor"} 587 588 Uninstall([]string{"platform"}, &b) 589 590 if !reflect.DeepEqual(b.uninstalledUnits, expected) { 591 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.uninstalledUnits)) 592 } 593 } 594 595 func TestUninstallStatelessPlatform(t *testing.T) { 596 t.Parallel() 597 598 b := backendStub{} 599 expected := []string{"router@*", "publisher", "controller", "builder", 600 "registry@*", "logspout"} 601 602 Uninstall([]string{"stateless-platform"}, &b) 603 604 if !reflect.DeepEqual(b.uninstalledUnits, expected) { 605 t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.uninstalledUnits)) 606 } 607 }