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