func (s *Simulator) buildDEA() string { guid := models.Guid() s.DEAs[guid] = make([]*appfixture.AppFixture, 0) s.DEAHeartbeatSchedule[guid] = s.randomizer.Intn(s.HeartbeatIntervalInSeconds) s.DEAAdvertiseSchedule[guid] = s.randomizer.Intn(s.AdvertiseIntervalInSeconds) return guid }
var err error store, err = storecassandra.New([]string{"127.0.0.1:9042"}, gocql.One, conf, timeprovider.NewTimeProvider()) Ω(err).ShouldNot(HaveOccured()) justOnce = true } }) for _, numApps := range numberOfApps { numApps := numApps iteration := 1 Context(fmt.Sprintf("With %d apps", numApps), func() { Measure("Read/Write/Delete Performance", func(b Benchmarker) { fmt.Printf("%d apps iteration %d\n", numApps, iteration) iteration += 1 heartbeat := models.Heartbeat{ DeaGuid: models.Guid(), InstanceHeartbeats: []models.InstanceHeartbeat{}, } n := 0 for i := 0; i < numApps; i++ { app := appfixture.NewAppFixture() for j := 0; j < numberOfInstancesPerApp; j++ { heartbeat.InstanceHeartbeats = append(heartbeat.InstanceHeartbeats, app.InstanceAtIndex(j).Heartbeat()) n += 1 } } b.Time("WRITE", func() { err := store.SyncHeartbeats(heartbeat) Ω(err).ShouldNot(HaveOccured()) }, StorePerformanceReport{
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)) Ω(startStopListener.Starts[0].InstanceIndex).Should(Equal(0)) Ω(startStopListener.Stops).Should(BeEmpty()) }) Context("when the app starts", func() { BeforeEach(func() { startStopListener.Reset() runningHeartbeat := app.InstanceAtIndex(0).Heartbeat() runningHeartbeat.InstanceGuid = models.Guid() simulator.SetCurrentHeartbeats(dea.HeartbeatWith(evacuatingHeartbeat)) simulator.SetCurrentHeartbeats(models.Heartbeat{ DeaGuid: "new-dea", InstanceHeartbeats: []models.InstanceHeartbeat{runningHeartbeat}, }) simulator.Tick(1) }) It("should stop the evacuated instance", func() { Ω(startStopListener.Starts).Should(BeEmpty()) Ω(startStopListener.Stops).Should(HaveLen(1)) Ω(startStopListener.Stops[0].AppGuid).Should(Equal(app.AppGuid)) Ω(startStopListener.Stops[0].AppVersion).Should(Equal(app.AppVersion)) Ω(startStopListener.Stops[0].InstanceGuid).Should(Equal(evacuatingHeartbeat.InstanceGuid)) })
simulator.SetDesiredState(a.DesiredState(2)) simulator.SetCurrentHeartbeats(a.Heartbeat(1)) var err error ip, err = localip.LocalIP() Ω(err).ShouldNot(HaveOccurred()) }) AfterEach(func() { cliRunner.StopMetricsServer() }) It("should register with the collector", func(done Done) { cliRunner.StartMetricsServer(simulator.currentTimestamp) guid := models.Guid() coordinator.MessageBus.Subscribe(guid, func(message *nats.Msg) { Ω(string(message.Data)).Should(ContainSubstring("%s:%d", ip, coordinator.MetricsServerPort)) Ω(string(message.Data)).Should(ContainSubstring(`"bob","password"`)) close(done) }) coordinator.MessageBus.PublishRequest("vcap.component.discover", guid, []byte("")) }) Context("when there is a desired app that failed to stage", func() { BeforeEach(func() { desiredState := a.DesiredState(2) desiredState.PackageState = models.AppPackageStateFailed simulator.SetDesiredState(desiredState)
}) Describe("Stopping duplicate instances (index < numDesired)", func() { var ( duplicateInstance1 appfixture.Instance duplicateInstance2 appfixture.Instance duplicateInstance3 appfixture.Instance ) BeforeEach(func() { store.SyncDesiredState( app.DesiredState(3), ) duplicateInstance1 = app.InstanceAtIndex(2) duplicateInstance1.InstanceGuid = models.Guid() duplicateInstance2 = app.InstanceAtIndex(2) duplicateInstance2.InstanceGuid = models.Guid() duplicateInstance3 = app.InstanceAtIndex(2) duplicateInstance3.InstanceGuid = models.Guid() }) Context("When there are missing instances on other indices", func() { It("should not schedule any stops but should start the missing indices", func() { //[-,-,2|2|2|2] store.SyncHeartbeats(dea.HeartbeatWith( app.InstanceAtIndex(2).Heartbeat(), duplicateInstance1.Heartbeat(), duplicateInstance2.Heartbeat(), duplicateInstance3.Heartbeat(), ))
"github.com/cloudfoundry/yagnats/fakeyagnats" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "time" ) var _ = Describe("Apiserver", func() { var store storepackage.Store var storeAdapter *fakestoreadapter.FakeStoreAdapter var timeProvider *faketimeprovider.FakeTimeProvider var messageBus *fakeyagnats.FakeYagnats conf, _ := config.DefaultConfig() makeRequest := func(request string) (response string) { replyToGuid := models.Guid() messageBus.Subscriptions["app.state"][0].Callback(&yagnats.Message{ Payload: []byte(request), ReplyTo: replyToGuid, }) Ω(messageBus.PublishedMessages[replyToGuid]).Should(HaveLen(1)) return string(messageBus.PublishedMessages[replyToGuid][0].Payload) } BeforeEach(func() { messageBus = fakeyagnats.New() storeAdapter = fakestoreadapter.New() store = storepackage.NewStore(conf, storeAdapter, fakelogger.NewFakeLogger()) timeProvider = &faketimeprovider.FakeTimeProvider{ TimeToProvide: time.Unix(100, 0),
simulator.SetDesiredState(a.DesiredState(2)) simulator.SetCurrentHeartbeats(a.Heartbeat(1)) }) AfterEach(func() { cliRunner.StopAPIServer() }) Context("when the store is fresh", func() { BeforeEach(func() { simulator.Tick(simulator.TicksToAttainFreshness) cliRunner.StartAPIServer(simulator.currentTimestamp) }) It("should return the app", func(done Done) { replyTo := models.Guid() _, err := coordinator.MessageBus.Subscribe(replyTo, func(message *yagnats.Message) { defer GinkgoRecover() Ω(string(message.Payload)).Should(ContainSubstring(`"droplet":"%s"`, a.AppGuid)) Ω(string(message.Payload)).Should(ContainSubstring(`"instances":2`)) Ω(string(message.Payload)).Should(ContainSubstring(`"instance":"%s"`, a.InstanceAtIndex(0).InstanceGuid)) close(done) }) Ω(err).ShouldNot(HaveOccurred()) err = coordinator.MessageBus.PublishWithReplyTo("app.state", replyTo, validRequest) Ω(err).ShouldNot(HaveOccurred()) }) })
BeforeEach(func() { store.SyncHeartbeats(dea.HeartbeatWith( app.InstanceAtIndex(0).Heartbeat(), app.InstanceAtIndex(1).Heartbeat(), )) }) Context("When index-to-stop is within the number of desired instances", func() { BeforeEach(func() { indexToStop = 0 }) Context("When there are other running instances on the index", func() { BeforeEach(func() { instance := app.InstanceAtIndex(0) instance.InstanceGuid = models.Guid() store.SyncHeartbeats(dea.HeartbeatWith( app.InstanceAtIndex(0).Heartbeat(), app.InstanceAtIndex(1).Heartbeat(), instance.Heartbeat(), )) }) assertMessageWasSent(0, true) }) Context("when there are other, crashed, instances on the index, and no running instances", func() { BeforeEach(func() { store.SyncHeartbeats(dea.HeartbeatWith( app.InstanceAtIndex(0).Heartbeat(),
func NewDeaFixture() DeaFixture { return DeaFixture{ DeaGuid: models.Guid(), apps: make(map[int]AppFixture, 0), } }
var _ = Describe("Stopping Duplicate Instances", func() { var dea appfixture.DeaFixture var a appfixture.AppFixture Context("when there are multiple instances on the same index", func() { var instance0, instance1, duplicateInstance1 appfixture.Instance var heartbeat models.Heartbeat BeforeEach(func() { dea = appfixture.NewDeaFixture() a = dea.GetApp(0) instance0 = a.InstanceAtIndex(0) instance1 = a.InstanceAtIndex(1) duplicateInstance1 = a.InstanceAtIndex(1) duplicateInstance1.InstanceGuid = models.Guid() heartbeat = dea.HeartbeatWith(instance0.Heartbeat(), instance1.Heartbeat(), duplicateInstance1.Heartbeat()) simulator.SetCurrentHeartbeats(heartbeat) simulator.SetDesiredState(a.DesiredState(2)) simulator.Tick(simulator.TicksToAttainFreshness) }) It("should not immediately stop anything", func() { Ω(startStopListener.Stops).Should(BeEmpty()) }) Context("after four grace periods", func() { Context("if both instances are still running", func() {
storeAdapter storeadapter.StoreAdapter conf *config.Config crashCount1 models.CrashCount crashCount2 models.CrashCount crashCount3 models.CrashCount ) BeforeEach(func() { var err error conf, err = config.DefaultConfig() Ω(err).ShouldNot(HaveOccurred()) storeAdapter = etcdstoreadapter.NewETCDStoreAdapter(etcdRunner.NodeURLS(), workerpool.NewWorkerPool(conf.StoreMaxConcurrentRequests)) err = storeAdapter.Connect() Ω(err).ShouldNot(HaveOccurred()) crashCount1 = models.CrashCount{AppGuid: models.Guid(), AppVersion: models.Guid(), InstanceIndex: 1, CrashCount: 17} crashCount2 = models.CrashCount{AppGuid: models.Guid(), AppVersion: models.Guid(), InstanceIndex: 4, CrashCount: 17} crashCount3 = models.CrashCount{AppGuid: models.Guid(), AppVersion: models.Guid(), InstanceIndex: 3, CrashCount: 17} store = NewStore(conf, storeAdapter, fakelogger.NewFakeLogger()) }) AfterEach(func() { storeAdapter.Disconnect() }) Describe("Saving crash state", func() { BeforeEach(func() { err := store.SaveCrashCounts(crashCount1, crashCount2) Ω(err).ShouldNot(HaveOccurred()) })