github.com/cloudfoundry-attic/ltc@v0.0.0-20151123212628-098adc7919fc/route_helpers/route_helpers_test.go (about) 1 package route_helpers_test 2 3 import ( 4 "encoding/json" 5 6 . "github.com/onsi/ginkgo" 7 . "github.com/onsi/gomega" 8 9 "github.com/cloudfoundry-incubator/ltc/route_helpers" 10 . "github.com/cloudfoundry-incubator/ltc/test_helpers/matchers" 11 "github.com/cloudfoundry-incubator/receptor" 12 ) 13 14 var _ = Describe("RoutingInfoHelpers", func() { 15 var ( 16 appRoute1 route_helpers.AppRoute 17 appRoute2 route_helpers.AppRoute 18 appRoute3 route_helpers.AppRoute 19 20 appRoutes route_helpers.AppRoutes 21 ) 22 23 BeforeEach(func() { 24 appRoute1 = route_helpers.AppRoute{ 25 Hostnames: []string{"foo1.example.com", "bar1.examaple.com"}, 26 Port: 11111, 27 } 28 appRoute2 = route_helpers.AppRoute{ 29 Hostnames: []string{"foo2.example.com", "bar2.examaple.com"}, 30 Port: 22222, 31 } 32 appRoute3 = route_helpers.AppRoute{ 33 Hostnames: []string{"foo3.example.com", "bar3.examaple.com"}, 34 Port: 33333, 35 } 36 37 appRoutes = route_helpers.AppRoutes{appRoute1, appRoute2, appRoute3} 38 }) 39 40 Describe("AppRoutes", func() { 41 Describe("RoutingInfo", func() { 42 var routingInfo receptor.RoutingInfo 43 44 JustBeforeEach(func() { 45 routingInfo = appRoutes.RoutingInfo() 46 }) 47 48 It("maps the serialized routes to the correct key", func() { 49 expectedBytes := []byte(`[{"hostnames":["foo1.example.com","bar1.examaple.com"],"port":11111},{"hostnames":["foo2.example.com","bar2.examaple.com"],"port":22222},{"hostnames":["foo3.example.com","bar3.examaple.com"],"port":33333}]`) 50 Expect(appRoutes.RoutingInfo()["cf-router"].MarshalJSON()).To(MatchJSON(expectedBytes)) 51 }) 52 53 Context("when AppRoutes is empty", func() { 54 BeforeEach(func() { 55 appRoutes = route_helpers.AppRoutes{} 56 }) 57 58 It("marshals an empty list", func() { 59 payload, err := routingInfo["cf-router"].MarshalJSON() 60 Expect(err).NotTo(HaveOccurred()) 61 62 Expect(payload).To(MatchJSON(`[]`)) 63 }) 64 }) 65 }) 66 }) 67 68 Describe("AppRoutesFromRoutingInfo", func() { 69 var routingInfo receptor.RoutingInfo 70 71 Context("when the method returns a value", func() { 72 var routesResult route_helpers.AppRoutes 73 74 JustBeforeEach(func() { 75 routesResult = route_helpers.AppRoutesFromRoutingInfo(routingInfo) 76 }) 77 78 Context("when lattice app routes are present in the routing info", func() { 79 BeforeEach(func() { 80 routingInfo = appRoutes.RoutingInfo() 81 }) 82 83 It("returns the routes", func() { 84 Expect(appRoutes).To(Equal(routesResult)) 85 }) 86 }) 87 88 Context("when the result should be nil", func() { 89 itReturnsNilRoutes := func() { 90 It("returns nil routes", func() { 91 Expect(routesResult).To(BeNil()) 92 }) 93 } 94 95 Context("when the lattice routes are nil", func() { 96 BeforeEach(func() { 97 routingInfo = receptor.RoutingInfo{route_helpers.AppRouter: nil} 98 }) 99 100 itReturnsNilRoutes() 101 }) 102 103 Context("when lattice app routes are not present in the routing info", func() { 104 BeforeEach(func() { 105 routingInfo = receptor.RoutingInfo{} 106 }) 107 108 itReturnsNilRoutes() 109 }) 110 111 Context("when the routing info is nil", func() { 112 BeforeEach(func() { 113 routingInfo = nil 114 }) 115 116 itReturnsNilRoutes() 117 }) 118 }) 119 }) 120 121 Context("when the json.RawMessage is malformed", func() { 122 BeforeEach(func() { 123 routingInfo = receptor.RoutingInfo{} 124 jsonMessage := json.RawMessage(`{"what": "up`) 125 routingInfo[route_helpers.AppRouter] = &jsonMessage 126 }) 127 128 It("panics at the disco", func() { 129 appRoutesFromRoutingInfo := func() func() { 130 return func() { route_helpers.AppRoutesFromRoutingInfo(routingInfo) } 131 } 132 133 Consistently(appRoutesFromRoutingInfo).Should(Panic(), "invalid json.RawMessage ought to panic") 134 }) 135 }) 136 }) 137 138 Describe("HostnamesByPort", func() { 139 It("returns map of ports to slice of hostnames", func() { 140 expectedHostnamesByPort := map[uint16][]string{ 141 11111: []string{"foo1.example.com", "bar1.examaple.com"}, 142 22222: []string{"foo2.example.com", "bar2.examaple.com"}, 143 33333: []string{"foo3.example.com", "bar3.examaple.com"}, 144 } 145 146 Expect(appRoutes.HostnamesByPort()).To(Equal(expectedHostnamesByPort)) 147 }) 148 }) 149 150 Describe("Routes", func() { 151 152 var ( 153 routes route_helpers.Routes 154 tcpRoute1, tcpRoute2 route_helpers.TcpRoute 155 diegoSSHRoute *route_helpers.DiegoSSHRoute 156 ) 157 158 BeforeEach(func() { 159 tcpRoute1 = route_helpers.TcpRoute{ 160 RouterGroupGuid: route_helpers.DefaultRouterGroupGuid, 161 ExternalPort: 50000, 162 Port: 5222, 163 } 164 tcpRoute2 = route_helpers.TcpRoute{ 165 RouterGroupGuid: route_helpers.DefaultRouterGroupGuid, 166 ExternalPort: 51000, 167 Port: 5223, 168 } 169 diegoSSHRoute = &route_helpers.DiegoSSHRoute{ 170 Port: 2222, 171 PrivateKey: "ssshhhhh", 172 } 173 routes = route_helpers.Routes{ 174 AppRoutes: route_helpers.AppRoutes{ 175 appRoute1, appRoute2, 176 }, 177 TcpRoutes: route_helpers.TcpRoutes{ 178 tcpRoute1, tcpRoute2, 179 }, 180 DiegoSSHRoute: diegoSSHRoute, 181 } 182 }) 183 184 Describe("RoutingInfo", func() { 185 var routingInfo receptor.RoutingInfo 186 187 JustBeforeEach(func() { 188 routingInfo = routes.RoutingInfo() 189 }) 190 191 It("wraps the serialized routes with the correct key", func() { 192 expectedAppRoutes, err := json.Marshal(route_helpers.AppRoutes{appRoute1, appRoute2}) 193 Expect(err).NotTo(HaveOccurred()) 194 195 appRoutesPayload, err := routingInfo[route_helpers.AppRouter].MarshalJSON() 196 Expect(err).NotTo(HaveOccurred()) 197 198 Expect(appRoutesPayload).To(MatchJSON(expectedAppRoutes)) 199 200 expectedTcpRoutes, err := json.Marshal(route_helpers.TcpRoutes{tcpRoute1, tcpRoute2}) 201 Expect(err).NotTo(HaveOccurred()) 202 203 tcpRoutesPayload, err := routingInfo[route_helpers.TcpRouter].MarshalJSON() 204 Expect(err).NotTo(HaveOccurred()) 205 206 Expect(tcpRoutesPayload).To(MatchJSON(expectedTcpRoutes)) 207 208 expectedBytes := []byte(`{"container_port":2222,"private_key":"ssshhhhh"}`) 209 Expect(routingInfo["diego-ssh"].MarshalJSON()).To(MatchJSON(expectedBytes)) 210 }) 211 212 Context("when Routes is empty", func() { 213 BeforeEach(func() { 214 routes = route_helpers.Routes{ 215 AppRoutes: route_helpers.AppRoutes{}, 216 TcpRoutes: route_helpers.TcpRoutes{}, 217 } 218 }) 219 220 It("marshals an empty list", func() { 221 appRoutesPayload, err := routingInfo[route_helpers.AppRouter].MarshalJSON() 222 Expect(err).NotTo(HaveOccurred()) 223 Expect(appRoutesPayload).To(MatchJSON("[]")) 224 225 tcpRoutesPayload, err := routingInfo[route_helpers.TcpRouter].MarshalJSON() 226 Expect(err).NotTo(HaveOccurred()) 227 Expect(tcpRoutesPayload).To(MatchJSON("[]")) 228 }) 229 }) 230 }) 231 232 Describe("RoutesFromRoutingInfo", func() { 233 var routingInfo receptor.RoutingInfo 234 235 Context("when the method returns a value", func() { 236 var routesResult route_helpers.Routes 237 238 JustBeforeEach(func() { 239 routesResult = route_helpers.RoutesFromRoutingInfo(routingInfo) 240 }) 241 242 Context("when lattice app routes are present in the routing info", func() { 243 BeforeEach(func() { 244 routingInfo = routes.RoutingInfo() 245 }) 246 247 It("returns the routes", func() { 248 Expect(routesResult).To(Equal(routes)) 249 }) 250 }) 251 252 Context("when the result should be nil", func() { 253 itReturnsEmptyRoutes := func() { 254 It("returns nil routes", func() { 255 Expect(routesResult).To(BeZero()) 256 }) 257 } 258 259 Context("when the both http and tcp routes are nil", func() { 260 BeforeEach(func() { 261 routingInfo = receptor.RoutingInfo{ 262 route_helpers.AppRouter: nil, 263 route_helpers.TcpRouter: nil, 264 } 265 }) 266 267 itReturnsEmptyRoutes() 268 }) 269 270 Context("when lattice app and tcp routes are not present in the routing info", func() { 271 BeforeEach(func() { 272 routingInfo = receptor.RoutingInfo{} 273 }) 274 275 itReturnsEmptyRoutes() 276 }) 277 278 Context("when the routing info is nil", func() { 279 BeforeEach(func() { 280 routingInfo = nil 281 }) 282 283 itReturnsEmptyRoutes() 284 }) 285 286 Context("when the http routes are nil", func() { 287 var onlyTcpRoutes route_helpers.Routes 288 BeforeEach(func() { 289 onlyTcpRoutes = route_helpers.Routes{ 290 TcpRoutes: route_helpers.TcpRoutes{tcpRoute1}, 291 } 292 routingInfo = onlyTcpRoutes.RoutingInfo() 293 }) 294 295 It("returns only tcp routes", func() { 296 Expect(routesResult).To(Equal(onlyTcpRoutes)) 297 }) 298 }) 299 300 Context("when the tcp routes are nil", func() { 301 var onlyHttpRoutes route_helpers.Routes 302 BeforeEach(func() { 303 onlyHttpRoutes = route_helpers.Routes{ 304 AppRoutes: route_helpers.AppRoutes{appRoute1}, 305 } 306 routingInfo = onlyHttpRoutes.RoutingInfo() 307 }) 308 309 It("returns only http routes", func() { 310 Expect(routesResult).To(Equal(onlyHttpRoutes)) 311 }) 312 }) 313 }) 314 }) 315 316 Context("when the json.RawMessage is malformed", func() { 317 BeforeEach(func() { 318 routingInfo = receptor.RoutingInfo{} 319 jsonMessage := json.RawMessage(`{"what": "up`) 320 routingInfo[route_helpers.TcpRouter] = &jsonMessage 321 }) 322 323 It("panics", func() { 324 routesFromRoutingInfo := func() func() { 325 return func() { route_helpers.RoutesFromRoutingInfo(routingInfo) } 326 } 327 Consistently(routesFromRoutingInfo).Should(Panic(), "invalid json.RawMessage ought to panic") 328 }) 329 }) 330 }) 331 }) 332 333 Describe("GetPrimaryPort", func() { 334 Context("when there is no monitor port, but exposedPorts are empty", func() { 335 It("return 0", func() { 336 returnPort := route_helpers.GetPrimaryPort(uint16(0), []uint16{}) 337 Expect(returnPort).To(BeZero()) 338 }) 339 }) 340 341 Context("when there is monitor port, and exposedPorts are not empty", func() { 342 It("return the first exposed port", func() { 343 returnPort := route_helpers.GetPrimaryPort(uint16(0), []uint16{2000, 3000}) 344 Expect(returnPort).To(Equal(uint16(2000))) 345 }) 346 }) 347 348 Context("when there is monitor port", func() { 349 It("return the monitor port", func() { 350 returnPort := route_helpers.GetPrimaryPort(uint16(1000), []uint16{2000, 3000}) 351 Expect(returnPort).To(Equal(uint16(1000))) 352 }) 353 }) 354 355 Context("when there is monitor port, and the exposedPorts is empty", func() { 356 It("return the monitor port", func() { 357 returnPort := route_helpers.GetPrimaryPort(uint16(1000), []uint16{}) 358 Expect(returnPort).To(Equal(uint16(1000))) 359 }) 360 }) 361 }) 362 363 Describe("BuildDefaultRoutingInfo", func() { 364 Context("when no exposedPorts is given", func() { 365 It("output empty approutes", func() { 366 appRoutes := route_helpers.BuildDefaultRoutingInfo("cool-app", []uint16{}, 5000, "cool-app-domain") 367 Expect(appRoutes).To(BeEmpty()) 368 }) 369 }) 370 371 Context("when primaryPort is not included in the exposedPorts", func() { 372 It("doesn't output the default route", func() { 373 expectedAppRoutes := route_helpers.AppRoutes{ 374 {Hostnames: []string{"cool-app-2000.cool-app-domain"}, Port: 2000}, 375 } 376 appRoutes := route_helpers.BuildDefaultRoutingInfo("cool-app", []uint16{2000}, 5000, "cool-app-domain") 377 Expect(appRoutes).To(Equal(expectedAppRoutes)) 378 }) 379 }) 380 381 Context("when primaryPort is included in the exposedPorts", func() { 382 It("outputs a default route with primary port in addition to the default route", func() { 383 expectedAppRoutes := route_helpers.AppRoutes{ 384 {Hostnames: []string{"cool-app-2000.cool-app-domain"}, Port: 2000}, 385 {Hostnames: []string{"cool-app.cool-app-domain", "cool-app-5000.cool-app-domain"}, Port: 5000}, 386 } 387 appRoutes := route_helpers.BuildDefaultRoutingInfo("cool-app", []uint16{5000, 2000}, 5000, "cool-app-domain") 388 Expect(appRoutes).Should(ContainExactly(expectedAppRoutes)) 389 }) 390 }) 391 }) 392 })