Merge "Show history of test results by date"
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/ConfigInfo.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/ConfigInfo.java
index c05a51f..4538e86 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/ConfigInfo.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/ConfigInfo.java
@@ -17,9 +17,11 @@
import com.google.gwt.core.client.JavaScriptObject;
public class ConfigInfo extends JavaScriptObject {
+ final native boolean showJobsSummaryPanel() /*-{ return this.show_jobs_summary_panel ? true : false; }-*/;
final native boolean showJobsPanel() /*-{ return this.show_jobs_panel ? true : false; }-*/;
final native boolean showJobsDropDownPanel() /*-{ return this.show_jobs_drop_down_panel ? true : false; }-*/;
+ final native void setShowJobsSummaryPanel(boolean s) /*-{ this.show_jobs_summary_panel = s; }-*/;
final native void setShowJobsPanel(boolean s) /*-{ this.show_jobs_panel = s; }-*/;
final native void setShowJobsDropDownPanel(boolean s) /*-{ this.show_jobs_drop_down_panel = s; }-*/;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java
index e8ceb89..727da7f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java
@@ -61,7 +61,7 @@
@Override
public void onSuccess(NativeMap<VerificationInfo> result) {
if (!result.isEmpty()) {
- final String patchsetId = change.id() + "," + rev.id();
+ final String patchsetId = change._number() + "/" + rev.id();
display(patchsetId, result);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsScreen.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsScreen.java
index b42b40d..508ed1a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsScreen.java
@@ -19,7 +19,6 @@
import com.google.gerrit.plugin.client.Plugin;
import com.google.gerrit.plugin.client.rpc.RestApi;
import com.google.gerrit.plugin.client.screen.Screen;
-import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.FlexTable;
@@ -30,19 +29,20 @@
public class JobsScreen extends VerticalPanel {
static class Factory implements Screen.EntryPoint {
@Override
- public void onLoad(Screen screen) {
- screen.setPageTitle("Reports for patchset " + screen.getToken(1));
- screen.show(new JobsScreen(screen.getToken(1)));
+ public void onLoad(final Screen screen) {
+ // get change and revision number from passed in patchsetId of form
+ // $changeNumber/$revisionNumber
+ String input = screen.getToken(1);
+ String[] patchsetId = input.split("/");
+ final String changeNumber = patchsetId[0];
+ final String revisionNumber = patchsetId[1];
+ screen.setPageTitle("Report History for Change " + input);
+ screen.show(new JobsScreen(changeNumber, revisionNumber));
}
}
- JobsScreen(final String patchsetId) {
- setStyleName("verifystatus-panel");
- String[] id = patchsetId.split(",");
- String decodedChagneId = URL.decodePathSegment(id[0]);
- String revId = id[1];
-
- new RestApi("changes").id(decodedChagneId).view("revisions").id(revId)
+ JobsScreen(String changeNumber, String revisionNumber) {
+ new RestApi("changes").id(changeNumber).view("revisions").id(revisionNumber)
.view(Plugin.get().getPluginName(), "verifications")
.addParameter("sort", "DATE")
.get(new AsyncCallback<NativeMap<VerificationInfo>>() {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsSummaryPanel.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsSummaryPanel.java
new file mode 100644
index 0000000..fc495df
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsSummaryPanel.java
@@ -0,0 +1,133 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.verifystatus.client;
+
+import com.google.gerrit.client.GerritUiExtensionPoint;
+import com.google.gerrit.client.info.ChangeInfo;
+import com.google.gerrit.client.info.ChangeInfo.RevisionInfo;
+import com.google.gerrit.client.rpc.NativeMap;
+import com.google.gerrit.plugin.client.Plugin;
+import com.google.gerrit.plugin.client.extension.Panel;
+import com.google.gerrit.plugin.client.rpc.RestApi;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Grid;
+import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
+
+import com.google.gwt.user.client.ui.Label;
+
+/**
+ * Extension for change screen that displays job summary table.
+ */
+public class JobsSummaryPanel extends FlowPanel {
+ static class Factory implements Panel.EntryPoint {
+ @Override
+ public void onLoad(Panel panel) {
+ RevisionInfo rev =
+ panel.getObject(GerritUiExtensionPoint.Key.REVISION_INFO).cast();
+ if (rev.isEdit()) {
+ return;
+ }
+
+ panel.setWidget(new JobsSummaryPanel(panel));
+ }
+ }
+
+ private final static String COLOR_GREEN = "#060";
+ private final static String COLOR_RED = "#F00";
+
+ JobsSummaryPanel(Panel panel) {
+ final ChangeInfo change =
+ panel.getObject(GerritUiExtensionPoint.Key.CHANGE_INFO).cast();
+ String decodedChangeId = URL.decodePathSegment(change.id());
+ final RevisionInfo rev =
+ panel.getObject(GerritUiExtensionPoint.Key.REVISION_INFO).cast();
+ new RestApi("changes").id(decodedChangeId).view("revisions").id(rev.id())
+ .view(Plugin.get().getPluginName(), "verifications")
+ .addParameter("sort", "REPORTER").addParameter("filter", "CURRENT")
+ .get(new AsyncCallback<NativeMap<VerificationInfo>>() {
+ @Override
+ public void onSuccess(NativeMap<VerificationInfo> result) {
+ if (!result.isEmpty()) {
+ display(result);
+ }
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ // never invoked
+ }
+ });
+ }
+
+ private void display(NativeMap<VerificationInfo> jobs) {
+ Grid g = createGrid(2, 3);
+ g.setText(0, 0, "Passed");
+ g.setText(0, 1, "Failed");
+ g.setText(0, 2, "Unstable");
+
+ int pass = 0;
+ int fail = 0;
+ int unstable = 0;
+ for (String key : jobs.keySet()) {
+ int value = jobs.get(key).value();
+ if (value > 0) {
+ pass++;
+ } else if (value < 0) {
+ fail++;
+ } else {
+ unstable++;
+ }
+ }
+
+ Label passedLbl = new Label(Integer.toString(pass));
+ passedLbl.getElement().getStyle().setColor(COLOR_GREEN);
+ g.setWidget(1, 0, passedLbl);
+ Label failedLbl = new Label(Integer.toString(fail));
+ failedLbl.getElement().getStyle().setColor(COLOR_RED);
+ g.setWidget(1, 1, failedLbl);
+ Label unstableLbl = new Label(Integer.toString(unstable));
+ g.setWidget(1, 2, unstableLbl);
+ add(g);
+ }
+
+ private static Grid createGrid(int rows, int columns) {
+ Grid g = new Grid(rows, columns);
+ g.addStyleName("infoBlock");
+ g.addStyleName("changeTable");
+
+ CellFormatter fmt = g.getCellFormatter();
+
+ for (int c = 0; c < columns; c++) {
+ fmt.addStyleName(0, c, "header");
+ fmt.addStyleName(0, c, "topmost");
+ }
+
+ for (int r = 1; r < rows; r++) {
+ fmt.addStyleName(r, 0, "leftMostCell");
+
+ for (int c = 1; c < columns; c++) {
+ fmt.addStyleName(r, c, "dataCell");
+ }
+ }
+
+ for (int c = 0; c < columns; c++) {
+ fmt.addStyleName(rows - 1, c, "bottomheader");
+ }
+
+ return g;
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java
index 0446757..2e2575c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java
@@ -34,6 +34,11 @@
.get(new AsyncCallback<ConfigInfo>() {
@Override
public void onSuccess(ConfigInfo info) {
+ if (info.showJobsSummaryPanel()) {
+ Plugin.get().panel(
+ GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
+ new JobsSummaryPanel.Factory());
+ }
if (info.showJobsPanel()) {
Plugin.get().panel(
GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetConfig.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetConfig.java
index bca56b7..8733fb0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetConfig.java
@@ -36,11 +36,13 @@
ConfigInfo info = new ConfigInfo();
info.showJobsPanel = cfg.getBoolean("showJobsPanel", true);
info.showJobsDropDownPanel = cfg.getBoolean("showJobsDropDownPanel", true);
+ info.showJobsSummaryPanel = cfg.getBoolean("showJobsSummaryPanel", true);
return info;
}
public static class ConfigInfo {
Boolean showJobsPanel;
Boolean showJobsDropDownPanel;
+ Boolean showJobsSummaryPanel;
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/PutConfig.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/PutConfig.java
index 8ca1c4a..9fee1a1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/PutConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/PutConfig.java
@@ -40,6 +40,7 @@
public static class Input {
public Boolean showJobsPanel;
public Boolean showJobsDropDownPanel;
+ public Boolean showJobsSummaryPanel;
}
private final PluginConfigFactory cfgFactory;
@@ -77,6 +78,12 @@
} else {
cfg.unset("plugin", pluginName, "showJobsDropDownPanel");
}
+ if (input.showJobsSummaryPanel != null) {
+ cfg.setBoolean("plugin", pluginName, "showJobsSummaryPanel",
+ input.showJobsSummaryPanel);
+ } else {
+ cfg.unset("plugin", pluginName, "showJobsSummaryPanel");
+ }
cfg.save();
cfgFactory.getFromGerritConfig(pluginName, true);
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index 55f030a..3f31ce9 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -1,25 +1,55 @@
-The @PLUGIN@ plugin allows CI system to report build and test results back to
-Gerrit. The reports are stored per patchset and are saved onto an external
-database. Included with this plugin are a set of SSH and REST APIs to automate
-the reporting of test results. This plugin will also handle displaying of the
-job results on the Gerrit UI.
+The @PLUGIN@ plugin seperates test results from comments. It provides a
+separate channel for Gerrit to store test metadata and view them on the
+Gerrit UI. The metadata can be stored in the Gerrit database or in a
+completely separate datastore.
+Typically a CI system, like [Jenkins], will post test metadata to Gerrit as a
+comment. It looks something like this..
+
+```
+Jenkins Aug 24 3:57 PM
+Patch Set 5: Verified-1
+Build Failed
+http://jenkins.acme.com/job/python-27-wacko/4/ : FAILURE
+http://jenkins.acme.com/job/python-27-pep8/6/ : SUCCESS
+http://jenkins.acme.com/job/python-27/4/ : SUCCESS
+..
+```
+
+The problem occurs when there are many jobs verifying each patchset. An
+increased number of reports from Jenkins can overwhelm reviewers who must look
+through the comments and decipher which replies to pay attention to. After a
+while the CI reports become more like spam. Usually human reviewers only
+want to view comments that have been posted by other humans reviewers not bots.
+Since humans and bots must share a communications (or comments) channel it's
+difficult to separate the two competing pieces of data for the purposes of
+reviewing, visualizations and even analytics.
+
+This is where the @PLUGIN@ plugin comes in. It creates a separate channel for
+bots to report info to Gerrit. It provides a separate database to store the
+info and it provides a set of SSH commands and REST endpoints to save
+and retrieve the data. It also provides UI components to view the data
+outside of the Gerrit comments.
### <a id="workflow"></a>
### `Workflow`
-A typical workflow for @PLUGIN@ plugin:
+Any CI system can be used with the @PLUGIN@ plugin.
+A typical workflow:
1. CI system triggers on a new patchset.
2. CI system executes build jobs.
-3. CI system reports build job results with @PLUGIN@ [ssh command](cmd-save.md)
-or [rest-api](rest-api-changes.md).
+3. CI system reports build job results with the @PLUGIN@
+[ssh command](cmd-save.md) or [rest-api](rest-api-changes.md).
4. CI system reports a combined `Verfiied` vote based on the results of each job
using the review [ssh command](../../../Documentation/cmd-review.html) or
-[rest-api](../../../Documentation/rest-api-changes.html#set-review).
+[rest api](../../../Documentation/rest-api-changes.html#set-review).
5. Users can view per patch job results on Gerrit UI or retrieve the results
using the @PLUGIN@ rest api.
+_NOTE_: The [verify-status-reporter] plugin documentation contains specific
+instructions on setting up this workflow with the Jenkins CI system.
+
### <a id="change-screen"></a>
### `Change Screen`
@@ -64,13 +94,16 @@
|:----------------------|:----------|
|showJobsPanel | Whether jobs panel should be displayed (default to true)|
|showJobsDropDownPanel | Whether jobs drop down panel should be displayed (default to true)|
+|showJobsSummaryPanel | Whether jobs summary panel should be displayed (default to true)|
#### Example
```
[plugin "@PLUGIN@"]
- showJobsPanel = false
showJobsDropDownPanel = false
```
+
+[Jenkins]: https://jenkins.io
+[verify-status-reporter]: https://wiki.jenkins-ci.org/display/JENKINS/Verify+Status+Reporter
diff --git a/src/main/resources/Documentation/database.md b/src/main/resources/Documentation/database.md
index cdea76d..852e54f 100644
--- a/src/main/resources/Documentation/database.md
+++ b/src/main/resources/Documentation/database.md
@@ -3,20 +3,20 @@
DESCRIPTION
-----------
-CI data is stored in a [CI database](#supported-dbs) which can be in the Gerrit
-review database or a completely separate database.
+Test metadata is stored in a [CI database](#supported-dbs) which can be in the
+Gerrit review database or a completely separate database.
### <a id="schema-initialization"> @PLUGIN@ schema initialization
Schema initialization
---------------------
-The database is initialized and the schema is created with during an initial
+The database is initialized and the schema is created during an initial
site creation.
```
*** SQL Database for @PLUGIN@
-***
+***
Database server type [h2]: ?
Supported options are:
@@ -35,13 +35,13 @@
Schema upgrade
--------------
-Schema upgrade takes place in init plugin step:
+Schema upgrade takes place in the init plugin step:
```
*** SQL Database for @PLUGIN@
-***
+***
-Database server type [h2]:
+Database server type [h2]:
Upgrading schema to 2 ...
Migrating data to schema 2 ...
@@ -56,8 +56,8 @@
(../../../Documentation/config-gerrit.html#_file_code_etc_gerrit_config_code)
file
-The [database section](#database-params) configures where the @PLUGIN@ stores
-per patchset CI results.
+The [database section](#database-params) configures where the @PLUGIN@ plugin
+stores per patchset test results.
```
[plugin "@PLUGIN@"]
@@ -105,7 +105,7 @@
Acccesing Database
------------------
-@PLUGIN@ provides an administrative interface to the database.
+@PLUGIN@ plugin provides an administrative interface to the database.
'ssh' -p <port> <host> '@PLUGIN@ gsql' [--format {PRETTY | JSON | JSON_SINGLE}] [-c QUERY]
diff --git a/src/main/resources/Documentation/rest-api-config.md b/src/main/resources/Documentation/rest-api-config.md
index eaf22e5..c4936a5 100644
--- a/src/main/resources/Documentation/rest-api-config.md
+++ b/src/main/resources/Documentation/rest-api-config.md
@@ -71,6 +71,7 @@
|:------------------------|:----------|
|show_jobs_panel | Whether jobs panel should be displayed|
|show_jobs_drop_down_panel| Whether jobs drop down panel should be displayed|
+|show_jobs_summary_panel | Whether jobs summary panel should be displayed|
SEE ALSO