diff options
Diffstat (limited to 'src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java')
-rw-r--r-- | src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java | 450 |
1 files changed, 268 insertions, 182 deletions
diff --git a/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java b/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java index 719ade9..210c980 100644 --- a/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java +++ b/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java @@ -17,6 +17,7 @@ package com.android.vts.servlet; import com.android.vts.entity.CodeCoverageEntity; +import com.android.vts.entity.DeviceInfoEntity; import com.android.vts.entity.TestCoverageStatusEntity; import com.android.vts.entity.TestEntity; import com.android.vts.entity.TestRunEntity; @@ -30,7 +31,6 @@ 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; @@ -50,15 +50,19 @@ import com.ibm.icu.util.TimeZone; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; -import java.time.Duration; -import java.time.Instant; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; +import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.function.Predicate; 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; @@ -69,79 +73,82 @@ import org.joda.time.format.DateTimeFormatter; import static com.googlecode.objectify.ObjectifyService.ofy; -/** - * Represents the servlet that is invoked on loading the coverage overview page. - */ +/** Represents the servlet that is invoked on loading the coverage overview page. */ public class ShowCoverageOverviewServlet extends BaseServlet { - @Override - public PageType getNavParentType() { - return PageType.COVERAGE_OVERVIEW; - } - - @Override - public List<Page> getBreadcrumbLinks(HttpServletRequest request) { - return null; - } - - @Override - public void doGetHandler(HttpServletRequest request, HttpServletResponse response) - throws IOException { + @Override + public PageType getNavParentType() { + return PageType.COVERAGE_OVERVIEW; + } - String pageType = - request.getParameter("pageType") == null ? "html" : request.getParameter("pageType"); + @Override + public List<Page> getBreadcrumbLinks(HttpServletRequest request) { + return null; + } - 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); + @Override + public void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException { + + 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 { - DataSourceHelper.setServletErrorResponse(e, request, response); + + 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 List<Key<TestRunEntity>> getTestCoverageStatusEntityKeyList( + private List<Key<TestRunEntity>> getTestRunEntityKeyList( List<TestCoverageStatusEntity> testCoverageStatusEntityList) { return testCoverageStatusEntityList.stream() .map( @@ -158,43 +165,102 @@ public class ShowCoverageOverviewServlet extends BaseServlet { .collect(Collectors.toList()); } - private RequestDispatcher getCoverageDispatcher( - HttpServletRequest request, HttpServletResponse response) { - - 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; - - // If no params are specified, set to default of postsubmit-only. - if (!(showPresubmit || showPostsubmit)) { - showPostsubmit = true; + private Predicate<DeviceInfoEntity> isBranchAndDevice(String branch, String device) { + return d -> d.getBranch().equals(branch) && d.getBuildFlavor().equals(device); } - // If unfiltered, set showPre- and Post-submit to true for accurate UI. - if (unfiltered) { - showPostsubmit = true; - showPresubmit = true; + private Predicate<DeviceInfoEntity> isBranch(String branch) { + return d -> d.getBranch().equals(branch); } - // Add test names to list - List<String> resultNames = new ArrayList<>(); - for (VtsReportMessage.TestCaseResult r : VtsReportMessage.TestCaseResult.values()) { - resultNames.add(r.name()); + private Predicate<DeviceInfoEntity> isDevice(String device) { + return d -> d.getBuildFlavor().equals(device); } - Map<String, String[]> parameterMap = request.getParameterMap(); + private RequestDispatcher getCoverageDispatcher( + HttpServletRequest request, HttpServletResponse response) { - List<TestCoverageStatusEntity> testCoverageStatusEntityList = - TestCoverageStatusEntity.getAllTestCoverage(); + String COVERAGE_OVERVIEW_JSP = "WEB-INF/jsp/show_coverage_overview.jsp"; - List<com.googlecode.objectify.Key<TestRunEntity>> testCoverageStatusEntityKeyList = - this.getTestCoverageStatusEntityKeyList(testCoverageStatusEntityList); + RequestDispatcher dispatcher = null; + boolean unfiltered = request.getParameter("unfiltered") != null; + boolean showPresubmit = request.getParameter("showPresubmit") != null; + boolean showPostsubmit = request.getParameter("showPostsubmit") != null; + + // If no params are specified, set to default of postsubmit-only. + if (!(showPresubmit || showPostsubmit)) { + showPostsubmit = true; + } + + // If unfiltered, set showPre- and Post-submit to true for accurate UI. + if (unfiltered) { + showPostsubmit = true; + showPresubmit = true; + } + + // Add test names to list + List<String> resultNames = + Arrays.stream(VtsReportMessage.TestCaseResult.values()) + .map(testCaseResult -> testCaseResult.name()) + .collect(Collectors.toList()); + + Map<String, String[]> parameterMap = request.getParameterMap(); + + List<TestCoverageStatusEntity> testCoverageStatusEntityList = + TestCoverageStatusEntity.getAllTestCoverage(); + + List<com.googlecode.objectify.Key<TestRunEntity>> testRunEntityKeyList = new ArrayList<>(); + + if (Objects.nonNull(parameterMap.get("branch")) + || Objects.nonNull(parameterMap.get("device"))) { + List<com.googlecode.objectify.Key<DeviceInfoEntity>> deviceInfoEntityKeyList = + TestCoverageStatusEntity.getDeviceInfoEntityKeyList( + testCoverageStatusEntityList); + + Collection<DeviceInfoEntity> deviceInfoEntityMap = + ofy().load().keys(() -> deviceInfoEntityKeyList.iterator()).values(); + + Stream<DeviceInfoEntity> deviceInfoEntityStream = Stream.empty(); + if (Objects.nonNull(parameterMap.get("branch")) + && Objects.nonNull(parameterMap.get("device"))) { + String branch = parameterMap.get("branch")[0]; + String device = parameterMap.get("device")[0]; + deviceInfoEntityStream = + deviceInfoEntityMap.stream().filter(isBranchAndDevice(branch, device)); + } else if (Objects.nonNull(parameterMap.get("branch"))) { + String branch = parameterMap.get("branch")[0]; + deviceInfoEntityStream = deviceInfoEntityMap.stream().filter(isBranch(branch)); + } else if (Objects.nonNull(parameterMap.get("device"))) { + String device = parameterMap.get("device")[0]; + deviceInfoEntityStream = deviceInfoEntityMap.stream().filter(isDevice(device)); + } else { + logger.log(Level.WARNING, "unmet search condition!"); + } + testRunEntityKeyList = + deviceInfoEntityStream + .map( + deviceInfoEntity -> { + com.googlecode.objectify.Key testKey = + com.googlecode.objectify.Key.create( + TestEntity.class, + deviceInfoEntity + .getParent() + .getParent() + .getName()); + return com.googlecode.objectify.Key.create( + testKey, + TestRunEntity.class, + deviceInfoEntity.getParent().getId()); + }) + .collect(Collectors.toList()); + logger.log(Level.INFO, "testRunEntityKeyList size => " + testRunEntityKeyList.size()); + } else { + testRunEntityKeyList = this.getTestRunEntityKeyList(testCoverageStatusEntityList); + } + Iterator<Key<TestRunEntity>> testRunEntityKeyIterator = testRunEntityKeyList.iterator(); Map<Key<TestRunEntity>, TestRunEntity> keyTestRunEntityMap = - ofy().load().keys(() -> testCoverageStatusEntityKeyList.iterator()); + ofy().load().keys(() -> testRunEntityKeyIterator); List<com.googlecode.objectify.Key<CodeCoverageEntity>> codeCoverageEntityKeyList = new ArrayList<>(); @@ -212,100 +278,120 @@ public class ShowCoverageOverviewServlet extends BaseServlet { keyCodeCoverageEntityMap = ofy().load().keys(() -> codeCoverageEntityKeyList.iterator()); - Map<Long, CodeCoverageEntity> codeCoverageEntityMap = new HashMap<>(); + Map<Long, CodeCoverageEntity> codeCoverageEntityMap = new HashMap<>(); for (Map.Entry<com.googlecode.objectify.Key<CodeCoverageEntity>, CodeCoverageEntity> entry : keyCodeCoverageEntityMap.entrySet()) { codeCoverageEntityMap.put(entry.getValue().getId(), entry.getValue()); } - int coveredLines = 0; - int uncoveredLines = 0; - int passCount = 0; - int failCount = 0; - for (Map.Entry<Long, CodeCoverageEntity> entry : codeCoverageEntityMap.entrySet()) { - TestRunEntity testRunEntity = testRunEntityMap.get(entry.getKey()); + int coveredLines = 0; + int uncoveredLines = 0; + int passCount = 0; + int failCount = 0; + for (Map.Entry<Long, CodeCoverageEntity> entry : codeCoverageEntityMap.entrySet()) { + TestRunEntity testRunEntity = testRunEntityMap.get(entry.getKey()); + + CodeCoverageEntity codeCoverageEntity = entry.getValue(); + + coveredLines += codeCoverageEntity.getCoveredLineCount(); + uncoveredLines += + codeCoverageEntity.getTotalLineCount() + - codeCoverageEntity.getCoveredLineCount(); + passCount += testRunEntity.getPassCount(); + failCount += testRunEntity.getFailCount(); + } + + FilterUtil.setAttributes(request, parameterMap); - CodeCoverageEntity codeCoverageEntity = entry.getValue(); + int[] testStats = new int[VtsReportMessage.TestCaseResult.values().length]; + testStats[VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_PASS.getNumber()] = passCount; + testStats[VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_FAIL.getNumber()] = failCount; - coveredLines += codeCoverageEntity.getCoveredLineCount(); - uncoveredLines += codeCoverageEntity.getTotalLineCount() - codeCoverageEntity.getCoveredLineCount(); - passCount += testRunEntity.getPassCount(); - failCount += testRunEntity.getFailCount(); + response.setStatus(HttpServletResponse.SC_OK); + request.setAttribute("resultNames", resultNames); + request.setAttribute("resultNamesJson", new Gson().toJson(resultNames)); + request.setAttribute("testRunEntityList", testRunEntityMap.values()); + request.setAttribute("codeCoverageEntityMap", codeCoverageEntityMap); + request.setAttribute("coveredLines", new Gson().toJson(coveredLines)); + request.setAttribute("uncoveredLines", new Gson().toJson(uncoveredLines)); + request.setAttribute("testStats", new Gson().toJson(testStats)); + + request.setAttribute("unfiltered", unfiltered); + request.setAttribute("showPresubmit", showPresubmit); + request.setAttribute("showPostsubmit", showPostsubmit); + + request.setAttribute( + "deviceOptions", + TestCoverageStatusEntity.getDeviceSet(testCoverageStatusEntityList)); + request.setAttribute( + "branchOptions", + TestCoverageStatusEntity.getBranchSet(testCoverageStatusEntityList)); + dispatcher = request.getRequestDispatcher(COVERAGE_OVERVIEW_JSP); + return dispatcher; } - FilterUtil.setAttributes(request, parameterMap); - - int[] testStats = new int[VtsReportMessage.TestCaseResult.values().length]; - testStats[VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_PASS.getNumber()] = passCount; - testStats[VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_FAIL.getNumber()] = failCount; - - response.setStatus(HttpServletResponse.SC_OK); - request.setAttribute("resultNames", resultNames); - request.setAttribute("resultNamesJson", new Gson().toJson(resultNames)); - request.setAttribute("testRunEntityList", testRunEntityMap.values()); - request.setAttribute("codeCoverageEntityMap", codeCoverageEntityMap); - request.setAttribute("coveredLines", new Gson().toJson(coveredLines)); - request.setAttribute("uncoveredLines", new Gson().toJson(uncoveredLines)); - request.setAttribute("testStats", new Gson().toJson(testStats)); - - request.setAttribute("unfiltered", unfiltered); - request.setAttribute("showPresubmit", showPresubmit); - request.setAttribute("showPostsubmit", showPostsubmit); - request.setAttribute("branches", new Gson().toJson(new ArrayList<>())); // DeviceInfoEntity.getAllBranches() - request.setAttribute("devices", new Gson().toJson(new ArrayList<>())); // DeviceInfoEntity.getAllBuildFlavors() - dispatcher = request.getRequestDispatcher(COVERAGE_OVERVIEW_JSP); - 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.MONTH, -6); - 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 codeCoverageFilter = CompositeFilter.and( - PropertyFilter.lt("__key__", endKey), - PropertyFilter.gt("__key__", startKey) - ); - - List<CodeCoverageEntity> codeCoverageEntityList = ofy().load() - .type(CodeCoverageEntity.class) - .filter(codeCoverageFilter) - .limit(10) - .list(); - - DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd"); - Map<String, List<CodeCoverageEntity>> codeCoverageEntityListMap = codeCoverageEntityList.stream().collect( - Collectors.groupingBy(v -> dateTimeFormatter.print(v.getId() / 1000)) - ); + 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.MONTH, -6); + 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 codeCoverageFilter = + CompositeFilter.and( + PropertyFilter.lt("__key__", endKey), + PropertyFilter.gt("__key__", startKey)); + + List<CodeCoverageEntity> codeCoverageEntityList = + ofy().load() + .type(CodeCoverageEntity.class) + .filter(codeCoverageFilter) + .limit(10) + .list(); + + DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd"); + Map<String, List<CodeCoverageEntity>> codeCoverageEntityListMap = + codeCoverageEntityList + .stream() + .collect( + Collectors.groupingBy( + v -> dateTimeFormatter.print(v.getId() / 1000))); codeCoverageEntityListMap.forEach( (key, entityList) -> { @@ -341,6 +427,6 @@ public class ShowCoverageOverviewServlet extends BaseServlet { } }); - return dataTable; - } + return dataTable; + } } |