Add new DUT Manage page to make it easier to add/remove/label DUT's
BUG=chromium:653727
TEST=local
Change-Id: Id554af22b672ecd1bb9f8eeb89bf9b0a4206a7a0
Reviewed-on: https://chromium-review.googlesource.com/396463
Commit-Ready: Keith Haddow <haddowk@chromium.org>
Tested-by: Keith Haddow <haddowk@chromium.org>
Reviewed-by: Keith Haddow <haddowk@chromium.org>
Reviewed-by: Michael Tang <ntang@chromium.org>
(cherry picked from commit 63cc4470e13cf7dab9edb7e18c0c39e9cd65ba47)
Reviewed-on: https://chromium-review.googlesource.com/399138
Commit-Queue: Keith Haddow <haddowk@chromium.org>
diff --git a/frontend/afe/moblab_rpc_interface.py b/frontend/afe/moblab_rpc_interface.py
index 22e6fef..f0ec8e3 100644
--- a/frontend/afe/moblab_rpc_interface.py
+++ b/frontend/afe/moblab_rpc_interface.py
@@ -18,17 +18,19 @@
import ConfigParser
import logging
import os
+import re
import shutil
import socket
-import re
-
+import subprocess
import common
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import global_config
+from autotest_lib.frontend.afe import models, model_logic, model_attributes
from autotest_lib.frontend.afe import rpc_utils
from autotest_lib.server.hosts import moblab_host
+
_CONFIG = global_config.global_config
MOBLAB_BOTO_LOCATION = '/home/moblab/.boto'
@@ -45,6 +47,11 @@
_RESULT_STORAGE_SERVER = 'results_storage_server'
_USE_EXISTING_BOTO_FILE = 'use_existing_boto_file'
+# Location where dhcp leases are stored.
+_DHCPD_LEASES = '/var/lib/dhcp/dhcpd.leases'
+
+# File where information about the current device is stored.
+_ETC_LSB_RELEASE = '/etc/lsb-release'
@rpc_utils.moblab_only
def get_config_values():
@@ -456,10 +463,106 @@
@rpc_utils.moblab_only
def get_version_info():
""" RPC handler to get informaiton about the version of the moblab.
+
@return: A serialized JSON RPC object.
"""
- lines = open('/etc/lsb-release').readlines()
- lines.remove('')
- version_response = {x.split('=')[0]: x.split('=')[1] for x in lines}
+ lines = open(_ETC_LSB_RELEASE).readlines()
+ version_response = {
+ x.split('=')[0]: x.split('=')[1] for x in lines if '=' in x}
return rpc_utils.prepare_for_serialization(version_response)
+
+@rpc_utils.moblab_only
+def get_connected_dut_info():
+ """ RPC handler to get informaiton about the DUTs connected to the moblab.
+
+ @return: A serialized JSON RPC object.
+ """
+ # Make a list of the connected DUT's
+ leases = _get_dhcp_dut_leases()
+
+ # Get a list of the AFE configured DUT's
+ hosts = list(rpc_utils.get_host_query((), False, False, True, {}))
+ models.Host.objects.populate_relationships(hosts, models.Label,
+ 'label_list')
+ configured_duts = {}
+ for host in hosts:
+ labels = [label.name for label in host.label_list]
+ labels.sort()
+ configured_duts[host.hostname] = ', '.join(labels)
+
+ return rpc_utils.prepare_for_serialization(
+ {'configured_duts': configured_duts,
+ 'connected_duts': leases})
+
+
+def _get_dhcp_dut_leases():
+ """ Extract information about connected duts from the dhcp server.
+
+ @return: A dict of ipaddress to mac address for each device connected.
+ """
+ lease_info = open(_DHCPD_LEASES).read()
+
+ leases = {}
+ for lease in lease_info.split('lease'):
+ if lease.find('binding state active;') != -1:
+ ipaddress = lease.split('\n')[0].strip(' {')
+ last_octet = int(ipaddress.split('.')[-1].strip())
+ if last_octet > 150:
+ continue
+ mac_address_search = re.search('hardware ethernet (.*);', lease)
+ if mac_address_search:
+ leases[ipaddress] = mac_address_search.group(1)
+ return leases
+
+
+@rpc_utils.moblab_only
+def add_moblab_dut(ipaddress):
+ """ RPC handler to add a connected DUT to autotest.
+
+ @return: A string giving information about the status.
+ """
+ cmd = '/usr/local/autotest/cli/atest host create %s &' % ipaddress
+ subprocess.call(cmd, shell=True)
+ return (True, 'DUT %s added to Autotest' % ipaddress)
+
+
+@rpc_utils.moblab_only
+def remove_moblab_dut(ipaddress):
+ """ RPC handler to remove DUT entry from autotest.
+
+ @return: True if the command succeeds without an exception
+ """
+ models.Host.smart_get(ipaddress).delete()
+ return (True, 'DUT %s deleted from Autotest' % ipaddress)
+
+
+@rpc_utils.moblab_only
+def add_moblab_label(ipaddress, label_name):
+ """ RPC handler to add a label in autotest to a DUT entry.
+
+ @return: A string giving information about the status.
+ """
+ # Try to create the label in case it does not already exist.
+ label = None
+ try:
+ label = models.Label.add_object(name=label_name)
+ except:
+ label = models.Label.smart_get(label_name)
+ host_obj = models.Host.smart_get(ipaddress)
+ if label:
+ label.host_set.add(host_obj)
+ return (True, 'Added label %s to DUT %s' % (label_name, ipaddress))
+ return (False, 'Failed to add label %s to DUT %s' % (label_name, ipaddress))
+
+
+@rpc_utils.moblab_only
+def remove_moblab_label(ipaddress, label_name):
+ """ RPC handler to remove a label in autotest from a DUT entry.
+
+ @return: A string giving information about the status.
+ """
+ host_obj = models.Host.smart_get(ipaddress)
+ models.Label.smart_get(label_name).host_set.remove(host_obj)
+ return (True, 'Removed label %s from DUT %s' % (label_name, ipaddress))
+
diff --git a/frontend/client/src/autotest/MoblabSetupClient.gwt.xml b/frontend/client/src/autotest/MoblabSetupClient.gwt.xml
index 97b2859..2face8e 100644
--- a/frontend/client/src/autotest/MoblabSetupClient.gwt.xml
+++ b/frontend/client/src/autotest/MoblabSetupClient.gwt.xml
@@ -2,6 +2,7 @@
<inherits name='com.google.gwt.user.User'/>
<inherits name='com.google.gwt.json.JSON'/>
<inherits name='com.google.gwt.http.HTTP'/>
+ <inherits name="com.google.gwt.user.theme.chrome.Chrome"/>
<source path="moblab"/>
<source path="common"/>
@@ -10,4 +11,5 @@
<stylesheet src='common.css'/>
<stylesheet src='afeclient.css'/>
<stylesheet src='standard.css'/>
+ <stylesheet src='moblabsetup.css'/>
</module>
diff --git a/frontend/client/src/autotest/moblab/DutManagementView.java b/frontend/client/src/autotest/moblab/DutManagementView.java
new file mode 100644
index 0000000..4e8ddad
--- /dev/null
+++ b/frontend/client/src/autotest/moblab/DutManagementView.java
@@ -0,0 +1,295 @@
+package autotest.moblab;
+
+import autotest.common.ui.TabView;
+import autotest.moblab.rpc.ConnectedDutInfo;
+import autotest.moblab.rpc.MoblabRpcCallbacks;
+import autotest.moblab.rpc.MoblabRpcHelper;
+import com.google.gwt.event.dom.client.ChangeEvent;
+import com.google.gwt.event.dom.client.ChangeHandler;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.CheckBox;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.HasVerticalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.ListBox;
+import com.google.gwt.user.client.ui.TextArea;
+import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+/**
+ * Implement a tab that makes it easier to add/remove/maintain duts.
+ */
+public class DutManagementView extends TabView {
+
+ private FlexTable dutInfoTable;
+ private VerticalPanel dutSetupPanel;
+ private ListBox options;
+ private TextArea informationArea;
+ private Button actionButton;
+ private CheckBox poolCheckBox;
+ private TextBox poolLabelName;
+ private Label poolLabel;
+
+ private static final int DHCP_IP_COLUMN = 0;
+ private static final int DHCP_MAC_COLUMN = 1;
+ private static final int SELECTION_COLUMN = 2;
+ private static final int LABELS_COLUMN = 3;
+
+ @Override
+ public String getElementId() {
+ return "dut_manage";
+ }
+
+ @Override
+ public void refresh() {
+ super.refresh();
+ dutInfoTable.removeAllRows();
+ poolCheckBox.setValue(false);
+ poolLabelName.setText("");
+ loadData();
+ }
+
+ @Override
+ public void initialize() {
+ super.initialize();
+ // Main table of connected DUT information.
+ dutInfoTable = new FlexTable();
+
+ // The row of controls underneath the main data table.
+ dutSetupPanel = new VerticalPanel();
+
+ // List of actions to be applied to connected DUT's.
+ options = new ListBox();
+ options.addItem("Add Selected DUT's");
+ options.addItem("Remove Selected DUT's");
+ options.addItem("Add Label Selected DUT's");
+ options.addItem("Remove Label Selected DUT's");
+ options.setStyleName("dut_manage_action_row");
+ options.addChangeHandler(new ChangeHandler() {
+ @Override
+ public void onChange(ChangeEvent event) {
+ if (options.getSelectedIndex() == 2 || options.getSelectedIndex() == 3) {
+ poolCheckBox.setEnabled(true);
+ poolCheckBox.setValue(false);
+ poolLabelName.setEnabled(true);
+ poolLabelName.setText("");
+ } else {
+ poolCheckBox.setEnabled(false);
+ poolLabelName.setEnabled(false);
+ }
+ }
+ });
+
+ // Logging area at the end of the screen that gives status messages about bulk
+ // actions requested.
+ informationArea = new TextArea();
+ informationArea.setVisibleLines(10);
+ informationArea.setCharacterWidth(80);
+ informationArea.setReadOnly(true);
+
+ // Apply button, each action needs to be applied after selecting the devices and
+ // the action to be performed.
+ actionButton = new Button("Apply", new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ ((Button)event.getSource()).setEnabled(false);
+ int action = options.getSelectedIndex();
+ try {
+ for (int i = 1; i < dutInfoTable.getRowCount(); i++) {
+ if (((CheckBox)dutInfoTable.getWidget(i, SELECTION_COLUMN)).getValue()) {
+ if (action == 0) {
+ addDut(i);
+ } else if (action == 1) {
+ removeDut(i);
+ } else if (action == 2) {
+ addLabel(i, getLabelString());
+ } else if (action == 3) {
+ removeLabel(i, getLabelString());
+ }
+ }
+ }
+ } finally {
+ ((Button)event.getSource()).setEnabled(true);
+ }
+ }});
+
+
+ // For adding and removing labels a text input of the label is required.
+ poolCheckBox = new CheckBox();
+
+ // Pools are just special labels, this is just a helper to so users get
+ // it correct more of the time.
+ poolCheckBox.setText("Is pool label ?");
+ poolCheckBox.setStyleName("dut_manage_action_row_item");
+
+ // The text label explaining the text box is for entering the label.
+ poolLabel = new Label();
+ poolLabel.setText("Label name:");
+ poolLabel.setStyleName("dut_manage_action_row_item");
+
+ // The text entry of the label to add or remove.
+ poolLabelName = new TextBox();
+ poolLabelName.setStyleName("dut_manage_action_row_item");
+ poolCheckBox.setEnabled(false);
+ poolLabelName.setEnabled(false);
+ }
+
+ private String getLabelString() {
+ StringBuilder builder = new StringBuilder(poolLabelName.getText());
+ if (poolCheckBox.getValue()) {
+ builder.insert(0, "pool:");
+ }
+ return builder.toString();
+ }
+
+ private void loadData() {
+
+ MoblabRpcHelper.fetchDutInformation(new MoblabRpcCallbacks.FetchConnectedDutInfoCallback() {
+ @Override
+ public void onFetchConnectedDutInfoSubmitted(ConnectedDutInfo info) {
+ addTableHeader();
+ // The header is row 0
+ int row = 1;
+ for (final String dutIpAddress : info.getConnectedIpsToMacAddress().keySet()) {
+ addRowStyles(row);
+ String labelString;
+ if (info.getConfiguredIpsToLabels().keySet().contains(dutIpAddress)) {
+ labelString = info.getConfiguredIpsToLabels().get(dutIpAddress);
+ } else {
+ labelString = "DUT Not Configured in Autotest";
+ }
+ addRow(row, dutIpAddress, info.getConnectedIpsToMacAddress().get(dutIpAddress), labelString);
+ row++;
+ }
+ for (final String dutIpAddress : info.getConfiguredIpsToLabels().keySet()) {
+ if (!info.getConnectedIpsToMacAddress().keySet().contains(dutIpAddress)) {
+ // Device is in AFE but not detected in the DHCP table.
+ addRowStyles(row);
+ addRow(row, dutIpAddress, "",
+ "DUT Configured in Autotest but does not appear to be attached.");
+ row++;
+ }
+ }
+ }
+ });
+
+ // Assemble the display panels in the correct order.
+ dutSetupPanel.add(dutInfoTable);
+ HorizontalPanel actionRow = new HorizontalPanel();
+ actionRow.setStyleName("dut_manage_action_row");
+ actionRow.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
+ actionRow.add(options);
+ actionRow.add(poolCheckBox);
+ actionRow.add(poolLabel);
+ actionRow.add(poolLabelName);
+ actionRow.add(actionButton);
+ dutSetupPanel.add(actionRow);
+ dutSetupPanel.add(informationArea);
+ addWidget(dutSetupPanel, "view_dut_manage");
+ }
+
+ /**
+ * Add the correct css styles for each data row.
+ * @param row index of the row to apply the styles for, first data row is 1.
+ */
+ private void addRowStyles(int row) {
+ dutInfoTable.getCellFormatter().addStyleName(row, DHCP_IP_COLUMN,"ip_cell");
+ dutInfoTable.getCellFormatter().addStyleName(row,DHCP_MAC_COLUMN,"mac_cell");
+ dutInfoTable.getCellFormatter().addStyleName(row,SELECTION_COLUMN,"selection_cell");
+ dutInfoTable.getCellFormatter().addStyleName(row,LABELS_COLUMN,"labels_cell");
+ }
+
+ /**
+ * Insert or update the data in the table for a given row.
+ * @param row The row index to update, first data row is 1.
+ * @param ipColumn String to be added into the first column.
+ * @param macColumn String to be added to the second column.
+ * @param labelsColumn String to be added to the fourth column.
+ */
+ private void addRow(int row, String ipColumn, String macColumn, String labelsColumn) {
+ dutInfoTable.setWidget(row, DHCP_IP_COLUMN, new Label(ipColumn));
+ dutInfoTable.setWidget(row, DHCP_MAC_COLUMN, new Label(macColumn));
+ dutInfoTable.setWidget(row, SELECTION_COLUMN, new CheckBox());
+ dutInfoTable.setWidget(row, LABELS_COLUMN, new Label(labelsColumn));
+ }
+
+ /**
+ * Add the column headers with the correct css styling into the data table.
+ */
+ private void addTableHeader() {
+ dutInfoTable.addStyleName("dut_info_table");
+ dutInfoTable.getCellFormatter().addStyleName(0, DHCP_IP_COLUMN,
+ "dut_manage_column_label_c");
+ dutInfoTable.getCellFormatter().addStyleName(0, DHCP_MAC_COLUMN,
+ "dut_manage_column_label_c");
+ dutInfoTable.getCellFormatter().addStyleName(0, SELECTION_COLUMN,
+ "dut_manage_column_label_c");
+ dutInfoTable.getCellFormatter().addStyleName(0, LABELS_COLUMN,
+ "dut_manage_column_label_c");
+ dutInfoTable.setWidget(0, DHCP_IP_COLUMN, new Label("DCHP Lease Address"));
+ dutInfoTable.setWidget(0, DHCP_MAC_COLUMN, new Label("DCHP MAC Address"));
+ dutInfoTable.setWidget(0, LABELS_COLUMN, new Label("DUT Labels"));
+ }
+
+ /**
+ * Make an RPC call to the autotest system to enroll the DUT listed at the given row number.
+ * @param row_number the row number in the table that has details of the device to enroll.
+ */
+ private void addDut(int row_number) {
+ String ipAddress = ((Label)dutInfoTable.getWidget(row_number, DHCP_IP_COLUMN)).getText();
+ MoblabRpcHelper.addMoblabDut(ipAddress, new LogAction(informationArea));
+ }
+
+ /**
+ * Make an RPC to to the autotest system to delete information about the DUT listed at the given
+ * row.
+ * @param row_number the row number in the table that has details of the device to remove.
+ */
+ private void removeDut(int row_number) {
+ String ipAddress = ((Label)dutInfoTable.getWidget(row_number, DHCP_IP_COLUMN)).getText();
+ MoblabRpcHelper.removeMoblabDut(ipAddress, new LogAction(informationArea));
+ }
+
+ /**
+ * Make an RPC to to the autotest system to add a label to a DUT whoes details are in the given
+ * row.
+ * @param row_number row in the data table that has the information about the DUT
+ * @param labelName the label string to be added.
+ */
+ private void addLabel(int row_number, String labelName) {
+ String ipAddress = ((Label)dutInfoTable.getWidget(row_number, DHCP_IP_COLUMN)).getText();
+ MoblabRpcHelper.addMoblabLabel(ipAddress, labelName, new LogAction(informationArea));
+ }
+
+ /**
+ * Make an RPC to to the autotest system to remove a label to a DUT whoes details are in the
+ * given row.
+ * @param row_number row in the data table that has the information about the DUT
+ * @param labelName the label string to be removed.
+ */
+ private void removeLabel(int row_number, String labelName) {
+ String ipAddress = ((Label)dutInfoTable.getWidget(row_number, DHCP_IP_COLUMN)).getText();
+ MoblabRpcHelper.removeMoblabLabel(ipAddress, labelName, new LogAction(informationArea));
+ }
+
+ /**
+ * Call back that inserts a string from an completed RPC into the UI.
+ */
+ private static class LogAction implements MoblabRpcCallbacks.LogActionCompleteCallback {
+ private TextArea informationArea;
+
+ LogAction(TextArea informationArea){
+ this.informationArea = informationArea;
+ }
+ @Override
+ public void onLogActionComplete(boolean status, String information) {
+ String currentText = informationArea.getText();
+ informationArea
+ .setText(new StringBuilder().append(information).append(
+ "\n").append(currentText).toString());
+ }
+ }
+}
diff --git a/frontend/client/src/autotest/moblab/MoblabSetupClient.java b/frontend/client/src/autotest/moblab/MoblabSetupClient.java
index e2a4fc9..a0138d3 100644
--- a/frontend/client/src/autotest/moblab/MoblabSetupClient.java
+++ b/frontend/client/src/autotest/moblab/MoblabSetupClient.java
@@ -13,6 +13,7 @@
private ConfigSettingsView configSettingsView;
private BotoKeyView botoKeyView;
private LaunchControlKeyView launchControlKeyView;
+ private DutManagementView dutManagementView;
public CustomTabPanel mainTabPanel = new CustomTabPanel();
@@ -28,10 +29,12 @@
configSettingsView = new ConfigSettingsView();
botoKeyView = new BotoKeyView();
launchControlKeyView = new LaunchControlKeyView();
+ dutManagementView = new DutManagementView();
mainTabPanel.addTabView(configWizardView);
mainTabPanel.addTabView(configSettingsView);
mainTabPanel.addTabView(botoKeyView);
mainTabPanel.addTabView(launchControlKeyView);
+ mainTabPanel.addTabView(dutManagementView);
final RootPanel rootPanel = RootPanel.get("tabs");
rootPanel.add(mainTabPanel);
diff --git a/frontend/client/src/autotest/moblab/rpc/ConnectedDutInfo.java b/frontend/client/src/autotest/moblab/rpc/ConnectedDutInfo.java
new file mode 100644
index 0000000..fc670f2
--- /dev/null
+++ b/frontend/client/src/autotest/moblab/rpc/ConnectedDutInfo.java
@@ -0,0 +1,44 @@
+package autotest.moblab.rpc;
+
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * The connected DUT information RPC entity.
+ */
+public class ConnectedDutInfo extends JsonRpcEntity {
+
+ private Map<String, String> connectedIpsToMacAddresses;
+ private Map<String, String> configuredIpsToLabels;
+
+ public ConnectedDutInfo() {
+ connectedIpsToMacAddresses = new TreeMap<String, String>();
+ configuredIpsToLabels = new TreeMap<String, String>();
+ }
+
+ public Map<String, String> getConnectedIpsToMacAddress() { return connectedIpsToMacAddresses; }
+ public Map<String, String> getConfiguredIpsToLabels() { return configuredIpsToLabels; }
+
+ @Override
+ public void fromJson(JSONObject object) {
+ JSONObject leases = object.get("connected_duts").isObject();
+ for (String lease : leases.keySet()) {
+ connectedIpsToMacAddresses.put(lease, leases.get(lease).isString().stringValue());
+ }
+ JSONObject configuredDuts = object.get("configured_duts").isObject();
+ for (String ipAddress : configuredDuts.keySet()) {
+ configuredIpsToLabels.put(ipAddress, configuredDuts.get(ipAddress).isString().stringValue());
+ }
+ }
+
+ @Override
+ public JSONObject toJson() {
+ // This is a read only RPC call so nothing to be submitted back to the
+ // server from the UI.
+ return null;
+ }
+}
diff --git a/frontend/client/src/autotest/moblab/rpc/MoblabRpcCallbacks.java b/frontend/client/src/autotest/moblab/rpc/MoblabRpcCallbacks.java
index 8429b6f..b439b9d 100644
--- a/frontend/client/src/autotest/moblab/rpc/MoblabRpcCallbacks.java
+++ b/frontend/client/src/autotest/moblab/rpc/MoblabRpcCallbacks.java
@@ -41,4 +41,18 @@
public void onVersionInfoFetched(VersionInfo info);
}
+ /**
+ * Callback for to get information about the connected DUT's.
+ */
+ public interface FetchConnectedDutInfoCallback {
+ public void onFetchConnectedDutInfoSubmitted(ConnectedDutInfo info);
+ }
+
+ /**
+ * Generic callback to return a status and information string from a RPC call.
+ */
+ public interface LogActionCompleteCallback {
+ public void onLogActionComplete(boolean didSucceed, String information);
+ }
+
}
diff --git a/frontend/client/src/autotest/moblab/rpc/MoblabRpcHelper.java b/frontend/client/src/autotest/moblab/rpc/MoblabRpcHelper.java
index 26d50c2..12795a6 100644
--- a/frontend/client/src/autotest/moblab/rpc/MoblabRpcHelper.java
+++ b/frontend/client/src/autotest/moblab/rpc/MoblabRpcHelper.java
@@ -1,12 +1,15 @@
package autotest.moblab.rpc;
+import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import autotest.common.JsonRpcCallback;
import autotest.common.JsonRpcProxy;
import autotest.common.SimpleCallback;
+import com.google.gwt.user.client.Window;
import java.util.Map;
/**
@@ -143,11 +146,111 @@
final MoblabRpcCallbacks.FetchVersionInfoCallback callback) {
JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
rpcProxy.rpcCall("get_version_info", null, new JsonRpcCallback() {
+ @Override
+ public void onSuccess(JSONValue result) {
+ VersionInfo info = new VersionInfo();
+ info.fromJson(result.isObject());
+ callback.onVersionInfoFetched(info);
+ }
+ });
+ }
+
+ /**
+ * Get information about the DUT's connected to the moblab.
+ */
+ public static void fetchDutInformation(
+ final MoblabRpcCallbacks.FetchConnectedDutInfoCallback callback) {
+ JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
+ rpcProxy.rpcCall("get_connected_dut_info", null, new JsonRpcCallback() {
@Override
public void onSuccess(JSONValue result) {
- VersionInfo info = new VersionInfo();
+ ConnectedDutInfo info = new ConnectedDutInfo();
info.fromJson(result.isObject());
- callback.onVersionInfoFetched(info);
+ callback.onFetchConnectedDutInfoSubmitted(info);
+ }
+ });
+ }
+
+ /**
+ * Enroll a device into the autotest syste.
+ * @param dutIpAddress ipAddress of the new DUT.
+ * @param callback Callback execute when the RPC is complete.
+ */
+ public static void addMoblabDut(String dutIpAddress,
+ final MoblabRpcCallbacks.LogActionCompleteCallback callback) {
+ JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
+ JSONObject params = new JSONObject();
+ params.put("ipaddress", new JSONString(dutIpAddress));
+ rpcProxy.rpcCall("add_moblab_dut", params, new JsonRpcCallback() {
+ @Override
+ public void onSuccess(JSONValue result) {
+ boolean didSucceed = result.isArray().get(0).isBoolean().booleanValue();
+ String information = result.isArray().get(1).isString().stringValue();
+ callback.onLogActionComplete(didSucceed, information);
+ }
+ });
+ }
+
+ /**
+ * Remove a device from the autotest system.
+ * @param dutIpAddress ipAddress of the DUT to remove.
+ * @param callback Callback to execute when the RPC is complete.
+ */
+ public static void removeMoblabDut(String dutIpAddress,
+ final MoblabRpcCallbacks.LogActionCompleteCallback callback) {
+ JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
+ JSONObject params = new JSONObject();
+ params.put("ipaddress", new JSONString(dutIpAddress));
+ rpcProxy.rpcCall("remove_moblab_dut", params, new JsonRpcCallback() {
+ @Override
+ public void onSuccess(JSONValue result) {
+ boolean didSucceed = result.isArray().get(0).isBoolean().booleanValue();
+ String information = result.isArray().get(1).isString().stringValue();
+ callback.onLogActionComplete(didSucceed, information);
+ }
+ });
+ }
+
+ /**
+ * Add a label to a specific DUT.
+ * @param dutIpAddress ipAddress of the device to have the new label applied.
+ * @param labelName the label to apply
+ * @param callback callback to execute when the RPC is complete.
+ */
+ public static void addMoblabLabel(String dutIpAddress, String labelName,
+ final MoblabRpcCallbacks.LogActionCompleteCallback callback) {
+ JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
+ JSONObject params = new JSONObject();
+ params.put("ipaddress", new JSONString(dutIpAddress));
+ params.put("label_name", new JSONString(labelName));
+ rpcProxy.rpcCall("add_moblab_label", params, new JsonRpcCallback() {
+ @Override
+ public void onSuccess(JSONValue result) {
+ boolean didSucceed = result.isArray().get(0).isBoolean().booleanValue();
+ String information = result.isArray().get(1).isString().stringValue();
+ callback.onLogActionComplete(didSucceed, information);
+ }
+ });
+ }
+
+ /**
+ * Remove a label from a specific DUT.
+ * @param dutIpAddress ipAddress of the device to have the label removed.
+ * @param labelName the label to remove
+ * @param callback callback to execute when the RPC is complete.
+ */
+ public static void removeMoblabLabel(String dutIpAddress, String labelName,
+ final MoblabRpcCallbacks.LogActionCompleteCallback callback) {
+ JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
+ JSONObject params = new JSONObject();
+ params.put("ipaddress", new JSONString(dutIpAddress));
+ params.put("label_name", new JSONString(labelName));
+ rpcProxy.rpcCall("remove_moblab_label", params, new JsonRpcCallback() {
+ @Override
+ public void onSuccess(JSONValue result) {
+ boolean didSucceed = result.isArray().get(0).isBoolean().booleanValue();
+ String information = result.isArray().get(1).isString().stringValue();
+ callback.onLogActionComplete(didSucceed, information);
}
});
}
diff --git a/frontend/client/src/autotest/public/MoblabSetupClient.html b/frontend/client/src/autotest/public/MoblabSetupClient.html
index 48bab03..14a8c8b 100644
--- a/frontend/client/src/autotest/public/MoblabSetupClient.html
+++ b/frontend/client/src/autotest/public/MoblabSetupClient.html
@@ -34,6 +34,10 @@
<span id="view_submit_launch_control_key"></span>
</div>
+ <div id="dut_manage" title="Manage DUTs">
+ <span id="view_dut_manage"></span><br>
+ </div>
+
</div>
<br>
diff --git a/frontend/client/src/autotest/public/moblabsetup.css b/frontend/client/src/autotest/public/moblabsetup.css
new file mode 100644
index 0000000..ed80b74
--- /dev/null
+++ b/frontend/client/src/autotest/public/moblabsetup.css
@@ -0,0 +1,58 @@
+
+.dut_info_table {
+ padding: 5px;
+ background-color: white;
+ border-spacing: 0;
+ border-collapse: collapse;
+ border-bottom: thin solid black;
+}
+
+.dut_manage_column_label_c {
+ color: black;
+ border-bottom: thin solid #111111;
+ text-align: center;
+ padding-left: 15px;
+ padding-right: 15px;
+ padding-bottom: 10px;
+}
+
+.dut_manage_column_label_l {
+ color: black;
+ border-bottom: thin solid #111111;
+ text-align: left;
+ padding-left: 5px;
+}
+
+.ip_cell,
+.mac_cell,
+.selection_cell,
+.labels_cell {
+ border-width: 0px 0px 0px 0px;
+ border-style: solid;
+ border-color: black;
+}
+
+.ip_cell,
+.mac_cell,
+.selection_cell {
+ text-align:center;
+}
+
+.labels_cell {
+ text-align:left;
+}
+
+
+.dut_manage_action_row {
+ padding: 5px;
+ text-align: center;
+}
+
+.dut_manage_action_row {
+ padding: 5px;
+ text-align: center;
+}
+
+.dut_manage_action_row_item {
+ padding-left: 20px;
+}