func buildAgent() (deps agentDeps, agent Agent) { deps = agentDeps{ logger: boshlog.NewLogger(boshlog.LEVEL_NONE), handler: &fakembus.FakeHandler{}, platform: fakeplatform.NewFakePlatform(), actionDispatcher: &FakeActionDispatcher{}, alertBuilder: fakealert.NewFakeAlertBuilder(), jobSupervisor: fakejobsup.NewFakeJobSupervisor(), } agent = New(deps.logger, deps.handler, deps.platform, deps.actionDispatcher, deps.alertBuilder, deps.jobSupervisor, 5*time.Millisecond) return }
func init() { Describe("Agent", func() { var ( agent Agent logger boshlog.Logger handler *fakembus.FakeHandler platform *fakeplatform.FakePlatform actionDispatcher *FakeActionDispatcher alertBuilder *fakealert.FakeAlertBuilder alertSender AlertSender jobSupervisor *fakejobsuper.FakeJobSupervisor specService *fakeas.FakeV1Service ) BeforeEach(func() { logger = boshlog.NewLogger(boshlog.LevelDebug) handler = &fakembus.FakeHandler{} platform = fakeplatform.NewFakePlatform() actionDispatcher = &FakeActionDispatcher{} alertBuilder = fakealert.NewFakeAlertBuilder() alertSender = NewAlertSender(handler, alertBuilder) jobSupervisor = fakejobsuper.NewFakeJobSupervisor() specService = fakeas.NewFakeV1Service() agent = New(logger, handler, platform, actionDispatcher, alertSender, jobSupervisor, specService, 5*time.Millisecond) }) Describe("Run", func() { It("lets dispatcher handle requests arriving via handler", func() { err := agent.Run() Expect(err).ToNot(HaveOccurred()) expectedResp := boshhandler.NewValueResponse("pong") actionDispatcher.DispatchResp = expectedResp req := boshhandler.NewRequest("fake-reply", "fake-action", []byte("fake-payload")) resp := handler.RunFunc(req) Expect(actionDispatcher.DispatchReq).To(Equal(req)) Expect(resp).To(Equal(expectedResp)) }) It("resumes persistent actions *before* dispatching new requests", func() { resumedBeforeStartingToDispatch := false handler.RunCallBack = func() { resumedBeforeStartingToDispatch = actionDispatcher.ResumedPreviouslyDispatchedTasks } err := agent.Run() Expect(err).ToNot(HaveOccurred()) Expect(resumedBeforeStartingToDispatch).To(BeTrue()) }) Context("when heartbeats can be sent", func() { BeforeEach(func() { handler.KeepOnRunning() }) BeforeEach(func() { jobName := "fake-job" jobIndex := 1 specService.Spec = boshas.V1ApplySpec{ JobSpec: boshas.JobSpec{Name: &jobName}, Index: &jobIndex, } jobSupervisor.StatusStatus = "fake-state" platform.FakeVitalsService.GetVitals = boshvitals.Vitals{ Load: []string{"a", "b", "c"}, } }) expectedJobName := "fake-job" expectedJobIndex := 1 expectedHb := boshmbus.Heartbeat{ Job: &expectedJobName, Index: &expectedJobIndex, JobState: "fake-state", Vitals: boshvitals.Vitals{Load: []string{"a", "b", "c"}}, } It("sends initial heartbeat", func() { // Configure periodic heartbeat every 5 hours // so that we are sure that we will not receive it agent = New(logger, handler, platform, actionDispatcher, alertSender, jobSupervisor, specService, 5*time.Hour) // Immediately exit after sending initial heartbeat handler.SendToHealthManagerErr = errors.New("stop") err := agent.Run() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("stop")) Expect(handler.HMRequests()).To(Equal([]fakembus.HMRequest{ fakembus.HMRequest{Topic: "heartbeat", Payload: expectedHb}, })) }) It("sends periodic heartbeats", func() { sentRequests := 0 handler.SendToHealthManagerCallBack = func(_ fakembus.HMRequest) { sentRequests++ if sentRequests == 3 { handler.SendToHealthManagerErr = errors.New("stop") } } err := agent.Run() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("stop")) Expect(handler.HMRequests()).To(Equal([]fakembus.HMRequest{ fakembus.HMRequest{Topic: "heartbeat", Payload: expectedHb}, fakembus.HMRequest{Topic: "heartbeat", Payload: expectedHb}, fakembus.HMRequest{Topic: "heartbeat", Payload: expectedHb}, })) }) }) Context("when the agent fails to get job spec for a heartbeat", func() { BeforeEach(func() { specService.GetErr = errors.New("fake-spec-service-error") handler.KeepOnRunning() }) It("returns the error", func() { err := agent.Run() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-spec-service-error")) }) }) Context("when the agent fails to get vitals for a heartbeat", func() { BeforeEach(func() { platform.FakeVitalsService.GetErr = errors.New("fake-vitals-service-error") handler.KeepOnRunning() }) It("returns the error", func() { err := agent.Run() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-vitals-service-error")) }) }) It("sends job failure alerts to health manager", func() { handler.KeepOnRunning() failureAlert := boshalert.MonitAlert{ID: "fake-monit-alert"} jobSupervisor.JobFailureAlert = &failureAlert builtAlert := boshalert.Alert{ID: "fake-built-alert"} alertBuilder.BuildAlert = builtAlert // Immediately exit from Run() after alert is sent handler.SendToHealthManagerCallBack = func(hmRequest fakembus.HMRequest) { if hmRequest.Topic == "alert" { handler.SendToHealthManagerErr = errors.New("stop") } } err := agent.Run() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("stop")) Expect(alertBuilder.BuildInput).To(Equal(failureAlert)) // Check for inclusion because heartbeats might have been received Expect(handler.HMRequests()).To(ContainElement( fakembus.HMRequest{Topic: "alert", Payload: builtAlert}, )) }) }) }) }
func init() { Describe("Agent", func() { var ( agent Agent logger boshlog.Logger handler *fakembus.FakeHandler platform *fakeplatform.FakePlatform actionDispatcher *FakeActionDispatcher alertBuilder *fakealert.FakeAlertBuilder jobSupervisor *fakejobsuper.FakeJobSupervisor specService *fakeas.FakeV1Service ) BeforeEach(func() { logger = boshlog.NewLogger(boshlog.LEVEL_NONE) handler = &fakembus.FakeHandler{} platform = fakeplatform.NewFakePlatform() actionDispatcher = &FakeActionDispatcher{} alertBuilder = fakealert.NewFakeAlertBuilder() jobSupervisor = fakejobsuper.NewFakeJobSupervisor() specService = fakeas.NewFakeV1Service() agent = New(logger, handler, platform, actionDispatcher, alertBuilder, jobSupervisor, specService, 5*time.Millisecond) }) Describe("Run", func() { It("sets the dispatcher as message handler", func() { actionDispatcher.DispatchResp = boshhandler.NewValueResponse("pong") err := agent.Run() Expect(err).ToNot(HaveOccurred()) Expect(handler.ReceivedRun).To(BeTrue()) req := boshhandler.NewRequest("fake-reply", "fake-action", []byte("fake-payload")) resp := handler.Func(req) Expect(req).To(Equal(actionDispatcher.DispatchReq)) Expect(actionDispatcher.DispatchResp).To(Equal(resp)) }) It("resumes persistent actions *before* dispatching new requests", func() { resumedBefore := false handler.RunFunc = func() { resumedBefore = actionDispatcher.ResumedPreviouslyDispatchedTasks } err := agent.Run() Expect(err).ToNot(HaveOccurred()) Expect(resumedBefore).To(BeTrue()) }) Context("when heartbeats can be sent", func() { BeforeEach(func() { jobName := "fake-job" jobIndex := 1 specService.Spec = boshas.V1ApplySpec{ JobSpec: boshas.JobSpec{Name: &jobName}, Index: &jobIndex, } jobSupervisor.StatusStatus = "fake-state" platform.FakeVitalsService.GetVitals = boshvitals.Vitals{ Load: []string{"a", "b", "c"}, } }) expectedJobName := "fake-job" expectedJobIndex := 1 expectedHb := boshmbus.Heartbeat{ Job: &expectedJobName, Index: &expectedJobIndex, JobState: "fake-state", Vitals: boshvitals.Vitals{Load: []string{"a", "b", "c"}}, } It("sends initial heartbeat", func() { err := agent.Run() Expect(err).ToNot(HaveOccurred()) Expect(handler.InitialHeartbeatSent).To(BeTrue()) Expect(handler.TickHeartbeatsSent).To(BeFalse()) Expect(handler.SendToHealthManagerTopic).To(Equal("heartbeat")) Expect(handler.SendToHealthManagerPayload.(boshmbus.Heartbeat)).To(Equal(expectedHb)) }) It("sends periodic heartbeats", func() { err := agent.Run() Expect(err).ToNot(HaveOccurred()) Expect(handler.TickHeartbeatsSent).To(BeFalse()) time.Sleep(5 * time.Millisecond) Expect(handler.TickHeartbeatsSent).To(BeTrue()) Expect(handler.SendToHealthManagerTopic).To(Equal("heartbeat")) Expect(handler.SendToHealthManagerPayload.(boshmbus.Heartbeat)).To(Equal(expectedHb)) }) }) Context("when the agent fails to get job spec for a heartbeat", func() { BeforeEach(func() { block := make(chan error) handler.RunFunc = func() { <-block } specService.GetErr = errors.New("fake-spec-service-error") }) It("returns the error", func() { err := agent.Run() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-spec-service-error")) }) }) Context("when the agent fails to get vitals for a heartbeat", func() { BeforeEach(func() { block := make(chan error) handler.RunFunc = func() { <-block } platform.FakeVitalsService.GetErr = errors.New("fake-vitals-service-error") }) It("returns the error", func() { err := agent.Run() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-vitals-service-error")) }) }) It("sets the callback for job failures monitoring", func() { builtAlert := boshalert.Alert{Id: "some built alert id"} alertBuilder.BuildAlert = builtAlert err := agent.Run() Expect(err).ToNot(HaveOccurred()) Expect(handler.SendToHealthManagerTopic).ToNot(Equal("alert")) failureAlert := boshalert.MonitAlert{Id: "some random id"} jobSupervisor.OnJobFailure(failureAlert) Expect(failureAlert).To(Equal(alertBuilder.BuildInput)) Expect(handler.SendToHealthManagerTopic).To(Equal("alert")) Expect(builtAlert).To(Equal(handler.SendToHealthManagerPayload)) }) }) }) }
faketime "bosh/time/fakes" fakeuuid "bosh/uuid/fakes" ) var _ = Describe("concreteAlertSender", func() { var ( handler *fakembus.FakeHandler alertBuilder *fakealert.FakeAlertBuilder uuidGenerator *fakeuuid.FakeGenerator timeService *faketime.FakeService alertSender AlertSender ) BeforeEach(func() { handler = fakembus.NewFakeHandler() alertBuilder = fakealert.NewFakeAlertBuilder() uuidGenerator = &fakeuuid.FakeGenerator{} timeService = &faketime.FakeService{} alertSender = NewConcreteAlertSender(handler, alertBuilder, uuidGenerator, timeService) }) Describe("SendAlert", func() { monitAlert := boshalert.MonitAlert{ID: "fake-monit-alert"} It("sends monit alerts to health manager", func() { builtAlert := boshalert.Alert{ID: "fake-built-alert"} alertBuilder.BuildAlert = builtAlert err := alertSender.SendAlert(monitAlert) Expect(err).ToNot(HaveOccurred())