func AddETCDNode(etcdAdapter storeadapter.StoreAdapter, key string, value string) { node := storeadapter.StoreNode{ Key: key, Value: []byte(value), TTL: uint64(20), } etcdAdapter.Create(node) recvNode, err := etcdAdapter.Get(key) Expect(err).NotTo(HaveOccurred()) Expect(string(recvNode.Value)).To(Equal(value)) }
{Key: "/hm/v18/leave/me/alone", Value: []byte("abc")}, {Key: "/hm/delete/me", Value: []byte("abc")}, {Key: "/hm/v1ola/delete/me", Value: []byte("abc")}, {Key: "/hm/delete/me/too", Value: []byte("abc")}, {Key: "/hm/locks/keep", Value: []byte("abc")}, {Key: "/other/keep", Value: []byte("abc")}, {Key: "/foo", Value: []byte("abc")}, {Key: "/v3/keep", Value: []byte("abc")}, }) err := store.Compact() Ω(err).ShouldNot(HaveOccurred()) }) It("should delete everything under older versions", func() { _, err := storeAdapter.Get("/hm/v3/delete/me") Ω(err).Should(Equal(storeadapter.ErrorKeyNotFound)) _, err = storeAdapter.Get("/hm/v16/delete/me") Ω(err).Should(Equal(storeadapter.ErrorKeyNotFound)) }) It("should leave the current version alone", func() { _, err := storeAdapter.Get("/hm/v17/leave/me/alone") Ω(err).ShouldNot(HaveOccurred()) _, err = storeAdapter.Get("/hm/v17/leave/me/v1/alone") Ω(err).ShouldNot(HaveOccurred()) }) It("should leave newer versions alone", func() {
BeforeEach(func() { storeAdapter = etcdstoreadapter.NewETCDStoreAdapter(etcdRunner.NodeURLS(), workerpool.NewWorkerPool(conf.StoreMaxConcurrentRequests)) err := storeAdapter.Connect() Ω(err).ShouldNot(HaveOccurred()) store = NewStore(conf, storeAdapter, fakelogger.NewFakeLogger()) }) Describe("Getting and setting a metric", func() { BeforeEach(func() { err := store.SaveMetric("sprockets", 17) Ω(err).ShouldNot(HaveOccurred()) }) It("should store the metric under /metrics", func() { _, err := storeAdapter.Get("/hm/v1/metrics/sprockets") Ω(err).ShouldNot(HaveOccurred()) }) Context("when the metric is present", func() { It("should return the stored value and no error", func() { value, err := store.GetMetric("sprockets") Ω(err).ShouldNot(HaveOccurred()) Ω(value).Should(BeNumerically("==", 17)) }) Context("and it is overwritten", func() { BeforeEach(func() { err := store.SaveMetric("sprockets", 23.5) Ω(err).ShouldNot(HaveOccurred()) })
var _ = BeforeEach(func() { const ( BLUE = 34 PURPLE = 35 LIGHT_BLUE = 36 ) dopplerSession = startComponent(dopplerExecutablePath, "doppler", PURPLE, "--config=fixtures/doppler.json") var err error LocalIPAddress, err = localip.LocalIP() Expect(err).ToNot(HaveOccurred()) // Wait for doppler to startup Eventually(func() error { _, err := etcdAdapter.Get("healthstatus/doppler/z1/doppler_z1/0") return err }, 11).Should(BeNil()) metronSession = startComponent(metronExecutablePath, "metron", BLUE, "--config=fixtures/metron.json") tcSession = startComponent(trafficControllerExecutablePath, "tc", LIGHT_BLUE, "--config=fixtures/trafficcontroller.json", "--disableAccessControl") // Wait for traffic controller to startup waitOnURL("http://" + LocalIPAddress + ":49630") // Metron will report that it is up when it really isn't (at least according to the /varz endpoint) time.Sleep(200 * time.Millisecond) }) func buildComponent(componentName string) (pathToComponent string) {
dopplerservice.Announce(localIP, time.Second, &conf, fakeadapter, loggertesthelper.Logger()) }).To(Panic()) }) Context("when tls transport is enabled", func() { It("announces udp, tcp, and tls values", func() { dopplerMeta := fmt.Sprintf(`{"version": 1, "endpoints":["udp://%[1]s:1234", "tcp://%[1]s:5678", "ws://%[1]s:8888", "tls://%[1]s:9012"]}`, localIP) conf.EnableTLSTransport = true conf.TLSListenerConfig = config.TLSListenerConfig{ Port: 9012, } stopChan = dopplerservice.Announce(localIP, time.Second, &conf, etcdAdapter, loggertesthelper.Logger()) Eventually(func() []byte { node, err := etcdAdapter.Get(dopplerKey) if err != nil { return nil } return node.Value }).Should(MatchJSON(dopplerMeta)) }) }) Context("when tls transport is disabled", func() { It("announces only udp and tcp values", func() { dopplerMeta := fmt.Sprintf(`{"version": 1, "endpoints":["udp://%[1]s:1234", "tcp://%[1]s:5678", "ws://%[1]s:8888" ]}`, localIP) conf.EnableTLSTransport = false stopChan = dopplerservice.Announce(localIP, time.Second, &conf, etcdAdapter, loggertesthelper.Logger())
Ω(err).ShouldNot(HaveOccurred()) store = NewStore(conf, storeAdapter, fakelogger.NewFakeLogger()) }) Describe("Bumping freshness", func() { bumpingFreshness := func(key string, ttl uint64, bump func(store Store, timestamp time.Time) error) { var timestamp time.Time BeforeEach(func() { timestamp = time.Now() }) Context("when the key is missing", func() { BeforeEach(func() { _, err := storeAdapter.Get(key) Ω(err).Should(Equal(storeadapter.ErrorKeyNotFound)) err = bump(store, timestamp) Ω(err).ShouldNot(HaveOccurred()) }) It("should create the key with the current timestamp and a TTL", func() { value, err := storeAdapter.Get(key) Ω(err).ShouldNot(HaveOccurred()) var freshnessTimestamp models.FreshnessTimestamp json.Unmarshal(value.Value, &freshnessTimestamp) Ω(freshnessTimestamp.Timestamp).Should(Equal(timestamp.Unix()))
"loggregator/domain" ) var _ = Describe("AppServiceStore", func() { var store *AppServiceStore var adapter storeadapter.StoreAdapter var incomingChan chan domain.AppServices var app1Service1 domain.AppService var app1Service2 domain.AppService var app2Service1 domain.AppService assertInStore := func(appServices ...domain.AppService) { for _, appService := range appServices { Eventually(func() error { _, err := adapter.Get(path.Join("/loggregator/services/", appService.AppId, appService.Id())) return err }).ShouldNot(HaveOccurred()) } } assertNotInStore := func(appServices ...domain.AppService) { for _, appService := range appServices { Eventually(func() error { _, err := adapter.Get(path.Join("/loggregator/services/", appService.AppId, appService.Id())) return err }).Should(Equal(storeadapter.ErrorKeyNotFound)) } } assertAppNotInStore := func(appIds ...string) {
drainOutgoingChannel(outAddChan, 3) }) It("does not send updates when the data has already been processed", func() { adapter.Create(buildNode(app1Service1)) adapter.Create(buildNode(app1Service2)) Expect(outAddChan).To(BeEmpty()) Expect(outRemoveChan).To(BeEmpty()) }) Context("when there is new data in the store", func() { Context("when an existing app has a new service through a create operation", func() { It("adds that service to the outgoing add channel", func() { app2Service2 := appservice.AppService{AppId: APP2_ID, Url: "syslog://new.example.com:12345"} _, err := adapter.Get(key(app2Service2)) Expect(err).To(Equal(storeadapter.ErrorKeyNotFound)) adapter.Create(buildNode(app2Service2)) var appService appservice.AppService Eventually(outAddChan).Should(Receive(&appService)) Expect(appService).To(Equal(app2Service2)) Expect(outRemoveChan).To(BeEmpty()) }) }) Context("When an existing app gets a new service through an update operation", func() { It("adds that service to the outgoing add channel", func() { app2Service2 := appservice.AppService{AppId: APP2_ID, Url: "syslog://new.example.com:12345"}
Ω(results).Should(HaveLen(3)) Ω(results).Should(ContainElement(otherDea.GetApp(0).InstanceAtIndex(1).Heartbeat())) Ω(results).Should(ContainElement(otherDea.GetApp(1).InstanceAtIndex(0).Heartbeat())) Ω(results).Should(ContainElement(heartbeatOnOtherDea)) //we fetch twice to ensure that nothing is incorrectly deleted results, err = store.GetInstanceHeartbeats() Ω(err).ShouldNot(HaveOccurred()) Ω(results).Should(HaveLen(3)) Ω(results).Should(ContainElement(otherDea.GetApp(0).InstanceAtIndex(1).Heartbeat())) Ω(results).Should(ContainElement(otherDea.GetApp(1).InstanceAtIndex(0).Heartbeat())) Ω(results).Should(ContainElement(heartbeatOnOtherDea)) }) It("should remove expired instance heartbeats from the store", func() { _, err := storeAdapter.Get("/hm/v1/apps/actual/" + store.AppKey(dea.GetApp(0).AppGuid, dea.GetApp(0).AppVersion) + "/" + dea.GetApp(0).InstanceAtIndex(1).Heartbeat().StoreKey()) Ω(err).ShouldNot(HaveOccurred()) _, err = storeAdapter.Get("/hm/v1/apps/actual/" + store.AppKey(dea.GetApp(1).AppGuid, dea.GetApp(1).AppVersion) + "/" + dea.GetApp(1).InstanceAtIndex(3).Heartbeat().StoreKey()) Ω(err).ShouldNot(HaveOccurred()) _, err = store.GetInstanceHeartbeats() Ω(err).ShouldNot(HaveOccurred()) _, err = storeAdapter.Get("/hm/v1/apps/actual/" + store.AppKey(dea.GetApp(0).AppGuid, dea.GetApp(0).AppVersion) + "/" + dea.GetApp(0).InstanceAtIndex(1).Heartbeat().StoreKey()) Ω(err).Should(Equal(storeadapter.ErrorKeyNotFound)) _, err = storeAdapter.Get("/hm/v1/apps/actual/" + store.AppKey(dea.GetApp(1).AppGuid, dea.GetApp(1).AppVersion) + "/" + dea.GetApp(1).InstanceAtIndex(3).Heartbeat().StoreKey()) Ω(err).Should(Equal(storeadapter.ErrorKeyNotFound)) }) Context("if it fails to remove them", func() { It("should soldier on", func() {
Eventually(metronSession.Buffer).Should(gbytes.Say("metron started")) dopplerSession = startComponent( dopplerExecutablePath, "doppler", PURPLE, "--config=fixtures/"+dopplerConfig+".json", ) var err error LocalIPAddress, err = localip.LocalIP() Expect(err).ToNot(HaveOccurred()) // wait for doppler to register key := fmt.Sprintf("%s/z1/doppler_z1/0", dopplerservice.LEGACY_ROOT) Eventually(func() bool { _, err := etcdAdapter.Get(key) return err == nil }, 5).Should(BeTrue()) key = fmt.Sprintf("%s/z1/doppler_z1/0", dopplerservice.META_ROOT) Eventually(func() bool { _, err := etcdAdapter.Get(key) return err == nil }, 1).Should(BeTrue()) tcSession = startComponent( trafficControllerExecutablePath, "tc", LIGHT_BLUE, "--config=fixtures/trafficcontroller.json", "--disableAccessControl",
}) AfterEach(func() { storeAdapter.Disconnect() }) Describe("Saving crash state", func() { BeforeEach(func() { err := store.SaveCrashCounts(crashCount1, crashCount2) Ω(err).ShouldNot(HaveOccurred()) }) It("stores the passed in crash state", func() { expectedTTL := uint64(conf.MaximumBackoffDelay().Seconds()) * 2 node, err := storeAdapter.Get("/hm/v1/apps/crashes/" + crashCount1.AppGuid + "," + crashCount1.AppVersion + "/1") Ω(err).ShouldNot(HaveOccurred()) Ω(node).Should(Equal(storeadapter.StoreNode{ Key: "/hm/v1/apps/crashes/" + crashCount1.AppGuid + "," + crashCount1.AppVersion + "/1", Value: crashCount1.ToJSON(), TTL: expectedTTL, })) node, err = storeAdapter.Get("/hm/v1/apps/crashes/" + crashCount2.AppGuid + "," + crashCount2.AppVersion + "/4") Ω(err).ShouldNot(HaveOccurred()) Ω(node).Should(Equal(storeadapter.StoreNode{ Key: "/hm/v1/apps/crashes/" + crashCount2.AppGuid + "," + crashCount2.AppVersion + "/4", Value: crashCount2.ToJSON(), TTL: expectedTTL, })) })