"errors" "time" "github.com/cloudfoundry/hm9000/config" "github.com/cloudfoundry/hm9000/models" storepackage "github.com/cloudfoundry/hm9000/store" "github.com/cloudfoundry/hm9000/testhelpers/appfixture" "github.com/cloudfoundry/hm9000/testhelpers/fakelogger" "github.com/cloudfoundry/storeadapter/fakestoreadapter" ) var _ = Describe("Analyzer", func() { var ( analyzer *Analyzer storeAdapter *fakestoreadapter.FakeStoreAdapter store storepackage.Store clock *fakeclock.FakeClock dea appfixture.DeaFixture app appfixture.AppFixture ) conf, _ := config.DefaultConfig() BeforeEach(func() { storeAdapter = fakestoreadapter.New() store = storepackage.NewStore(conf, storeAdapter, fakelogger.NewFakeLogger()) clock = fakeclock.NewFakeClock(time.Unix(1000, 0)) dea = appfixture.NewDeaFixture() app = dea.GetApp(0)
import ( "fmt" "io/ioutil" "net/http" "github.com/cloudfoundry/hm9000/models" "github.com/cloudfoundry/hm9000/testhelpers/appfixture" "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()
}) }) }) Describe("ToJson", func() { It("should, like, totally encode JSON", func() { jsonHeartbeat, err := NewHeartbeatFromJSON(heartbeat.ToJSON()) Ω(err).ShouldNot(HaveOccurred()) Ω(jsonHeartbeat).Should(Equal(heartbeat)) }) }) Context("With a complex heartbeat", func() { var heartbeat Heartbeat var app appfixture.AppFixture BeforeEach(func() { app = appfixture.NewAppFixture() crashedHeartbeat := app.InstanceAtIndex(2).Heartbeat() crashedHeartbeat.State = InstanceStateCrashed startingHeartbeat := app.InstanceAtIndex(3).Heartbeat() startingHeartbeat.State = InstanceStateStarting evacuatingHeartbeat := app.InstanceAtIndex(4).Heartbeat() evacuatingHeartbeat.State = InstanceStateEvacuating heartbeat = Heartbeat{ DeaGuid: "abc", InstanceHeartbeats: []InstanceHeartbeat{
package mcat_test import ( "github.com/cloudfoundry/hm9000/testhelpers/appfixture" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Expiring Heartbeats Test", func() { 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(
. "github.com/cloudfoundry/hm9000/testhelpers/custommatchers" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/cloudfoundry/hm9000/config" "github.com/cloudfoundry/hm9000/testhelpers/appfixture" "github.com/cloudfoundry/hm9000/testhelpers/fakelogger" "github.com/cloudfoundry/storeadapter" "github.com/cloudfoundry/storeadapter/etcdstoreadapter" ) var _ = Describe("Desired State", func() { var ( store Store storeAdapter storeadapter.StoreAdapter conf *config.Config app1 appfixture.AppFixture app2 appfixture.AppFixture app3 appfixture.AppFixture ) 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())
package desiredstatefetcher_test import ( "encoding/json" "fmt" . "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("should send an error down the result channel", func(done Done) { result := <-resultChan Ω(result.Success).Should(BeFalse()) Ω(result.Message).Should(Equal(expectedMessage)) Ω(result.Error).Should(HaveOccurred()) close(done) }, 1.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
package models_test import ( . "github.com/cloudfoundry/hm9000/models" "github.com/cloudfoundry/hm9000/testhelpers/appfixture" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "time" ) var _ = Describe("App", func() { var ( fixture appfixture.AppFixture appGuid string appVersion string desired DesiredAppState instanceHeartbeats []InstanceHeartbeat crashCounts map[int]CrashCount ) instance := func(instanceIndex int) appfixture.Instance { return fixture.InstanceAtIndex(instanceIndex) } heartbeat := func(instanceIndex int, state InstanceState) InstanceHeartbeat { hb := instance(instanceIndex).Heartbeat() hb.State = state return hb } app := func() *App {
"github.com/cloudfoundry/hm9000/testhelpers/appfixture" "github.com/cloudfoundry/hm9000/testhelpers/fakelogger" "github.com/cloudfoundry/hm9000/testhelpers/fakemetricsaccountant" "github.com/cloudfoundry/storeadapter/fakestoreadapter" "github.com/cloudfoundry/yagnats/fakeyagnats" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Sender", func() { var ( storeAdapter *fakestoreadapter.FakeStoreAdapter store storepackage.Store sender *Sender messageBus *fakeyagnats.FakeYagnats timeProvider *faketimeprovider.FakeTimeProvider dea appfixture.DeaFixture app appfixture.AppFixture conf *config.Config metricsAccountant *fakemetricsaccountant.FakeMetricsAccountant ) BeforeEach(func() { messageBus = fakeyagnats.New() dea = appfixture.NewDeaFixture() app = dea.GetApp(0) conf, _ = config.DefaultConfig() metricsAccountant = fakemetricsaccountant.New() timeProvider = &faketimeprovider.FakeTimeProvider{ TimeToProvide: time.Unix(int64(10+conf.ActualFreshnessTTL()), 0),
package mcat_test import ( "fmt" "github.com/cloudfoundry/hm9000/models" "github.com/cloudfoundry/hm9000/testhelpers/appfixture" "github.com/cloudfoundry/yagnats" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Serving API", func() { var ( a appfixture.AppFixture validRequest []byte ) Describe("app.state", func() { BeforeEach(func() { a = appfixture.NewAppFixture() validRequest = []byte(fmt.Sprintf(`{"droplet":"%s","version":"%s"}`, a.AppGuid, a.AppVersion)) simulator.SetDesiredState(a.DesiredState(2)) simulator.SetCurrentHeartbeats(a.Heartbeat(1)) }) AfterEach(func() { cliRunner.StopAPIServer() })
package mcat_test import ( "github.com/cloudfoundry/hm9000/models" "github.com/cloudfoundry/hm9000/testhelpers/appfixture" . "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()) }) })
resultChan <- results errChan <- err }() Ω(<-resultChan).Should(HaveLen(3)) Ω(<-resultChan).Should(HaveLen(3)) Ω(<-errChan).ShouldNot(HaveOccurred()) Ω(<-errChan).ShouldNot(HaveOccurred()) }) }) }) }) }) Describe("Fetching actual state for a specific app guid & version", func() { var app appfixture.AppFixture BeforeEach(func() { app = appfixture.NewAppFixture() }) Context("when there is none saved", func() { It("should come back empty", func() { results, err := store.GetInstanceHeartbeatsForApp(app.AppGuid, app.AppVersion) Ω(err).ShouldNot(HaveOccurred()) Ω(results).Should(BeEmpty()) }) }) Context("when there is actual state saved", func() { var heartbeatA, heartbeatB models.InstanceHeartbeat
package mcat_test import ( "github.com/cloudfoundry/hm9000/models" "github.com/cloudfoundry/hm9000/testhelpers/appfixture" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) 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)
. "github.com/cloudfoundry/hm9000/testhelpers/custommatchers" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/cloudfoundry/hm9000/config" "github.com/cloudfoundry/hm9000/testhelpers/appfixture" "github.com/cloudfoundry/hm9000/testhelpers/fakelogger" "github.com/cloudfoundry/storeadapter" "github.com/cloudfoundry/storeadapter/etcdstoreadapter" ) var _ = Describe("Desired State", func() { var ( store Store storeAdapter storeadapter.StoreAdapter conf *config.Config app1 appfixture.AppFixture app2 appfixture.AppFixture app3 appfixture.AppFixture ) BeforeEach(func() { var err error conf, err = config.DefaultConfig() Ω(err).ShouldNot(HaveOccurred()) storeAdapter = etcdstoreadapter.NewETCDStoreAdapter(etcdRunner.NodeURLS(), workpool.NewWorkPool(conf.StoreMaxConcurrentRequests)) err = storeAdapter.Connect() Ω(err).ShouldNot(HaveOccurred()) app1 = appfixture.NewAppFixture() app2 = appfixture.NewAppFixture()
"github.com/cloudfoundry/hm9000/models" storepackage "github.com/cloudfoundry/hm9000/store" "github.com/cloudfoundry/hm9000/testhelpers/appfixture" "github.com/cloudfoundry/hm9000/testhelpers/fakelogger" "github.com/cloudfoundry/hm9000/testhelpers/fakemetricsaccountant" "github.com/cloudfoundry/storeadapter/fakestoreadapter" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) 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),
"io/ioutil" "net/http" "github.com/cloudfoundry/hm9000/apiserver" "github.com/cloudfoundry/hm9000/testhelpers/appfixture" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/tedsuo/rata" ) var _ = Describe("Serving API", func() { var ( a appfixture.AppFixture validRequest string requestGenerator *rata.RequestGenerator httpClient *http.Client apiServerAddr string username string password string ) 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{}, }
Ω(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 the store is fresh", func() { var dea appfixture.DeaFixture var a appfixture.AppFixture BeforeEach(func() { dea = appfixture.NewDeaFixture() a = dea.GetApp(0) store.BumpDesiredFreshness(time.Unix(0, 0)) store.BumpActualFreshness(time.Unix(0, 0)) }) Context("when the apps fail to load", func() { BeforeEach(func() { storeAdapter.ListErrInjector = fakestoreadapter.NewFakeStoreAdapterErrorInjector("apps", errors.New("oops")) }) It("should emit -1 for all its metrics", func() { context := metricsServer.Emit()
package mcat_test import ( "github.com/cloudfoundry/hm9000/models" "github.com/cloudfoundry/hm9000/testhelpers/appfixture" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) 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), )
Ω(body).Should(Equal("{}")) }) }) Context("when no reply-to is given", func() { 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 *models.App 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,
package mcat_test 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() })
. "github.com/cloudfoundry/hm9000/testhelpers/custommatchers" "github.com/cloudfoundry/hm9000/testhelpers/fakelogger" "github.com/cloudfoundry/storeadapter/fakestoreadapter" "github.com/cloudfoundry/yagnats/fakeyagnats" . "github.com/cloudfoundry/hm9000/evacuator" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Evacuator", func() { var ( evacuator *Evacuator messageBus *fakeyagnats.FakeNATSConn storeAdapter *fakestoreadapter.FakeStoreAdapter timeProvider *faketimeprovider.FakeTimeProvider store storepackage.Store app appfixture.AppFixture ) conf, _ := config.DefaultConfig() BeforeEach(func() { storeAdapter = fakestoreadapter.New() messageBus = fakeyagnats.Connect() store = storepackage.NewStore(conf, storeAdapter, fakelogger.NewFakeLogger()) timeProvider = &faketimeprovider.FakeTimeProvider{ TimeToProvide: time.Unix(100, 0), }
. "github.com/cloudfoundry/hm9000/testhelpers/custommatchers" "github.com/cloudfoundry/hm9000/testhelpers/fakelogger" "github.com/cloudfoundry/storeadapter" "github.com/cloudfoundry/storeadapter/etcdstoreadapter" "github.com/cloudfoundry/storeadapter/workerpool" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Apps", func() { var ( store Store storeAdapter storeadapter.StoreAdapter conf *config.Config dea appfixture.DeaFixture app1 appfixture.AppFixture app2 appfixture.AppFixture app3 appfixture.AppFixture app4 appfixture.AppFixture crashCount []models.CrashCount ) conf, _ = config.DefaultConfig() BeforeEach(func() { storeAdapter = etcdstoreadapter.NewETCDStoreAdapter(etcdRunner.NodeURLS(), workerpool.NewWorkerPool(conf.StoreMaxConcurrentRequests)) err := storeAdapter.Connect() Ω(err).ShouldNot(HaveOccurred()) store = NewStore(conf, storeAdapter, fakelogger.NewFakeLogger())
"github.com/cloudfoundry/hm9000/testhelpers/appfixture" . "github.com/cloudfoundry/hm9000/testhelpers/custommatchers" "github.com/cloudfoundry/hm9000/testhelpers/fakelogger" "github.com/cloudfoundry/storeadapter" "github.com/cloudfoundry/storeadapter/etcdstoreadapter" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Apps", func() { var ( store Store storeAdapter storeadapter.StoreAdapter conf *config.Config dea appfixture.DeaFixture app1 appfixture.AppFixture app2 appfixture.AppFixture app3 appfixture.AppFixture app4 appfixture.AppFixture crashCount []models.CrashCount ) conf, _ = config.DefaultConfig() BeforeEach(func() { wpool, err := workpool.NewWorkPool(conf.StoreMaxConcurrentRequests) Expect(err).NotTo(HaveOccurred()) storeAdapter, err = etcdstoreadapter.New( &etcdstoreadapter.ETCDOptions{ClusterUrls: etcdRunner.NodeURLS()}, wpool, )