Expect(outputBuffer).To(test_helpers.SayLine("Error submitting build of droplet-name: failed")) Expect(fakeDropletRunner.UploadBitsCallCount()).To(Equal(1)) Expect(fakeDropletRunner.BuildDropletCallCount()).To(Equal(1)) Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.CommandFailed})) }) }) Describe("waiting for the build to finish", func() { It("polls for the build to complete, outputting logs while the build runs", func() { fakeTaskExaminer.TaskStatusReturns(task_examiner.TaskInfo{State: "PENDING"}, nil) args := []string{ "droplet-name", "http://some.url/for/buildpack", } doneChan := test_helpers.AsyncExecuteCommandWithArgs(buildDropletCommand, args) Eventually(outputBuffer).Should(test_helpers.SayLine("Submitted build of droplet-name")) Eventually(fakeTailedLogsOutputter.OutputTailedLogsCallCount).Should(Equal(1)) Expect(fakeTailedLogsOutputter.OutputTailedLogsArgsForCall(0)).To(Equal("build-droplet-droplet-name")) Eventually(fakeTaskExaminer.TaskStatusCallCount).Should(Equal(1)) Expect(fakeTaskExaminer.TaskStatusArgsForCall(0)).To(Equal("build-droplet-droplet-name")) fakeClock.IncrementBySeconds(1) Expect(doneChan).NotTo(BeClosed()) Expect(fakeTailedLogsOutputter.StopOutputtingCallCount()).To(Equal(0)) fakeTaskExaminer.TaskStatusReturns(task_examiner.TaskInfo{State: "RUNNING"}, nil)
}) }) Describe("polling for the app to start after desiring the app", func() { It("polls for the app to start with correct number of instances, outputting logs while the app starts", func() { fakeDockerMetadataFetcher.FetchMetadataReturns(&docker_metadata_fetcher.ImageMetadata{}, nil) fakeAppExaminer.RunningAppInstancesInfoReturns(0, false, nil) args := []string{ "--instances=10", "cool-web-app", "superfun/app", "--", "/start-me-please", } doneChan := test_helpers.AsyncExecuteCommandWithArgs(createCommand, args) Eventually(outputBuffer).Should(test_helpers.SayLine("Creating App: cool-web-app")) Expect(fakeTailedLogsOutputter.OutputTailedLogsCallCount()).To(Equal(1)) Expect(fakeTailedLogsOutputter.OutputTailedLogsArgsForCall(0)).To(Equal("cool-web-app")) Expect(fakeAppExaminer.RunningAppInstancesInfoCallCount()).To(Equal(1)) Expect(fakeAppExaminer.RunningAppInstancesInfoArgsForCall(0)).To(Equal("cool-web-app")) fakeClock.IncrementBySeconds(1) Expect(fakeTailedLogsOutputter.StopOutputtingCallCount()).To(Equal(0)) fakeAppExaminer.RunningAppInstancesInfoReturns(9, false, nil) fakeClock.IncrementBySeconds(1) Expect(doneChan).ShouldNot(BeClosed())
It("should ssh to instance index specified", func() { test_helpers.ExecuteCommandWithArgs(sshCommand, []string{"--instance", "2", "app-name"}) Expect(outputBuffer).To(test_helpers.SayLine("Connecting to app-name/2 at %s", config.Target())) Expect(fakeSecureShell.ConnectToShellCallCount()).To(Equal(1)) appName, instanceIndex, command, actualConfig := fakeSecureShell.ConnectToShellArgsForCall(0) Expect(appName).To(Equal("app-name")) Expect(instanceIndex).To(Equal(2)) Expect(command).To(BeEmpty()) Expect(actualConfig).To(Equal(config)) }) It("should run a command remotely instead of the login shell", func() { doneChan := test_helpers.AsyncExecuteCommandWithArgs(sshCommand, []string{"app-name", "echo", "1", "2", "3"}) Eventually(doneChan).Should(BeClosed()) Expect(outputBuffer).NotTo(test_helpers.Say("Connecting to app-name")) Expect(fakeSecureShell.ConnectToShellCallCount()).To(Equal(1)) appName, instanceIndex, command, actualConfig := fakeSecureShell.ConnectToShellArgsForCall(0) Expect(appName).To(Equal("app-name")) Expect(instanceIndex).To(Equal(0)) Expect(command).To(Equal("echo 1 2 3")) Expect(actualConfig).To(Equal(config)) }) It("should support -- delimiter for args", func() { doneChan := test_helpers.AsyncExecuteCommandWithArgs(sshCommand, []string{"app-name", "--", "/bin/ls", "-l"})
It("alerts the user if no target is set", func() { config.SetBlobTarget("", 0, "", "", "") config.Save() test_helpers.ExecuteCommandWithArgs(targetBlobCommand, []string{}) Expect(outputBuffer).To(test_helpers.SayLine("Blob target not set")) }) }) Context("setting the blob target", func() { It("sets the blob target and credentials", func() { fakeTargetVerifier.VerifyBlobTargetReturns(true, nil) commandFinishChan := test_helpers.AsyncExecuteCommandWithArgs(targetBlobCommand, []string{"192.168.11.11:8980"}) Eventually(outputBuffer).Should(test_helpers.Say("Access Key: ")) stdinWriter.Write([]byte("yaykey\n")) Eventually(outputBuffer).Should(test_helpers.Say("Secret Key: ")) stdinWriter.Write([]byte("superserial\n")) Eventually(outputBuffer).Should(test_helpers.Say("Bucket Name [condenser-bucket]: ")) stdinWriter.Write([]byte("bhuket\n")) Eventually(commandFinishChan).Should(BeClosed()) Expect(fakeTargetVerifier.VerifyBlobTargetCallCount()).To(Equal(1)) host, port, accessKey, secretKey, bucketName := fakeTargetVerifier.VerifyBlobTargetArgsForCall(0) Expect(host).To(Equal("192.168.11.11")) Expect(port).To(Equal(uint16(8980))) Expect(accessKey).To(Equal("yaykey"))
) BeforeEach(func() { commandRan = false cliCommand = cli.Command{ Name: "exec", Action: func(*cli.Context) { commandRan = true }, } }) Describe("ExecuteCommandWithArgs", func() { It("executes the command", func() { test_helpers.ExecuteCommandWithArgs(cliCommand, []string{}) Expect(commandRan).To(BeTrue()) }) }) Describe("AsyncExecuteCommandWithArgs", func() { It("executes the command", func() { doneChan := test_helpers.AsyncExecuteCommandWithArgs(cliCommand, []string{}) Eventually(doneChan, 3).Should(BeClosed()) Expect(commandRan).To(BeTrue()) }) }) })
Eventually(outputBuffer).Should(test_helpers.SayLine("some error")) verifyOldTargetStillSet() Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.FileSystemError})) }) }) }) Context("when the receptor requires authentication", func() { BeforeEach(func() { fakeTargetVerifier.VerifyTargetReturns(true, false, nil) fakeBlobStoreVerifier.VerifyReturns(true, nil) fakePasswordReader.PromptForPasswordReturns("testpassword") }) It("prompts for credentials and stores them in the config", func() { doneChan := test_helpers.AsyncExecuteCommandWithArgs(targetCommand, []string{"myapi.com"}) Eventually(outputBuffer).Should(test_helpers.Say("Username: "******"testusername\n")) Eventually(doneChan, 3).Should(BeClosed()) Expect(config.Target()).To(Equal("myapi.com")) Expect(config.Receptor()).To(Equal("http://*****:*****@receptor.myapi.com")) Expect(outputBuffer).To(test_helpers.SayLine("API location set.")) Expect(fakePasswordReader.PromptForPasswordCallCount()).To(Equal(1)) Expect(fakePasswordReader.PromptForPasswordArgsForCall(0)).To(Equal("Password")) Expect(fakeTargetVerifier.VerifyTargetCallCount()).To(Equal(2))
Expect(fakeDropletRunner.UploadBitsCallCount()).To(Equal(1)) Expect(fakeDropletRunner.BuildDropletCallCount()).To(Equal(1)) Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.CommandFailed})) }) }) Describe("waiting for the build to finish", func() { It("polls for the build to complete, outputting logs while the build runs", func() { args := []string{ "droplet-name", "http://some.url/for/buildpack", } fakeTaskExaminer.TaskStatusReturns(task_examiner.TaskInfo{State: "PENDING"}, nil) commandFinishChan := test_helpers.AsyncExecuteCommandWithArgs(buildDropletCommand, args) Eventually(outputBuffer).Should(test_helpers.Say("Submitted build of droplet-name")) Expect(fakeTailedLogsOutputter.OutputTailedLogsCallCount()).To(Equal(1)) Expect(fakeTailedLogsOutputter.OutputTailedLogsArgsForCall(0)).To(Equal("build-droplet-droplet-name")) Expect(fakeTaskExaminer.TaskStatusCallCount()).To(Equal(1)) Expect(fakeTaskExaminer.TaskStatusArgsForCall(0)).To(Equal("build-droplet-droplet-name")) fakeClock.IncrementBySeconds(1) Expect(commandFinishChan).ShouldNot(BeClosed()) Expect(fakeTailedLogsOutputter.StopOutputtingCallCount()).To(Equal(0)) fakeTaskExaminer.TaskStatusReturns(task_examiner.TaskInfo{State: "RUNNING"}, nil)
Context("when a rate flag is provided", func() { var closeChan chan struct{} AfterEach(func() { go fakeExitHandler.Exit(exit_codes.SigInt) Eventually(closeChan).Should(BeClosed()) }) It("dynamically displays the visualization", func() { setNumberOfRunningInstances := func(count int) { fakeAppExaminer.ListCellsReturns([]app_examiner.CellInfo{app_examiner.CellInfo{CellID: "cell-0", RunningInstances: count}, app_examiner.CellInfo{CellID: "cell-1", RunningInstances: count, Missing: true}}, nil) } setNumberOfRunningInstances(0) closeChan = test_helpers.AsyncExecuteCommandWithArgs(visualizeCommand, []string{"--rate", "2s"}) Eventually(outputBuffer).Should(test_helpers.SayLine("cell-0: " + colors.Red("empty") + cursor.ClearToEndOfLine())) Eventually(outputBuffer).Should(test_helpers.SayLine("cell-1" + colors.Red("[MISSING]") + ": " + cursor.ClearToEndOfLine())) setNumberOfRunningInstances(2) fakeClock.IncrementBySeconds(1) Consistently(outputBuffer).ShouldNot(test_helpers.Say("cell: \n")) // TODO: how would this happen fakeClock.IncrementBySeconds(1) Eventually(outputBuffer).Should(test_helpers.Say(cursor.Hide())) Eventually(outputBuffer).Should(test_helpers.Say(cursor.Up(2))) Eventually(outputBuffer).Should(test_helpers.SayLine("cell-0: " + colors.Green("••") + cursor.ClearToEndOfLine()))
It("alerts the user if no target is set", func() { config.SetTarget("") test_helpers.ExecuteCommandWithArgs(targetCommand, []string{}) Expect(outputBuffer).To(test_helpers.Say("Target not set.")) }) }) Context("setting target without auth", func() { BeforeEach(func() { fakeTargetVerifier.VerifyTargetReturns(true, true, nil) }) It("saves the new target", func() { commandFinishChan := test_helpers.AsyncExecuteCommandWithArgs(targetCommand, []string{"myapi.com"}) Eventually(commandFinishChan).Should(BeClosed()) Expect(fakeTargetVerifier.VerifyTargetCallCount()).To(Equal(1)) Expect(fakeTargetVerifier.VerifyTargetArgsForCall(0)).To(Equal("http://receptor.myapi.com")) Expect(config.Receptor()).To(Equal("http://receptor.myapi.com")) }) It("clears out existing saved target credentials", func() { test_helpers.ExecuteCommandWithArgs(targetCommand, []string{"myapi.com"}) Expect(fakeTargetVerifier.VerifyTargetCallCount()).To(Equal(1)) Expect(fakeTargetVerifier.VerifyTargetArgsForCall(0)).To(Equal("http://receptor.myapi.com")) })
signalChan = make(chan os.Signal) fakeExitHandler = &fake_exit_handler.FakeExitHandler{} }) Describe("LogsCommand", func() { var logsCommand cli.Command BeforeEach(func() { commandFactory := command_factory.NewLogsCommandFactory(appExaminer, taskExaminer, terminalUI, fakeTailedLogsOutputter, fakeExitHandler) logsCommand = commandFactory.MakeLogsCommand() }) It("tails logs", func() { appExaminer.AppExistsReturns(true, nil) doneChan := test_helpers.AsyncExecuteCommandWithArgs(logsCommand, []string{"my-app-guid"}) Eventually(fakeTailedLogsOutputter.OutputTailedLogsCallCount).Should(Equal(1)) Expect(fakeTailedLogsOutputter.OutputTailedLogsArgsForCall(0)).To(Equal("my-app-guid")) Consistently(doneChan).ShouldNot(BeClosed()) }) It("handles invalid appguids", func() { test_helpers.ExecuteCommandWithArgs(logsCommand, []string{}) Expect(outputBuffer).To(test_helpers.SayIncorrectUsage()) Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.InvalidSyntax})) }) It("handles non existent application", func() {
Expect(fakeAppRunner.ScaleAppCallCount()).To(Equal(1)) name, instances := fakeAppRunner.ScaleAppArgsForCall(0) Expect(name).To(Equal("cool-web-app")) Expect(instances).To(Equal(22)) }) It("polls until the required number of instances are running", func() { args := []string{ "cool-web-app", "22", } fakeAppExaminer.RunningAppInstancesInfoReturns(1, false, nil) commandFinishChan := test_helpers.AsyncExecuteCommandWithArgs(scaleCommand, args) Eventually(outputBuffer).Should(test_helpers.Say("Scaling cool-web-app to 22 instances")) Expect(fakeAppExaminer.RunningAppInstancesInfoCallCount()).To(Equal(1)) Expect(fakeAppExaminer.RunningAppInstancesInfoArgsForCall(0)).To(Equal("cool-web-app")) fakeClock.IncrementBySeconds(1) Eventually(outputBuffer).Should(test_helpers.Say(".")) fakeClock.IncrementBySeconds(1) Eventually(outputBuffer).Should(test_helpers.Say(".")) fakeAppExaminer.RunningAppInstancesInfoReturns(22, false, nil) fakeClock.IncrementBySeconds(1) Eventually(commandFinishChan).Should(BeClosed())