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