예제 #1
0
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
}
예제 #2
0
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
}
예제 #3
0
				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",
예제 #5
0
			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{
예제 #7
0
func (t *ETCDHelper) CreateOrphanedRunInfo(guid string, createdAt time.Time) {
	lrp := model_helpers.NewValidDesiredLRP(guid)
	_, runInfo := lrp.CreateComponents(createdAt)

	t.SetRawDesiredLRPRunInfo(&runInfo)
}
예제 #8
0
					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))))
예제 #9
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() {
예제 #10
0
func (t *ETCDHelper) CreateOrphanedSchedulingInfo(guid string, createdAt time.Time) {
	lrp := model_helpers.NewValidDesiredLRP(guid)
	schedulingInfo, _ := lrp.CreateComponents(createdAt)

	t.SetRawDesiredLRPSchedulingInfo(&schedulingInfo)
}
예제 #11
0
	"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())
예제 #12
0
	"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())
예제 #13
0
				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)
		})
예제 #14
0
		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))
			})
		})
예제 #15
0
	)

	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())
		})
예제 #16
0
				})

				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)
예제 #18
0
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},
		}
예제 #20
0
			{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)