[autotest] Abort special tasks through AFE.
On View Host page, after checking the show special tasks checkbox,
the job table becomes a mixing of special tasks and regular jobs.
But only regular jobs are able to be aborted before.
I made the special tasks selectable as well and made the Abort action
apply to both regular and special tasks.
On the GWT side, the selected entries will be divided into special tasks
and regular jobs. Two rpc calls will be made separately to abort them.
BUG=chromium:290476
TEST=ran afe, abort regular jobs and special tasks separately and together
DEPLOY=afe,apache
Change-Id: I0a861552e67602a9f9a5f6ee096104b745e9fc5f
Reviewed-on: https://chromium-review.googlesource.com/206068
Tested-by: Jiaxi Luo <jiaxiluo@chromium.org>
Reviewed-by: Simran Basi <sbasi@chromium.org>
Commit-Queue: Jiaxi Luo <jiaxiluo@chromium.org>
diff --git a/frontend/afe/rpc_utils.py b/frontend/afe/rpc_utils.py
index 4433836..6cb369b 100644
--- a/frontend/afe/rpc_utils.py
+++ b/frontend/afe/rpc_utils.py
@@ -644,7 +644,8 @@
execution_path=entry.execution_path(),
status=entry.status,
started_on=entry.started_on,
- id=str(entry.id) + type)
+ id=str(entry.id) + type,
+ oid=entry.id)
def _special_task_to_dict(special_task):
diff --git a/frontend/client/src/autotest/afe/AfeUtils.java b/frontend/client/src/autotest/afe/AfeUtils.java
index a7a0183..3890c77 100644
--- a/frontend/client/src/autotest/afe/AfeUtils.java
+++ b/frontend/client/src/autotest/afe/AfeUtils.java
@@ -124,6 +124,7 @@
JSONObject job = entry.get("job").isObject();
int synchCount = (int) job.get("synch_count").isNumber().doubleValue();
boolean hasExecutionSubdir =
+ entry.containsKey("execution_subdir") &&
!Utils.jsonToString(entry.get("execution_subdir")).equals("");
if (synchCount > 1 && hasExecutionSubdir) {
synchronousEntries.add(entry);
@@ -135,7 +136,10 @@
// metahost row
extendJsonArray(asynchronousEntryIds, idListValue.isArray());
} else {
- asynchronousEntryIds.set(asynchronousEntryIds.size(), entry.get("id"));
+ JSONValue id = entry.get("id");
+ if (entry.containsKey("oid"))
+ id = entry.get("oid");
+ asynchronousEntryIds.set(asynchronousEntryIds.size(), id);
}
}
@@ -156,6 +160,24 @@
}
}
+ public static void abortSpecialTasks(final JSONArray specialTaskIds,
+ final SimpleCallback onSuccess) {
+ if (specialTaskIds.size() == 0) {
+ NotifyManager.getInstance().showError("No entries selected to abort");
+ return;
+ }
+
+ SimpleCallback abortSpecialTasks = new SimpleCallback() {
+ public void doCallback(Object source) {
+ JSONObject params = new JSONObject();
+ params.put("id__in", specialTaskIds);
+ AfeUtils.callAbortSpecialTasks(params, onSuccess);
+ }
+ };
+
+ abortSpecialTasks.doCallback(null);
+ }
+
private static void extendJsonArray(JSONArray array, JSONArray newValues) {
for (JSONValue value : new JSONArrayList<JSONValue>(newValues)) {
array.set(array.size(), value);
@@ -182,6 +204,26 @@
callAbort(params, onSuccess, true);
}
+ public static void callAbortSpecialTasks(JSONObject params, final SimpleCallback onSuccess,
+ final boolean showMessage) {
+ JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
+ rpcProxy.rpcCall("abort_special_tasks", params, new JsonRpcCallback() {
+ @Override
+ public void onSuccess(JSONValue result) {
+ if (showMessage) {
+ NotifyManager.getInstance().showMessage("Special tasks aborted");
+ }
+ if (onSuccess != null) {
+ onSuccess.doCallback(null);
+ }
+ }
+ });
+ }
+
+ public static void callAbortSpecialTasks(JSONObject params, final SimpleCallback onSuccess) {
+ callAbortSpecialTasks(params, onSuccess, true);
+ }
+
public static void callReverify(JSONObject params, final SimpleCallback onSuccess,
final String messagePrefix) {
JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
diff --git a/frontend/client/src/autotest/afe/HostDetailView.java b/frontend/client/src/autotest/afe/HostDetailView.java
index efd9a03..972c7af 100644
--- a/frontend/client/src/autotest/afe/HostDetailView.java
+++ b/frontend/client/src/autotest/afe/HostDetailView.java
@@ -11,9 +11,9 @@
import autotest.common.table.DataTable;
import autotest.common.table.DynamicTable;
import autotest.common.table.DynamicTable.DynamicTableListener;
+import autotest.common.table.JSONObjectSet;
import autotest.common.table.RpcDataSource;
import autotest.common.table.SelectionManager;
-import autotest.common.table.SelectionManager.SelectableRowFilter;
import autotest.common.table.SimpleFilter;
import autotest.common.table.TableDecorator;
import autotest.common.ui.ContextMenu;
@@ -38,9 +38,9 @@
import java.util.List;
import java.util.Map;
+import java.util.Set;
-public class HostDetailView extends DetailView
- implements DataCallback, TableActionsListener, SelectableRowFilter {
+public class HostDetailView extends DetailView implements DataCallback, TableActionsListener {
private static final String[][] HOST_JOBS_COLUMNS = {
{DataTable.WIDGET_COLUMN, ""}, {"type", "Type"}, {"job__id", "Job ID"},
{"job_owner", "Job Owner"}, {"job_name", "Job Name"}, {"started_on", "Time started"},
@@ -302,7 +302,6 @@
});
tableDecorator.addPaginators();
selectionManager = tableDecorator.addSelectionManager(false);
- selectionManager.setSelectableRowFilter(this);
jobsTable.setWidgetFactory(selectionManager);
tableDecorator.addTableActionsPanel(this, true);
tableDecorator.addControl("Show verifies, repairs, cleanups and resets",
@@ -311,6 +310,7 @@
showSpecialTasks.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
+ selectionManager.deselectAll();
jobsTable.setSpecialTasksEnabled(showSpecialTasks.getValue());
jobsTable.refresh();
}
@@ -368,20 +368,39 @@
public ContextMenu getActionMenu() {
ContextMenu menu = new ContextMenu();
- menu.addItem("Abort job entries", new Command() {
+ menu.addItem("Abort", new Command() {
public void execute() {
- abortSelectedQueueEntries();
+ abortSelectedQueueEntriesAndSpecialTasks();
}
});
return menu;
}
- private void abortSelectedQueueEntries() {
- AfeUtils.abortHostQueueEntries(selectionManager.getSelectedObjects(), new SimpleCallback() {
- public void doCallback(Object source) {
- refresh();
- }
- });
+ private void abortSelectedQueueEntriesAndSpecialTasks() {
+ Set<JSONObject> selectedEntries = selectionManager.getSelectedObjects();
+ Set<JSONObject> selectedQueueEntries = new JSONObjectSet<JSONObject>();
+ JSONArray selectedSpecialTaskIds = new JSONArray();
+ for (JSONObject entry : selectedEntries) {
+ if (isJobRow(entry))
+ selectedQueueEntries.add(entry);
+ else
+ selectedSpecialTaskIds.set(selectedSpecialTaskIds.size(),
+ entry.get("oid"));
+ }
+ if (!selectedQueueEntries.isEmpty()) {
+ AfeUtils.abortHostQueueEntries(selectedQueueEntries, new SimpleCallback() {
+ public void doCallback(Object source) {
+ refresh();
+ }
+ });
+ }
+ if (selectedSpecialTaskIds.size() > 0) {
+ AfeUtils.abortSpecialTasks(selectedSpecialTaskIds, new SimpleCallback() {
+ public void doCallback(Object source) {
+ refresh();
+ }
+ });
+ }
}
private void updateLockButton() {