import (
	"github.com/cloudfoundry/hm9000/models"
	"github.com/cloudfoundry/hm9000/testhelpers/appfixture"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Evacuation and Shutdown", func() {
	var dea appfixture.DeaFixture
	var app appfixture.AppFixture

	BeforeEach(func() {
		dea = appfixture.NewDeaFixture()
		app = dea.GetApp(0)
		simulator.SetCurrentHeartbeats(dea.HeartbeatWith(app.InstanceAtIndex(0).Heartbeat()))
		simulator.SetDesiredState(app.DesiredState(1))
		simulator.Tick(simulator.TicksToAttainFreshness)
	})

	Describe("Shutdown handling by the evacuator component", func() {
		Context("when a SHUTDOWN droplet.exited message comes in", func() {
			BeforeEach(func() {
				cliRunner.StartEvacuator(simulator.currentTimestamp)
				coordinator.MessageBus.Publish("droplet.exited", app.InstanceAtIndex(0).DropletExited(models.DropletExitedReasonDEAShutdown).ToJSON())
			})

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

			It("should immediately start the app", func() {
var _ = Describe("Crashes", func() {
	var (
		dea               appfixture.DeaFixture
		a                 appfixture.AppFixture
		crashingHeartbeat models.Heartbeat
	)

	BeforeEach(func() {
		dea = appfixture.NewDeaFixture()
		a = dea.GetApp(0)
	})

	Describe("when all instances are crashed", func() {
		BeforeEach(func() {
			simulator.SetDesiredState(a.DesiredState(3))

			crashingHeartbeat = dea.HeartbeatWith(
				a.CrashedInstanceHeartbeatAtIndex(0),
				a.CrashedInstanceHeartbeatAtIndex(1),
				a.CrashedInstanceHeartbeatAtIndex(2),
			)

			simulator.SetCurrentHeartbeats(crashingHeartbeat)
			simulator.Tick(simulator.TicksToAttainFreshness)
		})

		It("should only try to start instance at index 0", func() {
			Ω(startStopListener.Starts).Should(HaveLen(1))
			Ω(startStopListener.Starts[0].AppVersion).Should(Equal(a.AppVersion))
			Ω(startStopListener.Starts[0].InstanceIndex).Should(Equal(0))
		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),
			)
			Expect(err).NotTo(HaveOccurred())
		})

		It("To store the passed in desired state", func() {
			desiredState, err := store.GetDesiredState()
			Expect(err).NotTo(HaveOccurred())

			Expect(desiredState).To(HaveLen(2))
			Expect(desiredState[app1.DesiredState(1).StoreKey()]).To(EqualDesiredState(app1.DesiredState(1)))
			Expect(desiredState[app2.DesiredState(1).StoreKey()]).To(EqualDesiredState(app2.DesiredState(1)))
		})

		Context("When the desired state already exists", func() {
Exemple #4
0
		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),
			)
			Ω(err).ShouldNot(HaveOccurred())
		})

		It("should store the passed in desired state", func() {
			desiredState, err := store.GetDesiredState()
			Ω(err).ShouldNot(HaveOccurred())

			Ω(desiredState).Should(HaveLen(2))
			Ω(desiredState[app1.DesiredState(1).StoreKey()]).Should(EqualDesiredState(app1.DesiredState(1)))
			Ω(desiredState[app2.DesiredState(1).StoreKey()]).Should(EqualDesiredState(app2.DesiredState(1)))
		})

		Context("When the desired state already exists", func() {
	Describe("LogDescription", func() {
		It("should report the app guid and version", func() {
			Ω(app().LogDescription()["AppGuid"]).Should(Equal(appGuid))
			Ω(app().LogDescription()["AppVersion"]).Should(Equal(appVersion))
		})

		Context("when there is no desired state", func() {
			It("should report that", func() {
				Ω(app().LogDescription()["Desired"]).Should(Equal("None"))
			})
		})

		Context("when there is a desired state", func() {
			It("should report on the desired state", func() {
				desired = fixture.DesiredState(2)
				Ω(app().LogDescription()["Desired"]).Should(ContainSubstring(`"NumberOfInstances":2`))
				Ω(app().LogDescription()["Desired"]).Should(ContainSubstring(`"State":"STARTED"`))
				Ω(app().LogDescription()["Desired"]).Should(ContainSubstring(`"PackageState":"STAGED"`))
			})
		})

		Context("When there are no heartbeats", func() {
			It("should report that", func() {
				Ω(app().LogDescription()["InstanceHeartbeats"]).Should(Equal("[]"))
			})
		})

		Context("When there are heartbeats", func() {
			It("should report on them", func() {
				instanceHeartbeats = []InstanceHeartbeat{
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Simple Cases Test", func() {
	var app1, app2 appfixture.AppFixture

	BeforeEach(func() {
		app1 = appfixture.NewAppFixture()
		app2 = appfixture.NewAppFixture()
	})

	Context("when all running instances are desired", func() {
		BeforeEach(func() {
			simulator.SetCurrentHeartbeats(app1.Heartbeat(1), app2.Heartbeat(1))
			simulator.SetDesiredState(app1.DesiredState(1), app2.DesiredState(1))
			simulator.Tick(simulator.TicksToAttainFreshness)
			simulator.Tick(1)
		})

		It("should not send any messages", func() {
			Ω(startStopListener.Starts).Should(BeEmpty())
			Ω(startStopListener.Stops).Should(BeEmpty())
		})
	})

	Context("when a desired app is pending staging", func() {
		Context("and it has a running instance", func() {
			BeforeEach(func() {
				desired := app1.DesiredState(1)
				desired.PackageState = models.AppPackageStatePending
Exemple #7
0
	"github.com/nats-io/nats"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/pivotal-golang/localip"
)

var _ = Describe("Serving Metrics", func() {
	var (
		a  appfixture.AppFixture
		ip string
	)

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

		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()
				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 = models.NewApp(
					app.AppGuid,
					app.AppVersion,
					app.DesiredState(3),
					instanceHeartbeats,
					map[int]models.CrashCount{1: crashCount},
				)

				store.SyncDesiredState(app.DesiredState(3))
				store.SyncHeartbeats(app.Heartbeat(3))
				store.SaveCrashCounts(crashCount)
				validRequestPayload = fmt.Sprintf(`{"droplet":"%s","version":"%s"}`, app.AppGuid, app.AppVersion)
			})

			Context("when the store is fresh", func() {
				BeforeEach(func() {
					store.BumpDesiredFreshness(time.Unix(0, 0))
					store.BumpActualFreshness(time.Unix(0, 0))
				})
	var dea1, dea2 appfixture.DeaFixture
	var app1, app2, app3 appfixture.AppFixture

	BeforeEach(func() {
		dea1 = appfixture.NewDeaFixture()
		dea2 = appfixture.NewDeaFixture()

		app1 = dea1.GetApp(0)
		app2 = dea1.GetApp(1)
		app3 = dea2.GetApp(2)

		simulator.SetCurrentHeartbeats(
			dea1.HeartbeatWith(app1.InstanceAtIndex(0).Heartbeat(), app2.InstanceAtIndex(0).Heartbeat()),
			dea2.HeartbeatWith(app3.InstanceAtIndex(0).Heartbeat()),
		)
		simulator.SetDesiredState(app1.DesiredState(1), app2.DesiredState(1), app3.DesiredState(1))
		simulator.Tick(simulator.TicksToAttainFreshness)
	})

	Context("when a dea reports than an instance is no longer present", func() {
		BeforeEach(func() {
			simulator.SetCurrentHeartbeats(
				dea1.HeartbeatWith(app1.InstanceAtIndex(0).Heartbeat()),
				dea2.HeartbeatWith(app3.InstanceAtIndex(0).Heartbeat()),
			)
		})

		It("should start the instance after a grace period", func() {
			simulator.Tick(simulator.GracePeriod)
			Ω(startStopListener.StartCount()).Should(Equal(0))
			simulator.Tick(1)
		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)
	})

	It("requests for the first set of data from the CC and stores the response", func() {
		var desired map[string]models.DesiredAppState
		var err error
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfAppsWithAllInstancesReporting", Value: -1}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfAppsWithMissingInstances", Value: -1}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfUndesiredRunningApps", Value: -1}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfRunningInstances", Value: -1}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfMissingIndices", Value: -1}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfCrashedInstances", Value: -1}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfCrashedIndices", Value: -1}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfDesiredApps", Value: -1}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfDesiredInstances", Value: -1}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfDesiredAppsPendingStaging", Value: -1}))
				})
			})

			Context("When a desired app is pending staging", func() {
				BeforeEach(func() {
					desired := a.DesiredState(3)
					desired.PackageState = models.AppPackageStatePending
					store.SyncDesiredState(desired)
					store.SyncHeartbeats(a.Heartbeat(1))
				})

				It("should have the correct stats", func() {
					context := metricsServer.Emit()
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfAppsWithAllInstancesReporting", Value: 0}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfAppsWithMissingInstances", Value: 0}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfUndesiredRunningApps", Value: 0}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfRunningInstances", Value: 1}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfMissingIndices", Value: 0}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfCrashedInstances", Value: 0}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfCrashedIndices", Value: 0}))
					Ω(context.Metrics).Should(ContainElement(instrumentation.Metric{Name: "NumberOfDesiredApps", Value: 0}))
		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)
				failedStagingDesiredState.PackageState = models.AppPackageStateFailed
				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,
					Desired:            app.DesiredState(3),
					InstanceHeartbeats: instanceHeartbeats,
					CrashCounts:        []models.CrashCount{crashCount},
				}

				store.SyncDesiredState(app.DesiredState(3))
				store.SyncHeartbeats(app.Heartbeat(3))
				store.SaveCrashCounts(crashCount)
				validRequestPayload = fmt.Sprintf(`{"droplet":"%s","version":"%s"}`, app.AppGuid, app.AppVersion)
			})

			Context("when the store is fresh", func() {
				BeforeEach(func() {
					store.BumpDesiredFreshness(time.Unix(0, 0))
					store.BumpActualFreshness(time.Unix(0, 0))
				})
		It("should not send any messages", func() {
			err := sender.Send()
			Ω(err).ShouldNot(HaveOccurred())
			Ω(messageBus.PublishedMessages).Should(BeEmpty())
		})
	})

	Context("when there are start messages", func() {
		var keepAliveTime int
		var sentOn int64
		var err error
		var pendingMessage models.PendingStartMessage
		var storeSetErrInjector *fakestoreadapter.FakeStoreAdapterErrorInjector

		JustBeforeEach(func() {
			store.SyncDesiredState(app.DesiredState(1))
			pendingMessage = models.NewPendingStartMessage(time.Unix(100, 0), 30, keepAliveTime, app.AppGuid, app.AppVersion, 0, 1.0, models.PendingStartMessageReasonInvalid)
			pendingMessage.SentOn = sentOn
			store.SavePendingStartMessages(
				pendingMessage,
			)
			storeAdapter.SetErrInjector = storeSetErrInjector
			err = sender.Send()
		})

		BeforeEach(func() {
			keepAliveTime = 0
			sentOn = 0
			err = nil
			storeSetErrInjector = nil
		})
	. "github.com/cloudfoundry/hm9000/desiredstatefetcher"
	"github.com/cloudfoundry/hm9000/testhelpers/appfixture"
	. "github.com/cloudfoundry/hm9000/testhelpers/custommatchers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Desired State Server Response JSON", func() {
	var (
		a        appfixture.AppFixture
		response DesiredStateServerResponse
	)
	BeforeEach(func() {
		a = appfixture.NewAppFixture()

		desired, _ := json.Marshal(a.DesiredState(1))
		responseJson := fmt.Sprintf(`
        {
            "results":{"%s":%s},
            "bulk_token":{"id":17}
        }
        `, a.AppGuid, string(desired))

		var err error
		response, err = NewDesiredStateServerResponse([]byte(responseJson))
		Ω(err).ShouldNot(HaveOccurred())
	})

	It("can parse from JSON", func() {
		Ω(response.Results).Should(HaveLen(1))
		Ω(response.Results[a.AppGuid]).Should(EqualDesiredState(a.DesiredState(1)))
Exemple #16
0
		return messagesArr
	}

	Describe("The steady state", func() {
		Context("When there are no desired or running apps", func() {
			It("should not send any start or stop messages", func() {
				err := analyzer.Analyze()
				Ω(err).ShouldNot(HaveOccurred())
				Ω(startMessages()).Should(BeEmpty())
				Ω(stopMessages()).Should(BeEmpty())
			})
		})

		Context("When the desired number of instances and the running number of instances match", func() {
			BeforeEach(func() {
				desired := app.DesiredState(3)
				desired.State = models.AppStateStarted
				store.SyncDesiredState(
					desired,
				)
				store.SyncHeartbeats(app.Heartbeat(3))
			})

			It("should not send any start or stop messages", func() {
				err := analyzer.Analyze()
				Ω(err).ShouldNot(HaveOccurred())
				Ω(startMessages()).Should(BeEmpty())
				Ω(stopMessages()).Should(BeEmpty())
			})
		})
	})
Exemple #17
0
		dea = appfixture.NewDeaFixture()
		app1 = dea.GetApp(0)
		app2 = dea.GetApp(1)
		app3 = dea.GetApp(2)
		app4 = dea.GetApp(3)

		actualState := []models.InstanceHeartbeat{
			app1.InstanceAtIndex(0).Heartbeat(),
			app1.InstanceAtIndex(1).Heartbeat(),
			app1.InstanceAtIndex(2).Heartbeat(),
			app2.InstanceAtIndex(0).Heartbeat(),
		}

		desiredState := []models.DesiredAppState{
			app1.DesiredState(1),
			app3.DesiredState(1),
		}

		crashCount = []models.CrashCount{
			{
				AppGuid:       app1.AppGuid,
				AppVersion:    app1.AppVersion,
				InstanceIndex: 1,
				CrashCount:    12,
			},
			{
				AppGuid:       app1.AppGuid,
				AppVersion:    app1.AppVersion,
				InstanceIndex: 2,
				CrashCount:    17,
Exemple #18
0
		dea = appfixture.NewDeaFixture()
		app1 = dea.GetApp(0)
		app2 = dea.GetApp(1)
		app3 = dea.GetApp(2)
		app4 = dea.GetApp(3)

		actualState := []models.InstanceHeartbeat{
			app1.InstanceAtIndex(0).Heartbeat(),
			app1.InstanceAtIndex(1).Heartbeat(),
			app1.InstanceAtIndex(2).Heartbeat(),
			app2.InstanceAtIndex(0).Heartbeat(),
		}

		desiredState := []models.DesiredAppState{
			app1.DesiredState(1),
			app3.DesiredState(1),
		}

		crashCount = []models.CrashCount{
			{
				AppGuid:       app1.AppGuid,
				AppVersion:    app1.AppVersion,
				InstanceIndex: 1,
				CrashCount:    12,
			},
			{
				AppGuid:       app1.AppGuid,
				AppVersion:    app1.AppVersion,
				InstanceIndex: 2,
				CrashCount:    17,