Home | History | Annotate | Download | only in tko
      1 package autotest.tko;
      2 
      3 import autotest.common.JsonRpcCallback;
      4 import autotest.common.JsonRpcProxy;
      5 import autotest.common.PaddedJsonRpcProxy;
      6 import autotest.common.Utils;
      7 import autotest.common.ui.DetailView;
      8 import autotest.common.ui.NotifyManager;
      9 import autotest.common.ui.RealHyperlink;
     10 
     11 import com.google.gwt.event.logical.shared.OpenEvent;
     12 import com.google.gwt.event.logical.shared.OpenHandler;
     13 import com.google.gwt.event.logical.shared.ResizeEvent;
     14 import com.google.gwt.event.logical.shared.ResizeHandler;
     15 import com.google.gwt.json.client.JSONNumber;
     16 import com.google.gwt.json.client.JSONObject;
     17 import com.google.gwt.json.client.JSONString;
     18 import com.google.gwt.json.client.JSONValue;
     19 import com.google.gwt.user.client.Window;
     20 import com.google.gwt.user.client.ui.Composite;
     21 import com.google.gwt.user.client.ui.DisclosurePanel;
     22 import com.google.gwt.user.client.ui.FlexTable;
     23 import com.google.gwt.user.client.ui.FlowPanel;
     24 import com.google.gwt.user.client.ui.HTML;
     25 import com.google.gwt.user.client.ui.Panel;
     26 import com.google.gwt.user.client.ui.ScrollPanel;
     27 import com.google.gwt.user.client.ui.SimplePanel;
     28 
     29 import java.util.ArrayList;
     30 import java.util.Arrays;
     31 import java.util.Collections;
     32 import java.util.List;
     33 
     34 class TestDetailView extends DetailView {
     35     private static final int NO_TEST_ID = -1;
     36 
     37     private static final JsonRpcProxy logLoadingProxy =
     38         new PaddedJsonRpcProxy(Utils.RETRIEVE_LOGS_URL);
     39 
     40     private int testId = NO_TEST_ID;
     41     private String jobTag;
     42     private List<LogFileViewer> logFileViewers = new ArrayList<LogFileViewer>();
     43     private RealHyperlink logLink = new RealHyperlink("(view all logs)");
     44     private RealHyperlink testLogLink = new RealHyperlink("(view test logs)");
     45     private Panel logPanel;
     46     private Panel attributePanel = new SimplePanel();
     47 
     48     private class LogFileViewer extends Composite
     49                                 implements OpenHandler<DisclosurePanel>, ResizeHandler {
     50         private DisclosurePanel panel;
     51         private ScrollPanel scroller; // ScrollPanel wrapping log contents
     52         private String logFilePath;
     53 
     54         private JsonRpcCallback rpcCallback = new JsonRpcCallback() {
     55             @Override
     56             public void onError(JSONObject errorObject) {
     57                 super.onError(errorObject);
     58                 String errorString = getErrorString(errorObject);
     59                 if (errorString.equals("")) {
     60                     errorString = "Failed to load log "+ logFilePath;
     61                 }
     62                 setStatusText(errorString);
     63             }
     64 
     65             @Override
     66             public void onSuccess(JSONValue result) {
     67                 handle(result);
     68             }
     69         };
     70 
     71         public LogFileViewer(String logFilePath, String logFileName) {
     72             this.logFilePath = logFilePath;
     73             panel = new DisclosurePanel(logFileName);
     74             panel.addOpenHandler(this);
     75             panel.addStyleName("log-file-panel");
     76             initWidget(panel);
     77 
     78             Window.addResizeHandler(this);
     79         }
     80 
     81         @Override
     82         public void onOpen(OpenEvent<DisclosurePanel> event) {
     83             JSONObject params = new JSONObject();
     84             params.put("path", new JSONString(getLogUrl()));
     85             logLoadingProxy.rpcCall("dummy", params, rpcCallback);
     86 
     87             setStatusText("Loading...");
     88         }
     89 
     90         private String getLogUrl() {
     91             return Utils.getLogsUrl(jobTag + "/" + logFilePath);
     92         }
     93 
     94         public void handle(JSONValue value) {
     95             String logContents = value.isString().stringValue();
     96             if (logContents.equals("")) {
     97                 setStatusText("Log file is empty");
     98             } else {
     99                 setLogText(logContents);
    100             }
    101         }
    102 
    103         private void setLogText(String text) {
    104             panel.clear();
    105             scroller = new ScrollPanel();
    106             scroller.getElement().setInnerText(text);
    107             panel.add(scroller);
    108             setScrollerWidth();
    109         }
    110 
    111         /**
    112          * Firefox fails to set relative widths correctly for elements with overflow: scroll (or
    113          * auto, or hidden).  Instead, it just expands the element to fit the contents.  So we use
    114          * this trick to dynamically implement width: 100%.
    115          */
    116         private void setScrollerWidth() {
    117             assert panel.isOpen();
    118             scroller.setWidth("0px"); // allow the parent to assume its natural size
    119             int targetWidthPx = scroller.getParent().getOffsetWidth();
    120             NotifyManager.getInstance().log(targetWidthPx + "px");
    121             scroller.setWidth(targetWidthPx + "px");
    122         }
    123 
    124         @Override
    125         public void onResize(ResizeEvent event) {
    126             if (panel.isOpen()) {
    127                 setScrollerWidth();
    128             }
    129         }
    130 
    131         private void setStatusText(String status) {
    132             panel.clear();
    133             panel.add(new HTML("<i>" + status + "</i>"));
    134         }
    135     }
    136 
    137     private static class AttributeTable extends Composite {
    138         private DisclosurePanel container = new DisclosurePanel("Test attributes");
    139         private FlexTable table = new FlexTable();
    140 
    141         public AttributeTable(JSONObject attributes) {
    142             processAttributes(attributes);
    143             setupTableStyle();
    144             container.add(table);
    145             initWidget(container);
    146         }
    147 
    148         private void processAttributes(JSONObject attributes) {
    149             if (attributes.size() == 0) {
    150                 table.setText(0, 0, "No test attributes");
    151                 return;
    152             }
    153 
    154             List<String> sortedKeys = new ArrayList<String>(attributes.keySet());
    155             Collections.sort(sortedKeys);
    156             for (String key : sortedKeys) {
    157                 String value = Utils.jsonToString(attributes.get(key));
    158                 int row = table.getRowCount();
    159                 table.setText(row, 0, key);
    160                 table.setText(row, 1, value);
    161             }
    162         }
    163 
    164         private void setupTableStyle() {
    165             container.addStyleName("test-attributes");
    166         }
    167     }
    168 
    169     @Override
    170     public void initialize() {
    171         super.initialize();
    172 
    173         addWidget(attributePanel, "td_attributes");
    174         logPanel = new FlowPanel();
    175         addWidget(logPanel, "td_log_files");
    176         testLogLink.setOpensNewWindow(true);
    177         addWidget(testLogLink, "td_view_logs_link");
    178         logLink.setOpensNewWindow(true);
    179         addWidget(logLink, "td_view_logs_link");
    180     }
    181 
    182     private void addLogViewers(String testName) {
    183         logPanel.clear();
    184         addLogFileViewer(testName + "/debug/" + testName + ".DEBUG", "Test debug log");
    185         addLogFileViewer(testName + "/debug/" + testName + ".ERROR", "Test error log");
    186         addLogFileViewer("status.log", "Job status log");
    187         addLogFileViewer("debug/autoserv.DEBUG", "Job debug log");
    188         addLogFileViewer("debug/autoserv.ERROR", "Job error log");
    189     }
    190 
    191     private void addLogFileViewer(String logPath, String logName) {
    192         LogFileViewer viewer = new LogFileViewer(logPath, logName);
    193         logFileViewers.add(viewer);
    194         logPanel.add(viewer);
    195     }
    196 
    197     @Override
    198     protected void fetchData() {
    199         JSONObject params = new JSONObject();
    200         params.put("test_idx", new JSONNumber(testId));
    201         rpcProxy.rpcCall("get_detailed_test_views", params, new JsonRpcCallback() {
    202             @Override
    203             public void onSuccess(JSONValue result) {
    204                 JSONObject test;
    205                 try {
    206                     test = Utils.getSingleObjectFromArray(result.isArray());
    207                 }
    208                 catch (IllegalArgumentException exc) {
    209                     NotifyManager.getInstance().showError("No such job found");
    210                     resetPage();
    211                     return;
    212                 }
    213 
    214                 showTest(test);
    215             }
    216 
    217             @Override
    218             public void onError(JSONObject errorObject) {
    219                 super.onError(errorObject);
    220                 resetPage();
    221             }
    222         });
    223     }
    224 
    225     @Override
    226     protected void setObjectId(String id) {
    227         try {
    228             testId = Integer.parseInt(id);
    229         }
    230         catch (NumberFormatException exc) {
    231             throw new IllegalArgumentException();
    232         }
    233     }
    234 
    235     @Override
    236     protected String getObjectId() {
    237         if (testId == NO_TEST_ID) {
    238             return NO_OBJECT;
    239         }
    240         return Integer.toString(testId);
    241     }
    242 
    243     @Override
    244     protected String getDataElementId() {
    245         return "td_data";
    246     }
    247 
    248     @Override
    249     protected String getFetchControlsElementId() {
    250         return "td_fetch_controls";
    251     }
    252 
    253     @Override
    254     protected String getNoObjectText() {
    255         return "No test selected";
    256     }
    257 
    258     @Override
    259     protected String getTitleElementId() {
    260         return "td_title";
    261     }
    262 
    263     @Override
    264     public String getElementId() {
    265         return "test_detail_view";
    266     }
    267 
    268     @Override
    269     public void display() {
    270         super.display();
    271         CommonPanel.getPanel().setConditionVisible(false);
    272     }
    273 
    274     protected void showTest(JSONObject test) {
    275         String testName = test.get("test_name").isString().stringValue();
    276         jobTag = test.get("job_tag").isString().stringValue();
    277 
    278         showText(testName, "td_test");
    279         showText(jobTag, "td_job_tag");
    280         showField(test, "job_name", "td_job_name");
    281         showField(test, "status", "td_status");
    282         showField(test, "reason", "td_reason");
    283         showField(test, "test_started_time", "td_test_started");
    284         showField(test, "test_finished_time", "td_test_finished");
    285         showField(test, "hostname", "td_hostname");
    286         showField(test, "platform", "td_platform");
    287         showField(test, "kernel", "td_kernel");
    288 
    289         String[] labels = Utils.JSONtoStrings(test.get("labels").isArray());
    290         String labelList = Utils.joinStrings(", ", Arrays.asList(labels));
    291         if (labelList.equals("")) {
    292             labelList = "none";
    293         }
    294         showText(labelList, "td_test_labels");
    295 
    296         JSONObject attributes = test.get("attributes").isObject();
    297         attributePanel.clear();
    298         attributePanel.add(new AttributeTable(attributes));
    299 
    300         logLink.setHref(Utils.getRetrieveLogsUrl(jobTag));
    301         testLogLink.setHref(Utils.getRetrieveLogsUrl(jobTag) + "/" + testName);
    302         addLogViewers(testName);
    303 
    304         displayObjectData("Test " + testName + " (job " + jobTag + ")");
    305     }
    306     @Override
    307     public void resetPage() {
    308         super.resetPage();
    309     }
    310 }
    311