func (t *ETCDHelper) CreateDesiredLRPsInDomains(domainCounts map[string]int) map[string][]*models.DesiredLRP { createdDesiredLRPs := map[string][]*models.DesiredLRP{} for domain, count := range domainCounts { createdDesiredLRPs[domain] = []*models.DesiredLRP{} for i := 0; i < count; i++ { guid := fmt.Sprintf("guid-%d-for-%s", i, domain) desiredLRP := model_helpers.NewValidDesiredLRP(guid) desiredLRP.Domain = domain schedulingInfo, runInfo := desiredLRP.CreateComponents(t.clock.Now()) schedulingInfoValue, err := t.serializer.Marshal(t.logger, t.format, &schedulingInfo) Expect(err).NotTo(HaveOccurred()) t.client.Set(etcddb.DesiredLRPSchedulingInfoSchemaPath(guid), schedulingInfoValue, 0) Expect(err).NotTo(HaveOccurred()) runInfoValue, err := t.serializer.Marshal(t.logger, t.format, &runInfo) Expect(err).NotTo(HaveOccurred()) t.client.Set(etcddb.DesiredLRPRunInfoSchemaPath(guid), runInfoValue, 0) Expect(err).NotTo(HaveOccurred()) createdDesiredLRPs[domain] = append(createdDesiredLRPs[domain], desiredLRP) } } return createdDesiredLRPs }
func createDesiredLRPsInDomains(client bbs.InternalClient, domainCounts map[string]int) map[string][]*models.DesiredLRP { createdDesiredLRPs := map[string][]*models.DesiredLRP{} for domain, count := range domainCounts { createdDesiredLRPs[domain] = []*models.DesiredLRP{} for i := 0; i < count; i++ { guid := fmt.Sprintf("guid-%d-for-%s", i, domain) desiredLRP := model_helpers.NewValidDesiredLRP(guid) desiredLRP.Domain = domain err := client.DesireLRP(logger, desiredLRP) Expect(err).NotTo(HaveOccurred()) createdDesiredLRPs[domain] = append(createdDesiredLRPs[domain], desiredLRP) } } return createdDesiredLRPs }
etcdRunner.Start() }) It("errors", func() { _, err := etcdDB.DesiredLRPs(logger, filter) Expect(err).To(HaveOccurred()) }) }) }) Describe("DesiredLRPByProcessGuid", func() { Context("when there is a desired lrp", func() { var desiredLRP *models.DesiredLRP BeforeEach(func() { desiredLRP = model_helpers.NewValidDesiredLRP("process-guid") etcdHelper.SetRawDesiredLRP(desiredLRP) }) It("returns the desired lrp", func() { lrp, err := etcdDB.DesiredLRPByProcessGuid(logger, "process-guid") Expect(err).NotTo(HaveOccurred()) Expect(lrp).To(Equal(desiredLRP)) }) }) Context("when there is no LRP", func() { It("returns a ResourceNotFound", func() { _, err := etcdDB.DesiredLRPByProcessGuid(logger, "nota-guid") Expect(err).To(Equal(models.ErrResourceNotFound)) })
Expect(migrationErr).NotTo(HaveOccurred()) _, err := db.TaskByGuid(logger, task.TaskGuid) Expect(err).NotTo(HaveOccurred()) }) }) }) Describe("DesiredLRP Migration", func() { var ( processGuid string desiredLRP *models.DesiredLRP ) BeforeEach(func() { processGuid = "process-guid-1" desiredLRP = model_helpers.NewValidDesiredLRP(processGuid) desiredLRP.DeprecatedStartTimeoutS = 15 desiredLRP.Action = models.WrapAction(&models.TimeoutAction{Action: models.WrapAction(&models.RunAction{Path: "ls", User: "******"}), DeprecatedTimeoutNs: 4 * int64(time.Second), }) desiredLRP.Setup = models.WrapAction(&models.TimeoutAction{Action: models.WrapAction(&models.RunAction{Path: "ls", User: "******"}), DeprecatedTimeoutNs: 7 * int64(time.Second), }) desiredLRP.Monitor = models.WrapAction(models.EmitProgressFor( &models.TimeoutAction{ Action: models.WrapAction(models.Try(models.Parallel(models.Serial(&models.RunAction{Path: "ls", User: "******"})))), DeprecatedTimeoutNs: 10 * int64(time.Second), }, "start-message", "success-message",
bbsRunner = testrunner.New(bbsBinPath, bbsArgs) bbsProcess = ginkgomon.Invoke(bbsRunner) cellPresence := models.NewCellPresence( "some-cell", "cell.example.com", "the-zone", models.NewCellCapacity(128, 1024, 6), []string{}, []string{}, []string{}, []string{}, ) consulHelper.RegisterCell(&cellPresence) processGuid = "some-process-guid" err := client.DesireLRP(logger, model_helpers.NewValidDesiredLRP(processGuid)) Expect(err).NotTo(HaveOccurred()) err = client.RemoveActualLRP(logger, processGuid, 0, nil) Expect(err).NotTo(HaveOccurred()) }) It("converges the lrps", func() { Eventually(func() []*models.ActualLRPGroup { groups, err := client.ActualLRPGroupsByProcessGuid(logger, processGuid) Expect(err).NotTo(HaveOccurred()) return groups }).Should(HaveLen(1)) }) Context("when a task is desired but its cell is dead", func() { BeforeEach(func() {
Expect(response.Error).To(Equal(models.ErrUnknownError)) }) }) }) Describe("DesireDesiredLRP_r0", func() { var ( desiredLRP *models.DesiredLRP expectedDesiredLRP *models.DesiredLRP requestBody interface{} ) BeforeEach(func() { desiredLRP = model_helpers.NewValidDesiredLRP("some-guid") desiredLRP.Instances = 5 desiredLRP.StartTimeoutMs = 0 desiredLRP.DeprecatedStartTimeoutS = 15 desiredLRP.Setup = &models.Action{ TimeoutAction: &models.TimeoutAction{ Action: models.WrapAction(&models.UploadAction{ From: "web_location", To: "potato", User: "******", }), DeprecatedTimeoutNs: int64(time.Second), }, } desiredLRP.Action = &models.Action{ TimeoutAction: &models.TimeoutAction{
func (t *ETCDHelper) CreateOrphanedRunInfo(guid string, createdAt time.Time) { lrp := model_helpers.NewValidDesiredLRP(guid) _, runInfo := lrp.CreateComponents(createdAt) t.SetRawDesiredLRPRunInfo(&runInfo) }
schedulingInfo := lrp.DesiredLRPSchedulingInfo() expectedSchedulingInfos = append(expectedSchedulingInfos, &schedulingInfo) } Expect(schedulingInfos).To(ConsistOf(expectedSchedulingInfos)) }) }) }) Describe("DesireLRP", func() { var ( desiredLRP *models.DesiredLRP desireErr error ) BeforeEach(func() { desiredLRP = model_helpers.NewValidDesiredLRP("super-lrp") }) JustBeforeEach(func() { desireErr = client.DesireLRP(logger, desiredLRP) }) It("creates the desired LRP in the system", func() { Expect(desireErr).NotTo(HaveOccurred()) persistedDesiredLRP, err := client.DesiredLRPByProcessGuid(logger, "super-lrp") Expect(err).NotTo(HaveOccurred()) Expect(persistedDesiredLRP.DesiredLRPKey()).To(Equal(desiredLRP.DesiredLRPKey())) Expect(persistedDesiredLRP.DesiredLRPResource()).To(Equal(desiredLRP.DesiredLRPResource())) Expect(persistedDesiredLRP.Annotation).To(Equal(desiredLRP.Annotation)) Expect(persistedDesiredLRP.Instances).To(Equal(desiredLRP.Instances)) Expect(persistedDesiredLRP.DesiredLRPRunInfo(time.Unix(42, 0))).To(Equal(desiredLRP.DesiredLRPRunInfo(time.Unix(42, 0))))
Expect(err).NotTo(HaveOccurred()) Expect(response.Error).To(Equal(models.ErrUnknownError)) }) }) }) Describe("DesireDesiredLRP", func() { var ( desiredLRP *models.DesiredLRP requestBody interface{} ) BeforeEach(func() { desiredLRP = model_helpers.NewValidDesiredLRP("some-guid") desiredLRP.Instances = 5 requestBody = &models.DesireLRPRequest{ DesiredLrp: desiredLRP, } }) JustBeforeEach(func() { request := newTestRequest(requestBody) handler.DesireDesiredLRP(logger, responseRecorder, request) }) Context("when creating desired lrp in DB succeeds", func() { var createdActualLRPGroups []*models.ActualLRPGroup BeforeEach(func() {
func (t *ETCDHelper) CreateOrphanedSchedulingInfo(guid string, createdAt time.Time) { lrp := model_helpers.NewValidDesiredLRP(guid) schedulingInfo, _ := lrp.CreateComponents(createdAt) t.SetRawDesiredLRPSchedulingInfo(&schedulingInfo) }
"github.com/tedsuo/ifrit/ginkgomon" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Evacuation API", func() { var actual *models.ActualLRP BeforeEach(func() { bbsRunner = testrunner.New(bbsBinPath, bbsArgs) bbsProcess = ginkgomon.Invoke(bbsRunner) actual = model_helpers.NewValidActualLRP("some-process-guid", 1) actual.State = models.ActualLRPStateRunning desiredLRP := model_helpers.NewValidDesiredLRP(actual.ProcessGuid) desiredLRP.Instances = 2 Expect(client.DesireLRP(logger, desiredLRP)).To(Succeed()) Expect(client.ClaimActualLRP(logger, actual.ProcessGuid, 1, &actual.ActualLRPInstanceKey)).To(Succeed()) _, err := client.ActualLRPGroupByProcessGuidAndIndex(logger, actual.ProcessGuid, int(actual.Index)) Expect(err).NotTo(HaveOccurred()) }) Describe("RemoveEvacuatingActualLRP", func() { It("removes the evacuating actual_lrp", func() { _, err := client.EvacuateClaimedActualLRP(logger, &actual.ActualLRPKey, &actual.ActualLRPInstanceKey) Expect(err).NotTo(HaveOccurred()) err = client.RemoveEvacuatingActualLRP(logger, &actual.ActualLRPKey, &actual.ActualLRPInstanceKey) Expect(err).NotTo(HaveOccurred())
"encoding/json" "fmt" "code.cloudfoundry.org/bbs/models" "code.cloudfoundry.org/bbs/models/test/model_helpers" "code.cloudfoundry.org/bbs/test_helpers" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("DesiredLRPDB", func() { Describe("DesireLRP", func() { var expectedDesiredLRP *models.DesiredLRP BeforeEach(func() { expectedDesiredLRP = model_helpers.NewValidDesiredLRP("the-guid") }) It("saves the lrp in the database", func() { err := sqlDB.DesireLRP(logger, expectedDesiredLRP) Expect(err).NotTo(HaveOccurred()) desiredLRP, err := sqlDB.DesiredLRPByProcessGuid(logger, "the-guid") Expect(err).NotTo(HaveOccurred()) Expect(desiredLRP).To(Equal(expectedDesiredLRP)) }) Context("when the process_guid is already taken", func() { BeforeEach(func() { err := sqlDB.DesireLRP(logger, expectedDesiredLRP) Expect(err).NotTo(HaveOccurred())
Expect(response.Error).To(Equal(models.ErrResourceNotFound)) }) }) }) Describe("EvacuateClaimedActualLRP", func() { var ( request *http.Request requestBody *models.EvacuateClaimedActualLRPRequest actual *models.ActualLRP afterActual *models.ActualLRP desiredLRP *models.DesiredLRP ) BeforeEach(func() { desiredLRP = model_helpers.NewValidDesiredLRP("the-guid") fakeDesiredLRPDB.DesiredLRPByProcessGuidReturns(desiredLRP, nil) actual = model_helpers.NewValidActualLRP("process-guid", 1) requestBody = &models.EvacuateClaimedActualLRPRequest{ ActualLrpKey: &actual.ActualLRPKey, ActualLrpInstanceKey: &actual.ActualLRPInstanceKey, } afterActual = model_helpers.NewValidActualLRP("process-guid", 1) afterActual.State = models.ActualLRPStateUnclaimed fakeActualLRPDB.ActualLRPGroupByProcessGuidAndIndexReturns(&models.ActualLRPGroup{Evacuating: actual}, nil) fakeActualLRPDB.UnclaimActualLRPReturns(&models.ActualLRPGroup{Instance: actual}, &models.ActualLRPGroup{Instance: afterActual}, nil) request = newTestRequest(requestBody) })
BeforeEach(func() { server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { handler.Subscribe_r0(logger, w, r) close(eventStreamDone) })) }) Describe("Subscribe to Desired Events", func() { ItStreamsEventsFromHub(&desiredHub) It("migrates desired lrps down to v0", func() { response, err := http.Get(server.URL) Expect(err).NotTo(HaveOccurred()) reader := sse.NewReadCloser(response.Body) desiredLRP := model_helpers.NewValidDesiredLRP("guid") event := models.NewDesiredLRPCreatedEvent(desiredLRP) migratedLRP := desiredLRP.VersionDownTo(format.V0) Expect(migratedLRP).NotTo(Equal(desiredLRP)) migratedEvent := models.NewDesiredLRPCreatedEvent(migratedLRP) desiredHub.Emit(event) events := events.NewEventSource(reader) actualEvent, err := events.Next() Expect(err).NotTo(HaveOccurred()) Expect(actualEvent).To(Equal(migratedEvent)) }) })
) BeforeEach(func() { bbsRunner = testrunner.New(bbsBinPath, bbsArgs) bbsProcess = ginkgomon.Invoke(bbsRunner) }) Describe("Legacy Events", func() { JustBeforeEach(func() { var err error eventSource, err = client.SubscribeToEvents(logger) Expect(err).NotTo(HaveOccurred()) eventChannel = streamEvents(eventSource) primerLRP := model_helpers.NewValidDesiredLRP("primer-guid") primeEventStream(eventChannel, models.EventTypeDesiredLRPRemoved, func() { err := client.DesireLRP(logger, primerLRP) Expect(err).NotTo(HaveOccurred()) }, func() { err := client.RemoveDesiredLRP(logger, "primer-guid") Expect(err).NotTo(HaveOccurred()) }) }) AfterEach(func() { err := eventSource.Close() Expect(err).NotTo(HaveOccurred()) Eventually(eventChannel).Should(BeClosed()) })
}) It("returns a validation error", func() { Expect(request.Validate()).To(ConsistOf(models.ErrInvalidField{"process_guid"})) }) }) }) }) Describe("DesireLRPRequest", func() { Describe("Validate", func() { var request models.DesireLRPRequest BeforeEach(func() { request = models.DesireLRPRequest{ DesiredLrp: model_helpers.NewValidDesiredLRP("some-guid"), } }) Context("when valid", func() { It("returns nil", func() { Expect(request.Validate()).To(BeNil()) }) }) Context("when the DesiredLRP is blank", func() { BeforeEach(func() { request.DesiredLrp = nil }) It("returns a validation error", func() {
It("returns the timestamp from which it was created", func() { Expect(migration.Version()).To(BeEquivalentTo(1441411196)) }) }) Describe("Up", func() { var ( expectedDesiredLRP *models.DesiredLRP expectedActualLRP, expectedEvacuatingActualLRP *models.ActualLRP expectedTask *models.Task migrationErr error ) BeforeEach(func() { // DesiredLRP expectedDesiredLRP = model_helpers.NewValidDesiredLRP("process-guid") jsonValue, err := json.Marshal(expectedDesiredLRP) Expect(err).NotTo(HaveOccurred()) _, err = storeClient.Set(deprecations.DesiredLRPSchemaPath(expectedDesiredLRP), jsonValue, 0) Expect(err).NotTo(HaveOccurred()) // ActualLRP expectedActualLRP = model_helpers.NewValidActualLRP("process-guid", 1) jsonValue, err = json.Marshal(expectedActualLRP) Expect(err).NotTo(HaveOccurred()) _, err = storeClient.Set(etcd.ActualLRPSchemaPath(expectedActualLRP.ProcessGuid, 1), jsonValue, 0) Expect(err).NotTo(HaveOccurred()) // Evacuating ActualLRP expectedEvacuatingActualLRP = model_helpers.NewValidActualLRP("process-guid", 4) jsonValue, err = json.Marshal(expectedEvacuatingActualLRP)
func (t *ETCDHelper) CreateValidDesiredLRP(guid string) { t.SetRawDesiredLRP(model_helpers.NewValidDesiredLRP(guid)) }
desiredLRP1, desiredLRP2 models.DesiredLRPSchedulingInfo unclaimingActualLRP1 *models.ActualLRP unclaimingActualLRP2 *models.ActualLRP cellID string cellSet models.CellSet controller *controllers.LRPConvergenceController ) BeforeEach(func() { fakeLRPDB = new(dbfakes.FakeLRPDB) fakeAuctioneerClient = new(auctioneerfakes.FakeClient) logger = lagertest.NewTestLogger("test") request1 := auctioneer.NewLRPStartRequestFromModel(model_helpers.NewValidDesiredLRP("to-auction-1"), 1, 2) request2 := auctioneer.NewLRPStartRequestFromModel(model_helpers.NewValidDesiredLRP("to-auction-2"), 0, 4) retiringActualLRP1 = model_helpers.NewValidActualLRP("to-retire-1", 0) retiringActualLRP2 = model_helpers.NewValidActualLRP("to-retire-2", 1) keysToRetire = []*models.ActualLRPKey{&retiringActualLRP1.ActualLRPKey, &retiringActualLRP2.ActualLRPKey} desiredLRP1 = model_helpers.NewValidDesiredLRP("to-unclaim-1").DesiredLRPSchedulingInfo() unclaimingActualLRP1 = model_helpers.NewValidActualLRP("to-unclaim-1", 0) desiredLRP2 = model_helpers.NewValidDesiredLRP("to-unclaim-2").DesiredLRPSchedulingInfo() unclaimingActualLRP2 = model_helpers.NewValidActualLRP("to-unclaim-2", 1) keysWithMissingCells = []*models.ActualLRPKeyWithSchedulingInfo{ {Key: &unclaimingActualLRP1.ActualLRPKey, SchedulingInfo: &desiredLRP1}, {Key: &unclaimingActualLRP2.ActualLRPKey, SchedulingInfo: &desiredLRP2}, }
{CellId: "existing-cell"}, }) // This function will create the following for the given domain: // 1. a desired lrp with 2 instances and 2 stale unclaimed actual lrps // 2. a desired lrp with 1 instance and actual lrp on a missing cell // 3. a desired lrp with 1 instance and two actual lrps // 4. a desired lrp with 1 instance and no actual lrps // 5. a desired lrp with 4 instances and 2 unclaimed actual lrps // 6. a restartable desired lrp with 2 instances and 2 crashed actual lrps // 7. actual lrp with no desired lrp createConvergeableScenarios := func(domain string, evacuating bool) { var processGuid string var instanceGuid string processGuid = "desired-with-stale-actuals" + "-" + domain desiredLRPWithStaleActuals := model_helpers.NewValidDesiredLRP(processGuid) desiredLRPWithStaleActuals.Domain = domain desiredLRPWithStaleActuals.Instances = 2 err = sqlDB.DesireLRP(logger, desiredLRPWithStaleActuals) Expect(err).NotTo(HaveOccurred()) fakeClock.Increment(-models.StaleUnclaimedActualLRPDuration) _, err = sqlDB.CreateUnclaimedActualLRP(logger, &models.ActualLRPKey{ProcessGuid: processGuid, Index: 0, Domain: domain}) Expect(err).NotTo(HaveOccurred()) _, err = sqlDB.CreateUnclaimedActualLRP(logger, &models.ActualLRPKey{ProcessGuid: processGuid, Index: 1, Domain: domain}) Expect(err).NotTo(HaveOccurred()) fakeClock.Increment(models.StaleUnclaimedActualLRPDuration) queryStr := `UPDATE actual_lrps SET evacuating = ? WHERE process_guid = ?` if test_helpers.UsePostgres() { queryStr = test_helpers.ReplaceQuestionMarks(queryStr) } _, err = db.Exec(queryStr, evacuating, processGuid)