Describe("Swap", func() { Context("when a new routing key arrives", func() { Context("when the routing key has both routes and endpoints", func() { BeforeEach(func() { tempTable := routing_table.NewTempTable( routing_table.RoutesByRoutingKey{key: routing_table.Routes{Hostnames: []string{hostname1, hostname2}, LogGuid: logGuid}}, routing_table.EndpointsByRoutingKey{key: {endpoint1, endpoint2}}, ) messagesToEmit = table.Swap(tempTable) }) It("emits registrations for each pairing", func() { expected := routing_table.MessagesToEmit{ RegistrationMessages: []routing_table.RegistryMessage{ routing_table.RegistryMessageFor(endpoint1, routing_table.Routes{Hostnames: []string{hostname1, hostname2}, LogGuid: logGuid}), routing_table.RegistryMessageFor(endpoint2, routing_table.Routes{Hostnames: []string{hostname1, hostname2}, LogGuid: logGuid}), }, } Expect(messagesToEmit).To(MatchMessagesToEmit(expected)) }) }) Context("when the process only has routes", func() { BeforeEach(func() { tempTable := routing_table.NewTempTable( routing_table.RoutesByRoutingKey{key: routing_table.Routes{Hostnames: []string{hostname1}, LogGuid: logGuid}}, routing_table.EndpointsByRoutingKey{}, ) messagesToEmit = table.Swap(tempTable) })
}) It("unmarshals correctly", func() { message := routing_table.RegistryMessage{} err := json.Unmarshal([]byte(expectedJSON), &message) Expect(err).NotTo(HaveOccurred()) Expect(message).To(Equal(expectedMessage)) }) }) Describe("RegistryMessageFor", func() { It("creates a valid message from an endpoint and routes", func() { endpoint := routing_table.Endpoint{ InstanceGuid: "instance-guid", Host: "1.1.1.1", Port: 61001, ContainerPort: 11, } routes := routing_table.Routes{ Hostnames: []string{"host-1.example.com", "host-2.example.com"}, LogGuid: "app-guid", RouteServiceUrl: "https://hello.com", } message := routing_table.RegistryMessageFor(endpoint, routes) Expect(message).To(Equal(expectedMessage)) }) }) })
newEntry = &routing_table.RoutableEndpoints{ Hostnames: map[string]struct{}{hostname1: struct{}{}}, Endpoints: routing_table.EndpointsAsMap([]routing_table.Endpoint{endpoint1}), } }) JustBeforeEach(func() { messages = builder.RegistrationsFor(existingEntry, newEntry) }) Context("when no existing entry", func() { It("emits a registration", func() { expected := routing_table.MessagesToEmit{ RegistrationMessages: []routing_table.RegistryMessage{ routing_table.RegistryMessageFor(endpoint1, routing_table.Routes{Hostnames: []string{hostname1}}), }, } Expect(messages).To(MatchMessagesToEmit(expected)) }) }) Context("when new entry has no hostnames", func() { BeforeEach(func() { newEntry.Hostnames = make(map[string]struct{}) }) It("emits nothing", func() { Expect(messages).To(BeZero()) }) })
BeforeEach(func() { eventSource = new(eventfakes.FakeEventSource) bbsClient = new(fake_bbs.FakeClient) bbsClient.SubscribeToEventsReturns(eventSource, nil) table = &fake_routing_table.FakeRoutingTable{} emitter = &fake_nats_emitter.FakeNATSEmitter{} syncEvents = syncer.Events{ Sync: make(chan struct{}), Emit: make(chan struct{}), } logger = lagertest.NewTestLogger("test") dummyEndpoint := routing_table.Endpoint{InstanceGuid: expectedInstanceGuid, Host: expectedHost, Port: expectedContainerPort} dummyMessage := routing_table.RegistryMessageFor(dummyEndpoint, routing_table.Routes{Hostnames: []string{"foo.com", "bar.com"}, LogGuid: logGuid}) dummyMessagesToEmit = routing_table.MessagesToEmit{ RegistrationMessages: []routing_table.RegistryMessage{dummyMessage}, } clock = fakeclock.NewFakeClock(time.Now()) watcherProcess = watcher.NewWatcher(bbsClient, clock, table, emitter, syncEvents, logger) expectedRoutes = []string{"route-1", "route-2"} expectedCFRoute = cfroutes.CFRoute{Hostnames: expectedRoutes, Port: expectedContainerPort, RouteServiceUrl: expectedRouteServiceUrl} expectedRoutingKey = routing_table.RoutingKey{ ProcessGuid: expectedProcessGuid, ContainerPort: expectedContainerPort, }
routerStartMessages = startMessages natsClient.WhenSubscribing("router.start", func(callback nats.MsgHandler) error { go func() { for msg := range startMessages { callback(msg) } }() return nil }) //what follows is fake data to distinguish between //the "sync" and "emit" codepaths dummyEndpoint := routing_table.Endpoint{InstanceGuid: "instance-guid-1", Host: "1.1.1.1", Port: 11, ContainerPort: 1111} dummyMessage := routing_table.RegistryMessageFor(dummyEndpoint, routing_table.Routes{Hostnames: []string{"foo.com", "bar.com"}, LogGuid: logGuid}) syncMessages = routing_table.MessagesToEmit{ RegistrationMessages: []routing_table.RegistryMessage{dummyMessage}, } dummyEndpoint = routing_table.Endpoint{InstanceGuid: "instance-guid-2", Host: "2.2.2.2", Port: 22, ContainerPort: 2222} dummyMessage = routing_table.RegistryMessageFor(dummyEndpoint, routing_table.Routes{Hostnames: []string{"baz.com"}, LogGuid: logGuid}) messagesToEmit = routing_table.MessagesToEmit{ RegistrationMessages: []routing_table.RegistryMessage{dummyMessage}, } schedulingInfoResponse = &models.DesiredLRPSchedulingInfo{ DesiredLRPKey: models.NewDesiredLRPKey(processGuid, "domain", logGuid), Routes: cfroutes.CFRoutes{{Hostnames: []string{"route-1", "route-2"}, Port: containerPort}}.RoutingInfo(), }