github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/command/v3/v3_ssh_command_test.go (about) 1 package v3_test 2 3 import ( 4 "errors" 5 6 "code.cloudfoundry.org/cli/actor/actionerror" 7 "code.cloudfoundry.org/cli/actor/sharedaction" 8 "code.cloudfoundry.org/cli/actor/v3action" 9 "code.cloudfoundry.org/cli/api/cloudcontroller/ccversion" 10 "code.cloudfoundry.org/cli/command/commandfakes" 11 "code.cloudfoundry.org/cli/command/flag" 12 "code.cloudfoundry.org/cli/command/translatableerror" 13 "code.cloudfoundry.org/cli/command/v3" 14 "code.cloudfoundry.org/cli/command/v3/v3fakes" 15 "code.cloudfoundry.org/cli/util/configv3" 16 "code.cloudfoundry.org/cli/util/ui" 17 . "github.com/onsi/ginkgo" 18 . "github.com/onsi/ginkgo/extensions/table" 19 . "github.com/onsi/gomega" 20 . "github.com/onsi/gomega/gbytes" 21 ) 22 23 var _ = Describe("v3-ssh Command", func() { 24 var ( 25 cmd v3.V3SSHCommand 26 testUI *ui.UI 27 fakeConfig *commandfakes.FakeConfig 28 fakeSharedActor *commandfakes.FakeSharedActor 29 fakeActor *v3fakes.FakeV3SSHActor 30 fakeSSHActor *v3fakes.FakeSSHActor 31 executeErr error 32 appName string 33 ) 34 35 BeforeEach(func() { 36 testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer()) 37 fakeConfig = new(commandfakes.FakeConfig) 38 fakeSharedActor = new(commandfakes.FakeSharedActor) 39 fakeActor = new(v3fakes.FakeV3SSHActor) 40 fakeSSHActor = new(v3fakes.FakeSSHActor) 41 42 appName = "some-app" 43 cmd = v3.V3SSHCommand{ 44 RequiredArgs: flag.AppName{AppName: appName}, 45 46 ProcessType: "some-process-type", 47 ProcessIndex: 1, 48 Commands: []string{"some", "commands"}, 49 SkipHostValidation: true, 50 SkipRemoteExecution: true, 51 52 UI: testUI, 53 Config: fakeConfig, 54 SharedActor: fakeSharedActor, 55 Actor: fakeActor, 56 SSHActor: fakeSSHActor, 57 } 58 59 fakeActor.CloudControllerAPIVersionReturns(ccversion.MinVersionV3) 60 }) 61 62 Describe("Execute", func() { 63 JustBeforeEach(func() { 64 executeErr = cmd.Execute(nil) 65 }) 66 67 Context("when the API version is below the minimum", func() { 68 BeforeEach(func() { 69 fakeActor.CloudControllerAPIVersionReturns("0.0.0") 70 }) 71 72 It("returns a MinimumAPIVersionNotMetError", func() { 73 Expect(executeErr).To(MatchError(translatableerror.MinimumAPIVersionNotMetError{ 74 CurrentVersion: "0.0.0", 75 MinimumVersion: ccversion.MinVersionV3, 76 })) 77 }) 78 79 It("displays the experimental warning", func() { 80 Expect(testUI.Err).To(Say("This command is in EXPERIMENTAL stage and may change without notice")) 81 }) 82 }) 83 84 Context("when checking target fails", func() { 85 BeforeEach(func() { 86 fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: "steve"}) 87 }) 88 89 It("returns an error", func() { 90 Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: "steve"})) 91 92 Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1)) 93 checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0) 94 Expect(checkTargetedOrg).To(BeTrue()) 95 Expect(checkTargetedSpace).To(BeTrue()) 96 }) 97 }) 98 99 Context("when the user is targeted to an organization and space", func() { 100 BeforeEach(func() { 101 fakeConfig.TargetedSpaceReturns(configv3.Space{GUID: "some-space-guid"}) 102 }) 103 104 Context("when getting the secure shell authentication information succeeds", func() { 105 var sshAuth v3action.SSHAuthentication 106 107 BeforeEach(func() { 108 sshAuth = v3action.SSHAuthentication{ 109 Endpoint: "some-endpoint", 110 HostKeyFingerprint: "some-fingerprint", 111 Passcode: "some-passcode", 112 Username: "some-username", 113 } 114 115 fakeActor.GetSecureShellConfigurationByApplicationNameSpaceProcessTypeAndIndexReturns(sshAuth, v3action.Warnings{"some-warnings"}, nil) 116 }) 117 118 Context("when executing the secure shell succeeds", func() { 119 BeforeEach(func() { 120 cmd.DisablePseudoTTY = true 121 }) 122 123 It("displays all warnings", func() { 124 Expect(executeErr).ToNot(HaveOccurred()) 125 Expect(testUI.Err).To(Say("some-warnings")) 126 127 Expect(fakeActor.GetSecureShellConfigurationByApplicationNameSpaceProcessTypeAndIndexCallCount()).To(Equal(1)) 128 appNameArg, spaceGUIDArg, processTypeArg, processIndexArg := fakeActor.GetSecureShellConfigurationByApplicationNameSpaceProcessTypeAndIndexArgsForCall(0) 129 Expect(appNameArg).To(Equal(appName)) 130 Expect(spaceGUIDArg).To(Equal("some-space-guid")) 131 Expect(processTypeArg).To(Equal("some-process-type")) 132 Expect(processIndexArg).To(Equal(uint(1))) 133 134 Expect(fakeSSHActor.ExecuteSecureShellCallCount()).To(Equal(1)) 135 _, sshOptionsArg := fakeSSHActor.ExecuteSecureShellArgsForCall(0) 136 Expect(sshOptionsArg).To(Equal(sharedaction.SSHOptions{ 137 Commands: []string{"some", "commands"}, 138 Endpoint: "some-endpoint", 139 HostKeyFingerprint: "some-fingerprint", 140 Passcode: "some-passcode", 141 SkipHostValidation: true, 142 SkipRemoteExecution: true, 143 TTYOption: sharedaction.RequestTTYNo, 144 Username: "some-username", 145 })) 146 }) 147 148 Context("when working with local port forwarding", func() { 149 BeforeEach(func() { 150 cmd.LocalPortForwardSpecs = []flag.SSHPortForwarding{ 151 {LocalAddress: "localhost:8888", RemoteAddress: "remote:4444"}, 152 {LocalAddress: "localhost:7777", RemoteAddress: "remote:3333"}, 153 } 154 }) 155 156 It("passes along port forwarding information", func() { 157 Expect(executeErr).ToNot(HaveOccurred()) 158 Expect(testUI.Err).To(Say("some-warnings")) 159 160 Expect(fakeSSHActor.ExecuteSecureShellCallCount()).To(Equal(1)) 161 _, sshOptionsArg := fakeSSHActor.ExecuteSecureShellArgsForCall(0) 162 Expect(sshOptionsArg).To(Equal(sharedaction.SSHOptions{ 163 Commands: []string{"some", "commands"}, 164 Endpoint: "some-endpoint", 165 HostKeyFingerprint: "some-fingerprint", 166 Passcode: "some-passcode", 167 TTYOption: sharedaction.RequestTTYNo, 168 SkipHostValidation: true, 169 SkipRemoteExecution: true, 170 LocalPortForwardSpecs: []sharedaction.LocalPortForward{ 171 {LocalAddress: "localhost:8888", RemoteAddress: "remote:4444"}, 172 {LocalAddress: "localhost:7777", RemoteAddress: "remote:3333"}, 173 }, 174 Username: "some-username", 175 })) 176 }) 177 }) 178 }) 179 180 Context("when executing the secure shell fails", func() { 181 BeforeEach(func() { 182 cmd.DisablePseudoTTY = true 183 184 fakeSSHActor.ExecuteSecureShellReturns(errors.New("banananannananana")) 185 }) 186 187 It("displays all warnings", func() { 188 Expect(executeErr).To(MatchError("banananannananana")) 189 Expect(testUI.Err).To(Say("some-warnings")) 190 }) 191 }) 192 }) 193 194 Context("when getting the secure shell authentication fails", func() { 195 BeforeEach(func() { 196 fakeActor.GetSecureShellConfigurationByApplicationNameSpaceProcessTypeAndIndexReturns(v3action.SSHAuthentication{}, v3action.Warnings{"some-warnings"}, errors.New("some-error")) 197 }) 198 199 It("returns the error and displays all warnings", func() { 200 Expect(executeErr).To(MatchError("some-error")) 201 Expect(testUI.Err).To(Say("some-warnings")) 202 }) 203 }) 204 }) 205 }) 206 207 DescribeTable("EvaluateTTYOption", 208 func(disablePseudoTTY bool, forcePseudoTTY bool, requestPseudoTTY bool, expectedErr error, ttyOption sharedaction.TTYOption) { 209 cmd.DisablePseudoTTY = disablePseudoTTY 210 cmd.ForcePseudoTTY = forcePseudoTTY 211 cmd.RequestPseudoTTY = requestPseudoTTY 212 returnedTTYOption, executeErr := cmd.EvaluateTTYOption() 213 214 if expectedErr == nil { 215 Expect(executeErr).To(BeNil()) 216 Expect(returnedTTYOption).To(Equal(ttyOption)) 217 } else { 218 Expect(executeErr).To(MatchError(expectedErr)) 219 } 220 }, 221 Entry("default - auto TTY", false, false, false, nil, sharedaction.RequestTTYAuto), 222 Entry("disable tty - no TTY", true, false, false, nil, sharedaction.RequestTTYNo), 223 Entry("force tty - forced TTY", false, true, false, nil, sharedaction.RequestTTYForce), 224 Entry("psudo tty - yes TTY", false, false, true, nil, sharedaction.RequestTTYYes), 225 Entry("disable and force tty", true, true, false, 226 translatableerror.ArgumentCombinationError{Args: []string{ 227 "--disable-pseudo-tty", "-T", "--force-pseudo-tty", "--request-pseudo-tty", "-t", 228 }}, 229 sharedaction.TTYOption(0), 230 ), 231 Entry("disable and requst tty", true, false, true, 232 translatableerror.ArgumentCombinationError{Args: []string{ 233 "--disable-pseudo-tty", "-T", "--force-pseudo-tty", "--request-pseudo-tty", "-t", 234 }}, 235 sharedaction.TTYOption(0), 236 ), 237 Entry("force and request tty", false, true, true, 238 translatableerror.ArgumentCombinationError{Args: []string{ 239 "--disable-pseudo-tty", "-T", "--force-pseudo-tty", "--request-pseudo-tty", "-t", 240 }}, 241 sharedaction.TTYOption(0), 242 ), 243 Entry("disable, force, and request tty", true, true, true, 244 translatableerror.ArgumentCombinationError{Args: []string{ 245 "--disable-pseudo-tty", "-T", "--force-pseudo-tty", "--request-pseudo-tty", "-t", 246 }}, 247 sharedaction.TTYOption(0), 248 ), 249 ) 250 })