"code.cloudfoundry.org/bbs/format" "code.cloudfoundry.org/bbs/models" "code.cloudfoundry.org/bbs/models/test/model_helpers" ) var _ = Describe("Format", func() { var ( serializer format.Serializer cryptor *encryptionfakes.FakeCryptor encoder format.Encoder logger lager.Logger task *models.Task ) BeforeEach(func() { task = model_helpers.NewValidTask("a-guid") logger = lagertest.NewTestLogger("test") cryptor = &encryptionfakes.FakeCryptor{} cryptor.EncryptStub = func(plaintext []byte) (encryption.Encrypted, error) { nonce := [12]byte{} return encryption.Encrypted{ KeyLabel: "label", Nonce: nonce[:], CipherText: plaintext, }, nil } cryptor.DecryptStub = func(ciphered encryption.Encrypted) ([]byte, error) { return ciphered.CipherText, nil } encoder = format.NewEncoder(cryptor) serializer = format.NewSerializer(cryptor)
"code.cloudfoundry.org/lager/lagertest" "github.com/gogo/protobuf/proto" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) 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)) 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 := &formatfakes.FakeVersioner{} _, err := format.MarshalEnvelope(format.PROTO, model)
_, 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
Expect(err).To(MatchError("kaboom")) }) }) }) }) Describe("CancelTask", func() { var ( taskGuid, cellID string err error ) BeforeEach(func() { taskGuid = "task-guid" cellID = "the-cell" task := model_helpers.NewValidTask("hi-bob") fakeTaskDB.CancelTaskReturns(task, cellID, nil) }) JustBeforeEach(func() { err = controller.CancelTask(logger, taskGuid) }) 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"} fakeServiceClient.CellByIdReturns(&cellPresence, nil) }) It("returns no error", func() {
var _ = Describe("TaskDB", func() { Describe("DesireTask", func() { var ( errDesire error task *models.Task taskDef *models.TaskDefinition taskGuid, taskDomain string ) JustBeforeEach(func() { errDesire = sqlDB.DesireTask(logger, taskDef, taskGuid, taskDomain) }) BeforeEach(func() { taskGuid = "the-task-guid" task = model_helpers.NewValidTask(taskGuid) taskDomain = task.Domain taskDef = task.TaskDefinition }) Context("when a task is not already present at the desired key", func() { It("persists the task", func() { Expect(errDesire).NotTo(HaveOccurred()) queryStr := "SELECT * FROM tasks WHERE guid = ?" if test_helpers.UsePostgres() { queryStr = test_helpers.ReplaceQuestionMarks(queryStr) } rows, err := db.Query(queryStr, taskGuid) Expect(err).NotTo(HaveOccurred()) defer rows.Close()
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() { task := model_helpers.NewValidTask("task-guid") err := client.DesireTask(logger, task.TaskGuid, task.Domain, task.TaskDefinition) Expect(err).NotTo(HaveOccurred()) _, err = client.StartTask(logger, task.TaskGuid, "dead-cell") Expect(err).NotTo(HaveOccurred()) }) It("marks the task as completed and failed", func() { Eventually(func() []*models.Task { return getTasksByState(client, models.Task_Completed) }).Should(HaveLen(1)) Expect(getTasksByState(client, models.Task_Completed)[0].Failed).To(BeTrue()) })
Describe("Down", func() { It("returns a not implemented error", func() { Expect(migration.Down(logger)).To(HaveOccurred()) }) }) Describe("Up", func() { var ( task *models.Task migrationErr error ) Describe("Task Migration", func() { BeforeEach(func() { task = model_helpers.NewValidTask("task-guid-1") task.Action = models.WrapAction(&models.TimeoutAction{Action: model_helpers.NewValidAction(), DeprecatedTimeoutNs: 5 * int64(time.Second), }) }) JustBeforeEach(func() { 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()) migration.SetStoreClient(storeClient) migration.SetCryptor(cryptor) migration.SetClock(fakeClock) migrationErr = migration.Up(logger)
etcdHelper.CreateMalformedTask(taskGuid) }) 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 a Task is invalid", func() { BeforeEach(func() { task := model_helpers.NewValidTask(taskGuid) task.Domain = "" etcdHelper.SetRawTask(task) }) 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() {
func (t *ETCDHelper) CreateValidTask(guid string) { t.SetRawTask(model_helpers.NewValidTask(guid)) }
httpClient = cfhttp.NewClient() statusCodes = make(chan int) 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() {
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())
"code.cloudfoundry.org/bbs/models" . "code.cloudfoundry.org/bbs/models/test/matchers" "code.cloudfoundry.org/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)