cliRunner.StopEvacuator() }) It("should immediately start the app", func() { simulator.Tick(1) Ω(startStopListener.Starts).Should(HaveLen(1)) Ω(startStopListener.Starts[0].AppGuid).Should(Equal(app.AppGuid)) Ω(startStopListener.Starts[0].AppVersion).Should(Equal(app.AppVersion)) Ω(startStopListener.Starts[0].InstanceIndex).Should(Equal(0)) }) }) }) Describe("Deterministic evacuation", func() { Context("when an app enters the evacuation state", func() { var evacuatingHeartbeat models.InstanceHeartbeat BeforeEach(func() { Ω(startStopListener.Starts).Should(BeEmpty()) Ω(startStopListener.Stops).Should(BeEmpty()) evacuatingHeartbeat = app.InstanceAtIndex(0).Heartbeat() evacuatingHeartbeat.State = models.InstanceStateEvacuating simulator.SetCurrentHeartbeats(dea.HeartbeatWith(evacuatingHeartbeat)) simulator.Tick(1) }) It("should immediately start the app", func() { Ω(startStopListener.Starts).Should(HaveLen(1)) Ω(startStopListener.Starts[0].AppGuid).Should(Equal(app.AppGuid)) Ω(startStopListener.Starts[0].AppVersion).Should(Equal(app.AppVersion))
expectedMessage := models.NewPendingStopMessage(clock.Now(), 0, conf.GracePeriod(), app.AppGuid, app.AppVersion, app.InstanceAtIndex(3).InstanceGuid, models.PendingStopMessageReasonExtra) Ω(stopMessages()).Should(ContainElement(EqualPendingStopMessage(expectedMessage))) expectedMessage = models.NewPendingStopMessage(clock.Now(), 0, conf.GracePeriod(), app.AppGuid, app.AppVersion, duplicateExtraInstance1.InstanceGuid, models.PendingStopMessageReasonExtra) Ω(stopMessages()).Should(ContainElement(EqualPendingStopMessage(expectedMessage))) expectedMessage = models.NewPendingStopMessage(clock.Now(), 0, conf.GracePeriod(), app.AppGuid, app.AppVersion, duplicateExtraInstance2.InstanceGuid, models.PendingStopMessageReasonExtra) Ω(stopMessages()).Should(ContainElement(EqualPendingStopMessage(expectedMessage))) }) }) }) Describe("Handling evacuating instances", func() { var heartbeat models.Heartbeat var evacuatingHeartbeat models.InstanceHeartbeat BeforeEach(func() { evacuatingHeartbeat = app.InstanceAtIndex(1).Heartbeat() evacuatingHeartbeat.State = models.InstanceStateEvacuating heartbeat = dea.HeartbeatWith( app.InstanceAtIndex(0).Heartbeat(), evacuatingHeartbeat, ) store.SyncHeartbeats(heartbeat) }) Context("when the app is no longer desired", func() { It("should send an immediate stop", func() { err := analyzer.Analyze() Ω(err).ShouldNot(HaveOccurred())
func (store *RealStore) storeNodeForInstanceHeartbeat(instanceHeartbeat models.InstanceHeartbeat) storeadapter.StoreNode { return storeadapter.StoreNode{ Key: store.instanceHeartbeatStoreKey(instanceHeartbeat.AppGuid, instanceHeartbeat.AppVersion, instanceHeartbeat.InstanceGuid), Value: instanceHeartbeat.ToCSV(), } }
import ( . "github.com/cloudfoundry/hm9000/store" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/cloudfoundry/hm9000/config" "github.com/cloudfoundry/hm9000/models" "github.com/cloudfoundry/hm9000/storeadapter" "github.com/cloudfoundry/hm9000/testhelpers/app" ) var _ = Describe("Actual State", func() { var ( store Store etcdAdapter storeadapter.StoreAdapter conf config.Config heartbeat1 models.InstanceHeartbeat heartbeat2 models.InstanceHeartbeat heartbeat3 models.InstanceHeartbeat ) BeforeEach(func() { var err error conf, err = config.DefaultConfig() Ω(err).ShouldNot(HaveOccured()) etcdAdapter = storeadapter.NewETCDStoreAdapter(etcdRunner.NodeURLS(), conf.StoreMaxConcurrentRequests) err = etcdAdapter.Connect() Ω(err).ShouldNot(HaveOccured()) a := app.NewApp() heartbeat1 = a.GetInstance(0).Heartbeat(17) heartbeat2 = a.GetInstance(1).Heartbeat(12)
store.SyncHeartbeats(dea.HeartbeatWith( dea.GetApp(0).InstanceAtIndex(1).Heartbeat(), dea.GetApp(1).InstanceAtIndex(3).Heartbeat(), )) }) It("should save the instance heartbeats for the passed-in heartbeat", func() { results, err := store.GetInstanceHeartbeats() Ω(err).ShouldNot(HaveOccurred()) Ω(results).Should(HaveLen(2)) Ω(results).Should(ContainElement(dea.GetApp(0).InstanceAtIndex(1).Heartbeat())) Ω(results).Should(ContainElement(dea.GetApp(1).InstanceAtIndex(3).Heartbeat())) }) Context("when there are already instance heartbeats stored for the DEA in question", func() { var modifiedHeartbeat models.InstanceHeartbeat BeforeEach(func() { modifiedHeartbeat = dea.GetApp(1).InstanceAtIndex(3).Heartbeat() modifiedHeartbeat.State = models.InstanceStateEvacuating store.SyncHeartbeats(dea.HeartbeatWith( modifiedHeartbeat, dea.GetApp(2).InstanceAtIndex(2).Heartbeat(), )) }) It("should sync the heartbeats (add new ones, adjust ones that have changed state, and delete old ones)", func() { results, err := store.GetInstanceHeartbeats() Ω(err).ShouldNot(HaveOccurred()) Ω(results).Should(HaveLen(2)) Ω(results).Should(ContainElement(modifiedHeartbeat)) Ω(results).Should(ContainElement(dea.GetApp(2).InstanceAtIndex(2).Heartbeat()))