// getTaskQueueSize returns a JSON response with a SUCCESS flag if all task queues have a size // less than the size indicated. If a distro's task queue has size greater than or equal to the size given, // there will be an ERROR flag along with a map of the distro name to the size of the task queue. // If the size is 0 or the size is not sent, the JSON response will be SUCCESS with a list of all distros and their // task queue sizes. func (as *APIServer) checkTaskQueueSize(w http.ResponseWriter, r *http.Request) { size, err := util.GetIntValue(r, "size", 0) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } distro := r.FormValue("distro") distroNames := make(map[string]int) status := "SUCCESS" if distro != "" { taskQueue, err := model.FindTaskQueueForDistro(distro) if err != nil { as.LoggedError(w, r, http.StatusBadRequest, err) return } if taskQueue.Length() >= size { distroNames[distro] = taskQueue.Length() status = "ERROR" } } else { taskQueues, err := model.FindAllTaskQueues() if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } for _, queue := range taskQueues { if queue.Length() >= size { distroNames[queue.Distro] = queue.Length() status = "ERROR" } } } growthResponse := struct { Status string Distros map[string]int }{status, distroNames} as.WriteJSON(w, http.StatusOK, growthResponse) }
// getNextDistroTask fetches the next task to run for the given distro and marks // the task as dispatched in the given host's document func getNextDistroTask(currentTask *model.Task, host *host.Host) ( nextTask *model.Task, err error) { taskQueue, err := model.FindTaskQueueForDistro(currentTask.DistroId) if err != nil { return nil, fmt.Errorf("Error locating distro queue (%v) for task "+ "'%v': %v", currentTask.DistroId, currentTask.Id, err) } if taskQueue == nil { return nil, fmt.Errorf("Nil task queue found for task '%v's distro "+ "queue - '%v'", currentTask.Id, currentTask.DistroId) } // dispatch the next task for this host nextTask, err = taskrunner.DispatchTaskForHost(taskQueue, host) if err != nil { return nil, fmt.Errorf("Error dequeuing task for host %v: %v", host.Id, err) } if nextTask == nil { return nil, nil } return nextTask, nil }
func TestDBTaskQueuePersister(t *testing.T) { var taskQueuePersister *DBTaskQueuePersister var distroIds []string var displayNames []string var buildVariants []string var RevisionOrderNumbers []int var requesters []string var gitspecs []string var projects []string var taskIds []string var durations []time.Duration var tasks []task.Task Convey("With a DBTaskQueuePersister", t, func() { taskQueuePersister = &DBTaskQueuePersister{} distroIds = []string{"d1", "d2"} taskIds = []string{"t1", "t2", "t3", "t4", "t5"} displayNames = []string{"dn1", "dn2", "dn3", "dn4", "dn5"} buildVariants = []string{"bv1", "bv2", "bv3", "bv4", "bv5"} RevisionOrderNumbers = []int{0, 1, 2, 3, 4} requesters = []string{"r1", "r2", "r3", "r4", "r5"} gitspecs = []string{"g1", "g2", "g3", "g4", "g5"} projects = []string{"p1", "p2", "p3", "p4", "p5"} durations = []time.Duration{ time.Duration(1) * time.Minute, time.Duration(2) * time.Minute, time.Duration(3) * time.Minute, time.Duration(4) * time.Minute, } tasks = []task.Task{ { Id: taskIds[0], DisplayName: displayNames[0], BuildVariant: buildVariants[0], RevisionOrderNumber: RevisionOrderNumbers[0], Requester: requesters[0], Revision: gitspecs[0], Project: projects[0], }, { Id: taskIds[1], DisplayName: displayNames[1], BuildVariant: buildVariants[1], RevisionOrderNumber: RevisionOrderNumbers[1], Requester: requesters[1], Revision: gitspecs[1], Project: projects[1], }, { Id: taskIds[2], DisplayName: displayNames[2], BuildVariant: buildVariants[2], RevisionOrderNumber: RevisionOrderNumbers[2], Requester: requesters[2], Revision: gitspecs[2], Project: projects[2], }, { Id: taskIds[3], DisplayName: displayNames[3], BuildVariant: buildVariants[3], RevisionOrderNumber: RevisionOrderNumbers[3], Requester: requesters[3], Revision: gitspecs[3], Project: projects[3], }, { Id: taskIds[4], DisplayName: displayNames[4], BuildVariant: buildVariants[4], RevisionOrderNumber: RevisionOrderNumbers[4], Requester: requesters[4], Revision: gitspecs[4], Project: projects[4], }, } durationMappings := model.ProjectTaskDurations{ map[string]*model.BuildVariantTaskDurations{ projects[0]: { map[string]*model.TaskDurations{ buildVariants[0]: { map[string]time.Duration{ displayNames[0]: durations[0], }, }, }, }, projects[1]: { map[string]*model.TaskDurations{ buildVariants[1]: { map[string]time.Duration{ displayNames[1]: durations[1], }, }, }, }, projects[2]: { map[string]*model.TaskDurations{ buildVariants[2]: { map[string]time.Duration{ displayNames[2]: durations[2], }, }, }, }, projects[3]: { map[string]*model.TaskDurations{ buildVariants[3]: { map[string]time.Duration{ displayNames[3]: durations[3], }, }, }, }, }, } So(db.Clear(model.TaskQueuesCollection), ShouldBeNil) Convey("saving task queues should place them in the database with the "+ "correct ordering of tasks along with the relevant average task "+ "completion times", func() { _, err := taskQueuePersister.PersistTaskQueue(distroIds[0], []task.Task{tasks[0], tasks[1], tasks[2]}, durationMappings) So(err, ShouldBeNil) _, err = taskQueuePersister.PersistTaskQueue(distroIds[1], []task.Task{tasks[3], tasks[4]}, durationMappings) So(err, ShouldBeNil) taskQueue, err := model.FindTaskQueueForDistro(distroIds[0]) So(err, ShouldBeNil) So(len(taskQueue.Queue), ShouldEqual, 3) So(taskQueue.Queue[0].Id, ShouldEqual, taskIds[0]) So(taskQueue.Queue[0].DisplayName, ShouldEqual, tasks[0].DisplayName) So(taskQueue.Queue[0].BuildVariant, ShouldEqual, tasks[0].BuildVariant) So(taskQueue.Queue[0].RevisionOrderNumber, ShouldEqual, tasks[0].RevisionOrderNumber) So(taskQueue.Queue[0].Requester, ShouldEqual, tasks[0].Requester) So(taskQueue.Queue[0].Revision, ShouldEqual, tasks[0].Revision) So(taskQueue.Queue[0].Project, ShouldEqual, tasks[0].Project) So(taskQueue.Queue[0].ExpectedDuration, ShouldEqual, durations[0]) So(taskQueue.Queue[1].Id, ShouldEqual, taskIds[1]) So(taskQueue.Queue[1].DisplayName, ShouldEqual, tasks[1].DisplayName) So(taskQueue.Queue[1].BuildVariant, ShouldEqual, tasks[1].BuildVariant) So(taskQueue.Queue[1].RevisionOrderNumber, ShouldEqual, tasks[1].RevisionOrderNumber) So(taskQueue.Queue[1].Requester, ShouldEqual, tasks[1].Requester) So(taskQueue.Queue[1].Revision, ShouldEqual, tasks[1].Revision) So(taskQueue.Queue[1].Project, ShouldEqual, tasks[1].Project) So(taskQueue.Queue[1].ExpectedDuration, ShouldEqual, durations[1]) So(taskQueue.Queue[2].Id, ShouldEqual, taskIds[2]) So(taskQueue.Queue[2].DisplayName, ShouldEqual, tasks[2].DisplayName) So(taskQueue.Queue[2].BuildVariant, ShouldEqual, tasks[2].BuildVariant) So(taskQueue.Queue[2].RevisionOrderNumber, ShouldEqual, tasks[2].RevisionOrderNumber) So(taskQueue.Queue[2].Requester, ShouldEqual, tasks[2].Requester) So(taskQueue.Queue[2].Revision, ShouldEqual, tasks[2].Revision) So(taskQueue.Queue[2].Project, ShouldEqual, tasks[2].Project) So(taskQueue.Queue[2].ExpectedDuration, ShouldEqual, durations[2]) taskQueue, err = model.FindTaskQueueForDistro(distroIds[1]) So(err, ShouldBeNil) So(len(taskQueue.Queue), ShouldEqual, 2) So(taskQueue.Queue[0].Id, ShouldEqual, taskIds[3]) So(taskQueue.Queue[0].DisplayName, ShouldEqual, tasks[3].DisplayName) So(taskQueue.Queue[0].BuildVariant, ShouldEqual, tasks[3].BuildVariant) So(taskQueue.Queue[0].RevisionOrderNumber, ShouldEqual, tasks[3].RevisionOrderNumber) So(taskQueue.Queue[0].Requester, ShouldEqual, tasks[3].Requester) So(taskQueue.Queue[0].Revision, ShouldEqual, tasks[3].Revision) So(taskQueue.Queue[0].Project, ShouldEqual, tasks[3].Project) So(taskQueue.Queue[0].ExpectedDuration, ShouldEqual, durations[3]) So(taskQueue.Queue[1].Id, ShouldEqual, taskIds[4]) So(taskQueue.Queue[1].DisplayName, ShouldEqual, tasks[4].DisplayName) So(taskQueue.Queue[1].BuildVariant, ShouldEqual, tasks[4].BuildVariant) So(taskQueue.Queue[1].RevisionOrderNumber, ShouldEqual, tasks[4].RevisionOrderNumber) So(taskQueue.Queue[1].Requester, ShouldEqual, tasks[4].Requester) So(taskQueue.Queue[1].Revision, ShouldEqual, tasks[4].Revision) So(taskQueue.Queue[1].Project, ShouldEqual, tasks[4].Project) So(taskQueue.Queue[1].ExpectedDuration, ShouldEqual, model.DefaultTaskDuration) }) }) }
// Finds the task queue for the specified distro, by fetching the appropriate // task queue document from the database func (self *DBTaskQueueFinder) FindTaskQueue(distroId string) (*model.TaskQueue, error) { return model.FindTaskQueueForDistro(distroId) }