Beispiel #1
0
			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() {
Beispiel #2
0
							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() {
Beispiel #5
0
	"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)
Beispiel #6
0
func (t *ETCDHelper) CreateValidTask(guid string) {
	t.SetRawTask(model_helpers.NewValidTask(guid))
}
Beispiel #7
0
			})
		})
	})

	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"}
Beispiel #8
0
		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())
Beispiel #9
0
	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())
Beispiel #10
0
func NewTask(taskGuid, cellID string, taskState models.Task_State) *models.Task {
	task := model_helpers.NewValidTask(taskGuid)
	task.CellId = cellID
	task.State = taskState
	return task
}
Beispiel #11
0
	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)
Beispiel #12
0
	"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,