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))
				})
Beispiel #4
0
		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)
Beispiel #5
0
	})

	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())
		})