Initial implementation of Test Planner Machine View. No coloring or
drilldowns yet.

Signed-off-by: James Ren <[email protected]>

--- autotest/frontend/client/src/autotest/planner/MachineViewTab.java   
2010-05-05 15:58:00.000000000 -0700
+++ /dev/null   2009-12-17 12:29:38.000000000 -0800
@@ -1,17 +0,0 @@
-package autotest.planner;
-
-
-public class MachineViewTab {
-    
-    public static interface Display {
-        // Not yet implemented
-    }
-
-    @SuppressWarnings("unused")
-    private Display display;
-    
-    public void bindDisplay(Display display) {
-        this.display = display;
-    }
-    
-}
==== (deleted) 
//depot/google_vendor_src_branch/autotest/frontend/client/src/autotest/planner/MachineViewTabDisplay.java
 ====
--- autotest/frontend/client/src/autotest/planner/MachineViewTabDisplay.java    
2010-05-05 15:58:00.000000000 -0700
+++ /dev/null   2009-12-17 12:29:38.000000000 -0800
@@ -1,13 +0,0 @@
-package autotest.planner;
-
-import autotest.common.ui.TabView;
-
-
-public class MachineViewTabDisplay extends TabView implements 
MachineViewTab.Display {
-    
-    @Override
-    public String getElementId() {
-        return "machine_view";
-    }
-    
-}
--- autotest/frontend/client/src/autotest/planner/TestPlannerClient.java        
2010-05-05 15:58:00.000000000 -0700
+++ autotest/frontend/client/src/autotest/planner/TestPlannerClient.java        
2010-05-05 15:58:00.000000000 -0700
@@ -6,40 +6,40 @@
 import autotest.common.StaticDataRepository;
 import autotest.common.ui.CustomTabPanel;
 import autotest.common.ui.NotifyManager;
+import autotest.planner.machine.MachineViewTab;
 import autotest.planner.triage.TriageViewTab;
 
 import com.google.gwt.core.client.EntryPoint;
 import com.google.gwt.user.client.ui.RootPanel;
 
 public class TestPlannerClient implements EntryPoint {
-    
+
     private TestPlanSelector planSelector = new TestPlanSelector();
     private TestPlanSelectorDisplay planSelectorView = new 
TestPlanSelectorDisplay();
-    
+
     private OverviewTab overviewTab = new OverviewTab();
     private OverviewTabDisplay overviewTabDisplay = new OverviewTabDisplay();
-    
-    private MachineViewTab machineViewTab = new MachineViewTab();
-    private MachineViewTabDisplay machineViewTabDisplay = new 
MachineViewTabDisplay();
-    
+
+    private MachineViewTab machineViewTab = new MachineViewTab(planSelector);
+
     private TestViewTab testViewTab = new TestViewTab();
     private TestViewTabDisplay testViewTabDisplay = new TestViewTabDisplay();
-    
+
     private TriageViewTab triageViewTab = new TriageViewTab(planSelector);
-    
+
     private AutoprocessedTab autoprocessedTab = new AutoprocessedTab();
     private AutoprocessedTabDisplay autoprocessedTabDisplay = new 
AutoprocessedTabDisplay();
-    
+
     private HistoryTab historyTab = new HistoryTab();
     private HistoryTabDisplay historyTabDisplay = new HistoryTabDisplay();
-    
+
     private CustomTabPanel mainTabPanel = new CustomTabPanel();
-    
+
     public void onModuleLoad() {
         JsonRpcProxy.setDefaultBaseUrl(JsonRpcProxy.PLANNER_BASE_URL);
-        
+
         NotifyManager.getInstance().initialize();
-        
+
         StaticDataRepository.getRepository().refresh(
                                  new StaticDataRepository.FinishedCallback() {
             public void onFinished() {
@@ -47,27 +47,26 @@
             }
         });
     }
-    
+
     private void finishLoading() {
         SiteCommonClassFactory.globalInitialize();
-        
+
         overviewTab.bindDisplay(overviewTabDisplay);
-        machineViewTab.bindDisplay(machineViewTabDisplay);
         testViewTab.bindDisplay(testViewTabDisplay);
         autoprocessedTab.bindDisplay(autoprocessedTabDisplay);
         historyTab.bindDisplay(historyTabDisplay);
-        
+
         planSelectorView.initialize();
         planSelector.bindDisplay(planSelectorView);
         mainTabPanel.getCommonAreaPanel().add(planSelectorView);
-        
+
         mainTabPanel.addTabView(overviewTabDisplay);
-        mainTabPanel.addTabView(machineViewTabDisplay);
+        mainTabPanel.addTabView(machineViewTab);
         mainTabPanel.addTabView(testViewTabDisplay);
         mainTabPanel.addTabView(triageViewTab);
         mainTabPanel.addTabView(autoprocessedTabDisplay);
         mainTabPanel.addTabView(historyTabDisplay);
-        
+
         final RootPanel tabsRoot = RootPanel.get("tabs");
         tabsRoot.add(mainTabPanel);
         CustomHistory.processInitialToken();
--- /dev/null   2009-12-17 12:29:38.000000000 -0800
+++ autotest/frontend/client/src/autotest/planner/TestPlannerUtils.java 
2010-05-05 15:58:00.000000000 -0700
@@ -0,0 +1,37 @@
+package autotest.planner;
+
+import com.google.gwt.gen2.table.client.FixedWidthFlexTable;
+import com.google.gwt.gen2.table.client.FixedWidthGrid;
+import com.google.gwt.gen2.table.client.ScrollTable;
+
+public class TestPlannerUtils {
+
+    private static final int HEIGHT_FUDGE = 300;
+
+    public static String getHeightParam(int windowHeight) {
+        return (windowHeight - HEIGHT_FUDGE) + "px";
+    }
+
+    public static void resizeScrollTable(ScrollTable scrollTable) {
+        resizeScrollTable(scrollTable, false);
+    }
+
+    public static void resizeScrollTable(ScrollTable scrollTable, boolean 
hasSelectAllHeader) {
+        FixedWidthGrid dataTable = scrollTable.getDataTable();
+        FixedWidthFlexTable header = scrollTable.getHeaderTable();
+
+        for (int column = 0; column < dataTable.getColumnCount(); column++) {
+            int headerColumn = column;
+            if (hasSelectAllHeader) {
+                headerColumn++;
+            }
+
+            int width = Math.max(
+                      dataTable.getIdealColumnWidth(column),
+                      header.getIdealColumnWidth(headerColumn));
+
+            header.setColumnWidth(headerColumn, width);
+            dataTable.setColumnWidth(column, width);
+        }
+    }
+}
--- /dev/null   2009-12-17 12:29:38.000000000 -0800
+++ 
autotest/frontend/client/src/autotest/planner/machine/MachineViewDisplay.java   
    2010-05-05 15:58:00.000000000 -0700
@@ -0,0 +1,38 @@
+package autotest.planner.machine;
+
+import autotest.common.ui.NotifyManager;
+import autotest.planner.TestPlannerDisplay;
+import autotest.planner.machine.MachineViewTable.Display;
+
+import com.google.gwt.user.client.ui.HTMLPanel;
+import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.SimplePanel;
+
+
+public class MachineViewDisplay implements TestPlannerDisplay, 
MachineViewPresenter.Display {
+
+    private Panel container = new SimplePanel();
+
+    @Override
+    public void initialize(HTMLPanel htmlPanel) {
+        htmlPanel.add(container, "machine_view_main");
+    }
+
+    @Override
+    public void clearAllData() {
+        container.clear();
+    }
+
+    @Override
+    public void setLoading(boolean loading) {
+        NotifyManager.getInstance().setLoading(loading);
+        container.setVisible(!loading);
+    }
+
+    @Override
+    public Display generateMachineViewTableDisplay() {
+        MachineViewTableDisplay display = new MachineViewTableDisplay();
+        container.add(display);
+        return display;
+    }
+}
--- /dev/null   2009-12-17 12:29:38.000000000 -0800
+++ 
autotest/frontend/client/src/autotest/planner/machine/MachineViewPresenter.java 
    2010-05-05 15:58:00.000000000 -0700
@@ -0,0 +1,51 @@
+package autotest.planner.machine;
+
+import autotest.common.JsonRpcCallback;
+import autotest.common.JsonRpcProxy;
+import autotest.planner.TestPlannerPresenter;
+
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONString;
+import com.google.gwt.json.client.JSONValue;
+
+
+public class MachineViewPresenter extends TestPlannerPresenter {
+
+    public static interface Display {
+        public void setLoading(boolean loading);
+        public void clearAllData();
+        public MachineViewTable.Display generateMachineViewTableDisplay();
+    }
+
+    private Display display;
+
+    public void bindDisplay(Display display) {
+        this.display = display;
+    }
+
+    @Override
+    public void refresh(String planId) {
+        display.setLoading(true);
+
+        JSONObject params = new JSONObject();
+        params.put("plan_id", new JSONString(planId));
+
+        JsonRpcProxy.getProxy().rpcCall("get_machine_view_data", params, new 
JsonRpcCallback() {
+            @Override
+            public void onSuccess(JSONValue result) {
+                display.clearAllData();
+                display.setLoading(false);
+
+                MachineViewTable table = new MachineViewTable();
+                table.bindDisplay(display.generateMachineViewTableDisplay());
+                table.setData(result.isArray());
+            }
+
+            @Override
+            public void onError(JSONObject errorObject) {
+                super.onError(errorObject);
+                display.setLoading(false);
+            }
+        });
+    }
+}
--- /dev/null   2009-12-17 12:29:38.000000000 -0800
+++ autotest/frontend/client/src/autotest/planner/machine/MachineViewTab.java   
2010-05-05 15:58:00.000000000 -0700
@@ -0,0 +1,37 @@
+package autotest.planner.machine;
+
+import autotest.planner.TestPlanSelector;
+import autotest.planner.TestPlannerDisplay;
+import autotest.planner.TestPlannerPresenter;
+import autotest.planner.TestPlannerTab;
+
+
+public class MachineViewTab extends TestPlannerTab {
+
+    private MachineViewPresenter presenter = new MachineViewPresenter();
+    private MachineViewDisplay display = new MachineViewDisplay();
+
+    public MachineViewTab(TestPlanSelector selector) {
+        super(selector);
+    }
+
+    @Override
+    public String getElementId() {
+        return "machine_view";
+    }
+
+    @Override
+    protected TestPlannerDisplay getDisplay() {
+        return display;
+    }
+
+    @Override
+    protected TestPlannerPresenter getPresenter() {
+        return presenter;
+    }
+
+    @Override
+    protected void bindDisplay() {
+        presenter.bindDisplay(display);
+    }
+}
--- /dev/null   2009-12-17 12:29:38.000000000 -0800
+++ autotest/frontend/client/src/autotest/planner/machine/MachineViewTable.java 
2010-05-05 15:56:49.000000000 -0700
@@ -0,0 +1,122 @@
+package autotest.planner.machine;
+
+import autotest.common.Utils;
+
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class MachineViewTable {
+
+    public static class PassRate {
+        int passed;
+        int total;
+    }
+
+    public static class Row {
+        String machine;
+        String status;
+        Map<String, PassRate> passRates;
+        List<String> bugIds;
+
+        private Row(String machine, String status,
+                Map<String, PassRate> passRates, List<String> bugIds) {
+            this.machine = machine;
+            this.status = status;
+            this.passRates = passRates;
+            this.bugIds = bugIds;
+        }
+
+        public static Row fromJsonObject(JSONObject rowObject) {
+            Map<String, PassRate> passRates = new HashMap<String, PassRate>();
+
+            JSONArray testsRun = rowObject.get("tests_run").isArray();
+            for (int i = 0; i < testsRun.size(); i++) {
+                JSONObject test = testsRun.get(i).isObject();
+                String testName = Utils.jsonToString(test.get("test_name"));
+
+                PassRate passRate = passRates.get(testName);
+                if (passRate == null) {
+                    passRate = new PassRate();
+                    passRates.put(testName, passRate);
+                }
+
+                passRate.total++;
+                if (test.get("success").isBoolean().booleanValue()) {
+                    passRate.passed++;
+                }
+            }
+
+            return new Row(Utils.jsonToString(rowObject.get("machine")),
+                    Utils.jsonToString(rowObject.get("status")),
+                    passRates,
+                    
Arrays.asList(Utils.JSONtoStrings(rowObject.get("bug_ids").isArray())));
+        }
+    }
+
+    public static interface Display {
+        public void clearData();
+        public void setHeaders(Collection<String> headers);
+        public void addRow(Collection<String> rowData);
+        public void finalRender();
+    }
+
+    private Display display;
+    private List<Row> rows = new ArrayList<Row>();
+
+    public void bindDisplay(Display display) {
+        this.display = display;
+    }
+
+    public void setData(JSONArray data) {
+        for (int i = 0; i < data.size(); i++) {
+            rows.add(Row.fromJsonObject(data.get(i).isObject()));
+        }
+
+        display.clearData();
+        displayData();
+    }
+
+    private void displayData() {
+        Set<String> allTestNames = new TreeSet<String>();
+        for (Row row : rows) {
+            allTestNames.addAll(row.passRates.keySet());
+        }
+
+        List<String> headers = new ArrayList<String>();
+        headers.add("Machine");
+        headers.add("Status");
+        headers.addAll(allTestNames);
+        headers.add("Bugs Filed");
+        display.setHeaders(headers);
+
+        for (Row row : rows) {
+            List<String> rowData = new ArrayList<String>();
+            rowData.add(row.machine);
+            rowData.add(row.status);
+
+            for (String testName : allTestNames) {
+                PassRate passRate = row.passRates.get(testName);
+                if (passRate != null) {
+                    rowData.add(passRate.passed + "/" + passRate.total);
+                } else {
+                    rowData.add("");
+                }
+            }
+
+            rowData.add(String.valueOf(row.bugIds.size()));
+
+            display.addRow(rowData);
+        }
+
+        display.finalRender();
+    }
+}
--- /dev/null   2009-12-17 12:29:38.000000000 -0800
+++ 
autotest/frontend/client/src/autotest/planner/machine/MachineViewTableDisplay.java
  2010-05-05 15:56:49.000000000 -0700
@@ -0,0 +1,77 @@
+package autotest.planner.machine;
+
+import autotest.planner.TestPlannerUtils;
+
+import com.google.gwt.event.logical.shared.ResizeEvent;
+import com.google.gwt.event.logical.shared.ResizeHandler;
+import com.google.gwt.gen2.table.client.FixedWidthFlexTable;
+import com.google.gwt.gen2.table.client.FixedWidthGrid;
+import com.google.gwt.gen2.table.client.ScrollTable;
+import com.google.gwt.gen2.table.client.AbstractScrollTable.ResizePolicy;
+import com.google.gwt.gen2.table.client.AbstractScrollTable.ScrollPolicy;
+import com.google.gwt.gen2.table.client.AbstractScrollTable.SortPolicy;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Composite;
+
+import java.util.Collection;
+
+public class MachineViewTableDisplay extends Composite
+        implements MachineViewTable.Display, ResizeHandler {
+
+    private FixedWidthFlexTable headerTable = new FixedWidthFlexTable();
+    private FixedWidthGrid dataTable = new FixedWidthGrid();
+    private ScrollTable scrollTable = new ScrollTable(dataTable, headerTable);
+
+    public MachineViewTableDisplay() {
+        scrollTable.setSortPolicy(SortPolicy.DISABLED);
+        scrollTable.setResizePolicy(ResizePolicy.UNCONSTRAINED);
+        scrollTable.setScrollPolicy(ScrollPolicy.BOTH);
+
+        scrollTable.setSize("100%", 
TestPlannerUtils.getHeightParam(Window.getClientHeight()));
+        scrollTable.setVisible(false);
+
+        initWidget(scrollTable);
+    }
+
+    @Override
+    public void addRow(Collection<String> rowData) {
+        assert rowData.size() == dataTable.getColumnCount();
+
+        int row = dataTable.insertRow(dataTable.getRowCount());
+
+        int column = 0;
+        for (String data : rowData) {
+            dataTable.setText(row, column++, data);
+        }
+    }
+
+    @Override
+    public void finalRender() {
+        TestPlannerUtils.resizeScrollTable(scrollTable);
+    }
+
+    @Override
+    public void clearData() {
+        scrollTable.setVisible(false);
+        headerTable.clear();
+        dataTable.clear();
+    }
+
+    @Override
+    public void setHeaders(Collection<String> headers) {
+        int column = 0;
+        for (String header : headers) {
+            headerTable.setText(0, column, header);
+            scrollTable.setHeaderColumnTruncatable(column++, false);
+        }
+
+        dataTable.resize(0, headers.size());
+
+        scrollTable.setVisible(true);
+    }
+
+    @Override
+    public void onResize(ResizeEvent event) {
+        
scrollTable.setHeight(TestPlannerUtils.getHeightParam(event.getHeight()));
+    }
+}
--- autotest/frontend/client/src/autotest/planner/triage/FailureTable.java      
2010-05-05 15:58:00.000000000 -0700
+++ autotest/frontend/client/src/autotest/planner/triage/FailureTable.java      
2010-05-05 15:58:00.000000000 -0700
@@ -11,17 +11,18 @@
 import java.util.Set;
 
 class FailureTable implements ClickHandler {
-    
+
     public static final String[] COLUMN_NAMES = {"Machine", "Test", "Reason"};
-    
+
     public static interface Display {
         public void addRow(String[] cells, boolean isNew);
+        public void finalRender();
         public void setAllRowsSelected(boolean selected);
         public HasClickHandlers getSelectAllControl();
         public HasValue<Boolean> getSelectAllValue();
         public Set<Integer> getSelectedFailures();
     }
-    
+
     private static class Failure {
         int id;
         String machine;
@@ -29,7 +30,7 @@
         String testName;
         String reason;
         boolean seen;
-        
+
         private Failure(int id, String machine, boolean blocked,
                 String testName, String reason, boolean seen) {
             this.id = id;
@@ -39,7 +40,7 @@
             this.reason = reason;
             this.seen = seen;
         }
-        
+
         public static Failure fromJsonObject(JSONObject failureObj) {
             return new Failure(
                 (int) failureObj.get("id").isNumber().doubleValue(),
@@ -50,34 +51,38 @@
                 failureObj.get("seen").isBoolean().booleanValue());
         }
     }
-    
+
     private Display display;
     private List<Integer> failureIds = new ArrayList<Integer>();
-    
+
     public void bindDisplay(Display display) {
         this.display = display;
         display.getSelectAllControl().addClickHandler(this);
     }
-    
+
     public void addFailure(JSONObject failureObj) {
         Failure failure = Failure.fromJsonObject(failureObj);
-        
+
         String machineDisplay = failure.machine;
         if (failure.blocked) {
             machineDisplay += " (blocked)";
         }
-        
+
         display.addRow(
                 new String[] {machineDisplay, failure.testName, 
failure.reason}, !failure.seen);
         failureIds.add(failure.id);
     }
 
+    public void finishedAdding() {
+        display.finalRender();
+    }
+
     @Override
     public void onClick(ClickEvent event) {
         assert event.getSource() == display.getSelectAllControl();
         display.setAllRowsSelected(display.getSelectAllValue().getValue());
     }
-    
+
     public List<Integer> getSelectedFailureIds() {
         List<Integer> selected = new ArrayList<Integer>();
         for (int i : display.getSelectedFailures()) {
--- 
autotest/frontend/client/src/autotest/planner/triage/FailureTableDisplay.java   
    2010-05-05 15:58:00.000000000 -0700
+++ 
autotest/frontend/client/src/autotest/planner/triage/FailureTableDisplay.java   
    2010-05-05 15:58:00.000000000 -0700
@@ -1,5 +1,7 @@
 package autotest.planner.triage;
 
+import autotest.planner.TestPlannerUtils;
+
 import com.google.gwt.event.dom.client.HasClickHandlers;
 import com.google.gwt.gen2.table.client.FixedWidthFlexTable;
 import com.google.gwt.gen2.table.client.FixedWidthGrid;
@@ -17,52 +19,61 @@
 
 
 public class FailureTableDisplay extends Composite implements 
FailureTable.Display {
-    
+
     private FixedWidthFlexTable header = new FixedWidthFlexTable();
     private FixedWidthGrid dataTable;
     private ScrollTable scrollTable;
     private CheckBox selectAll = new CheckBox();
-    
+
+    private String group;
+
     public FailureTableDisplay(String group, String[] columnNames) {
-        FlexCellFormatter formatter = header.getFlexCellFormatter();
-        
+        this.group = group;
+
+
         dataTable = new FixedWidthGrid(0, columnNames.length);
         dataTable.setSelectionPolicy(SelectionPolicy.CHECKBOX);
-        
+
         scrollTable = new ScrollTable(dataTable, header);
         scrollTable.setSortPolicy(SortPolicy.DISABLED);
         scrollTable.setResizePolicy(ResizePolicy.UNCONSTRAINED);
         scrollTable.setScrollPolicy(ScrollPolicy.BOTH);
         scrollTable.setHeight("200px");
-        
-        header.setText(0, 0, group);
+
         header.setWidget(1, 0, selectAll);
-        
-        formatter.setColSpan(0, 0, columnNames.length + 1);
+
         for (int i = 0; i < columnNames.length; i++) {
             header.setText(1, i + 1, columnNames[i]);
         }
-        
+
         initWidget(scrollTable);
     }
-    
+
     @Override
     public void addRow(String[] cells, boolean isNew) {
         assert dataTable.getColumnCount() == cells.length;
-        
+
         int row = dataTable.getRowCount();
         dataTable.resizeRows(row + 1);
         for (int cell = 0; cell < cells.length; cell++) {
             dataTable.setText(row, cell, cells[cell]);
         }
-        
-        for (int column = 0; column < dataTable.getColumnCount(); column++) {
-            int width = Math.max(
-                      dataTable.getIdealColumnWidth(column), 
header.getColumnWidth(column + 1));
-            
-            header.setColumnWidth(column + 1, width);
-            dataTable.setColumnWidth(column, width);
-        }
+    }
+
+    @Override
+    public void finalRender() {
+        TestPlannerUtils.resizeScrollTable(scrollTable, true);
+
+        /*
+         * Add the group header and redraw the table after the column 
resizing. This is to work
+         * around a bug (feature?) where getIdealColumnWidth() computes weird 
numbers for ideal
+         * width when there's a colspan'd column.
+         */
+        header.setText(0, 0, group);
+        FlexCellFormatter formatter = header.getFlexCellFormatter();
+        formatter.setColSpan(0, 0, header.getColumnCount());
+
+        scrollTable.redraw();
     }
 
     @Override
--- autotest/frontend/client/src/autotest/planner/triage/TriageViewDisplay.java 
2010-05-05 15:58:00.000000000 -0700
+++ autotest/frontend/client/src/autotest/planner/triage/TriageViewDisplay.java 
2010-05-05 15:58:00.000000000 -0700
@@ -2,6 +2,7 @@
 
 import autotest.common.ui.NotifyManager;
 import autotest.planner.TestPlannerDisplay;
+import autotest.planner.TestPlannerUtils;
 
 import com.google.gwt.event.dom.client.HasClickHandlers;
 import com.google.gwt.event.logical.shared.ResizeEvent;
@@ -16,8 +17,6 @@
 public class TriageViewDisplay implements TestPlannerDisplay,
         TriageViewPresenter.Display, ResizeHandler {
 
-    private static final int HEIGHT_FUDGE = 300;
-
     private VerticalPanel container = new VerticalPanel();
     private ScrollPanel scroll = new ScrollPanel(container);
     private Button triage = new Button("Triage");
@@ -27,7 +26,7 @@
         container.setSpacing(25);
         container.setWidth("90%");
 
-        scroll.setSize("100%", getHeightParam(Window.getClientHeight()));
+        scroll.setSize("100%", 
TestPlannerUtils.getHeightParam(Window.getClientHeight()));
         scroll.setVisible(false);
         triage.setVisible(false);
 
@@ -68,10 +67,6 @@
 
     @Override
     public void onResize(ResizeEvent event) {
-        scroll.setHeight(getHeightParam(event.getHeight()));
-    }
-
-    private String getHeightParam(int height) {
-        return (height - HEIGHT_FUDGE) + "px";
+        scroll.setHeight(TestPlannerUtils.getHeightParam(event.getHeight()));
     }
 }
--- 
autotest/frontend/client/src/autotest/planner/triage/TriageViewPresenter.java   
    2010-05-05 15:58:00.000000000 -0700
+++ 
autotest/frontend/client/src/autotest/planner/triage/TriageViewPresenter.java   
    2010-05-05 15:58:00.000000000 -0700
@@ -72,6 +72,7 @@
                 table.addFailure(groupFailures.get(i).isObject());
             }
 
+            table.finishedAdding();
             failureTables.add(table);
         }
     }
--- autotest/frontend/client/src/autotest/public/TestPlannerClient.html 
2010-05-05 15:58:00.000000000 -0700
+++ autotest/frontend/client/src/autotest/public/TestPlannerClient.html 
2010-05-05 15:58:00.000000000 -0700
@@ -39,6 +39,7 @@
       </div>
 
       <div id="machine_view" title="Machine View">
+          <div id="machine_view_main"></div>
       </div>
 
       <div id="test_view"  title="Test View">
--- autotest/frontend/planner/planner_test_utils.py     2010-05-05 
15:58:00.000000000 -0700
+++ autotest/frontend/planner/planner_test_utils.py     2010-05-05 
15:58:00.000000000 -0700
@@ -59,8 +59,7 @@
                 plan=self._plan, alias='config', control_file=self._control,
                 execution_order=1, estimated_runtime=1)
         self._afe_job = self._create_job(hosts=(1,))
-        self._planner_host = models.Host.objects.create(plan=self._plan,
-                                                        host=self.hosts[0])
+        self._planner_host = self._plan.host_set.get(host=self.hosts[0])
         self._planner_job = models.Job.objects.create(
                 plan=self._plan, test_config=self._test_config,
                 afe_job=self._afe_job)
--- autotest/frontend/planner/rpc_interface.py  2010-05-05 15:58:00.000000000 
-0700
+++ autotest/frontend/planner/rpc_interface.py  2010-05-05 15:58:00.000000000 
-0700
@@ -344,6 +344,48 @@
                 bugs=bugs, reason=reason, invalidate=invalidate)
 
 
+def get_machine_view_data(plan_id):
+    """
+    Gets the data required for the web frontend Machine View.
+
+    @param plan_id: The ID of the test plan
+    @return An array. Each element is a dictionary:
+                    machine: The name of the machine
+                    status: The machine's status (one of
+                            model_attributes.HostStatus)
+                    bug_ids: List of the IDs for the bugs filed
+                    tests_run: An array of dictionaries:
+                            test_name: The TKO name of the test
+                            success: True if the test passed
+    """
+    plan = models.Plan.smart_get(plan_id)
+    result = []
+    for host in plan.host_set.all():
+        tests_run = []
+
+        machine = host.host.hostname
+        status = host.status()
+        bug_ids = set()
+
+        testruns = plan.testrun_set.filter(host=host, invalidated=False,
+                                           finalized=True)
+        for testrun in testruns:
+            test_name = testrun.tko_test.test
+            success = (testrun.tko_test.status.word == 'GOOD')
+            testrun_bug_ids = testrun.bugs.all().values_list(
+                    'external_uid', flat=True)
+
+            tests_run.append({'test_name': test_name,
+                              'success': success})
+            bug_ids.update(testrun_bug_ids)
+
+        result.append({'machine': machine,
+                       'status': status,
+                       'tests_run': tests_run,
+                       'bug_ids': list(bug_ids)})
+    return result
+
+
 def get_motd():
     return afe_rpc_utils.get_motd()
 
--- autotest/frontend/planner/rpc_interface_unittest.py 2010-05-05 
15:58:00.000000000 -0700
+++ autotest/frontend/planner/rpc_interface_unittest.py 2010-05-05 
15:58:00.000000000 -0700
@@ -164,5 +164,51 @@
         self.god.check_playback()
 
 
+    def test_get_machine_view_data(self):
+        self._setup_active_plan()
+
+        host1_expected = {'machine': 'host1',
+                          'status': 'Running',
+                          'tests_run': [],
+                          'bug_ids': []}
+        host2_expected = {'machine': 'host2',
+                          'status': 'Running',
+                          'tests_run': [],
+                          'bug_ids': []}
+
+        expected = (host1_expected, host2_expected)
+        actual = rpc_interface.get_machine_view_data(plan_id=self._plan.id)
+        self.assertEqual(sorted(actual), sorted(expected))
+
+        # active TKO test
+        tko_test = tko_models.Test.objects.create(job=self._tko_job,
+                                                  test='test',
+                                                  machine=self._tko_machine,
+                                                  kernel=self._tko_kernel,
+                                                  status=self._running_status)
+        testrun = models.TestRun.objects.create(plan=self._plan,
+                                                test_job=self._planner_job,
+                                                host=self._planner_host,
+                                                tko_test=tko_test,
+                                                finalized=True)
+
+        host1_expected['tests_run'] = [{'test_name': 'test',
+                                        'success': False}]
+        actual = rpc_interface.get_machine_view_data(plan_id=self._plan.id)
+        self.assertEqual(sorted(actual), sorted(expected))
+
+        # TKO test complete, passed, with bug filed
+        tko_test.status = self._good_status
+        tko_test.save()
+        bug = models.Bug.objects.create(external_uid='bug')
+        testrun.bugs.add(bug)
+
+        host1_expected['tests_run'] = [{'test_name': 'test',
+                                        'success': True}]
+        host1_expected['bug_ids'] = ['bug']
+        actual = rpc_interface.get_machine_view_data(plan_id=self._plan.id)
+        self.assertEqual(sorted(actual), sorted(expected))
+
+
 if __name__ == '__main__':
     unittest.main()
_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

Reply via email to