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  })