summaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorYoung Gyu Park <younggyu@google.com>2018-06-26 11:36:17 +0900
committerYoung Gyu Park <younggyu@google.com>2018-07-11 10:45:31 +0900
commitc0204c1c2c600bb21515207356d6f5a2626153d7 (patch)
tree2fde7ed4011683dba452ad1f05f06c8cbaf841c5 /src/main/java
parentf967235ef688948f3aef233424966f6b92558772 (diff)
downloaddashboard-c0204c1c2c600bb21515207356d6f5a2626153d7.tar.gz
Coverage Line Graph on coverage page.android-p-preview-5
Test: go/vts-web-staging Bug: 110806899 Change-Id: Ieade25661ac681550ca7be2ce00c3ad89a605f6c
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java214
1 files changed, 207 insertions, 7 deletions
diff --git a/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java b/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java
index 2d09c0b..f0cafbe 100644
--- a/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java
+++ b/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java
@@ -19,6 +19,7 @@ package com.android.vts.servlet;
import com.android.vts.entity.TestCoverageStatusEntity;
import com.android.vts.entity.TestEntity;
import com.android.vts.entity.TestRunEntity;
+import com.android.vts.entity.TestRunEntity.TestRunType;
import com.android.vts.proto.VtsReportMessage;
import com.android.vts.util.DatastoreHelper;
import com.android.vts.util.FilterUtil;
@@ -27,27 +28,59 @@ import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
+import com.google.cloud.datastore.Datastore;
+import com.google.cloud.datastore.DatastoreOptions;
+import com.google.cloud.datastore.LongValue;
+import com.google.cloud.datastore.PathElement;
+import com.google.cloud.datastore.QueryResults;
+import com.google.cloud.datastore.StringValue;
+import com.google.cloud.datastore.StructuredQuery.CompositeFilter;
+import com.google.cloud.datastore.StructuredQuery.Filter;
+import com.google.cloud.datastore.StructuredQuery.PropertyFilter;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
+import com.google.visualization.datasource.DataSourceHelper;
+import com.google.visualization.datasource.DataSourceRequest;
+import com.google.visualization.datasource.base.DataSourceException;
+import com.google.visualization.datasource.base.ReasonType;
+import com.google.visualization.datasource.base.ResponseStatus;
+import com.google.visualization.datasource.base.StatusType;
+import com.google.visualization.datasource.base.TypeMismatchException;
+import com.google.visualization.datasource.datatable.ColumnDescription;
+import com.google.visualization.datasource.datatable.DataTable;
+import com.google.visualization.datasource.datatable.TableRow;
+import com.google.visualization.datasource.datatable.value.DateTimeValue;
+import com.google.visualization.datasource.datatable.value.DateValue;
+import com.google.visualization.datasource.datatable.value.NumberValue;
+import com.google.visualization.datasource.datatable.value.ValueType;
+import com.ibm.icu.util.GregorianCalendar;
+import com.ibm.icu.util.TimeZone;
import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.logging.Level;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
/**
* Represents the servlet that is invoked on loading the coverage overview page.
*/
public class ShowCoverageOverviewServlet extends BaseServlet {
- private static final String COVERAGE_OVERVIEW_JSP = "WEB-INF/jsp/show_coverage_overview.jsp";
-
@Override
public PageType getNavParentType() {
return PageType.COVERAGE_OVERVIEW;
@@ -61,8 +94,68 @@ public class ShowCoverageOverviewServlet extends BaseServlet {
@Override
public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
throws IOException {
- RequestDispatcher dispatcher = null;
+
+ String pageType =
+ request.getParameter("pageType") == null ? "html" : request.getParameter("pageType");
+
+ RequestDispatcher dispatcher;
+ if (pageType.equalsIgnoreCase("html")) {
+ dispatcher = this.getCoverageDispatcher(request, response);
+ try {
+ request.setAttribute("pageType", pageType);
+ response.setStatus(HttpServletResponse.SC_OK);
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Exception caught : ", e);
+ }
+ } else {
+
+ String testName = request.getParameter("testName");
+
+ DataTable data = getCoverageDataTable(testName);
+ DataSourceRequest dsRequest = null;
+
+ try {
+ // Extract the datasource request parameters.
+ dsRequest = new DataSourceRequest(request);
+
+ // NOTE: If you want to work in restricted mode, which means that only
+ // requests from the same domain can access the data source, uncomment the following call.
+ //
+ // DataSourceHelper.verifyAccessApproved(dsRequest);
+
+ // Apply the query to the data table.
+ DataTable newData = DataSourceHelper.applyQuery(dsRequest.getQuery(), data,
+ dsRequest.getUserLocale());
+
+ // Set the response.
+ DataSourceHelper.setServletResponse(newData, dsRequest, response);
+ } catch (RuntimeException rte) {
+ logger.log(Level.SEVERE, "A runtime exception has occured", rte);
+ ResponseStatus status = new ResponseStatus(StatusType.ERROR, ReasonType.INTERNAL_ERROR,
+ rte.getMessage());
+ if (dsRequest == null) {
+ dsRequest = DataSourceRequest.getDefaultDataSourceRequest(request);
+ }
+ DataSourceHelper.setServletErrorResponse(status, dsRequest, response);
+ } catch (DataSourceException e) {
+ if (dsRequest != null) {
+ DataSourceHelper.setServletErrorResponse(e, dsRequest, response);
+ } else {
+ DataSourceHelper.setServletErrorResponse(e, request, response);
+ }
+ }
+ }
+ }
+
+ private RequestDispatcher getCoverageDispatcher(
+ HttpServletRequest request, HttpServletResponse response) {
+
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+
+ String COVERAGE_OVERVIEW_JSP = "WEB-INF/jsp/show_coverage_overview.jsp";
+
+ RequestDispatcher dispatcher = null;
boolean unfiltered = request.getParameter("unfiltered") != null;
boolean showPresubmit = request.getParameter("showPresubmit") != null;
boolean showPostsubmit = request.getParameter("showPostsubmit") != null;
@@ -164,10 +257,117 @@ public class ShowCoverageOverviewServlet extends BaseServlet {
request.setAttribute("branches", new Gson().toJson(DatastoreHelper.getAllBranches()));
request.setAttribute("devices", new Gson().toJson(DatastoreHelper.getAllBuildFlavors()));
dispatcher = request.getRequestDispatcher(COVERAGE_OVERVIEW_JSP);
- try {
- dispatcher.forward(request, response);
- } catch (ServletException e) {
- logger.log(Level.SEVERE, "Servlet Exception caught : ", e);
+ return dispatcher;
+ }
+
+ private DataTable getCoverageDataTable(String testName) {
+
+ Datastore datastore = DatastoreOptions.getDefaultInstance().getService();
+
+ DataTable dataTable = new DataTable();
+ ArrayList<ColumnDescription> cd = new ArrayList<>();
+ ColumnDescription startDate = new ColumnDescription("startDate", ValueType.DATETIME, "Date");
+ startDate.setPattern("yyyy-MM-dd");
+ cd.add(startDate);
+ cd.add(new ColumnDescription("coveredLineCount", ValueType.NUMBER,
+ "Covered Source Code Line Count"));
+ cd.add(
+ new ColumnDescription("totalLineCount", ValueType.NUMBER, "Total Source Code Line Count"));
+ cd.add(new ColumnDescription("percentage", ValueType.NUMBER, "Coverage Ratio (%)"));
+
+ dataTable.addColumns(cd);
+
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.DATE, -30);
+ Long startTime = cal.getTime().getTime() * 1000;
+ Long endTime = Calendar.getInstance().getTime().getTime() * 1000;
+
+ com.google.cloud.datastore.Key startKey = datastore.newKeyFactory()
+ .setKind(TestRunEntity.KIND)
+ .addAncestors(PathElement.of(TestEntity.KIND, testName),
+ PathElement.of(TestRunEntity.KIND, startTime))
+ .newKey(startTime);
+
+ com.google.cloud.datastore.Key endKey = datastore.newKeyFactory()
+ .setKind(TestRunEntity.KIND)
+ .addAncestors(PathElement.of(TestEntity.KIND, testName),
+ PathElement.of(TestRunEntity.KIND, endTime))
+ .newKey(endTime);
+
+ Filter testRunFilter = CompositeFilter.and(
+ PropertyFilter.lt("__key__", endKey),
+ PropertyFilter.gt("__key__", startKey),
+ PropertyFilter.eq("hasCoverage", true)
+ );
+
+ com.google.cloud.datastore.Query<com.google.cloud.datastore.Entity> testRunQuery =
+ com.google.cloud.datastore.Query
+ .newEntityQueryBuilder()
+ .setKind(TestRunEntity.KIND)
+ .setFilter(testRunFilter)
+ .build();
+
+ List<TestRunEntity> testRunEntityList = new ArrayList<>();
+ QueryResults<com.google.cloud.datastore.Entity> testRunIterator = datastore.run(testRunQuery);
+ while (testRunIterator.hasNext()) {
+ com.google.cloud.datastore.Entity entity = testRunIterator.next();
+
+ Key parentKey = KeyFactory.createKey(TestEntity.KIND, entity.getString("testName"));
+
+ List<LongValue> testCaseIdList = entity.getList("testCaseIds");
+ List<StringValue> linkList = new ArrayList<>();
+ if (entity.contains("logLinks")) {
+ linkList = entity.getList("logLinks");
+ }
+ TestRunEntity testRunEntity = new TestRunEntity(
+ KeyFactory.createKey(parentKey, TestRunEntity.KIND, entity.getLong("startTimestamp")),
+ TestRunType.fromNumber(Long.valueOf(entity.getLong("type")).intValue()),
+ entity.getLong("startTimestamp"),
+ entity.getLong("endTimestamp"),
+ entity.getString("testBuildId"),
+ entity.getString("hostName"),
+ entity.getLong("passCount"),
+ entity.getLong("failCount"),
+ testCaseIdList.stream().map(value -> value.get()).collect(Collectors.toList()),
+ linkList.stream().map(v -> v.get()).collect(Collectors.toList()),
+ entity.getLong("coveredLineCount"),
+ entity.getLong("totalLineCount")
+ );
+ testRunEntityList.add(testRunEntity);
}
+
+ DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd");
+ Map<String, List<TestRunEntity>> testRunEntityListMap = testRunEntityList.stream().collect(
+ Collectors.groupingBy(v -> dateTimeFormatter.print(v.getStartTimestamp() / 1000))
+ );
+
+ testRunEntityListMap.forEach((key, entityList) -> {
+ if (dataTable.getRows().size() < 10) {
+ GregorianCalendar gCal = new GregorianCalendar();
+ gCal.setTimeZone(TimeZone.getTimeZone("GMT"));
+ gCal.setTimeInMillis(entityList.get(0).getStartTimestamp() / 1000);
+
+ Long sumCoveredLine = entityList.stream().mapToLong(val -> val.getCoveredLineCount()).sum();
+ Long sumTotalLine = entityList.stream().mapToLong(val -> val.getTotalLineCount()).sum();
+ BigDecimal coveredLineNum = new BigDecimal(sumCoveredLine);
+ BigDecimal totalLineNum = new BigDecimal(sumTotalLine);
+ BigDecimal totalPercent = new BigDecimal(100);
+ float percentage = coveredLineNum.multiply(totalPercent).divide(totalLineNum, 2,
+ RoundingMode.HALF_DOWN).floatValue();
+
+ TableRow tableRow = new TableRow();
+ tableRow.addCell(new DateTimeValue(gCal));
+ tableRow.addCell(new NumberValue(sumCoveredLine));
+ tableRow.addCell(new NumberValue(sumTotalLine));
+ tableRow.addCell(new NumberValue(percentage));
+ try {
+ dataTable.addRow(tableRow);
+ } catch (TypeMismatchException e) {
+ logger.log(Level.WARNING, "Invalid type! ");
+ }
+ }
+ });
+
+ return dataTable;
}
}