github.com/cloudfoundry-attic/ltc@v0.0.0-20151123212628-098adc7919fc/version/version_manager_test.go (about)

     1  package version_test
     2  
     3  import (
     4  	"errors"
     5  	"io/ioutil"
     6  	"net"
     7  	"net/http"
     8  	"net/url"
     9  	"os"
    10  
    11  	. "github.com/onsi/ginkgo"
    12  	. "github.com/onsi/gomega"
    13  	"github.com/onsi/gomega/ghttp"
    14  
    15  	config_package "github.com/cloudfoundry-incubator/ltc/config"
    16  	"github.com/cloudfoundry-incubator/ltc/receptor_client/fake_receptor_client_creator"
    17  	"github.com/cloudfoundry-incubator/ltc/version"
    18  	"github.com/cloudfoundry-incubator/ltc/version/fake_file_swapper"
    19  	"github.com/cloudfoundry-incubator/receptor"
    20  	"github.com/cloudfoundry-incubator/receptor/fake_receptor"
    21  )
    22  
    23  var _ = Describe("VersionManager", func() {
    24  	var (
    25  		fakeFileSwapper           *fake_file_swapper.FakeFileSwapper
    26  		fakeServer                *ghttp.Server
    27  		config                    *config_package.Config
    28  		versionManager            version.VersionManager
    29  		fakeReceptorClientCreator *fake_receptor_client_creator.FakeCreator
    30  		fakeReceptorClient        *fake_receptor.FakeClient
    31  
    32  		ltcTempFile *os.File
    33  	)
    34  
    35  	BeforeEach(func() {
    36  		fakeFileSwapper = &fake_file_swapper.FakeFileSwapper{}
    37  
    38  		fakeServer = ghttp.NewServer()
    39  		fakeServerURL, err := url.Parse(fakeServer.URL())
    40  		Expect(err).NotTo(HaveOccurred())
    41  
    42  		fakeServerHost, fakeServerPort, err := net.SplitHostPort(fakeServerURL.Host)
    43  		Expect(err).NotTo(HaveOccurred())
    44  
    45  		ltcTempFile, err = ioutil.TempFile("", "fake-ltc")
    46  		Expect(err).NotTo(HaveOccurred())
    47  
    48  		fakeReceptorClient = &fake_receptor.FakeClient{}
    49  		fakeReceptorClientCreator = &fake_receptor_client_creator.FakeCreator{}
    50  		fakeReceptorClientCreator.CreateReceptorClientReturns(fakeReceptorClient)
    51  
    52  		config = config_package.New(nil)
    53  		config.SetTarget(fakeServerHost + ".xip.io:" + fakeServerPort)
    54  		versionManager = version.NewVersionManager(fakeReceptorClientCreator, fakeFileSwapper, "")
    55  	})
    56  
    57  	AfterEach(func() {
    58  		ltcTempFile.Close()
    59  		Expect(os.Remove(ltcTempFile.Name())).To(Succeed())
    60  	})
    61  
    62  	Describe("ServerVersions", func() {
    63  		It("should fetch versions from receptor", func() {
    64  			fakeReceptorClient.GetVersionReturns(receptor.VersionResponse{
    65  				CFRelease:           "v219",
    66  				CFRoutingRelease:    "v220",
    67  				DiegoRelease:        "v221",
    68  				GardenLinuxRelease:  "v222",
    69  				LatticeRelease:      "v223",
    70  				LatticeReleaseImage: "v224",
    71  				LTC:                 "v225",
    72  				Receptor:            "v226",
    73  			}, nil)
    74  
    75  			serverVersions, _ := versionManager.ServerVersions("some-target")
    76  
    77  			Expect(fakeReceptorClientCreator.CreateReceptorClientCallCount()).To(Equal(1))
    78  			Expect(fakeReceptorClientCreator.CreateReceptorClientArgsForCall(0)).To(Equal("some-target"))
    79  
    80  			Expect(serverVersions).To(Equal(version.ServerVersions{
    81  				CFRelease:           "v219",
    82  				CFRoutingRelease:    "v220",
    83  				DiegoRelease:        "v221",
    84  				GardenLinuxRelease:  "v222",
    85  				LatticeRelease:      "v223",
    86  				LatticeReleaseImage: "v224",
    87  				LTC:                 "v225",
    88  				Receptor:            "v226",
    89  			}))
    90  		})
    91  
    92  		Context("when call to receptor fails", func() {
    93  			It("should return the error", func() {
    94  				err := errors.New("error")
    95  				fakeReceptorClient.GetVersionReturns(receptor.VersionResponse{}, err)
    96  
    97  				_, actualError := versionManager.ServerVersions("")
    98  				Expect(actualError).To(Equal(err))
    99  			})
   100  		})
   101  	})
   102  
   103  	Describe("#SyncLTC", func() {
   104  		It("should download ltc from the target and swap it with ltc", func() {
   105  			fakeServer.RouteToHandler("GET", "/v1/sync/amiga/ltc", ghttp.CombineHandlers(
   106  				ghttp.RespondWith(200, []byte{0x01, 0x02, 0x03}, http.Header{
   107  					"Content-Type":   []string{"application/octet-stream"},
   108  					"Content-Length": []string{"3"},
   109  				}),
   110  			))
   111  
   112  			tmpFile, err := ioutil.TempFile("", "")
   113  			Expect(err).NotTo(HaveOccurred())
   114  			defer os.Remove(tmpFile.Name())
   115  
   116  			fakeFileSwapper.GetTempFileReturns(tmpFile, nil)
   117  
   118  			versionManager.SyncLTC(ltcTempFile.Name(), "amiga", config)
   119  
   120  			Expect(fakeServer.ReceivedRequests()).To(HaveLen(1))
   121  
   122  			Expect(fakeFileSwapper.GetTempFileCallCount()).To(Equal(1))
   123  
   124  			Expect(fakeFileSwapper.SwapTempFileCallCount()).To(Equal(1))
   125  			actualDest, actualSrc := fakeFileSwapper.SwapTempFileArgsForCall(0)
   126  			Expect(actualDest).To(Equal(ltcTempFile.Name()))
   127  			Expect(actualSrc).To(Equal(tmpFile.Name()))
   128  
   129  			tmpFile, err = os.OpenFile(tmpFile.Name(), os.O_RDONLY, 0)
   130  			Expect(err).NotTo(HaveOccurred())
   131  
   132  			bytes, err := ioutil.ReadAll(tmpFile)
   133  			Expect(err).NotTo(HaveOccurred())
   134  			Expect(bytes).To(Equal([]byte{0x01, 0x02, 0x03}))
   135  		})
   136  
   137  		Context("when the http request returns a non-200 status", func() {
   138  			It("should return an error", func() {
   139  				fakeServer.RouteToHandler("GET", "/v1/sync/amiga/ltc", ghttp.CombineHandlers(
   140  					ghttp.RespondWith(500, "", nil),
   141  				))
   142  
   143  				err := versionManager.SyncLTC(ltcTempFile.Name(), "amiga", config)
   144  				Expect(err).To(MatchError(HavePrefix("failed to download ltc")))
   145  			})
   146  		})
   147  
   148  		Context("when the http request fails", func() {
   149  			It("should return an error", func() {
   150  				config.SetTarget("localhost:1")
   151  
   152  				err := versionManager.SyncLTC(ltcTempFile.Name(), "amiga", config)
   153  				Expect(err).To(MatchError(HavePrefix("failed to connect to receptor")))
   154  			})
   155  		})
   156  
   157  		Context("when opening the temp file fails", func() {
   158  			It("should return an error", func() {
   159  				fakeServer.RouteToHandler("GET", "/v1/sync/amiga/ltc", ghttp.CombineHandlers(
   160  					ghttp.RespondWith(200, []byte{0x01, 0x02, 0x03}, http.Header{
   161  						"Content-Type":   []string{"application/octet-stream"},
   162  						"Content-Length": []string{"3"},
   163  					}),
   164  				))
   165  
   166  				fakeFileSwapper.GetTempFileReturns(nil, errors.New("boom"))
   167  
   168  				err := versionManager.SyncLTC(ltcTempFile.Name(), "amiga", config)
   169  				Expect(err).To(MatchError("failed to open temp file: boom"))
   170  			})
   171  		})
   172  
   173  		Context("when the file copy fails", func() {
   174  			It("should return an error", func() {
   175  				fakeServer.RouteToHandler("GET", "/v1/sync/amiga/ltc", ghttp.CombineHandlers(
   176  					ghttp.RespondWith(200, []byte{0x01, 0x02, 0x03}, http.Header{
   177  						"Content-Type":   []string{"application/octet-stream"},
   178  						"Content-Length": []string{"3"},
   179  					}),
   180  				))
   181  
   182  				tmpFile, err := ioutil.TempFile("", "")
   183  				Expect(err).NotTo(HaveOccurred())
   184  				defer os.Remove(tmpFile.Name())
   185  				tmpFile, err = os.OpenFile(tmpFile.Name(), os.O_RDONLY, 0)
   186  				Expect(err).NotTo(HaveOccurred())
   187  
   188  				fakeFileSwapper.GetTempFileReturns(tmpFile, nil)
   189  
   190  				err = versionManager.SyncLTC(ltcTempFile.Name(), "amiga", config)
   191  				Expect(err).To(MatchError(HavePrefix("failed to write to temp ltc")))
   192  			})
   193  		})
   194  
   195  		Context("when swapping the files fails", func() {
   196  			It("should return an error", func() {
   197  				fakeServer.RouteToHandler("GET", "/v1/sync/amiga/ltc", ghttp.CombineHandlers(
   198  					ghttp.RespondWith(200, []byte{0x01, 0x02, 0x03}, http.Header{
   199  						"Content-Type":   []string{"application/octet-stream"},
   200  						"Content-Length": []string{"3"},
   201  					}),
   202  				))
   203  
   204  				tmpFile, err := ioutil.TempFile("", "")
   205  				Expect(err).NotTo(HaveOccurred())
   206  				defer os.Remove(tmpFile.Name())
   207  
   208  				fakeFileSwapper.GetTempFileReturns(tmpFile, nil)
   209  				fakeFileSwapper.SwapTempFileReturns(errors.New("failed"))
   210  
   211  				err = versionManager.SyncLTC(ltcTempFile.Name(), "amiga", config)
   212  				Expect(err).To(MatchError(HavePrefix("failed to swap ltc")))
   213  			})
   214  		})
   215  	})
   216  
   217  	Describe("#LatticeVersion", func() {
   218  		It("should return its latticeVersion", func() {
   219  			versionManager := version.NewVersionManager(fakeReceptorClientCreator, fakeFileSwapper, "some-version")
   220  			Expect(versionManager.LatticeVersion()).To(Equal("some-version"))
   221  		})
   222  	})
   223  
   224  	Describe("#LtcMatchesServer", func() {
   225  		BeforeEach(func() {
   226  			fakeReceptorClient.GetVersionReturns(receptor.VersionResponse{
   227  				CFRelease:           "v219",
   228  				CFRoutingRelease:    "v220",
   229  				DiegoRelease:        "v221",
   230  				GardenLinuxRelease:  "v222",
   231  				LatticeRelease:      "v223",
   232  				LatticeReleaseImage: "v224",
   233  				LTC:                 "v225",
   234  				Receptor:            "v226",
   235  			}, nil)
   236  		})
   237  
   238  		Context("when the local lattice version matches the server's expected version", func() {
   239  			It("should return true", func() {
   240  				versionManager := version.NewVersionManager(fakeReceptorClientCreator, fakeFileSwapper, "v223")
   241  				Expect(versionManager.LtcMatchesServer("some-target")).To(BeTrue())
   242  				Expect(fakeReceptorClientCreator.CreateReceptorClientCallCount()).To(Equal(1))
   243  				Expect(fakeReceptorClientCreator.CreateReceptorClientArgsForCall(0)).To(Equal("some-target"))
   244  			})
   245  		})
   246  
   247  		Context("when the local lattice version does not match the server's expected version", func() {
   248  			It("should return false", func() {
   249  				versionManager := version.NewVersionManager(fakeReceptorClientCreator, fakeFileSwapper, "mismatched-version")
   250  				Expect(versionManager.LtcMatchesServer("some-target")).To(BeFalse())
   251  				Expect(fakeReceptorClientCreator.CreateReceptorClientCallCount()).To(Equal(1))
   252  				Expect(fakeReceptorClientCreator.CreateReceptorClientArgsForCall(0)).To(Equal("some-target"))
   253  			})
   254  		})
   255  	})
   256  })