statusCodes = make(chan int) reqCount = make(chan struct{}) fakeServer.RouteToHandler("POST", "/the-callback/url", func(w http.ResponseWriter, req *http.Request) { w.WriteHeader(<-statusCodes) }) callbackURL = fakeServer.URL() + "/the-callback/url" taskDB = new(dbfakes.FakeTaskDB) taskDB.ResolvingTaskReturns(nil) taskDB.DeleteTaskReturns(nil) }) simulateTaskCompleting := func(signals <-chan os.Signal, ready chan<- struct{}) error { close(ready) task = model_helpers.NewValidTask("the-task-guid") task.CompletionCallbackUrl = callbackURL taskworkpool.HandleCompletedTask(logger, httpClient, taskDB, task) return nil } var process ifrit.Process JustBeforeEach(func() { process = ifrit.Invoke(ifrit.RunFunc(simulateTaskCompleting)) }) AfterEach(func() { ginkgomon.Kill(process) }) Context("when the task has a completion callback URL", func() {
body, err := ioutil.ReadAll(r.Body) Expect(err).NotTo(HaveOccurred()) Expect(string(body)).To(ContainSubstring(`"handle":"the-task-guid"`)) Expect(r.Body.Close()).NotTo(HaveOccurred()) close(containersCalled) }, )) fakeGarden.RouteToHandler("PUT", "/containers/the-task-guid/limits/memory", ghttp.RespondWithJSONEncoded(http.StatusOK, garden.MemoryLimits{})) fakeGarden.RouteToHandler("PUT", "/containers/the-task-guid/limits/disk", ghttp.RespondWithJSONEncoded(http.StatusOK, garden.DiskLimits{})) fakeGarden.RouteToHandler("PUT", "/containers/the-task-guid/limits/cpu", ghttp.RespondWithJSONEncoded(http.StatusOK, garden.CPULimits{})) fakeGarden.RouteToHandler("POST", "/containers/the-task-guid/net/out", ghttp.RespondWithJSONEncoded(http.StatusOK, garden.CPULimits{})) fakeGarden.RouteToHandler("GET", "/containers/the-task-guid/info", ghttp.RespondWithJSONEncoded(http.StatusOK, garden.ContainerInfo{})) taskModel := model_helpers.NewValidTask("the-task-guid") task = rep.NewTask( taskModel.TaskGuid, taskModel.Domain, rep.NewResource(taskModel.MemoryMb, taskModel.DiskMb, taskModel.RootFs), ) err := bbsClient.DesireTask(taskModel.TaskGuid, taskModel.Domain, taskModel.TaskDefinition) Expect(err).NotTo(HaveOccurred()) }) It("makes a request to executor to allocate the container", func() { Expect(getTasksByState(bbsClient, models.Task_Pending)).To(HaveLen(1)) Expect(getTasksByState(bbsClient, models.Task_Running)).To(BeEmpty()) works := rep.Work{ Tasks: []rep.Task{task},
_, 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) Expect(err).NotTo(HaveOccurred()) _, err = storeClient.Set( etcd.EvacuatingActualLRPSchemaPath(expectedEvacuatingActualLRP.ProcessGuid, 1), jsonValue, 0, ) Expect(err).NotTo(HaveOccurred()) // Tasks expectedTask = model_helpers.NewValidTask("task-guid") jsonValue, err = json.Marshal(expectedTask) Expect(err).NotTo(HaveOccurred()) _, err = storeClient.Set(etcd.TaskSchemaPath(expectedTask), jsonValue, 0) Expect(err).NotTo(HaveOccurred()) }) JustBeforeEach(func() { migration.SetStoreClient(storeClient) migration.SetCryptor(cryptor) migrationErr = migration.Up(logger) }) var validateConversionToProto = func(node *goetcd.Node, actual, expected format.Versioner) { value := node.Value
}) It("should delete it", func() { _, modelErr := etcdDB.TaskByGuid(logger, taskGuid) Expect(modelErr).To(BeEquivalentTo(models.ErrResourceNotFound)) }) It("bumps the pruned counter", func() { Expect(sender.GetCounter("ConvergenceTasksPruned")).To(Equal(uint64(1))) }) }) Context("when Tasks are pending", func() { BeforeEach(func() { expectedTasks := []*models.Task{ model_helpers.NewValidTask(taskGuid), model_helpers.NewValidTask(taskGuid2), } for _, t := range expectedTasks { t.CreatedAt = clock.Now().UnixNano() t.UpdatedAt = clock.Now().UnixNano() t.FirstCompletedAt = 0 etcdHelper.SetRawTask(t) } }) It("emits a pending metric", func() { Expect(sender.GetValue("TasksPending").Value).To(Equal(float64(2))) }) Context("when the Task has NOT been pending for too long", func() {
"github.com/cloudfoundry-incubator/bbs/models" . "github.com/cloudfoundry-incubator/bbs/models/test/matchers" "github.com/cloudfoundry-incubator/bbs/models/test/model_helpers" "github.com/tedsuo/ifrit/ginkgomon" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Task API", func() { var expectedTasks []*models.Task BeforeEach(func() { bbsRunner = testrunner.New(bbsBinPath, bbsArgs) bbsProcess = ginkgomon.Invoke(bbsRunner) expectedTasks = []*models.Task{model_helpers.NewValidTask("a-guid"), model_helpers.NewValidTask("b-guid")} expectedTasks[1].Domain = "b-domain" for _, t := range expectedTasks { err := client.DesireTask(logger, t.TaskGuid, t.Domain, t.TaskDefinition) Expect(err).NotTo(HaveOccurred()) } client.StartTask(logger, expectedTasks[1].TaskGuid, "b-cell") }) AfterEach(func() { ginkgomon.Kill(bbsProcess) }) Describe("Tasks", func() { It("has the correct number of responses", func() { actualTasks, err := client.Tasks(logger)
func (t *ETCDHelper) CreateValidTask(guid string) { t.SetRawTask(model_helpers.NewValidTask(guid)) }
}) }) }) Describe("CancelTask", func() { var ( request *http.Request cellID string ) BeforeEach(func() { requestBody = &models.TaskGuidRequest{ TaskGuid: "task-guid", } task := model_helpers.NewValidTask("hi-bob") cellID = "the-cell" fakeTaskDB.CancelTaskReturns(task, cellID, nil) request = newTestRequest(requestBody) }) JustBeforeEach(func() { handler.CancelTask(responseRecorder, request) Expect(responseRecorder.Code).To(Equal(http.StatusOK)) }) Context("when the cancel request is normal", func() { Context("when canceling the task in the db succeeds", func() { BeforeEach(func() { cellPresence := models.CellPresence{CellId: "cell-id"}
Expect(err).NotTo(HaveOccurred()) tasks := []*models.Task{} for _, task := range allTasks { if task.State == state { tasks = append(tasks, task) } } return tasks } Describe("Tasks", func() { Context("when there are tasks", func() { var expectedTasks []*models.Task BeforeEach(func() { task1 := model_helpers.NewValidTask("a-guid") task1.Domain = "domain-1" task1.CellId = "cell-1" task2 := model_helpers.NewValidTask("b-guid") task2.Domain = "domain-2" task2.CellId = "cell-2" expectedTasks = []*models.Task{task1, task2} for _, t := range expectedTasks { etcdHelper.SetRawTask(t) } }) It("returns all the tasks", func() { tasks, err := etcdDB.Tasks(logger, models.TaskFilter{}) Expect(err).NotTo(HaveOccurred())
etcddb "github.com/cloudfoundry-incubator/bbs/db/etcd" "github.com/cloudfoundry-incubator/bbs/encryption" "github.com/cloudfoundry-incubator/bbs/format" "github.com/cloudfoundry-incubator/bbs/models" "github.com/cloudfoundry-incubator/bbs/models/test/model_helpers" "github.com/tedsuo/ifrit/ginkgomon" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Encryption", func() { var task *models.Task BeforeEach(func() { task = model_helpers.NewValidTask("task-1") }) JustBeforeEach(func() { bbsRunner = testrunner.New(bbsBinPath, bbsArgs) bbsProcess = ginkgomon.Invoke(bbsRunner) }) AfterEach(func() { ginkgomon.Kill(bbsProcess) }) Describe("read-write encrypted data", func() { JustBeforeEach(func() { err := client.DesireTask(task.TaskGuid, task.Domain, task.TaskDefinition) Expect(err).NotTo(HaveOccurred())
func NewTask(taskGuid, cellID string, taskState models.Task_State) *models.Task { task := model_helpers.NewValidTask(taskGuid) task.CellId = cellID task.State = taskState return task }
AfterEach(func() { ginkgomon.Kill(bbsProcess) ginkgomon.Kill(convergerProcess) consulRunner.Stop() etcdRunner.Stop() }) startConverger := func() { runner = convergerrunner.New(convergerConfig) convergerProcess = ginkgomon.Invoke(runner) time.Sleep(convergeRepeatInterval) } createRunningTaskWithDeadCell := func() { task := model_helpers.NewValidTask("task-guid") err := bbsClient.DesireTask(task.TaskGuid, task.Domain, task.TaskDefinition) Expect(err).NotTo(HaveOccurred()) _, err = bbsClient.StartTask(task.TaskGuid, "dead-cell") Expect(err).NotTo(HaveOccurred()) } itIsInactive := func() { Describe("when a task is desired but its cell is dead", func() { JustBeforeEach(createRunningTaskWithDeadCell) It("does not converge the task", func() { Consistently(func() []*models.Task { return getTasksByState(bbsClient, models.Task_Completed)
"github.com/gogo/protobuf/proto" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/pivotal-golang/lager/lagertest" ) var _ = Describe("Envelope", func() { var logger *lagertest.TestLogger BeforeEach(func() { logger = lagertest.NewTestLogger("test") }) Describe("Marshal", func() { It("can successfully marshal a model object envelope", func() { task := model_helpers.NewValidTask("some-guid") encoded, err := format.MarshalEnvelope(format.PROTO, task) Expect(err).NotTo(HaveOccurred()) Expect(format.EnvelopeFormat(encoded[0])).To(Equal(format.PROTO)) Expect(format.Version(encoded[1])).To(Equal(format.V0)) var newTask models.Task modelErr := proto.Unmarshal(encoded[2:], &newTask) Expect(modelErr).To(BeNil()) Expect(*task).To(Equal(newTask)) }) It("returns an error when marshalling when the envelope doesn't support the model", func() { model := &fakes.FakeVersioner{}
Expect(actualLRPs).To(ConsistOf(existingActualLRPs)) }) }) Describe("Tasks", func() { var ( existingTasks []migrations.ETCDToSQLTask tasksToCreate int ) BeforeEach(func() { tasksToCreate = 3 for i := 0; i < tasksToCreate; i++ { taskGuid := fmt.Sprintf("task-guid-%d", i) task := model_helpers.NewValidTask(taskGuid) taskData, err := serializer.Marshal(logger, format.ENCRYPTED_PROTO, task) Expect(err).NotTo(HaveOccurred()) _, err = storeClient.Set(etcddb.TaskSchemaPath(task), taskData, 0) Expect(err).NotTo(HaveOccurred()) encoder := format.NewEncoder(cryptor) encryptedDefinition, err := serializer.Marshal(logger, format.ENCRYPTED_PROTO, task.TaskDefinition) Expect(err).NotTo(HaveOccurred()) definitionData, err := encoder.Decode(encryptedDefinition) Expect(err).NotTo(HaveOccurred()) existingTasks = append(existingTasks, migrations.ETCDToSQLTask{ TaskGuid: task.TaskGuid, Domain: task.Domain,