blob: b56ce9ce9ee869c2adbe2db4fa006cde02f53fae [file] [log] [blame]
/*
* Copyright (c) 2016 Google Inc. All Rights Reserved.
*
* 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.android.vts.servlet;
import com.android.vts.entity.CodeCoverageEntity;
import com.android.vts.entity.TestCaseRunEntity;
import com.android.vts.entity.TestEntity;
import com.android.vts.entity.TestRunEntity;
import com.android.vts.proto.VtsReportMessage.TestCaseResult;
import com.android.vts.util.DatastoreHelper;
import com.android.vts.util.FilterUtil;
import com.android.vts.util.TestResults;
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.Filter;
import com.google.appengine.api.datastore.Query.SortDirection;
import com.google.gson.Gson;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/** Servlet for handling requests to load individual tables. */
public class ShowTableServlet extends BaseServlet {
private static final String TABLE_JSP = "WEB-INF/jsp/show_table.jsp";
// Error message displayed on the webpage is tableName passed is null.
private static final String TABLE_NAME_ERROR = "Error : Table name must be passed!";
private static final String PROFILING_DATA_ALERT = "No profiling data was found.";
private static final int MAX_BUILD_IDS_PER_PAGE = 10;
@Override
public PageType getNavParentType() {
return PageType.TOT;
}
@Override
public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
List<Page> links = new ArrayList<>();
String testName = request.getParameter("testName");
links.add(new Page(PageType.TABLE, testName, "?testName=" + testName));
return links;
}
public static void processTestRun(TestResults testResults, Entity testRun) {
TestRunEntity testRunEntity = TestRunEntity.fromEntity(testRun);
if (testRunEntity == null) {
return;
}
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
List<Key> gets = new ArrayList<>();
for (long testCaseId : testRunEntity.getTestCaseIds()) {
gets.add(KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseId));
}
List<Entity> testCases = new ArrayList<>();
Map<Key, Entity> entityMap = datastore.get(gets);
for (Key key : gets) {
if (entityMap.containsKey(key)) {
testCases.add(entityMap.get(key));
}
}
testResults.addTestRun(testRun, testCases);
}
@Override
public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
throws IOException {
boolean unfiltered = request.getParameter("unfiltered") != null;
boolean showPresubmit = request.getParameter("showPresubmit") != null;
boolean showPostsubmit = request.getParameter("showPostsubmit") != null;
Long startTime = null; // time in microseconds
Long endTime = null; // time in microseconds
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
RequestDispatcher dispatcher = null;
// message to display if profiling point data is not available
String profilingDataAlert = "";
if (request.getParameter("testName") == null) {
request.setAttribute("testName", TABLE_NAME_ERROR);
return;
}
String testName = request.getParameter("testName");
if (request.getParameter("startTime") != null) {
String time = request.getParameter("startTime");
try {
startTime = Long.parseLong(time);
startTime = startTime > 0 ? startTime : null;
} catch (NumberFormatException e) {
startTime = null;
}
}
if (request.getParameter("endTime") != null) {
String time = request.getParameter("endTime");
try {
endTime = Long.parseLong(time);
endTime = endTime > 0 ? endTime : null;
} catch (NumberFormatException e) {
endTime = 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 result names to list
List<String> resultNames = new ArrayList<>();
for (TestCaseResult r : TestCaseResult.values()) {
resultNames.add(r.name());
}
TestResults testResults = new TestResults(testName);
SortDirection dir = SortDirection.DESCENDING;
if (startTime != null && endTime == null) {
dir = SortDirection.ASCENDING;
}
Key testKey = KeyFactory.createKey(TestEntity.KIND, testName);
Filter typeFilter = FilterUtil.getTestTypeFilter(showPresubmit, showPostsubmit, unfiltered);
Filter testFilter =
FilterUtil.getTimeFilter(
testKey, TestRunEntity.KIND, startTime, endTime, typeFilter);
Map<String, String[]> parameterMap = request.getParameterMap();
List<Filter> userTestFilters = FilterUtil.getUserTestFilters(parameterMap);
userTestFilters.add(0, testFilter);
Filter userDeviceFilter = FilterUtil.getUserDeviceFilter(parameterMap);
List<Key> gets =
FilterUtil.getMatchingKeys(
testKey,
TestRunEntity.KIND,
userTestFilters,
userDeviceFilter,
dir,
MAX_BUILD_IDS_PER_PAGE);
Map<Key, Entity> entityMap = datastore.get(gets);
for (Key key : gets) {
if (!entityMap.containsKey(key)) {
continue;
}
processTestRun(testResults, entityMap.get(key));
}
testResults.processReport();
if (testResults.profilingPointNames.length == 0) {
profilingDataAlert = PROFILING_DATA_ALERT;
}
FilterUtil.setAttributes(request, parameterMap);
request.setAttribute("testName", request.getParameter("testName"));
request.setAttribute("error", profilingDataAlert);
// pass values by converting to JSON
request.setAttribute("headerRow", new Gson().toJson(testResults.headerRow));
request.setAttribute("timeGrid", new Gson().toJson(testResults.timeGrid));
request.setAttribute("durationGrid", new Gson().toJson(testResults.durationGrid));
request.setAttribute("summaryGrid", new Gson().toJson(testResults.summaryGrid));
request.setAttribute("resultsGrid", new Gson().toJson(testResults.resultsGrid));
request.setAttribute("profilingPointNames", testResults.profilingPointNames);
request.setAttribute("resultNames", resultNames);
request.setAttribute("resultNamesJson", new Gson().toJson(resultNames));
request.setAttribute("logInfoMap", new Gson().toJson(testResults.logInfoMap));
// data for pie chart
request.setAttribute(
"topBuildResultCounts", new Gson().toJson(testResults.totResultCounts));
request.setAttribute("topBuildId", testResults.totBuildId);
request.setAttribute("startTime", new Gson().toJson(testResults.startTime));
request.setAttribute("endTime", new Gson().toJson(testResults.endTime));
request.setAttribute(
"hasNewer",
new Gson()
.toJson(
DatastoreHelper.hasNewer(
testKey, TestRunEntity.KIND, testResults.endTime)));
request.setAttribute(
"hasOlder",
new Gson()
.toJson(
DatastoreHelper.hasOlder(
testKey, TestRunEntity.KIND, testResults.startTime)));
request.setAttribute("unfiltered", unfiltered);
request.setAttribute("showPresubmit", showPresubmit);
request.setAttribute("showPostsubmit", showPostsubmit);
request.setAttribute("branches", new Gson().toJson(DatastoreHelper.getAllBranches()));
request.setAttribute("devices", new Gson().toJson(DatastoreHelper.getAllBuildFlavors()));
dispatcher = request.getRequestDispatcher(TABLE_JSP);
try {
dispatcher.forward(request, response);
} catch (ServletException e) {
logger.log(Level.SEVERE, "Servlet Exception caught : " + e.toString());
}
}
}