github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/actor/sharedaction/ssh_test.go (about)

     1  package sharedaction_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	. "code.cloudfoundry.org/cli/actor/sharedaction"
     7  	"code.cloudfoundry.org/cli/actor/sharedaction/sharedactionfakes"
     8  	"code.cloudfoundry.org/cli/util/clissh"
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  )
    12  
    13  var _ = Describe("SSH Actions", func() {
    14  	var (
    15  		fakeConfig            *sharedactionfakes.FakeConfig
    16  		actor                 *Actor
    17  		fakeSecureShellClient *sharedactionfakes.FakeSecureShellClient
    18  	)
    19  
    20  	BeforeEach(func() {
    21  		fakeSecureShellClient = new(sharedactionfakes.FakeSecureShellClient)
    22  		fakeConfig = new(sharedactionfakes.FakeConfig)
    23  		actor = NewActor(fakeConfig)
    24  	})
    25  
    26  	Describe("ExecuteSecureShell", func() {
    27  		var (
    28  			sshOptions SSHOptions
    29  			executeErr error
    30  		)
    31  
    32  		BeforeEach(func() {
    33  			sshOptions = SSHOptions{
    34  				Username:           "some-user",
    35  				Passcode:           "some-passcode",
    36  				Endpoint:           "some-endpoint",
    37  				HostKeyFingerprint: "some-fingerprint",
    38  				SkipHostValidation: true,
    39  			}
    40  		})
    41  
    42  		JustBeforeEach(func() {
    43  			executeErr = actor.ExecuteSecureShell(fakeSecureShellClient, sshOptions)
    44  		})
    45  
    46  		It("calls connect with the provided authorization info", func() {
    47  			Expect(fakeSecureShellClient.ConnectCallCount()).To(Equal(1))
    48  			usernameArg, passcodeArg, endpointArg, fingerprintArg, skipHostValidationArg := fakeSecureShellClient.ConnectArgsForCall(0)
    49  			Expect(usernameArg).To(Equal("some-user"))
    50  			Expect(passcodeArg).To(Equal("some-passcode"))
    51  			Expect(endpointArg).To(Equal("some-endpoint"))
    52  			Expect(fingerprintArg).To(Equal("some-fingerprint"))
    53  			Expect(skipHostValidationArg).To(BeTrue())
    54  		})
    55  
    56  		When("connecting fails", func() {
    57  			BeforeEach(func() {
    58  				fakeSecureShellClient.ConnectReturns(errors.New("some-connect-error"))
    59  			})
    60  
    61  			It("does not call Close", func() {
    62  				Expect(fakeSecureShellClient.CloseCallCount()).To(Equal(0))
    63  			})
    64  
    65  			It("returns the error", func() {
    66  				Expect(executeErr).To(MatchError("some-connect-error"))
    67  			})
    68  		})
    69  
    70  		When("connecting succeeds", func() {
    71  			BeforeEach(func() {
    72  				sshOptions.LocalPortForwardSpecs = []LocalPortForward{
    73  					{LocalAddress: "local-address-1", RemoteAddress: "remote-address-1"},
    74  					{LocalAddress: "local-address-2", RemoteAddress: "remote-address-2"},
    75  				}
    76  			})
    77  
    78  			AfterEach(func() {
    79  				Expect(fakeSecureShellClient.CloseCallCount()).To(Equal(1))
    80  			})
    81  
    82  			It("forwards the local ports", func() {
    83  				Expect(fakeSecureShellClient.LocalPortForwardCallCount()).To(Equal(1))
    84  				Expect(fakeSecureShellClient.LocalPortForwardArgsForCall(0)).To(Equal(
    85  					[]clissh.LocalPortForward{
    86  						{LocalAddress: "local-address-1", RemoteAddress: "remote-address-1"},
    87  						{LocalAddress: "local-address-2", RemoteAddress: "remote-address-2"},
    88  					},
    89  				))
    90  			})
    91  
    92  			When("local port forwarding fails", func() {
    93  				BeforeEach(func() {
    94  					fakeSecureShellClient.LocalPortForwardReturns(errors.New("some-forwarding-error"))
    95  				})
    96  
    97  				It("returns the error", func() {
    98  					Expect(executeErr).To(MatchError("some-forwarding-error"))
    99  				})
   100  			})
   101  
   102  			When("local port forwarding succeeds", func() {
   103  				When("skipping remote execution", func() {
   104  					BeforeEach(func() {
   105  						sshOptions.SkipRemoteExecution = true
   106  					})
   107  
   108  					It("waits and does not create an interactive session", func() {
   109  						Expect(fakeSecureShellClient.WaitCallCount()).To(Equal(1))
   110  						Expect(fakeSecureShellClient.InteractiveSessionCallCount()).To(Equal(0))
   111  					})
   112  
   113  					When("waiting errors", func() {
   114  						// TODO: Handle different errors caused by interrupt signals
   115  						BeforeEach(func() {
   116  							fakeSecureShellClient.WaitReturns(errors.New("some-wait-error"))
   117  						})
   118  
   119  						It("returns the error", func() {
   120  							Expect(executeErr).To(MatchError(errors.New("some-wait-error")))
   121  						})
   122  					})
   123  
   124  					When("waiting succeeds", func() {
   125  						It("returns no error", func() {
   126  							Expect(executeErr).ToNot(HaveOccurred())
   127  						})
   128  					})
   129  				})
   130  
   131  				When("creating an interactive session", func() {
   132  					BeforeEach(func() {
   133  						sshOptions.SkipRemoteExecution = false
   134  						sshOptions.Commands = []string{"some-command-1", "some-command-2"}
   135  						sshOptions.TTYOption = RequestTTYForce
   136  					})
   137  
   138  					It("creates an interactive session with the provided commands and tty type", func() {
   139  						Expect(fakeSecureShellClient.InteractiveSessionCallCount()).To(Equal(1))
   140  						commandsArg, ttyTypeArg := fakeSecureShellClient.InteractiveSessionArgsForCall(0)
   141  						Expect(commandsArg).To(ConsistOf("some-command-1", "some-command-2"))
   142  						Expect(ttyTypeArg).To(Equal(clissh.RequestTTYForce))
   143  						Expect(fakeSecureShellClient.WaitCallCount()).To(Equal(0))
   144  					})
   145  
   146  					When("the interactive session errors", func() {
   147  						// TODO: Handle different errors caused by interrupt signals
   148  						BeforeEach(func() {
   149  							fakeSecureShellClient.InteractiveSessionReturns(errors.New("some-interactive-session-error"))
   150  						})
   151  
   152  						It("returns the error", func() {
   153  							Expect(executeErr).To(MatchError("some-interactive-session-error"))
   154  						})
   155  					})
   156  
   157  					When("the interactive session succeeds", func() {
   158  						It("returns no error", func() {
   159  							Expect(executeErr).ToNot(HaveOccurred())
   160  						})
   161  					})
   162  				})
   163  			})
   164  		})
   165  	})
   166  })