func TestTaskAbortion(t *testing.T) { setupTlsConfigs(t) testutil.ConfigureIntegrationTest(t, testConfig, "TestTaskAbortion") for tlsString, tlsConfig := range tlsConfigs { for _, testSetup := range testSetups { Convey(testSetup.testSpec, t, func() { Convey("With agent running a slow test and live API server over "+tlsString, func() { testTask, _, err := setupAPITestData(testConfig, "very_slow_task", "linux-64", filepath.Join(testDirectory, "testdata/config_test_plugin/project/evergreen-ci-render.yml"), NoPatch, t) testutil.HandleTestingErr(err, t, "Failed to find test task") testServer, err := service.CreateTestServer(testConfig, tlsConfig, plugin.APIPlugins, Verbose) testutil.HandleTestingErr(err, t, "Couldn't create apiserver: %v", err) testAgent, err := createAgent(testServer, testTask) testutil.HandleTestingErr(err, t, "failed to create agent: %v") Convey("when the abort signal is triggered on the task", func() { go func() { // Wait for a few seconds, then switch the task to aborted! time.Sleep(3 * time.Second) err := model.AbortTask(testTask.Id, "") testutil.HandleTestingErr(err, t, "Failed to abort test task") fmt.Println("aborted task.") }() // actually run the task. // this function won't return until the whole thing is done. _, err := testAgent.RunTask() So(err, ShouldBeNil) testAgent.APILogger.Flush() time.Sleep(1 * time.Second) printLogsForTask(testTask.Id) Convey("the pre and post-run scripts should have run", func() { So(scanLogsForTask(testTask.Id, "", "executing the pre-run script"), ShouldBeTrue) So(scanLogsForTask(testTask.Id, "", "executing the post-run script!"), ShouldBeTrue) So(scanLogsForTask(testTask.Id, "", "Received abort signal - stopping."), ShouldBeTrue) So(scanLogsForTask(testTask.Id, "", "done with very_slow_task!"), ShouldBeFalse) testTask, err = task.FindOne(task.ById(testTask.Id)) testutil.HandleTestingErr(err, t, "Failed to find test task") So(testTask.Status, ShouldEqual, evergreen.TaskUndispatched) }) }) }) }) } } }
// avoids type-checking json params for the below function func (uis *UIServer) taskModify(w http.ResponseWriter, r *http.Request) { projCtx := MustHaveProjectContext(r) if projCtx.Task == nil { http.Error(w, "Not Found", http.StatusNotFound) return } reqBody, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer r.Body.Close() putParams := struct { Action string `json:"action"` Priority string `json:"priority"` // for the set_active option Active bool `json:"active"` }{} err = json.Unmarshal(reqBody, &putParams) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } authUser := GetUser(r) authName := authUser.DisplayName() // determine what action needs to be taken switch putParams.Action { case "restart": if err := model.TryResetTask(projCtx.Task.Id, authName, evergreen.UIPackage, projCtx.Project, nil); err != nil { http.Error(w, fmt.Sprintf("Error restarting task %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } // Reload the task from db, send it back projCtx.Task, err = task.FindOne(task.ById(projCtx.Task.Id)) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, err) } uis.WriteJSON(w, http.StatusOK, projCtx.Task) return case "abort": if err := model.AbortTask(projCtx.Task.Id, authName, true); err != nil { http.Error(w, fmt.Sprintf("Error aborting task %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } // Reload the task from db, send it back projCtx.Task, err = task.FindOne(task.ById(projCtx.Task.Id)) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, err) } uis.WriteJSON(w, http.StatusOK, projCtx.Task) return case "set_active": active := putParams.Active if err := model.SetActiveState(projCtx.Task.Id, authName, active); err != nil { http.Error(w, fmt.Sprintf("Error activating task %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } // Reload the task from db, send it back projCtx.Task, err = task.FindOne(task.ById(projCtx.Task.Id)) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, err) } uis.WriteJSON(w, http.StatusOK, projCtx.Task) return case "set_priority": priority, err := strconv.ParseInt(putParams.Priority, 10, 64) if err != nil { http.Error(w, "Bad priority value, must be int", http.StatusBadRequest) return } if err = projCtx.Task.SetPriority(priority); err != nil { http.Error(w, fmt.Sprintf("Error setting task priority %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } // Reload the task from db, send it back projCtx.Task, err = task.FindOne(task.ById(projCtx.Task.Id)) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, err) } uis.WriteJSON(w, http.StatusOK, projCtx.Task) return default: uis.WriteJSON(w, http.StatusBadRequest, "Unrecognized action: "+putParams.Action) } }