github.com/cloudfoundry-incubator/stembuild@v0.0.0-20211223202937-5b61d62226c6/remotemanager/winrm_remotemanager_test.go (about) 1 package remotemanager_test 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "github.com/cloudfoundry-incubator/stembuild/remotemanager" 8 "github.com/cloudfoundry-incubator/stembuild/remotemanager/remotemanagerfakes" 9 "github.com/masterzen/winrm" 10 . "github.com/onsi/ginkgo" 11 . "github.com/onsi/gomega" 12 . "github.com/onsi/gomega/ghttp" 13 "log" 14 "net/http" 15 "net/url" 16 "strconv" 17 ) 18 19 ////go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . FakeShell 20 //type FakeShell interface { 21 // Close() error 22 //} 23 24 func setupTestServer() *Server { 25 server := NewServer() 26 27 // Suppresses ginkgo server logs 28 server.HTTPTestServer.Config.ErrorLog = log.New(&bytes.Buffer{}, "", 0) 29 30 response := ` 31 <s:Envelope xmlns:s="https://www.w3.org/2003/05/soap-envelope" 32 xmlns:a="https://schemas.xmlsoap.org/ws/2004/08/addressing" 33 xmlns:w="https://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"> 34 <s:Header> 35 <w:ShellId>153600</w:ShellId> 36 </s:Header> 37 <s:Body/> 38 </s:Envelope> 39 ` // Looks for: //w:Selector[@Name='ShellId'] 40 server.AppendHandlers( 41 RespondWith(http.StatusOK, response, http.Header{ 42 "Content-Type": {"application/soap+xml;charset=UTF-8"}, 43 }), 44 ) 45 server.AllowUnhandledRequests = true 46 return server 47 } 48 49 var _ = Describe("WinRM RemoteManager", func() { 50 Describe("ExecuteCommand", func() { 51 var ( 52 fakeClientFactory *remotemanagerfakes.FakeWinRMClientFactoryI 53 fakeClient *remotemanagerfakes.FakeWinRMClient 54 ) 55 56 Context("when a command runs successfully", func() { 57 BeforeEach(func() { 58 fakeClient = &remotemanagerfakes.FakeWinRMClient{} 59 fakeClient.RunReturns(0, nil) 60 fakeClientFactory = &remotemanagerfakes.FakeWinRMClientFactoryI{} 61 fakeClientFactory.BuildReturns(fakeClient, nil) 62 }) 63 64 It("returns an exit code of 0 and no error", func() { 65 remoteManager := remotemanager.NewWinRM("foo", "bar", "baz", fakeClientFactory) 66 exitCode, err := remoteManager.ExecuteCommand("foobar") 67 68 Expect(err).NotTo(HaveOccurred()) 69 Expect(exitCode).To(Equal(0)) 70 }) 71 72 }) 73 Context("when a command does not run successfully", func() { 74 75 BeforeEach(func() { 76 fakeClient = &remotemanagerfakes.FakeWinRMClient{} 77 fakeClientFactory = &remotemanagerfakes.FakeWinRMClientFactoryI{} 78 fakeClientFactory.BuildReturns(fakeClient, nil) 79 }) 80 81 Context("when a command returns a nonzero exit code and an error", func() { 82 BeforeEach(func() { 83 fakeClient.RunReturns(2, errors.New("command error")) 84 }) 85 86 It("returns the command's nonzero exit code and errors", func() { 87 remoteManager := remotemanager.NewWinRM("foo", "bar", "baz", fakeClientFactory) 88 exitCode, err := remoteManager.ExecuteCommand("foobar") 89 90 Expect(err).To(HaveOccurred()) 91 Expect(exitCode).To(Equal(2)) 92 }) 93 }) 94 Context("when a command returns a nonzero exit code but does not error", func() { 95 BeforeEach(func() { 96 fakeClient.RunReturns(2, nil) 97 }) 98 99 It("returns the command's nonzero exit code and errors", func() { 100 remoteManager := remotemanager.NewWinRM("foo", "bar", "baz", fakeClientFactory) 101 exitCode, err := remoteManager.ExecuteCommand("foobar") 102 103 Expect(err).To(HaveOccurred()) 104 Expect(exitCode).To(Equal(2)) 105 }) 106 }) 107 Context("when a command exits 0 but errors", func() { 108 BeforeEach(func() { 109 fakeClient.RunReturns(0, errors.New("command error")) 110 }) 111 112 It("returns the command's exit code and errors", func() { 113 remoteManager := remotemanager.NewWinRM("foo", "bar", "baz", fakeClientFactory) 114 exitCode, err := remoteManager.ExecuteCommand("foobar") 115 116 Expect(err).To(HaveOccurred()) 117 Expect(exitCode).To(Equal(0)) 118 }) 119 }) 120 }) 121 122 }) 123 Describe("CanLoginVM", func() { 124 var ( 125 testServer *Server 126 winRMClient *winrm.Client 127 ) 128 129 BeforeEach(func() { 130 testServer = setupTestServer() 131 132 testServerURL, err := url.Parse(testServer.URL()) 133 Expect(err).NotTo(HaveOccurred()) 134 port, err := strconv.Atoi(testServerURL.Port()) 135 Expect(err).NotTo(HaveOccurred()) 136 137 endpoint := &winrm.Endpoint{ 138 Host: testServerURL.Hostname(), 139 Port: port, 140 } 141 winRMClient, err = winrm.NewClient(endpoint, "", "") 142 Expect(err).NotTo(HaveOccurred()) 143 }) 144 145 var _ = AfterEach(func() { 146 testServer.Close() 147 }) 148 149 It("returns nil if shell can be created", func() { 150 winRMClientFactory := new(remotemanagerfakes.FakeWinRMClientFactoryI) 151 winRMClientFactory.BuildReturns(winRMClient, nil) 152 153 remotemanager := remotemanager.NewWinRM("some-host", "some-user", "some-pass", winRMClientFactory) 154 155 err := remotemanager.CanLoginVM() 156 157 Expect(err).NotTo(HaveOccurred()) 158 }) 159 It("returns error if winrmclient cannot be created", func() { 160 winRMClientFactory := new(remotemanagerfakes.FakeWinRMClientFactoryI) 161 buildError := errors.New("unable to build a client") 162 winRMClientFactory.BuildReturns(nil, buildError) 163 164 remotemanager := remotemanager.NewWinRM("some-host", "some-user", "some-pass", winRMClientFactory) 165 err := remotemanager.CanLoginVM() 166 167 Expect(err).To(HaveOccurred()) 168 Expect(err).To(MatchError(fmt.Errorf("failed to create winrm client: %s", buildError))) 169 }) 170 It("returns error if shell cannot be created", func() { 171 winRMClientFactory := new(remotemanagerfakes.FakeWinRMClientFactoryI) 172 winRMClient := new(remotemanagerfakes.FakeWinRMClient) 173 winRMClientFactory.BuildReturns(winRMClient, nil) 174 175 winRMClient.CreateShellReturns(nil, errors.New("some shell creation error")) 176 remotemanager := remotemanager.NewWinRM("some-host", "some-user", "some-pass", winRMClientFactory) 177 178 err := remotemanager.CanLoginVM() 179 180 Expect(err).To(HaveOccurred()) 181 Expect(err).To(MatchError(fmt.Errorf("failed to create winrm shell: some shell creation error"))) 182 183 }) 184 }) 185 })