BeforeEach(func() { var err error tmpFile, err = ioutil.TempFile("", "tmp_json") Expect(err).ToNot(HaveOccurred()) jsonContents = []byte(`{"Value":"test value"}`) Expect(ioutil.WriteFile(tmpFile.Name(), jsonContents, 0700)).To(Succeed()) }) It("submits a task from json", func() { fakeTaskRunner.SubmitTaskReturns("some-task", nil) args := []string{tmpFile.Name()} test_helpers.ExecuteCommandWithArgs(submitTaskCommand, args) Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("Successfully submitted some-task"))) Expect(fakeTaskRunner.SubmitTaskCallCount()).To(Equal(1)) Expect(fakeTaskRunner.SubmitTaskArgsForCall(0)).To(Equal(jsonContents)) }) It("prints an error returned by the task_runner", func() { fakeTaskRunner.SubmitTaskReturns("some-task", errors.New("taskypoo")) args := []string{tmpFile.Name()} test_helpers.ExecuteCommandWithArgs(submitTaskCommand, args) Expect(fakeTaskRunner.SubmitTaskCallCount()).To(Equal(1)) Expect(fakeTaskRunner.SubmitTaskArgsForCall(0)).To(Equal(jsonContents)) Expect(outputBuffer).To(test_helpers.SayLine("Error submitting some-task: taskypoo")) Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.CommandFailed}))
Describe("SSHCommand", func() { var sshCommand cli.Command BeforeEach(func() { commandFactory := command_factory.NewSSHCommandFactory(config, terminalUI, fakeExitHandler, fakeAppExaminer, fakeSSH) sshCommand = commandFactory.MakeSSHCommand() }) Context("when connecting fails", func() { It("should print an error", func() { fakeAppExaminer.AppStatusReturns(app_examiner.AppInfo{ActualRunningInstances: 1}, nil) fakeSSH.ConnectReturns(errors.New("connection failed")) test_helpers.ExecuteCommandWithArgs(sshCommand, []string{"good-name"}) Expect(outputBuffer).To(test_helpers.SayLine("Error connecting to good-name/0: connection failed")) Expect(fakeSSH.ConnectCallCount()).To(Equal(1)) Expect(fakeSSH.ForwardCallCount()).To(Equal(0)) Expect(fakeSSH.ShellCallCount()).To(Equal(0)) Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.CommandFailed})) }) }) Describe("port forwarding", func() { It("should forward a local port to a remote host and port", func() { fakeAppExaminer.AppStatusReturns(app_examiner.AppInfo{ActualRunningInstances: 1}, nil) test_helpers.ExecuteCommandWithArgs(sshCommand, []string{"app-name", "-N", "-L", "mrlocalhost:1234:remotehost:5678"}) Expect(outputBuffer).To(test_helpers.SayLine("Forwarding mrlocalhost:1234 to remotehost:5678 via app-name/0 at %s", config.Target()))
Expect(outputBuffer).To(test_helpers.Say("Cell ID")) Expect(outputBuffer).To(test_helpers.Say("cell-01")) Expect(outputBuffer).To(test_helpers.Say("Status")) Expect(outputBuffer).To(test_helpers.Say(colors.Red("COMPLETED"))) Expect(outputBuffer).NotTo(test_helpers.Say("Result")) Expect(outputBuffer).To(test_helpers.Say("Failure Reason")) Expect(outputBuffer).To(test_helpers.Say("womp womp")) Expect(fakeTaskExaminer.TaskStatusCallCount()).To(Equal(1)) Expect(fakeTaskExaminer.TaskStatusArgsForCall(0)).To(Equal("boop")) }) It("bails out when no task name passed", func() { test_helpers.ExecuteCommandWithArgs(taskCommand, []string{}) Expect(outputBuffer).To(test_helpers.SayLine("Please input a valid TASK_GUID")) Expect(fakeTaskExaminer.TaskStatusCallCount()).To(Equal(0)) Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.InvalidSyntax})) }) Context("when the task examiner returns errors", func() { It("prints no task found when error is tasknotfound", func() { fakeTaskExaminer.TaskStatusReturns(task_examiner.TaskInfo{}, errors.New(task_examiner.TaskNotFoundErrorMessage)) test_helpers.ExecuteCommandWithArgs(taskCommand, []string{"boop"}) Expect(outputBuffer).To(test_helpers.Say(colors.Red("No task 'boop' was found"))) Expect(fakeTaskExaminer.TaskStatusCallCount()).To(Equal(1)) Expect(fakeTaskExaminer.TaskStatusArgsForCall(0)).To(Equal("boop")) Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.CommandFailed})) })
Expect(createAppParams.Privileged).To(BeFalse()) Expect(createAppParams.User).To(Equal("some-user")) Expect(createAppParams.CPUWeight).To(Equal(uint(57))) Expect(createAppParams.MemoryMB).To(Equal(12)) Expect(createAppParams.DiskMB).To(Equal(12)) Expect(createAppParams.Monitor.Method).To(Equal(app_runner.PortMonitor)) Expect(createAppParams.Timeout).To(Equal(time.Second * 28)) Expect(createAppParams.RouteOverrides).To(ContainExactly(app_runner.RouteOverrides{ {HostnamePrefix: "route-3000-yay", Port: 3000}, {HostnamePrefix: "route-1111-wahoo", Port: 1111}, {HostnamePrefix: "route-1111-me-too", Port: 1111}, })) Expect(createAppParams.NoRoutes).To(BeFalse()) Expect(createAppParams.WorkingDir).To(Equal("/applications")) Expect(outputBuffer).To(test_helpers.SayLine("Creating App: cool-web-app")) Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("cool-web-app is now running."))) Expect(outputBuffer).To(test_helpers.SayLine("App is reachable at:")) Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("http://route-3000-yay.192.168.11.11.xip.io"))) Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("http://route-1111-wahoo.192.168.11.11.xip.io"))) Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("http://route-1111-me-too.192.168.11.11.xip.io"))) }) Context("when the PROCESS_GUID is passed in as --env", func() { It("sets the PROCESS_GUID to the value passed in", func() { fakeDockerMetadataFetcher.FetchMetadataReturns(&docker_metadata_fetcher.ImageMetadata{StartCommand: []string{""}}, nil) fakeAppExaminer.RunningAppInstancesInfoReturns(1, false, nil) args := []string{ "app-to-start", "fun-org/app",
fakeVersionManager.ServerVersionsReturns(version.ServerVersions{ CfRelease: "v219", CfRoutingRelease: "v220", DiegoRelease: "v221", GardenLinuxRelease: "v222", LatticeRelease: "v223", LatticeReleaseImage: "v224", Ltc: "v225", Receptor: "v226", }, nil) }) It("Prints the CLI and API versions", func() { test_helpers.ExecuteCommandWithArgs(versionCommand, []string{}) Expect(outputBuffer).To(test_helpers.SayLine("Client version: 1.8.0")) Expect(outputBuffer).To(test_helpers.SayLine("CF release version: v219")) Expect(outputBuffer).To(test_helpers.SayLine("CF routing release version: v220")) Expect(outputBuffer).To(test_helpers.SayLine("Diego release version: v221")) Expect(outputBuffer).To(test_helpers.SayLine("Garden linux release version: v222")) Expect(outputBuffer).To(test_helpers.SayLine("Lattice release version: v223")) Expect(outputBuffer).To(test_helpers.SayLine("Lattice release image version: v224")) Expect(outputBuffer).To(test_helpers.SayLine("Receptor version: v226")) }) Context("when the version manager returns an error", func() { It("should print an error", func() { fakeVersionManager.ServerVersionsReturns(version.ServerVersions{}, errors.New("failed")) test_helpers.ExecuteCommandWithArgs(versionCommand, []string{})
}) Context("when the archive path is a folder and exists", func() { BeforeEach(func() { fakeCFIgnore.ShouldIgnoreStub = func(path string) bool { return path == "some-ignored-file" } }) It("zips up current working folder and uploads as the droplet name", func() { fakeZipper.IsZipFileReturns(false) fakeZipper.ZipReturns("xyz.zip", nil) test_helpers.ExecuteCommandWithArgs(buildDropletCommand, []string{"droplet-name", "http://some.url/for/buildpack"}) Expect(outputBuffer).To(test_helpers.SayLine("Uploading application bits...")) Expect(outputBuffer).To(test_helpers.SayLine("Uploaded.")) Expect(fakeBlobStoreVerifier.VerifyCallCount()).To(Equal(1)) Expect(fakeBlobStoreVerifier.VerifyArgsForCall(0)).To(Equal(config)) Expect(outputBuffer).To(test_helpers.SayLine("Submitted build of droplet-name")) Expect(fakeDropletRunner.UploadBitsCallCount()).To(Equal(1)) dropletName, uploadPath := fakeDropletRunner.UploadBitsArgsForCall(0) Expect(dropletName).To(Equal("droplet-name")) Expect(uploadPath).NotTo(BeNil()) Expect(uploadPath).To(Equal("xyz.zip")) Expect(fakeZipper.ZipCallCount()).To(Equal(1)) _, cfIgnore := fakeZipper.ZipArgsForCall(0)
Expect(outputBuffer).To(test_helpers.Say("Cell ID")) Expect(outputBuffer).To(test_helpers.Say("cell-01")) Expect(outputBuffer).To(test_helpers.Say("Status")) Expect(outputBuffer).To(test_helpers.Say(colors.Red("COMPLETED"))) Expect(outputBuffer).NotTo(test_helpers.Say("Result")) Expect(outputBuffer).To(test_helpers.Say("Failure Reason")) Expect(outputBuffer).To(test_helpers.Say("womp womp")) Expect(fakeTaskExaminer.TaskStatusCallCount()).To(Equal(1)) Expect(fakeTaskExaminer.TaskStatusArgsForCall(0)).To(Equal("boop")) }) It("bails out when no task name passed", func() { test_helpers.ExecuteCommandWithArgs(taskCommand, []string{}) Expect(outputBuffer).To(test_helpers.SayLine("Please input a valid <task-guid>")) Expect(fakeTaskExaminer.TaskStatusCallCount()).To(Equal(0)) Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.InvalidSyntax})) }) Context("when the task examiner returns errors", func() { It("prints no task found when error is tasknotfound", func() { fakeTaskExaminer.TaskStatusReturns(task_examiner.TaskInfo{}, errors.New(task_examiner.TaskNotFoundErrorMessage)) test_helpers.ExecuteCommandWithArgs(taskCommand, []string{"boop"}) Expect(outputBuffer).To(test_helpers.Say(colors.Red("No task 'boop' was found"))) Expect(fakeTaskExaminer.TaskStatusCallCount()).To(Equal(1)) Expect(fakeTaskExaminer.TaskStatusArgsForCall(0)).To(Equal("boop")) Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.CommandFailed})) })
BeforeEach(func() { commandFactory := command_factory.NewConfigCommandFactory(config, terminalUI, fakeTargetVerifier, fakeBlobStoreVerifier, fakeExitHandler) targetCommand = commandFactory.MakeTargetCommand() config.SetTarget("oldtarget.com") config.SetLogin("olduser", "oldpass") Expect(config.Save()).To(Succeed()) }) Context("displaying the target", func() { JustBeforeEach(func() { test_helpers.ExecuteCommandWithArgs(targetCommand, []string{}) }) It("outputs the current user and target host", func() { Expect(outputBuffer).To(test_helpers.SayLine("Target:\t\[email protected]")) }) Context("when no username is set", func() { BeforeEach(func() { config.SetLogin("", "") Expect(config.Save()).To(Succeed()) }) It("only prints the target", func() { Expect(outputBuffer).To(test_helpers.SayLine("Target:\t\toldtarget.com")) }) }) Context("when no target is set", func() { BeforeEach(func() {
BeforeEach(func() { commandFactory := command_factory.NewConfigCommandFactory(config, terminalUI, fakeTargetVerifier, fakeBlobStoreVerifier, fakeExitHandler, fakeVersionManager) targetCommand = commandFactory.MakeTargetCommand() config.SetTarget("oldtarget.com") config.SetLogin("olduser", "oldpass") Expect(config.Save()).To(Succeed()) }) Context("displaying the target", func() { JustBeforeEach(func() { test_helpers.ExecuteCommandWithArgs(targetCommand, []string{}) }) It("outputs the current user and target host", func() { Expect(outputBuffer).To(test_helpers.SayLine("Target:\t\[email protected]")) }) Context("when no username is set", func() { BeforeEach(func() { config.SetLogin("", "") Expect(config.Save()).To(Succeed()) }) It("only prints the target", func() { Expect(outputBuffer).To(test_helpers.SayLine("Target:\t\toldtarget.com")) }) }) Context("when no target is set", func() { BeforeEach(func() {
Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("No compatible container"))) Expect(outputBuffer).To(test_helpers.Say(colors.Bold("task-guid-3"))) Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("N/A"))) Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("COMPLETED"))) Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("N/A"))) Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("N/A"))) }) It("alerts the user if there are no apps or tasks", func() { fakeAppExaminer.ListAppsReturns([]app_examiner.AppInfo{}, nil) fakeTaskExaminer.ListTasksReturns([]task_examiner.TaskInfo{}, nil) test_helpers.ExecuteCommandWithArgs(listAppsCommand, []string{}) Expect(outputBuffer).To(test_helpers.SayLine("No apps to display.")) Expect(outputBuffer).To(test_helpers.Say("No tasks to display.")) }) Context("when the app examiner returns an error", func() { It("alerts the user fetching the app list returns an error", func() { fakeAppExaminer.ListAppsReturns(nil, errors.New("The list was lost")) listTasks := []task_examiner.TaskInfo{ { TaskGuid: "task-guid-1", CellID: "cell-01", Failed: false, FailureReason: "", Result: "Finished", State: "COMPLETED", },
DiegoRelease: "v221", GardenLinuxRelease: "v222", LatticeRelease: "some-server-lattice-sha", LatticeReleaseImage: "some-server-lattice-image-sha", LTC: "v225", Receptor: "v226", }, nil) }) It("Prints the CLI and API versions", func() { test_helpers.ExecuteCommandWithArgs(versionCommand, []string{}) Expect(fakeVersionManager.ServerVersionsCallCount()).To(Equal(1)) Expect(fakeVersionManager.ServerVersionsArgsForCall(0)).To(Equal("http://receptor.lattice.xip.io")) Expect(outputBuffer).To(test_helpers.SayLine("Client: some-client-lattice-sha")) Expect(outputBuffer).To(test_helpers.SayLine("Server: some-server-lattice-sha")) Expect(outputBuffer).To(test_helpers.SayLine("\tImage: some-server-lattice-image-sha")) Expect(outputBuffer).To(test_helpers.SayLine("\tCF: v219")) Expect(outputBuffer).To(test_helpers.SayLine("\tDiego: v221")) Expect(outputBuffer).To(test_helpers.SayLine("\tGarden-Linux: v222")) Expect(outputBuffer).To(test_helpers.SayLine("\tRouting: v220")) }) Context("when the version manager returns an error", func() { It("should print an error", func() { fakeVersionManager.ServerVersionsReturns(version.ServerVersions{}, errors.New("failed")) test_helpers.ExecuteCommandWithArgs(versionCommand, []string{}) Expect(outputBuffer).To(test_helpers.SayLine("Error: failed"))
fakeExitHandler = &fake_exit_handler.FakeExitHandler{} fakeSync = &mocks.FakeSync{} }) Describe("SyncCommand", func() { var syncCommand cli.Command BeforeEach(func() { commandFactory := command_factory.NewSyncCommandFactory(config, terminalUI, fakeExitHandler, "darwin", "/fake/ltc", fakeSync) syncCommand = commandFactory.MakeSyncCommand() }) It("should sync ltc", func() { test_helpers.ExecuteCommandWithArgs(syncCommand, []string{}) Expect(outputBuffer).To(test_helpers.SayLine("Updated ltc to the latest version.")) Expect(fakeSync.SyncLTCCallCount()).To(Equal(1)) actualLTCPath, actualArch, actualConfig := fakeSync.SyncLTCArgsForCall(0) Expect(actualLTCPath).To(Equal("/fake/ltc")) Expect(actualArch).To(Equal("osx")) Expect(actualConfig).To(Equal(config)) }) Context("when not targeted", func() { It("should print an error", func() { config.SetTarget("") test_helpers.ExecuteCommandWithArgs(syncCommand, []string{}) Expect(outputBuffer).To(test_helpers.SayLine("Error: Must be targeted to sync.")) Expect(fakeSync.SyncLTCCallCount()).To(Equal(0))
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() { appExaminer.AppExistsReturns(false, nil) taskExaminer.TaskStatusReturns(task_examiner.TaskInfo{}, errors.New("task not found")) doneChan := test_helpers.AsyncExecuteCommandWithArgs(logsCommand, []string{"non_existent_app"}) Eventually(fakeTailedLogsOutputter.OutputTailedLogsCallCount).Should(Equal(1)) Expect(fakeTailedLogsOutputter.OutputTailedLogsArgsForCall(0)).To(Equal("non_existent_app")) Eventually(outputBuffer).Should(test_helpers.SayLine("Application or task non_existent_app not found.")) Eventually(outputBuffer).Should(test_helpers.SayLine("Tailing logs and waiting for non_existent_app to appear...")) Consistently(doneChan).ShouldNot(BeClosed()) }) It("handles tasks", func() { appExaminer.AppExistsReturns(false, nil) taskExaminer.TaskStatusReturns(task_examiner.TaskInfo{}, nil) doneChan := test_helpers.AsyncExecuteCommandWithArgs(logsCommand, []string{"task-guid"}) Eventually(fakeTailedLogsOutputter.OutputTailedLogsCallCount).Should(Equal(1)) Expect(fakeTailedLogsOutputter.OutputTailedLogsArgsForCall(0)).To(Equal("task-guid")) Consistently(doneChan).ShouldNot(BeClosed())
BeforeEach(func() { tmpDir = os.TempDir() var err error tmpFile, err = ioutil.TempFile(tmpDir, "tmp_json") Expect(err).NotTo(HaveOccurred()) Expect(ioutil.WriteFile(tmpFile.Name(), []byte(`{"Value":"test value"}`), 0700)).To(Succeed()) }) It("creates an app from json", func() { fakeAppRunner.SubmitLrpReturns("my-json-app", nil) args := []string{tmpFile.Name()} test_helpers.ExecuteCommandWithArgs(submitLrpCommand, args) Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("Successfully submitted my-json-app."))) Expect(outputBuffer).To(test_helpers.SayLine("To view the status of your application: ltc status my-json-app")) Expect(fakeAppRunner.SubmitLrpCallCount()).To(Equal(1)) Expect(fakeAppRunner.SubmitLrpArgsForCall(0)).To(Equal([]byte(`{"Value":"test value"}`))) }) It("prints an error returned by the app_runner", func() { fakeAppRunner.SubmitLrpReturns("app-that-broke", errors.New("some error")) args := []string{tmpFile.Name()} test_helpers.ExecuteCommandWithArgs(submitLrpCommand, args) Expect(outputBuffer).To(test_helpers.SayLine("Error creating app-that-broke: some error")) Expect(fakeAppRunner.SubmitLrpCallCount()).To(Equal(1)) Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.CommandFailed})) }) })
Expect(cliApp).NotTo(BeNil()) Expect(cliApp.Version).To(Equal("development (not versioned) (diego unknown)")) }) }) Describe("App.Action", func() { Context("when ltc is run without argument(s)", func() { It("prints app help", func() { cli.AppHelpTemplate = "HELP_TEMPLATE" flagSet := flag.NewFlagSet("flag_set", flag.ContinueOnError) flagSet.Parse([]string{}) testContext := cli.NewContext(cliApp, flagSet, nil) cliApp.Action(testContext) Expect(outputBuffer).To(test_helpers.SayLine("ltc - Command line interface for Lattice.")) }) }) Context("when ltc is run with argument(s)", func() { It("prints unknown command message", func() { flagSet := flag.NewFlagSet("flag_set", flag.ContinueOnError) flagSet.Parse([]string{"one_arg"}) testContext := cli.NewContext(cliApp, flagSet, nil) cliApp.Action(testContext) Expect(outputBuffer).To(test_helpers.SayLine("ltc: 'one_arg' is not a registered command. See 'ltc help'")) }) }) })
It("negated match", func() { Expect(outputBuffer).NotTo(test_helpers.Say("match that")) }) Context("when format string is passed with arguments", func() { It("matches with regex-escaped characters", func() { Expect(outputBuffer).To(test_helpers.Say(`match %s \|?-^$.(){}`, "this")) }) }) }) Describe("SayLine", func() { BeforeEach(func() { outputBuffer.Write([]byte(`match this \|?-^$.(){}` + "\n")) }) It("matches with regex-escaped characters", func() { Expect(outputBuffer).To(test_helpers.SayLine(`match this \|?-^$.(){}`)) }) It("negated match", func() { Expect(outputBuffer).NotTo(test_helpers.SayLine("match that")) }) Context("when format string is passed with arguments", func() { It("matches with regex-escaped characters", func() { Expect(outputBuffer).To(test_helpers.SayLine(`match %s \|?-^$.(){}`, "this")) }) }) }) Describe("SayIncorrectUsage", func() { It("matches", func() { outputBuffer.Write([]byte("Incorrect Usage")) Expect(outputBuffer).To(test_helpers.SayIncorrectUsage())