func (s *Simulator) buildNewApp() {
	app := appfixture.NewAppFixture()
	if s.randomizer.Float64() < s.FractionOfAppsThatAreCrashed {
		s.AppInstanceState[app.AppGuid] = models.InstanceStateCrashed
	} else {
		s.AppInstanceState[app.AppGuid] = models.InstanceStateRunning
	}

	winner := ""
	lowball := 1000000
	for dea, apps := range s.DEAs {
		if len(apps)+1 > s.MaxDEACapacity {
			continue
		}
		if len(apps) < lowball {
			lowball = len(apps)
			winner = dea
		}
	}

	if winner == "" {
		winner = s.buildDEA()
	}

	app.DeaGuid = winner
	s.DEAs[winner] = append(s.DEAs[winner], &app)
	s.Apps = append(s.Apps, &app)
}
	})

	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{
					NumApps: numApps,
					Subject: "write",
				})

				b.Time("READ", func() {
)

var _ = Describe("Prioritizing and sending messages in batches", func() {
	//Note: the sender is configured to only send 8 messages at a time
	//This is done by cli_runner_test.go when it generates the config
	Context("when there are start and stop messages", func() {
		var highPriorityAppGuids []string
		var lowPriorityAppGuids []string

		BeforeEach(func() {
			var desiredStates = []models.DesiredAppState{}
			var heartbeats = []models.Heartbeat{}

			lowPriorityAppGuids = make([]string, 0)
			for i := 0; i < 8; i += 1 {
				appToStart := appfixture.NewAppFixture()
				desiredState := appToStart.DesiredState(2)
				desiredStates = append(desiredStates, desiredState)
				lowPriorityAppGuids = append(lowPriorityAppGuids, appToStart.AppGuid)
				heartbeats = append(heartbeats, appToStart.Heartbeat(1))
			}

			highPriorityAppGuids = make([]string, 0)
			for i := 0; i < 9; i += 1 {
				appToStart := appfixture.NewAppFixture()
				desiredState := appToStart.DesiredState(1)
				desiredStates = append(desiredStates, desiredState)
				highPriorityAppGuids = append(highPriorityAppGuids, appToStart.AppGuid)
			}

			for i := 0; i < 40; i += 1 {
Example #4
0
	BeforeEach(func() {
		var err error
		conf, err = config.DefaultConfig()
		Expect(err).NotTo(HaveOccurred())
		wpool, err := workpool.NewWorkPool(conf.StoreMaxConcurrentRequests)
		Expect(err).NotTo(HaveOccurred())
		storeAdapter, err = etcdstoreadapter.New(
			&etcdstoreadapter.ETCDOptions{ClusterUrls: etcdRunner.NodeURLS()},
			wpool,
		)
		Expect(err).NotTo(HaveOccurred())
		err = storeAdapter.Connect()
		Expect(err).NotTo(HaveOccurred())

		app1 = appfixture.NewAppFixture()
		app2 = appfixture.NewAppFixture()
		app3 = appfixture.NewAppFixture()

		store = NewStore(conf, storeAdapter, fakelogger.NewFakeLogger())
	})

	AfterEach(func() {
		storeAdapter.Disconnect()
	})

	Describe("Syncing desired state", func() {
		BeforeEach(func() {
			err := store.SyncDesiredState(
				app1.DesiredState(1),
				app2.DesiredState(1),
Example #5
0
	)

	Describe("POST /bulk_app_state", func() {
		var b appfixture.AppFixture

		BeforeEach(func() {
			apiServerAddr = fmt.Sprintf("http://%s:%d", cliRunner.config.APIServerAddress, cliRunner.config.APIServerPort)
			requestGenerator = rata.NewRequestGenerator(apiServerAddr, apiserver.Routes)
			httpClient = &http.Client{
				Transport: &http.Transport{},
			}

			username = cliRunner.config.APIServerUsername
			password = cliRunner.config.APIServerPassword

			a = appfixture.NewAppFixture()
			b = appfixture.NewAppFixture()
			validRequest = fmt.Sprintf(`[{"droplet":"%s","version":"%s"}, {"droplet":"%s","version":"%s"}]`, a.AppGuid, a.AppVersion, b.AppGuid, b.AppVersion)

			simulator.SetDesiredState(a.DesiredState(2), b.DesiredState(3))
			simulator.SetCurrentHeartbeats(a.Heartbeat(1), b.Heartbeat(1))
		})

		AfterEach(func() {
			cliRunner.StopAPIServer()
		})

		Context("when the store is fresh", func() {
			BeforeEach(func() {
				simulator.Tick(simulator.TicksToAttainFreshness)
				cliRunner.StartAPIServer(simulator.currentTimestamp)
Example #6
0
			expectedStopMessage = models.NewPendingStopMessage(clock.Now(), 0, conf.GracePeriod(), undesiredApp.AppGuid, undesiredApp.AppVersion, undesiredApp.InstanceAtIndex(0).InstanceGuid, models.PendingStopMessageReasonExtra)
			Ω(stopMessages()).Should(ContainElement(EqualPendingStopMessage(expectedStopMessage)))
		})
	})

	Context("When the store is not fresh and/or fails to fetch data", func() {
		BeforeEach(func() {
			storeAdapter.Reset()

			desired := app.DesiredState(1)
			//this setup would, ordinarily, trigger a start and a stop
			store.SyncDesiredState(
				desired,
			)
			store.SyncHeartbeats(
				appfixture.NewAppFixture().Heartbeat(0),
			)
		})

		Context("when the desired state is not fresh", func() {
			BeforeEach(func() {
				store.BumpActualFreshness(time.Unix(10, 0))
			})

			It("should not send any start or stop messages", func() {
				err := analyzer.Analyze()
				Ω(err).Should(Equal(storepackage.DesiredIsNotFreshError))
				Ω(startMessages()).Should(BeEmpty())
				Ω(stopMessages()).Should(BeEmpty())
			})
		})
var _ = Describe("Fetching from CC and storing the result in the Store", func() {
	var (
		fetcher      *desiredstatefetcher.DesiredStateFetcher
		a1           appfixture.AppFixture
		a2           appfixture.AppFixture
		a3           appfixture.AppFixture
		store        storepackage.Store
		resultChan   chan desiredstatefetcher.DesiredStateFetcherResult
		conf         *config.Config
		storeAdapter *fakestoreadapter.FakeStoreAdapter
	)

	BeforeEach(func() {
		storeAdapter = fakestoreadapter.New()
		resultChan = make(chan desiredstatefetcher.DesiredStateFetcherResult, 1)
		a1 = appfixture.NewAppFixture()
		a2 = appfixture.NewAppFixture()
		a3 = appfixture.NewAppFixture()

		stateServer.SetDesiredState([]models.DesiredAppState{
			a1.DesiredState(1),
			a2.DesiredState(1),
			a3.DesiredState(1),
		})

		conf, _ = config.DefaultConfig()

		store = storepackage.NewStore(conf, storeAdapter, fakelogger.NewFakeLogger())

		fetcher = desiredstatefetcher.New(conf, store, fakemetricsaccountant.New(), httpclient.NewHttpClient(conf.SkipSSLVerification, conf.FetcherNetworkTimeout()), &timeprovider.RealTimeProvider{}, fakelogger.NewFakeLogger())
		fetcher.Fetch(resultChan)
		}

		Context("when a response with desired state is received", func() {
			var (
				a1                appfixture.AppFixture
				a2                appfixture.AppFixture
				stoppedApp        appfixture.AppFixture
				pendingStagingApp appfixture.AppFixture
				failedToStageApp  appfixture.AppFixture
				deletedApp        appfixture.AppFixture

				pendingStagingDesiredState models.DesiredAppState
			)

			BeforeEach(func() {
				deletedApp = appfixture.NewAppFixture()
				store.SyncDesiredState(deletedApp.DesiredState(1))

				a1 = appfixture.NewAppFixture()
				a2 = appfixture.NewAppFixture()

				stoppedApp = appfixture.NewAppFixture()
				stoppedDesiredState := stoppedApp.DesiredState(1)
				stoppedDesiredState.State = models.AppStateStopped

				pendingStagingApp = appfixture.NewAppFixture()
				pendingStagingDesiredState = pendingStagingApp.DesiredState(1)
				pendingStagingDesiredState.PackageState = models.AppPackageStatePending

				failedToStageApp = appfixture.NewAppFixture()
				failedStagingDesiredState := failedToStageApp.DesiredState(1)
			It("should drop the request on the floor", func() {
				messageBus.Subscriptions["app.state"][0].Callback(&yagnats.Message{
					Payload: []byte("{}"),
				})

				Ω(messageBus.PublishedMessages).Should(BeEmpty())
			})
		})

		Context("when the request contains the droplet and version", func() {
			var app appfixture.AppFixture
			var expectedApp AppResponse
			var validRequestPayload string

			BeforeEach(func() {
				app = appfixture.NewAppFixture()

				instanceHeartbeats := []models.InstanceHeartbeat{
					app.InstanceAtIndex(0).Heartbeat(),
					app.InstanceAtIndex(1).Heartbeat(),
					app.InstanceAtIndex(2).Heartbeat(),
				}
				crashCount := models.CrashCount{
					AppGuid:       app.AppGuid,
					AppVersion:    app.AppVersion,
					InstanceIndex: 1,
					CrashCount:    2,
				}
				expectedApp = AppResponse{
					AppGuid:            app.AppGuid,
					AppVersion:         app.AppVersion,
Example #10
0
	})

	Describe("Fetching all actual state", func() {
		Context("when there is none saved", func() {
			It("should come back empty", func() {
				results, err := store.GetInstanceHeartbeats()
				Ω(err).ShouldNot(HaveOccurred())
				Ω(results).Should(BeEmpty())
			})
		})

		Context("when there is actual state saved", func() {
			var heartbeatOnDea, heartbeatOnOtherDea models.InstanceHeartbeat

			BeforeEach(func() {
				appOnBothDeas := appfixture.NewAppFixture()

				heartbeatOnDea = appOnBothDeas.InstanceAtIndex(0).Heartbeat()
				heartbeatOnDea.DeaGuid = dea.DeaGuid

				heartbeatOnOtherDea = appOnBothDeas.InstanceAtIndex(1).Heartbeat()
				heartbeatOnOtherDea.DeaGuid = otherDea.DeaGuid

				store.SyncHeartbeats(dea.HeartbeatWith(
					dea.GetApp(0).InstanceAtIndex(1).Heartbeat(),
					dea.GetApp(1).InstanceAtIndex(3).Heartbeat(),
					heartbeatOnDea,
				))

				store.SyncHeartbeats(otherDea.HeartbeatWith(
					otherDea.GetApp(0).InstanceAtIndex(1).Heartbeat(),