Example #1
0
					Ω(app).Should(BeZero())
				})
			})

			Context("when the app is not found", func() {
				It("should return the app not found error", func() {
					app, err := store.GetApp("Marzipan", "Armadillo")
					Ω(err).Should(Equal(AppNotFoundError))
					Ω(app).Should(BeZero())
				})
			})

			Context("when the app directory is empty", func() {
				It("should return the app not found error", func() {
					storeAdapter.SetMulti([]storeadapter.StoreNode{{
						Key:   "/hm/v1/apps/actual/foo-bar/baz",
						Value: []byte("foo"),
					}})

					storeAdapter.Delete("/hm/v1/apps/actual/foo-bar/baz")

					app, err := store.GetApp("foo", "bar")
					Ω(err).Should(Equal(AppNotFoundError))
					Ω(app).Should(BeZero())
				})
			})

		})
	})
})
						})
					})
				})

				Context("when services exists", func() {
					JustBeforeEach(func() {
						err := storeAdapter.Create(node)
						Expect(err).NotTo(HaveOccurred())

						finder.Start()
						Eventually(finder.AllServers).ShouldNot(HaveLen(0))
						Expect(finder.PreferredServers()).NotTo(HaveLen(0))
					})

					It("removes the service", func() {
						err := storeAdapter.Delete(node.Key)
						Expect(err).NotTo(HaveOccurred())
						Eventually(finder.AllServers).Should(BeEmpty())
						Expect(getCallbackCount()).To(Equal(2))
						Expect(finder.PreferredServers()).To(BeEmpty())
						Expect(getPreferredCount()).To(Equal(1))
					})

					It("only finds nodes for the doppler server type", func() {
						router := storeadapter.StoreNode{
							Key:   "/healthstatus/router/z1/router_z1",
							Value: []byte("10.99.99.99"),
						}
						storeAdapter.Create(router)

						Consistently(finder.AllServers).Should(Equal(expectedAddress))
Example #3
0
		})
	})

	Describe("Recursively deleting empty directories", func() {
		BeforeEach(func() {
			storeAdapter.SetMulti([]storeadapter.StoreNode{
				{Key: "/hm/v17/pokemon/geodude", Value: []byte("foo")},
				{Key: "/hm/v17/deep-pokemon/abra/kadabra/alakazam", Value: []byte{}},
				{Key: "/hm/v17/pokemonCount", Value: []byte("151")},
			})
		})

		Context("when the node is a directory", func() {
			Context("and it is empty", func() {
				BeforeEach(func() {
					storeAdapter.Delete("/hm/v17/pokemon/geodude")
				})

				It("shreds it mercilessly", func() {
					err := store.Compact()
					Ω(err).ShouldNot(HaveOccurred())

					_, err = storeAdapter.Get("/hm/v17/pokemon")
					Ω(err).Should(Equal(storeadapter.ErrorKeyNotFound))
				})
			})

			Context("and it is non-empty", func() {
				It("spares it", func() {
					err := store.Compact()
					Ω(err).ShouldNot(HaveOccurred())
				})
			})
		})

		Context("When an existing service is updated", func() {
			It("should not notify the channel again", func() {
				adapter.SetMulti([]storeadapter.StoreNode{buildNode(app2Service1)})
				assertNoDataOnChannel(outAddChan)
				assertNoDataOnChannel(outRemoveChan)
			})
		})

		Context("when a service or app should be removed", func() {
			Context("when an existing app loses one of its services", func() {
				It("sends that service on the output remove channel", func(done Done) {
					adapter.Delete(path.Join("/loggregator/services", app1Service2.AppId, app1Service2.Id()))

					Expect(<-outRemoveChan).To(Equal(app1Service2))
					assertNoDataOnChannel(outAddChan)

					close(done)
				})
			})

			Context("when an existing app loses all of its services", func() {
				It("sends all of the app services on the outgoing remove channel", func(done Done) {
					adapter.Delete(path.Join("/loggregator/services", app1Service2.AppId))

					appServices := drainOutgoingChannel(outRemoveChan, 2)

					Expect(appServices).To(ContainElement(app1Service1))
				})
			})
		})

		Context("When an existing service is updated", func() {
			It("should not notify the channel again", func() {
				adapter.SetMulti([]storeadapter.StoreNode{buildNode(app2Service1)})
				Expect(outAddChan).To(BeEmpty())
				Expect(outRemoveChan).To(BeEmpty())
			})
		})

		Context("when a service or app should be removed", func() {
			Context("when an existing app loses one of its services", func() {
				It("sends that service on the output remove channel", func() {
					err := adapter.Delete(key(app1Service2))
					Expect(err).NotTo(HaveOccurred())

					var appService appservice.AppService
					Eventually(outRemoveChan).Should(Receive(&appService))
					Expect(appService).To(Equal(app1Service2))

					Expect(outAddChan).To(BeEmpty())
				})
			})

			Context("when an existing app loses all of its services", func() {
				It("sends all of the app services on the outgoing remove channel", func() {
					adapter.Get(path.Join("/loggregator/services", APP1_ID))
					adapter.Delete(path.Join("/loggregator/services", APP1_ID))
					appServices := drainOutgoingChannel(outRemoveChan, 2)
Example #6
0
						dea.GetApp(0).InstanceAtIndex(1).Heartbeat(),
					))
				}()

				err1 := <-done
				err2 := <-done
				Ω(err1).ShouldNot(HaveOccurred())
				Ω(err2).ShouldNot(HaveOccurred())
			})
		})

		Context("when something goes wrong and the in-memory cache no longer matches the store", func() {
			It("should eventually recover", func() {
				//Delete one of the heartbeats
				corruptedHeartbeat := dea.GetApp(0).InstanceAtIndex(1).Heartbeat()
				storeAdapter.Delete("/hm/v1/apps/actual/" + store.AppKey(corruptedHeartbeat.AppGuid, corruptedHeartbeat.AppVersion) + "/" + corruptedHeartbeat.InstanceGuid)

				//See that it's gone
				results, err := store.GetInstanceHeartbeats()
				Ω(err).ShouldNot(HaveOccurred())
				Ω(results).Should(HaveLen(1))

				//Try to put it back
				store.SyncHeartbeats(dea.HeartbeatWith(
					dea.GetApp(0).InstanceAtIndex(1).Heartbeat(),
					dea.GetApp(1).InstanceAtIndex(3).Heartbeat(),
				))

				//See that we didn't... because it's still in the cache...
				results, err = store.GetInstanceHeartbeats()
				Ω(err).ShouldNot(HaveOccurred())