diff options
Diffstat (limited to 'src/main/java')
-rw-r--r-- | src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java | 214 |
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; } } |