summaryrefslogtreecommitdiff
path: root/src/main/java/com/android/vts/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/android/vts/api')
-rw-r--r--src/main/java/com/android/vts/api/BaseApiServlet.java67
-rw-r--r--src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java157
-rw-r--r--src/main/java/com/android/vts/api/CoverageRestServlet.java182
-rw-r--r--src/main/java/com/android/vts/api/DataRestServlet.java81
-rw-r--r--src/main/java/com/android/vts/api/DatastoreRestServlet.java556
-rw-r--r--src/main/java/com/android/vts/api/TestAcknowledgmentRestServlet.java150
-rw-r--r--src/main/java/com/android/vts/api/TestDataForDevServlet.java676
-rw-r--r--src/main/java/com/android/vts/api/TestRunRestServlet.java134
-rw-r--r--src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java130
-rw-r--r--src/main/java/com/android/vts/api/UserFavoriteRestServlet.java207
10 files changed, 0 insertions, 2340 deletions
diff --git a/src/main/java/com/android/vts/api/BaseApiServlet.java b/src/main/java/com/android/vts/api/BaseApiServlet.java
deleted file mode 100644
index b7384a7..0000000
--- a/src/main/java/com/android/vts/api/BaseApiServlet.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2018 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.api;
-
-import com.google.apphosting.api.ApiProxy;
-import java.util.Properties;
-import java.util.logging.Logger;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletResponse;
-
-/** An abstract class to be subclassed to create API Servlet */
-public class BaseApiServlet extends HttpServlet {
-
- private static final Logger logger = Logger.getLogger(BaseApiServlet.class.getName());
-
- /** System Configuration Property class */
- protected Properties systemConfigProp = new Properties();
-
- /** Appengine server host name */
- protected String hostName;
-
- /**
- * This variable is for maximum number of entities per transaction You can find the detail here
- * (https://cloud.google.com/datastore/docs/concepts/limits)
- */
- protected int MAX_ENTITY_SIZE_PER_TRANSACTION = 300;
-
- @Override
- public void init(ServletConfig cfg) throws ServletException {
- super.init(cfg);
-
- systemConfigProp =
- Properties.class.cast(cfg.getServletContext().getAttribute("systemConfigProp"));
-
- this.MAX_ENTITY_SIZE_PER_TRANSACTION =
- Integer.parseInt(systemConfigProp.getProperty("datastore.maxEntitySize"));
-
- ApiProxy.Environment env = ApiProxy.getCurrentEnvironment();
- hostName =
- env.getAttributes()
- .get("com.google.appengine.runtime.default_version_hostname")
- .toString();
- }
-
- protected void setAccessControlHeaders(HttpServletResponse resp) {
- resp.setHeader("Access-Control-Allow-Origin", hostName);
- resp.setHeader("Access-Control-Allow-Methods", "GET, PUT, POST, OPTIONS, DELETE");
- resp.addHeader("Access-Control-Allow-Headers", "Content-Type");
- resp.addHeader("Access-Control-Max-Age", "86400");
- }
-}
diff --git a/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java b/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java
deleted file mode 100644
index d331d4b..0000000
--- a/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.api;
-
-import com.android.vts.proto.VtsReportMessage.TestReportMessage;
-import com.android.vts.servlet.BaseServlet;
-import com.android.vts.util.DatastoreHelper;
-import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
-import com.google.api.client.http.javanet.NetHttpTransport;
-import com.google.api.client.json.jackson.JacksonFactory;
-import com.google.api.services.oauth2.Oauth2;
-import com.google.api.services.oauth2.model.Tokeninfo;
-import com.google.protobuf.InvalidProtocolBufferException;
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.codec.binary.Base64;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/** REST endpoint for posting data JSON to the Dashboard. */
-@Deprecated
-public class BigtableLegacyJsonServlet extends HttpServlet {
- private static String SERVICE_CLIENT_ID;
- private static final String SERVICE_NAME = "VTS Dashboard";
- private static final Logger logger =
- Logger.getLogger(BigtableLegacyJsonServlet.class.getName());
-
- /** System Configuration Property class */
- protected Properties systemConfigProp = new Properties();
-
- @Override
- public void init(ServletConfig cfg) throws ServletException {
- super.init(cfg);
-
- try {
- InputStream defaultInputStream =
- BigtableLegacyJsonServlet.class
- .getClassLoader()
- .getResourceAsStream("config.properties");
- systemConfigProp.load(defaultInputStream);
-
- SERVICE_CLIENT_ID = systemConfigProp.getProperty("appengine.serviceClientID");
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- // Retrieve the params
- String payload = new String();
- JSONObject payloadJson;
- try {
- String line = null;
- BufferedReader reader = request.getReader();
- while ((line = reader.readLine()) != null) {
- payload += line;
- }
- payloadJson = new JSONObject(payload);
- } catch (IOException | JSONException e) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- logger.log(Level.WARNING, "Invalid JSON: " + payload);
- return;
- }
-
- // Verify service account access token.
- boolean authorized = false;
- if (payloadJson.has("accessToken")) {
- String accessToken = payloadJson.getString("accessToken").trim();
- GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
- Oauth2 oauth2 =
- new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credential)
- .setApplicationName(SERVICE_NAME)
- .build();
- Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute();
- if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) {
- authorized = true;
- }
- }
-
- if (!authorized) {
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- return;
- }
-
- // Parse the desired action and execute the command
- try {
- if (payloadJson.has("verb")) {
- switch (payloadJson.getString("verb")) {
- case "createTable":
- logger.log(Level.INFO, "Deprecated verb: createTable.");
- break;
- case "insertRow":
- insertData(payloadJson);
- break;
- default:
- logger.log(
- Level.WARNING,
- "Invalid Datastore REST verb: " + payloadJson.getString("verb"));
- throw new IOException("Unsupported POST verb.");
- }
- }
- } catch (IOException e) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- response.setStatus(HttpServletResponse.SC_OK);
- }
-
- /**
- * Inserts a data into the Cloud Datastore
- *
- * @param payloadJson The JSON object representing the row to be inserted. Of the form: {
- * (deprecated) 'tableName' : 'table', (deprecated) 'rowKey' : 'row', (deprecated) 'family'
- * : 'family', (deprecated) 'qualifier' : 'qualifier', 'value' : 'value' }
- * @throws IOException
- */
- private void insertData(JSONObject payloadJson) throws IOException {
- if (!payloadJson.has("value")) {
- logger.log(Level.WARNING, "Missing attributes for datastore api insertRow().");
- return;
- }
- try {
- byte[] value = Base64.decodeBase64(payloadJson.getString("value"));
- TestReportMessage testReportMessage = TestReportMessage.parseFrom(value);
- } catch (InvalidProtocolBufferException e) {
- logger.log(Level.WARNING, "Invalid report posted to dashboard.");
- }
- }
-}
diff --git a/src/main/java/com/android/vts/api/CoverageRestServlet.java b/src/main/java/com/android/vts/api/CoverageRestServlet.java
deleted file mode 100644
index aebd3e5..0000000
--- a/src/main/java/com/android/vts/api/CoverageRestServlet.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2018 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.api;
-
-import com.android.vts.entity.ApiCoverageEntity;
-import com.android.vts.entity.CoverageEntity;
-import com.android.vts.entity.TestCoverageStatusEntity;
-import com.android.vts.entity.TestPlanRunEntity;
-import com.android.vts.entity.TestRunEntity;
-import com.google.gson.Gson;
-import com.googlecode.objectify.Key;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import static com.googlecode.objectify.ObjectifyService.ofy;
-
-/** REST endpoint for posting test suite data to the Dashboard. */
-public class CoverageRestServlet extends BaseApiServlet {
-
- private static final Logger logger = Logger.getLogger(CoverageRestServlet.class.getName());
-
- @Override
- public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
- String pathInfo = request.getPathInfo();
- String json = "";
- if (Objects.nonNull(pathInfo)) {
- if (pathInfo.equalsIgnoreCase("/api/data")) {
- String key = request.getParameter("key");
- json = apiCoverageData(key);
- } else {
- json = "{error: 'true', message: 'unexpected path!!!'}";
- logger.log(Level.INFO, "Path Info => " + pathInfo);
- logger.log(Level.WARNING, "Unknown path access!");
- }
- } else {
- json = "{error: 'true', message: 'the path info is not existed!!!'}";
- }
-
- response.setStatus(HttpServletResponse.SC_OK);
- response.setContentType("application/json");
- response.setCharacterEncoding("UTF-8");
- response.getWriter().write(json);
- }
-
- private String apiCoverageData(String key) {
- ApiCoverageEntity apiCoverageEntity = ApiCoverageEntity.getByUrlSafeKey(key);
- String apiCoverageEntityJson = new Gson().toJson(apiCoverageEntity);
- return apiCoverageEntityJson;
- }
-
- @Override
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
-
- String pathInfo = request.getPathInfo();
- String json = "";
- if (Objects.nonNull(pathInfo)) {
- if (pathInfo.equalsIgnoreCase("/api/data")) {
- String cmd = request.getParameter("cmd");
- String coverageId = request.getParameter("coverageId");
- String testName = request.getParameter("testName");
- String testRunId = request.getParameter("testRunId");
- json = postCoverageData(cmd, coverageId, testName, testRunId);
- } else if (pathInfo.equalsIgnoreCase("/api/sum")) {
- String urlSafeKey = request.getParameter("urlSafeKey");
- json = postCoverageDataSum(urlSafeKey);
- } else {
- json = "{error: 'true', message: 'unexpected path!!!'}";
- }
- } else {
- json = "{error: 'true', message: 'the path info is not existed!!!'}";
- }
-
- response.setStatus(HttpServletResponse.SC_OK);
- response.setContentType("application/json");
- response.setCharacterEncoding("UTF-8");
- response.getWriter().write(json);
- }
-
- private String postCoverageDataSum(String urlSafeKey) {
- List<List<String>> allHalApiList = new ArrayList();
- List<List<String>> allCoveredHalApiList = new ArrayList();
-
- Key<TestPlanRunEntity> key = Key.create(urlSafeKey);
- TestPlanRunEntity testPlanRunEntity = ofy().load().key(key).safe();
-
- for (Key<TestRunEntity> testRunKey : testPlanRunEntity.getTestRuns()) {
- List<ApiCoverageEntity> apiCoverageEntityList =
- ofy().load().type(ApiCoverageEntity.class).ancestor(testRunKey).list();
- for (ApiCoverageEntity apiCoverageEntity : apiCoverageEntityList) {
- allHalApiList.add(apiCoverageEntity.getHalApi());
- allCoveredHalApiList.add(apiCoverageEntity.getCoveredHalApi());
- }
- }
- long totalHalApiNum = allHalApiList.stream().flatMap(Collection::stream).distinct().count();
- long totalCoveredHalApiNum =
- allCoveredHalApiList.stream().flatMap(Collection::stream).distinct().count();
- if (totalHalApiNum > 0) {
- testPlanRunEntity.setTotalApiCount(totalHalApiNum);
- if (totalCoveredHalApiNum > 0) {
- testPlanRunEntity.setCoveredApiCount(totalCoveredHalApiNum);
- }
- testPlanRunEntity.save();
- }
-
- Map<String, Long> halApiNumMap =
- new HashMap<String, Long>() {
- {
- put("totalHalApiNum", totalHalApiNum);
- put("totalCoveredHalApiNum", totalCoveredHalApiNum);
- }
- };
- String json = new Gson().toJson(halApiNumMap);
- return json;
- }
-
- /**
- * The API to ignore the irrelevant code for calculating ratio
- *
- * @param cmd disable or enable command to ignore the code.
- * @param coverageId the datastore ID for code coverage.
- * @param testName the test name.
- * @param testRunId the test run ID from datastore.
- * @return success json.
- */
- private String postCoverageData(
- String cmd, String coverageId, String testName, String testRunId) {
-
- Boolean isIgnored = false;
- if (cmd.equals("disable")) {
- isIgnored = true;
- }
- CoverageEntity coverageEntity = CoverageEntity.findById(testName, testRunId, coverageId);
- coverageEntity.setIsIgnored(isIgnored);
- coverageEntity.save();
-
- TestCoverageStatusEntity testCoverageStatusEntity =
- TestCoverageStatusEntity.findById(testName);
- Long newCoveredLineCount =
- cmd.equals("disable")
- ? testCoverageStatusEntity.getUpdatedCoveredLineCount()
- - coverageEntity.getCoveredCount()
- : testCoverageStatusEntity.getUpdatedCoveredLineCount()
- + coverageEntity.getCoveredCount();
- Long newTotalLineCount =
- cmd.equals("disable")
- ? testCoverageStatusEntity.getUpdatedTotalLineCount()
- - coverageEntity.getTotalCount()
- : testCoverageStatusEntity.getUpdatedTotalLineCount()
- + coverageEntity.getTotalCount();
- testCoverageStatusEntity.setUpdatedCoveredLineCount(newCoveredLineCount);
- testCoverageStatusEntity.setUpdatedTotalLineCount(newTotalLineCount);
- testCoverageStatusEntity.save();
-
- String json = new Gson().toJson("Success!");
- return json;
- }
-}
diff --git a/src/main/java/com/android/vts/api/DataRestServlet.java b/src/main/java/com/android/vts/api/DataRestServlet.java
deleted file mode 100644
index 409818e..0000000
--- a/src/main/java/com/android/vts/api/DataRestServlet.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2018 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.api;
-
-import com.android.vts.entity.BranchEntity;
-import com.android.vts.entity.TestCoverageStatusEntity;
-import com.google.gson.Gson;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.List;
-import java.util.Objects;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.android.vts.entity.BuildTargetEntity;
-
-/** REST endpoint for getting all branch and buildFlavors information. */
-public class DataRestServlet extends BaseApiServlet {
-
- private static final Logger logger = Logger.getLogger(DataRestServlet.class.getName());
-
- @Override
- public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
- String pathInfo = request.getPathInfo();
- String json = "";
- if (Objects.nonNull(pathInfo)) {
- String schKey =
- Objects.isNull(request.getParameter("schKey"))
- ? ""
- : request.getParameter("schKey");
- if (pathInfo.equalsIgnoreCase("/branch")) {
- json = new Gson().toJson(BranchEntity.getByBranch(schKey));
- } else if (pathInfo.equalsIgnoreCase("/device")) {
- json = new Gson().toJson(BuildTargetEntity.getByBuildTarget(schKey));
- } else if (pathInfo.startsWith("/code/coverage/status/")) {
- List<TestCoverageStatusEntity> testCoverageStatusEntityList =
- TestCoverageStatusEntity.getAllTestCoverage();
- if (pathInfo.endsWith("branch")) {
- json =
- new Gson()
- .toJson(
- TestCoverageStatusEntity.getBranchSet(
- testCoverageStatusEntityList));
- } else {
- json =
- new Gson()
- .toJson(
- TestCoverageStatusEntity.getDeviceSet(
- testCoverageStatusEntityList));
- }
- } else {
- json = "{error: 'true', message: 'unexpected path!!!'}";
- logger.log(Level.INFO, "Path Info => " + pathInfo);
- logger.log(Level.WARNING, "Unknown path access!");
- }
- } else {
- json = "{error: 'true', message: 'the path info is not existed!!!'}";
- }
-
- response.setStatus(HttpServletResponse.SC_OK);
- response.setContentType("application/json");
- response.setCharacterEncoding("UTF-8");
- response.getWriter().write(json);
- }
-}
diff --git a/src/main/java/com/android/vts/api/DatastoreRestServlet.java b/src/main/java/com/android/vts/api/DatastoreRestServlet.java
deleted file mode 100644
index fa0ae65..0000000
--- a/src/main/java/com/android/vts/api/DatastoreRestServlet.java
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * 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.api;
-
-import com.android.vts.entity.ApiCoverageEntity;
-import com.android.vts.entity.BranchEntity;
-import com.android.vts.entity.BuildTargetEntity;
-import com.android.vts.entity.CodeCoverageEntity;
-import com.android.vts.entity.CoverageEntity;
-import com.android.vts.entity.DashboardEntity;
-import com.android.vts.entity.DeviceInfoEntity;
-import com.android.vts.entity.HalApiEntity;
-import com.android.vts.entity.ProfilingPointRunEntity;
-import com.android.vts.entity.TestCaseRunEntity;
-import com.android.vts.entity.TestEntity;
-import com.android.vts.entity.TestPlanEntity;
-import com.android.vts.entity.TestPlanRunEntity;
-import com.android.vts.entity.TestRunEntity;
-import com.android.vts.proto.VtsReportMessage;
-import com.android.vts.proto.VtsReportMessage.DashboardPostMessage;
-import com.android.vts.proto.VtsReportMessage.TestPlanReportMessage;
-import com.android.vts.proto.VtsReportMessage.TestReportMessage;
-import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
-import com.google.api.client.http.javanet.NetHttpTransport;
-import com.google.api.client.json.jackson.JacksonFactory;
-import com.google.api.services.oauth2.Oauth2;
-import com.google.api.services.oauth2.model.Tokeninfo;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import com.google.appengine.api.datastore.Key;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.codec.binary.Base64;
-
-import static com.googlecode.objectify.ObjectifyService.ofy;
-
-@Slf4j
-/** REST endpoint for posting data to the Dashboard. */
-public class DatastoreRestServlet extends BaseApiServlet {
- private static String SERVICE_CLIENT_ID;
- private static final String SERVICE_NAME = "VTS Dashboard";
-
- @Override
- public void init(ServletConfig cfg) throws ServletException {
- super.init(cfg);
-
- SERVICE_CLIENT_ID = this.systemConfigProp.getProperty("appengine.serviceClientID");
- }
-
- @Override
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- // Retrieve the params
- DashboardPostMessage postMessage;
- try {
- String payload = request.getReader().lines().collect(Collectors.joining());
- byte[] value = Base64.decodeBase64(payload);
- postMessage = DashboardPostMessage.parseFrom(value);
- } catch (IOException e) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- log.error("Invalid proto: " + e.getLocalizedMessage());
- return;
- }
-
- String resultMsg = "";
- // Verify service account access token.
- if (postMessage.hasAccessToken()) {
- String accessToken = postMessage.getAccessToken();
- log.debug("accessToken => " + accessToken);
-
- GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
- Oauth2 oauth2 =
- new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credential)
- .setApplicationName(SERVICE_NAME)
- .build();
- Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute();
- if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) {
- for (TestReportMessage testReportMessage : postMessage.getTestReportList()) {
- this.insertTestReport(testReportMessage);
- }
-
- for (TestPlanReportMessage planReportMessage :
- postMessage.getTestPlanReportList()) {
- this.insertTestPlanReport(planReportMessage);
- }
-
- response.setStatus(HttpServletResponse.SC_OK);
- resultMsg = "Success!!";
- } else {
- log.warn("service_client_id didn't match!");
- log.debug("SERVICE_CLIENT_ID => " + tokenInfo.getIssuedTo());
- resultMsg = "Your SERVICE_CLIENT_ID is incorrect!";
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- }
- } else {
- log.error("postMessage do not contain any accessToken!");
- resultMsg = "Your message do not have access token!";
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- }
- response.setContentType("application/json");
- response.setCharacterEncoding("UTF-8");
- response.getWriter().write("{'result_msg': " + resultMsg + "}");
- }
-
- /**
- * Upload data from a test report message
- *
- * @param report The test report containing data to upload.
- */
- private void insertTestReport(TestReportMessage report) {
-
- if (!report.hasStartTimestamp()
- || !report.hasEndTimestamp()
- || !report.hasTest()
- || !report.hasHostInfo()
- || !report.hasBuildInfo()) {
- // missing information
- log.error("Missing information in report !");
- return;
- }
-
- List<TestEntity> testEntityList = new ArrayList<>();
- List<TestRunEntity> testRunEntityList = new ArrayList<>();
- List<BranchEntity> branchEntityList = new ArrayList<>();
- List<BuildTargetEntity> buildTargetEntityList = new ArrayList<>();
- List<CoverageEntity> coverageEntityList = new ArrayList<>();
- List<CodeCoverageEntity> codeCoverageEntityList = new ArrayList<>();
- List<DeviceInfoEntity> deviceInfoEntityList = new ArrayList<>();
- List<ProfilingPointRunEntity> profilingPointRunEntityList = new ArrayList<>();
- List<TestCaseRunEntity> testCaseRunEntityList = new ArrayList<>();
- List<ApiCoverageEntity> apiCoverageEntityList = new ArrayList<>();
-
- List<?> allEntityList =
- Arrays.asList(
- testEntityList,
- branchEntityList,
- buildTargetEntityList,
- coverageEntityList,
- codeCoverageEntityList,
- deviceInfoEntityList,
- profilingPointRunEntityList,
- testCaseRunEntityList,
- apiCoverageEntityList,
- testRunEntityList);
-
- long passCount = 0;
- long failCount = 0;
- long coveredLineCount = 0;
- long totalLineCount = 0;
-
- Set<Key> buildTargetKeys = new HashSet<>();
- Set<Key> branchKeys = new HashSet<>();
- List<Key> profilingPointKeyList = new ArrayList<>();
- List<String> linkList = new ArrayList<>();
-
- long startTimestamp = report.getStartTimestamp();
- long endTimestamp = report.getEndTimestamp();
- String testName = report.getTest().toStringUtf8();
- String testBuildId = report.getBuildInfo().getId().toStringUtf8();
- String hostName = report.getHostInfo().getHostname().toStringUtf8();
-
- TestEntity testEntity = new TestEntity(testName);
-
- com.googlecode.objectify.Key testRunKey =
- testEntity.getTestRunKey(report.getStartTimestamp());
-
- testEntityList.add(testEntity);
-
- int testCaseRunEntityIndex = 0;
- testCaseRunEntityList.add(new TestCaseRunEntity());
- // Process test cases
- for (VtsReportMessage.TestCaseReportMessage testCase : report.getTestCaseList()) {
- String testCaseName = testCase.getName().toStringUtf8();
- VtsReportMessage.TestCaseResult result = testCase.getTestResult();
- // Track global pass/fail counts
- if (result == VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_PASS) {
- ++passCount;
- } else if (result != VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_SKIP) {
- ++failCount;
- }
- if (testCase.getSystraceCount() > 0
- && testCase.getSystraceList().get(0).getUrlCount() > 0) {
- String systraceLink = testCase.getSystraceList().get(0).getUrl(0).toStringUtf8();
- linkList.add(systraceLink);
- }
-
- // Process coverage data for test case
- for (VtsReportMessage.CoverageReportMessage coverage : testCase.getCoverageList()) {
- CoverageEntity coverageEntity =
- CoverageEntity.fromCoverageReport(testRunKey, testCaseName, coverage);
- if (coverageEntity == null) {
- log.warn("Invalid coverage report in test run " + testRunKey);
- } else {
- coveredLineCount += coverageEntity.getCoveredCount();
- totalLineCount += coverageEntity.getTotalCount();
- coverageEntityList.add(coverageEntity);
- }
- }
-
- // Process profiling data for test case
- for (VtsReportMessage.ProfilingReportMessage profiling : testCase.getProfilingList()) {
- ProfilingPointRunEntity profilingPointRunEntity =
- ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling);
- if (profilingPointRunEntity == null) {
- log.warn("Invalid profiling report in test run " + testRunKey);
- } else {
- profilingPointRunEntityList.add(profilingPointRunEntity);
- profilingPointKeyList.add(profilingPointRunEntity.getKey());
- testEntity.setHasProfilingData(true);
- }
- }
-
- TestCaseRunEntity testCaseRunEntity = testCaseRunEntityList.get(testCaseRunEntityIndex);
- if (!testCaseRunEntity.addTestCase(testCaseName, result.getNumber())) {
- testCaseRunEntity = new TestCaseRunEntity();
- testCaseRunEntity.addTestCase(testCaseName, result.getNumber());
- testCaseRunEntityList.add(testCaseRunEntity);
- testCaseRunEntityIndex++;
- }
- }
-
- // Process device information
- long testRunType = 0;
- for (VtsReportMessage.AndroidDeviceInfoMessage device : report.getDeviceInfoList()) {
- DeviceInfoEntity deviceInfoEntity =
- DeviceInfoEntity.fromDeviceInfoMessage(testRunKey, device);
- if (deviceInfoEntity == null) {
- log.warn("Invalid device info in test run " + testRunKey);
- } else {
- // Run type on devices must be the same, else set to OTHER
- TestRunEntity.TestRunType runType =
- TestRunEntity.TestRunType.fromBuildId(deviceInfoEntity.getBuildId());
- if (runType == null) {
- testRunType = TestRunEntity.TestRunType.OTHER.getNumber();
- } else {
- testRunType = runType.getNumber();
- }
- deviceInfoEntityList.add(deviceInfoEntity);
- BuildTargetEntity target = new BuildTargetEntity(deviceInfoEntity.getBuildFlavor());
- if (buildTargetKeys.add(target.getKey())) {
- buildTargetEntityList.add(target);
- }
- BranchEntity branch = new BranchEntity(deviceInfoEntity.getBranch());
- if (branchKeys.add(branch.getKey())) {
- branchEntityList.add(branch);
- }
- }
- }
-
- // Overall run type should be determined by the device builds unless test build is OTHER
- if (testRunType == TestRunEntity.TestRunType.OTHER.getNumber()) {
- testRunType = TestRunEntity.TestRunType.fromBuildId(testBuildId).getNumber();
- } else if (TestRunEntity.TestRunType.fromBuildId(testBuildId)
- == TestRunEntity.TestRunType.OTHER) {
- testRunType = TestRunEntity.TestRunType.OTHER.getNumber();
- }
-
- // Process global coverage data
- for (VtsReportMessage.CoverageReportMessage coverage : report.getCoverageList()) {
- CoverageEntity coverageEntity =
- CoverageEntity.fromCoverageReport(testRunKey, new String(), coverage);
- if (coverageEntity == null) {
- log.warn("Invalid coverage report in test run " + testRunKey);
- } else {
- coveredLineCount += coverageEntity.getCoveredCount();
- totalLineCount += coverageEntity.getTotalCount();
- coverageEntityList.add(coverageEntity);
- }
- }
-
- // Process global API coverage data
- for (VtsReportMessage.ApiCoverageReportMessage apiCoverage : report.getApiCoverageList()) {
- VtsReportMessage.HalInterfaceMessage halInterfaceMessage =
- apiCoverage.getHalInterface();
- List<String> halApiList =
- apiCoverage
- .getHalApiList()
- .stream()
- .map(h -> h.toStringUtf8())
- .collect(Collectors.toList());
- List<String> coveredHalApiList =
- apiCoverage
- .getCoveredHalApiList()
- .stream()
- .map(h -> h.toStringUtf8())
- .collect(Collectors.toList());
- ApiCoverageEntity apiCoverageEntity =
- new ApiCoverageEntity(
- testRunKey,
- halInterfaceMessage.getHalPackageName().toStringUtf8(),
- halInterfaceMessage.getHalVersionMajor(),
- halInterfaceMessage.getHalVersionMinor(),
- halInterfaceMessage.getHalInterfaceName().toStringUtf8(),
- halApiList,
- coveredHalApiList);
- apiCoverageEntityList.add(apiCoverageEntity);
- }
-
- // Process global profiling data
- for (VtsReportMessage.ProfilingReportMessage profiling : report.getProfilingList()) {
- ProfilingPointRunEntity profilingPointRunEntity =
- ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling);
- if (profilingPointRunEntity == null) {
- log.warn("Invalid profiling report in test run " + testRunKey);
- } else {
- profilingPointRunEntityList.add(profilingPointRunEntity);
- profilingPointKeyList.add(profilingPointRunEntity.getKey());
- testEntity.setHasProfilingData(true);
- }
- }
-
- // Process log data
- for (VtsReportMessage.LogMessage log : report.getLogList()) {
- if (log.hasUrl()) {
- linkList.add(log.getUrl().toStringUtf8());
- }
- }
- // Process url resource
- for (VtsReportMessage.UrlResourceMessage resource : report.getLinkResourceList()) {
- if (resource.hasUrl()) {
- linkList.add(resource.getUrl().toStringUtf8());
- }
- }
-
- boolean hasCodeCoverage = totalLineCount > 0 && coveredLineCount >= 0;
- TestRunEntity testRunEntity =
- new TestRunEntity(
- testEntity.getOldKey(),
- testRunType,
- startTimestamp,
- endTimestamp,
- testBuildId,
- hostName,
- passCount,
- failCount,
- hasCodeCoverage,
- new ArrayList<>(),
- linkList);
- testRunEntityList.add(testRunEntity);
-
- CodeCoverageEntity codeCoverageEntity =
- new CodeCoverageEntity(
- testRunEntity.getId(),
- testRunEntity.getKey(),
- coveredLineCount,
- totalLineCount);
- codeCoverageEntityList.add(codeCoverageEntity);
-
- ofy().transact(
- () -> {
- List<Long> testCaseIds = new ArrayList<>();
- for (Object entity : allEntityList) {
- if (entity instanceof List) {
- List listEntity = (List) entity;
- if (listEntity.size() > 0
- && listEntity.get(0) instanceof TestCaseRunEntity) {
- Map<
- com.googlecode.objectify.Key<
- TestCaseRunEntity>,
- TestCaseRunEntity>
- testCaseRunEntityMap =
- DashboardEntity.saveAll(
- testCaseRunEntityList,
- this
- .MAX_ENTITY_SIZE_PER_TRANSACTION);
-
- testCaseIds =
- testCaseRunEntityMap
- .values()
- .stream()
- .map(
- testCaseRunEntity ->
- testCaseRunEntity.getId())
- .collect(Collectors.toList());
- } else if (listEntity.size() > 0
- && listEntity.get(0) instanceof TestRunEntity) {
- testRunEntityList.get(0).setTestCaseIds(testCaseIds);
- DashboardEntity.saveAll(
- testRunEntityList,
- this.MAX_ENTITY_SIZE_PER_TRANSACTION);
- } else {
- List<DashboardEntity> dashboardEntityList =
- (List<DashboardEntity>) entity;
- DashboardEntity.saveAll(
- dashboardEntityList,
- this.MAX_ENTITY_SIZE_PER_TRANSACTION);
- }
- }
- }
- });
- }
-
- /**
- * Upload data from a test plan report message
- *
- * @param report The test plan report containing data to upload.
- */
- private void insertTestPlanReport(TestPlanReportMessage report) {
- List<DeviceInfoEntity> deviceInfoEntityList = new ArrayList<>();
- List<HalApiEntity> halApiEntityList = new ArrayList<>();
-
- List allEntityList = Arrays.asList(deviceInfoEntityList, halApiEntityList);
-
- List<String> testModules = report.getTestModuleNameList();
- List<Long> testTimes = report.getTestModuleStartTimestampList();
- if (testModules.size() != testTimes.size() || !report.hasTestPlanName()) {
- log.error("TestPlanReportMessage is missing information.");
- return;
- }
-
- String testPlanName = report.getTestPlanName();
- TestPlanEntity testPlanEntity = new TestPlanEntity(testPlanName);
- List<com.googlecode.objectify.Key<TestRunEntity>> testRunKeyList = new ArrayList<>();
- for (int index = 0; index < testModules.size(); index++) {
- String test = testModules.get(index);
- long time = testTimes.get(index);
- com.googlecode.objectify.Key testKey =
- com.googlecode.objectify.Key.create(TestEntity.class, test);
- com.googlecode.objectify.Key testRunKey =
- com.googlecode.objectify.Key.create(testKey, TestRunEntity.class, time);
- testRunKeyList.add(testRunKey);
- }
-
- Map<com.googlecode.objectify.Key<TestRunEntity>, TestRunEntity> testRunEntityMap =
- ofy().load().keys(() -> testRunKeyList.iterator());
-
- long passCount = 0;
- long failCount = 0;
- long startTimestamp = -1;
- long endTimestamp = -1;
- String testBuildId = null;
- long testType = -1;
- Set<DeviceInfoEntity> deviceInfoEntitySet = new HashSet<>();
- for (TestRunEntity testRunEntity : testRunEntityMap.values()) {
- passCount += testRunEntity.getPassCount();
- failCount += testRunEntity.getFailCount();
- if (startTimestamp < 0 || testRunEntity.getStartTimestamp() < startTimestamp) {
- startTimestamp = testRunEntity.getStartTimestamp();
- }
- if (endTimestamp < 0 || testRunEntity.getEndTimestamp() > endTimestamp) {
- endTimestamp = testRunEntity.getEndTimestamp();
- }
- testType = testRunEntity.getType();
- testBuildId = testRunEntity.getTestBuildId();
-
- List<DeviceInfoEntity> deviceInfoEntityListWithTestRunKey =
- ofy().load()
- .type(DeviceInfoEntity.class)
- .ancestor(testRunEntity.getOfyKey())
- .list();
-
- for (DeviceInfoEntity deviceInfoEntity : deviceInfoEntityListWithTestRunKey) {
- deviceInfoEntitySet.add(deviceInfoEntity);
- }
- }
-
- if (startTimestamp < 0 || testBuildId == null || testType == -1) {
- log.debug("startTimestamp => " + startTimestamp);
- log.debug("testBuildId => " + testBuildId);
- log.debug("type => " + testType);
- log.error("Couldn't infer test run information from runs.");
- return;
- }
-
- TestPlanRunEntity testPlanRunEntity =
- new TestPlanRunEntity(
- testPlanEntity.getKey(),
- testPlanName,
- testType,
- startTimestamp,
- endTimestamp,
- testBuildId,
- passCount,
- failCount,
- 0L,
- 0L,
- testRunKeyList);
-
- // Create the device infos.
- for (DeviceInfoEntity device : deviceInfoEntitySet) {
- deviceInfoEntityList.add(device.copyWithParent(testPlanRunEntity.getOfyKey()));
- }
-
- // Process global HAL API coverage data
- for (VtsReportMessage.ApiCoverageReportMessage apiCoverage : report.getHalApiReportList()) {
- VtsReportMessage.HalInterfaceMessage halInterfaceMessage =
- apiCoverage.getHalInterface();
- List<String> halApiList =
- apiCoverage
- .getHalApiList()
- .stream()
- .map(h -> h.toStringUtf8())
- .collect(Collectors.toList());
- List<String> coveredHalApiList =
- apiCoverage
- .getCoveredHalApiList()
- .stream()
- .map(h -> h.toStringUtf8())
- .collect(Collectors.toList());
- HalApiEntity halApiEntity =
- new HalApiEntity(
- testPlanRunEntity.getOfyKey(),
- halInterfaceMessage.getHalReleaseLevel().toStringUtf8(),
- halInterfaceMessage.getHalPackageName().toStringUtf8(),
- halInterfaceMessage.getHalVersionMajor(),
- halInterfaceMessage.getHalVersionMinor(),
- halInterfaceMessage.getHalInterfaceName().toStringUtf8(),
- halApiList,
- coveredHalApiList);
- halApiEntityList.add(halApiEntity);
- }
-
- ofy().transact(
- () -> {
- testPlanEntity.save();
- testPlanRunEntity.save();
- for (Object entity : allEntityList) {
- List<DashboardEntity> dashboardEntityList =
- (List<DashboardEntity>) entity;
- Map<com.googlecode.objectify.Key<DashboardEntity>, DashboardEntity>
- mapInfo =
- DashboardEntity.saveAll(
- dashboardEntityList,
- this.MAX_ENTITY_SIZE_PER_TRANSACTION);
- }
- });
-
- // Add the task to calculate total number API list.
- testPlanRunEntity.addCoverageApiTask();
- }
-}
diff --git a/src/main/java/com/android/vts/api/TestAcknowledgmentRestServlet.java b/src/main/java/com/android/vts/api/TestAcknowledgmentRestServlet.java
deleted file mode 100644
index 309c3e2..0000000
--- a/src/main/java/com/android/vts/api/TestAcknowledgmentRestServlet.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.vts.api;
-
-import com.android.vts.entity.TestAcknowledgmentEntity;
-import com.android.vts.util.DatastoreHelper;
-import com.google.appengine.api.datastore.DatastoreFailureException;
-import com.google.appengine.api.datastore.DatastoreService;
-import com.google.appengine.api.datastore.DatastoreServiceFactory;
-import com.google.appengine.api.datastore.DatastoreTimeoutException;
-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.appengine.api.datastore.Transaction;
-import com.google.appengine.api.users.User;
-import com.google.appengine.api.users.UserService;
-import com.google.appengine.api.users.UserServiceFactory;
-import com.google.gson.Gson;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.ConcurrentModificationException;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/** Servlet for handling requests to fetch test acknowledgments. */
-public class TestAcknowledgmentRestServlet extends HttpServlet {
- protected static final Logger logger =
- Logger.getLogger(TestAcknowledgmentRestServlet.class.getName());
-
- /** Read all test acknowledgments. */
- @Override
- public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
- DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
-
- Query ackQuery = new Query(TestAcknowledgmentEntity.KIND);
- List<JsonObject> testAcks = new ArrayList<>();
- for (Entity ackEntity :
- datastore.prepare(ackQuery).asIterable(DatastoreHelper.getLargeBatchOptions())) {
- TestAcknowledgmentEntity ack = TestAcknowledgmentEntity.fromEntity(ackEntity);
- if (ack == null) continue;
- testAcks.add(ack.toJson());
- }
- response.setContentType("application/json");
- PrintWriter writer = response.getWriter();
- writer.print(new Gson().toJson(testAcks));
- writer.flush();
- }
-
- /** Create a test acknowledgment. */
- @Override
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- UserService userService = UserServiceFactory.getUserService();
- if (!userService.isUserAdmin()) {
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- return;
- }
- User currentUser = userService.getCurrentUser();
- DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
-
- StringBuilder sb = new StringBuilder();
- BufferedReader br = new BufferedReader(request.getReader());
- String str;
- while ((str = br.readLine()) != null) {
- sb.append(str);
- }
- JsonObject json;
- try {
- json = new JsonParser().parse(sb.toString()).getAsJsonObject();
- } catch (IllegalStateException e) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- TestAcknowledgmentEntity ack = TestAcknowledgmentEntity.fromJson(currentUser, json);
- Transaction txn = datastore.beginTransaction();
- try {
- Key key = datastore.put(ack.toEntity());
- txn.commit();
-
- response.setContentType("application/json");
- PrintWriter writer = response.getWriter();
- writer.print(new Gson().toJson(KeyFactory.keyToString(key)));
- writer.flush();
- } catch (ConcurrentModificationException
- | DatastoreFailureException
- | DatastoreTimeoutException e) {
- txn.rollback();
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return;
- } finally {
- if (txn.isActive()) {
- logger.log(Level.WARNING, "Transaction rollback forced acknowledgment post.");
- txn.rollback();
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- }
- response.setStatus(HttpServletResponse.SC_OK);
- }
-
- /** Remove a test acknowledgment. */
- @Override
- public void doDelete(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- UserService userService = UserServiceFactory.getUserService();
- if (!userService.isUserAdmin()) {
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- return;
- }
- DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
- String stringKey = request.getPathInfo();
- if (stringKey == null) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- if (stringKey.startsWith("/")) {
- stringKey = stringKey.substring(1);
- }
- Key key = KeyFactory.stringToKey(stringKey);
- if (!key.getKind().equals(TestAcknowledgmentEntity.KIND)) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- datastore.delete(key);
- response.setStatus(HttpServletResponse.SC_OK);
- }
-}
diff --git a/src/main/java/com/android/vts/api/TestDataForDevServlet.java b/src/main/java/com/android/vts/api/TestDataForDevServlet.java
deleted file mode 100644
index 2ed387b..0000000
--- a/src/main/java/com/android/vts/api/TestDataForDevServlet.java
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- * Copyright (c) 2017 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.api;
-
-import com.android.vts.entity.BranchEntity;
-import com.android.vts.entity.BuildTargetEntity;
-import com.android.vts.entity.CodeCoverageEntity;
-import com.android.vts.entity.CoverageEntity;
-import com.android.vts.entity.DeviceInfoEntity;
-import com.android.vts.entity.ProfilingPointRunEntity;
-import com.android.vts.entity.TestCaseRunEntity;
-import com.android.vts.entity.TestEntity;
-import com.android.vts.entity.TestPlanEntity;
-import com.android.vts.entity.TestPlanRunEntity;
-import com.android.vts.entity.TestRunEntity;
-import com.android.vts.entity.TestStatusEntity;
-import com.android.vts.entity.TestStatusEntity.TestCaseReference;
-import com.android.vts.entity.TestSuiteFileEntity;
-import com.android.vts.entity.TestSuiteResultEntity;
-import com.google.appengine.api.datastore.DatastoreFailureException;
-import com.google.appengine.api.datastore.DatastoreService;
-import com.google.appengine.api.datastore.DatastoreServiceFactory;
-import com.google.appengine.api.datastore.DatastoreTimeoutException;
-import com.google.appengine.api.datastore.Entity;
-import com.google.appengine.api.datastore.EntityNotFoundException;
-import com.google.appengine.api.datastore.Key;
-import com.google.appengine.api.datastore.KeyFactory;
-import com.google.appengine.api.datastore.Query;
-import com.google.appengine.api.datastore.Transaction;
-import com.google.appengine.api.users.User;
-import com.google.appengine.api.users.UserService;
-import com.google.appengine.api.users.UserServiceFactory;
-import com.google.appengine.api.utils.SystemProperty;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.nio.file.FileSystems;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.time.Instant;
-import java.time.temporal.ChronoUnit;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.ConcurrentModificationException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Random;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.stream.IntStream;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/** Servlet for handling requests to add mock data in datastore. */
-public class TestDataForDevServlet extends HttpServlet {
- protected static final Logger logger = Logger.getLogger(TestDataForDevServlet.class.getName());
-
- /** Google Cloud Storage project's default directory name for suite test result files */
- private static String GCS_SUITE_TEST_FOLDER_NAME;
-
- /** datastore instance to save the test data into datastore through datastore library. */
- private DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
- /**
- * Gson is a Java library that can be used to convert Java Objects into their JSON
- * representation. It can also be used to convert a JSON string to an equivalent Java object.
- */
- private Gson gson = new GsonBuilder().create();
-
- /** System Configuration Property class */
- protected Properties systemConfigProp = new Properties();
-
- @Override
- public void init(ServletConfig cfg) throws ServletException {
- super.init(cfg);
-
- try {
- InputStream defaultInputStream =
- TestDataForDevServlet.class
- .getClassLoader()
- .getResourceAsStream("config.properties");
- systemConfigProp.load(defaultInputStream);
-
- GCS_SUITE_TEST_FOLDER_NAME = systemConfigProp.getProperty("gcs.suiteTestFolderName");
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * TestReportData class for mapping test-report-data.json. This internal class's each fields
- * will be automatically mapped to test-report-data.json file through Gson
- */
- private class TestReportDataObject {
- private List<Test> testList;
-
- private class Test {
- private List<TestRun> testRunList;
-
- private class TestRun {
- private String testName;
- private int type;
- private long startTimestamp;
- private long endTimestamp;
- private String testBuildId;
- private String hostName;
- private long passCount;
- private long failCount;
- private boolean hasCoverage;
- private long coveredLineCount;
- private long totalLineCount;
- private List<Long> testCaseIds;
- private List<Long> failingTestcaseIds;
- private List<Integer> failingTestcaseOffsets;
- private List<String> links;
-
- private List<Coverage> coverageList;
- private List<Profiling> profilingList;
- private List<TestCaseRun> testCaseRunList;
- private List<DeviceInfo> deviceInfoList;
- private List<BuildTarget> buildTargetList;
- private List<Branch> branchList;
-
- private class Coverage {
- private String group;
- private long coveredLineCount;
- private long totalLineCount;
- private String filePath;
- private String projectName;
- private String projectVersion;
- private List<Long> lineCoverage;
- }
-
- private class Profiling {
- private String name;
- private int type;
- private int regressionMode;
- private List<String> labels;
- private List<Long> values;
- private String xLabel;
- private String yLabel;
- private List<String> options;
- }
-
- private class TestCaseRun {
- private List<String> testCaseNames;
- private List<Integer> results;
- }
-
- private class DeviceInfo {
- private String branch;
- private String product;
- private String buildFlavor;
- private String buildId;
- private String abiBitness;
- private String abiName;
- }
-
- private class BuildTarget {
- private String targetName;
- }
-
- private class Branch {
- private String branchName;
- }
- }
- }
-
- @Override
- public String toString() {
- return "(" + testList + ")";
- }
- }
-
- private class TestPlanReportDataObject {
- private List<TestPlan> testPlanList;
-
- private class TestPlan {
-
- private String testPlanName;
- private List<String> testModules;
- private List<Long> testTimes;
- }
-
- @Override
- public String toString() {
- return "(" + testPlanList + ")";
- }
- }
-
- private Map<String, Object> generateSuiteTestData(
- HttpServletRequest request, HttpServletResponse response) {
- Map<String, Object> resultMap = new HashMap<>();
- String fileSeparator = FileSystems.getDefault().getSeparator();
- Random rand = new Random();
- List<String> branchList = Arrays.asList("master", "oc_mr", "oc");
- List<String> targetList =
- Arrays.asList(
- "sailfish-userdebug",
- "marlin-userdebug",
- "taimen-userdebug",
- "walleye-userdebug",
- "aosp_arm_a-userdebug");
- branchList.forEach(
- branch ->
- targetList.forEach(
- target ->
- IntStream.range(0, 10)
- .forEach(
- idx -> {
- String year =
- String.format(
- "%04d", 2010 + idx);
- String month =
- String.format(
- "%02d",
- rand.nextInt(12));
- String day =
- String.format(
- "%02d",
- rand.nextInt(30));
- String fileName =
- String.format(
- "%02d%02d%02d.bin",
- rand.nextInt(23) + 1,
- rand.nextInt(59) + 1,
- rand.nextInt(59) + 1);
-
- List<String> pathList =
- Arrays.asList(
- GCS_SUITE_TEST_FOLDER_NAME
- == ""
- ? "suite_result"
- : GCS_SUITE_TEST_FOLDER_NAME,
- year,
- month,
- day,
- fileName);
-
- Path pathInfo =
- Paths.get(
- String.join(
- fileSeparator,
- pathList));
-
- TestSuiteFileEntity
- newTestSuiteFileEntity =
- new TestSuiteFileEntity(
- pathInfo
- .toString());
-
- com.googlecode.objectify.Key<
- TestSuiteFileEntity>
- testSuiteFileParent =
- com.googlecode.objectify
- .Key.create(
- TestSuiteFileEntity
- .class,
- newTestSuiteFileEntity
- .getFilePath());
-
-
- TestSuiteResultEntity
- testSuiteResultEntity =
- new TestSuiteResultEntity(
- testSuiteFileParent,
- Instant.now()
- .minus(
- rand
- .nextInt(
- 100),
- ChronoUnit
- .DAYS)
- .getEpochSecond(),
- Instant.now()
- .minus(
- rand
- .nextInt(
- 100),
- ChronoUnit
- .DAYS)
- .getEpochSecond(),
- 1,
- idx / 2 == 0
- ? false
- : true,
- pathInfo
- .toString(),
- idx / 2 == 0
- ? "/error/infra/log"
- : "",
- "Test Place Name -"
- + idx,
- "Suite Test Plan",
- "Suite Version "
- + idx,
- "Suite Test Name",
- "Suite Build Number "
- + idx,
- rand.nextInt(),
- rand.nextInt(),
- branch,
- target,
- Long.toString(
- Math
- .abs(
- rand
- .nextLong())),
- "Build System Fingerprint "
- + idx,
- "Build Vendor Fingerprint "
- + idx,
- rand.nextInt(),
- rand.nextInt());
-
- testSuiteResultEntity.save(newTestSuiteFileEntity);
- })));
- resultMap.put("result", "successfully generated!");
- return resultMap;
- }
-
- @Override
- public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
- String requestUri = request.getRequestURI();
- String requestArgs = request.getQueryString();
-
- Map<String, Object> resultMap = new HashMap<>();
- String pathInfo = requestUri.replace("/api/test_data/", "");
- switch (pathInfo) {
- case "suite":
- resultMap = this.generateSuiteTestData(request, response);
- break;
- default:
- throw new IllegalArgumentException("Invalid path info of URL");
- }
-
- String json = new Gson().toJson(resultMap);
- response.setStatus(HttpServletResponse.SC_OK);
- response.setContentType("application/json");
- response.setCharacterEncoding("UTF-8");
- response.getWriter().write(json);
- }
-
- /** Add mock data to local dev datastore. */
- @Override
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) {
- response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
- return;
- }
-
- UserService userService = UserServiceFactory.getUserService();
- User currentUser = userService.getCurrentUser();
-
- String pathInfo = request.getPathInfo();
- String[] pathParts = pathInfo.split("/");
- if (pathParts.length > 1) {
- // Read the json output
- Reader postJsonReader = new InputStreamReader(request.getInputStream());
- Gson gson = new GsonBuilder().create();
-
- String testType = pathParts[1];
- if (testType.equalsIgnoreCase("report")) {
- TestReportDataObject trdObj =
- gson.fromJson(postJsonReader, TestReportDataObject.class);
- logger.log(Level.INFO, "trdObj => " + trdObj);
- trdObj.testList.forEach(
- test -> {
- test.testRunList.forEach(
- testRun -> {
- TestEntity testEntity = new TestEntity(testRun.testName);
-
- Key testRunKey =
- KeyFactory.createKey(
- testEntity.getOldKey(),
- TestRunEntity.KIND,
- testRun.startTimestamp);
-
- List<TestCaseReference> failingTestCases =
- new ArrayList<>();
- for (int idx = 0;
- idx < testRun.failingTestcaseIds.size();
- idx++) {
- failingTestCases.add(
- new TestCaseReference(
- testRun.failingTestcaseIds.get(idx),
- testRun.failingTestcaseOffsets.get(
- idx)));
- }
-
- TestStatusEntity testStatusEntity =
- new TestStatusEntity(
- testRun.testName,
- testRun.startTimestamp,
- (int) testRun.passCount,
- failingTestCases.size(),
- failingTestCases);
- datastore.put(testStatusEntity.toEntity());
-
- testRun.coverageList.forEach(
- testRunCoverage -> {
- CoverageEntity coverageEntity =
- new CoverageEntity(
- testRunKey,
- testRunCoverage.group,
- testRunCoverage
- .coveredLineCount,
- testRunCoverage.totalLineCount,
- testRunCoverage.filePath,
- testRunCoverage.projectName,
- testRunCoverage.projectVersion,
- testRunCoverage.lineCoverage);
- datastore.put(coverageEntity.toEntity());
- });
-
- testRun.profilingList.forEach(
- testRunProfile -> {
- ProfilingPointRunEntity profilingEntity =
- new ProfilingPointRunEntity(
- testRunKey,
- testRunProfile.name,
- testRunProfile.type,
- testRunProfile.regressionMode,
- testRunProfile.labels,
- testRunProfile.values,
- testRunProfile.xLabel,
- testRunProfile.yLabel,
- testRunProfile.options);
- datastore.put(profilingEntity.toEntity());
- });
-
- TestCaseRunEntity testCaseEntity = new TestCaseRunEntity();
- testRun.testCaseRunList.forEach(
- testCaseRun -> {
- for (int idx = 0;
- idx < testCaseRun.testCaseNames.size();
- idx++) {
- testCaseEntity.addTestCase(
- testCaseRun.testCaseNames.get(idx),
- testCaseRun.results.get(idx));
- }
- });
- datastore.put(testCaseEntity.toEntity());
-
- testRun.deviceInfoList.forEach(
- deviceInfo -> {
- DeviceInfoEntity deviceInfoEntity =
- new DeviceInfoEntity(
- testRunKey,
- deviceInfo.branch,
- deviceInfo.product,
- deviceInfo.buildFlavor,
- deviceInfo.buildId,
- deviceInfo.abiBitness,
- deviceInfo.abiName);
- ;
- datastore.put(deviceInfoEntity.toEntity());
- });
-
- testRun.buildTargetList.forEach(
- buildTarget -> {
- BuildTargetEntity buildTargetEntity =
- new BuildTargetEntity(
- buildTarget.targetName);
- buildTargetEntity.save();
- });
-
- testRun.branchList.forEach(
- branch -> {
- BranchEntity branchEntity =
- new BranchEntity(branch.branchName);
- branchEntity.save();
- });
-
- boolean hasCodeCoverage =
- testRun.totalLineCount > 0
- && testRun.coveredLineCount >= 0;
- TestRunEntity testRunEntity =
- new TestRunEntity(
- testEntity.getOldKey(),
- testRun.type,
- testRun.startTimestamp,
- testRun.endTimestamp,
- testRun.testBuildId,
- testRun.hostName,
- testRun.passCount,
- testRun.failCount,
- hasCodeCoverage,
- testRun.testCaseIds,
- testRun.links);
- datastore.put(testRunEntity.toEntity());
-
- CodeCoverageEntity codeCoverageEntity =
- new CodeCoverageEntity(
- testRunEntity.getKey(),
- testRun.coveredLineCount,
- testRun.totalLineCount);
- datastore.put(codeCoverageEntity.toEntity());
-
- Entity newTestEntity = testEntity.toEntity();
-
- Transaction txn = datastore.beginTransaction();
- try {
- // Check if test already exists in the datastore
- try {
- Entity oldTest =
- datastore.get(testEntity.getOldKey());
- TestEntity oldTestEntity =
- TestEntity.fromEntity(oldTest);
- if (oldTestEntity == null
- || !oldTestEntity.equals(testEntity)) {
- datastore.put(newTestEntity);
- }
- } catch (EntityNotFoundException e) {
- datastore.put(newTestEntity);
- }
- txn.commit();
-
- } catch (ConcurrentModificationException
- | DatastoreFailureException
- | DatastoreTimeoutException e) {
- logger.log(
- Level.WARNING,
- "Retrying test run insert: "
- + newTestEntity.getKey());
- } finally {
- if (txn.isActive()) {
- logger.log(
- Level.WARNING,
- "Transaction rollback forced for run: "
- + testRunEntity.getKey());
- txn.rollback();
- }
- }
- });
- });
- } else {
- TestPlanReportDataObject tprdObj =
- gson.fromJson(postJsonReader, TestPlanReportDataObject.class);
- tprdObj.testPlanList.forEach(
- testPlan -> {
- Entity testPlanEntity =
- new TestPlanEntity(testPlan.testPlanName).toEntity();
- List<Key> testRunKeys = new ArrayList<>();
- for (int idx = 0; idx < testPlan.testModules.size(); idx++) {
- String test = testPlan.testModules.get(idx);
- long time = testPlan.testTimes.get(idx);
- Key parentKey = KeyFactory.createKey(TestEntity.KIND, test);
- Key testRunKey =
- KeyFactory.createKey(parentKey, TestRunEntity.KIND, time);
- testRunKeys.add(testRunKey);
- }
- Map<Key, Entity> testRuns = datastore.get(testRunKeys);
- long passCount = 0;
- long failCount = 0;
- long startTimestamp = -1;
- long endTimestamp = -1;
- String testBuildId = null;
- long type = 0;
- Set<DeviceInfoEntity> devices = new HashSet<>();
- for (Key testRunKey : testRuns.keySet()) {
- TestRunEntity testRun =
- TestRunEntity.fromEntity(testRuns.get(testRunKey));
- if (testRun == null) {
- continue; // not a valid test run
- }
- passCount += testRun.getPassCount();
- failCount += testRun.getFailCount();
- if (startTimestamp < 0 || testRunKey.getId() < startTimestamp) {
- startTimestamp = testRunKey.getId();
- }
- if (endTimestamp < 0 || testRun.getEndTimestamp() > endTimestamp) {
- endTimestamp = testRun.getEndTimestamp();
- }
- type = testRun.getType();
- testBuildId = testRun.getTestBuildId();
- Query deviceInfoQuery =
- new Query(DeviceInfoEntity.KIND).setAncestor(testRunKey);
- for (Entity deviceInfoEntity :
- datastore.prepare(deviceInfoQuery).asIterable()) {
- DeviceInfoEntity device =
- DeviceInfoEntity.fromEntity(deviceInfoEntity);
- if (device == null) {
- continue; // invalid entity
- }
- devices.add(device);
- }
- }
- if (startTimestamp < 0 || testBuildId == null || type == 0) {
- logger.log(
- Level.WARNING,
- "Couldn't infer test run information from runs.");
- return;
- }
- TestPlanRunEntity testPlanRun =
- new TestPlanRunEntity(
- testPlanEntity.getKey(),
- testPlan.testPlanName,
- type,
- startTimestamp,
- endTimestamp,
- testBuildId,
- passCount,
- failCount,
- 0L,
- 0L,
- testRunKeys);
-
- // Create the device infos.
- for (DeviceInfoEntity device : devices) {
- datastore.put(
- device.copyWithParent(testPlanRun.getOfyKey()).toEntity());
- }
- datastore.put(testPlanRun.toEntity());
-
- Transaction txn = datastore.beginTransaction();
- try {
- // Check if test already exists in the database
- try {
- datastore.get(testPlanEntity.getKey());
- } catch (EntityNotFoundException e) {
- datastore.put(testPlanEntity);
- }
- txn.commit();
- } catch (ConcurrentModificationException
- | DatastoreFailureException
- | DatastoreTimeoutException e) {
- logger.log(
- Level.WARNING,
- "Retrying test plan insert: " + testPlanEntity.getKey());
- } finally {
- if (txn.isActive()) {
- logger.log(
- Level.WARNING,
- "Transaction rollback forced for plan run: "
- + testPlanRun.key);
- txn.rollback();
- }
- }
- });
- }
- } else {
- logger.log(Level.WARNING, "URL path parameter is omitted!");
- }
-
- response.setStatus(HttpServletResponse.SC_OK);
- }
-}
diff --git a/src/main/java/com/android/vts/api/TestRunRestServlet.java b/src/main/java/com/android/vts/api/TestRunRestServlet.java
deleted file mode 100644
index 90fd3f9..0000000
--- a/src/main/java/com/android/vts/api/TestRunRestServlet.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2017 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.api;
-
-import com.android.vts.entity.TestCaseRunEntity;
-import com.android.vts.entity.TestEntity;
-import com.android.vts.entity.TestRunEntity;
-import com.android.vts.util.TestRunDetails;
-import com.google.gson.Gson;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.logging.Logger;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import static com.googlecode.objectify.ObjectifyService.ofy;
-
-/** Servlet for handling requests to fetch test case results. */
-public class TestRunRestServlet extends BaseApiServlet {
- private static final String LATEST = "latest";
- protected static final Logger logger = Logger.getLogger(TestRunRestServlet.class.getName());
-
- /**
- * Get the test case results for the specified run of the specified test.
- *
- * @param test The test whose test cases to get.
- * @param timeString The string representation of the test run timestamp (in microseconds).
- * @return A TestRunDetails object with the test case details for the specified run.
- */
- private TestRunDetails getTestRunDetails(String test, String timeString) {
- long timestamp;
- try {
- timestamp = Long.parseLong(timeString);
- if (timestamp <= 0) throw new NumberFormatException();
- timestamp = timestamp > 0 ? timestamp : null;
- } catch (NumberFormatException e) {
- return null;
- }
-
- TestRunEntity testRunEntity = TestRunEntity.getByTestNameId(test, timestamp);
-
- return getTestRunDetails(testRunEntity);
- }
-
- /**
- * Get the test case results for the latest run of the specified test.
- *
- * @param testName The test whose test cases to get.
- * @return A TestRunDetails object with the test case details for the latest run.
- */
- private TestRunDetails getLatestTestRunDetails(String testName) {
- com.googlecode.objectify.Key testKey =
- com.googlecode.objectify.Key.create(
- TestEntity.class, testName);
-
- TestRunEntity testRun = ofy().load().type(TestRunEntity.class).ancestor(testKey)
- .filter("type", 2).orderKey(true).first().now();
-
- if (testRun == null) return null;
-
- return getTestRunDetails(testRun);
- }
-
- /**
- * Get TestRunDetails instance from codeCoverageEntity instance.
- *
- * @param testRunEntity The TestRunEntity to access testCaseId.
- * @return A TestRunDetails object with the test case details for the latest run.
- */
- private TestRunDetails getTestRunDetails(TestRunEntity testRunEntity) {
- TestRunDetails details = new TestRunDetails();
- List<com.googlecode.objectify.Key<TestCaseRunEntity>> testCaseKeyList = new ArrayList<>();
- if ( Objects.isNull(testRunEntity.getTestCaseIds()) ) {
- return details;
- } else {
- for (long testCaseId : testRunEntity.getTestCaseIds()) {
- testCaseKeyList.add(
- com.googlecode.objectify.Key.create(TestCaseRunEntity.class, testCaseId));
- }
- Map<com.googlecode.objectify.Key<TestCaseRunEntity>, TestCaseRunEntity>
- testCaseRunEntityKeyMap = ofy().load().keys(() -> testCaseKeyList.iterator());
- testCaseRunEntityKeyMap.forEach((key, value) -> details.addTestCase(value));
- }
- return details;
- }
-
- /**
- * Get the test case details for a test run.
- *
- * Expected format: (1) /api/test_run?test=[test name]&timestamp=[timestamp] to the details
- * for a specific run, or (2) /api/test_run?test=[test name]&timestamp=latest -- the details for
- * the latest test run.
- */
- @Override
- public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
- String test = request.getParameter("test");
- String timeString = request.getParameter("timestamp");
- TestRunDetails details = null;
-
- if (timeString != null && timeString.equals(LATEST)) {
- details = getLatestTestRunDetails(test);
- } else if (timeString != null) {
- details = getTestRunDetails(test, timeString);
- }
-
- if (details == null) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- } else {
- response.setStatus(HttpServletResponse.SC_OK);
- response.setContentType("application/json");
- PrintWriter writer = response.getWriter();
- writer.print(new Gson().toJson(details.toJson()));
- writer.flush();
- }
- }
-}
diff --git a/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java b/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java
deleted file mode 100644
index 38be2c0..0000000
--- a/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2018 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.api;
-
-import com.android.vts.entity.TestSuiteFileEntity;
-import com.android.vts.entity.TestSuiteResultEntity;
-import com.android.vts.proto.TestSuiteResultMessageProto;
-import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
-import com.google.api.client.http.javanet.NetHttpTransport;
-import com.google.api.client.json.jackson.JacksonFactory;
-import com.google.api.services.oauth2.Oauth2;
-import com.google.api.services.oauth2.model.Tokeninfo;
-import com.google.gson.Gson;
-import com.googlecode.objectify.Key;
-import org.apache.commons.codec.binary.Base64;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.stream.Collectors;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-
-/** REST endpoint for posting test suite data to the Dashboard. */
-public class TestSuiteResultRestServlet extends BaseApiServlet {
- private static String SERVICE_CLIENT_ID;
- private static final String SERVICE_NAME = "VTS Dashboard";
- private static final Logger logger =
- Logger.getLogger(TestSuiteResultRestServlet.class.getName());
-
- @Override
- public void init(ServletConfig cfg) throws ServletException {
- super.init(cfg);
-
- SERVICE_CLIENT_ID = systemConfigProp.getProperty("appengine.serviceClientID");
- }
-
- @Override
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- // Retrieve the params
- TestSuiteResultMessageProto.TestSuiteResultMessage testSuiteResultMessage;
- try {
- String payload = request.getReader().lines().collect(Collectors.joining());
- byte[] value = Base64.decodeBase64(payload);
- testSuiteResultMessage =
- TestSuiteResultMessageProto.TestSuiteResultMessage.parseFrom(value);
- } catch (IOException e) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- logger.log(Level.WARNING, "Invalid proto: " + e.getLocalizedMessage());
- return;
- }
-
- Map<String, Object> resultMap = new HashMap<>();
- // Verify service account access token.
- if (testSuiteResultMessage.hasAccessToken()) {
- String accessToken = testSuiteResultMessage.getAccessToken();
- logger.log(Level.INFO, "accessToken => " + accessToken);
- GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
- Oauth2 oauth2 =
- new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credential)
- .setApplicationName(SERVICE_NAME)
- .build();
- Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute();
-
- if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) {
- String filePath = "suite_result/2019/04/06/132343.bin";
- Key<TestSuiteFileEntity> testSuiteFileParent =
- Key.create(TestSuiteFileEntity.class, filePath);
- TestSuiteFileEntity newTestSuiteFileEntity = new TestSuiteFileEntity(filePath);
- TestSuiteResultEntity testSuiteResultEntity =
- new TestSuiteResultEntity(
- testSuiteFileParent,
- testSuiteResultMessage.getStartTime(),
- testSuiteResultMessage.getEndTime(),
- testSuiteResultMessage.getTestType(),
- testSuiteResultMessage.getBootSuccess(),
- testSuiteResultMessage.getResultPath(),
- testSuiteResultMessage.getInfraLogPath(),
- testSuiteResultMessage.getHostName(),
- testSuiteResultMessage.getSuitePlan(),
- testSuiteResultMessage.getSuiteVersion(),
- testSuiteResultMessage.getSuiteName(),
- testSuiteResultMessage.getSuiteBuildNumber(),
- testSuiteResultMessage.getModulesDone(),
- testSuiteResultMessage.getModulesTotal(),
- testSuiteResultMessage.getBranch(),
- testSuiteResultMessage.getTarget(),
- testSuiteResultMessage.getBuildId(),
- testSuiteResultMessage.getBuildSystemFingerprint(),
- testSuiteResultMessage.getBuildVendorFingerprint(),
- testSuiteResultMessage.getPassedTestCaseCount(),
- testSuiteResultMessage.getFailedTestCaseCount());
-
- testSuiteResultEntity.save(newTestSuiteFileEntity);
- resultMap.put("result", "successfully saved!");
- } else {
- logger.log(Level.WARNING, "service_client_id didn't match!");
- logger.log(Level.INFO, "SERVICE_CLIENT_ID => " + tokenInfo.getIssuedTo());
- resultMap.put("result", "Wrong Service Client ID!");
- }
- } else {
- logger.log(Level.WARNING, "postMessage do not contain any accessToken!");
- resultMap.put("result", "Access Token Missing!");
- }
- String json = new Gson().toJson(resultMap);
- response.setStatus(HttpServletResponse.SC_OK);
- response.setContentType("application/json");
- response.setCharacterEncoding("UTF-8");
- response.getWriter().write(json);
- }
-}
diff --git a/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java b/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java
deleted file mode 100644
index 30fd649..0000000
--- a/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2017 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.api;
-
-import com.android.vts.entity.TestEntity;
-import com.android.vts.entity.UserFavoriteEntity;
-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.EntityNotFoundException;
-import com.google.appengine.api.datastore.Key;
-import com.google.appengine.api.datastore.KeyFactory;
-import com.google.appengine.api.datastore.Query;
-import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
-import com.google.appengine.api.datastore.Query.Filter;
-import com.google.appengine.api.datastore.Query.FilterOperator;
-import com.google.appengine.api.datastore.Query.FilterPredicate;
-import com.google.appengine.api.datastore.Transaction;
-import com.google.appengine.api.users.User;
-import com.google.appengine.api.users.UserService;
-import com.google.appengine.api.users.UserServiceFactory;
-import com.google.gson.Gson;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/** Servlet for handling requests to add or remove subscriptions. */
-public class UserFavoriteRestServlet extends BaseApiServlet {
- protected static final Logger logger =
- Logger.getLogger(UserFavoriteRestServlet.class.getName());
-
- /**
- * Add a new favorite entity.
- *
- * @param user The user for which to add a favorite.
- * @param test The name of the test.
- * @param muteNotifications True if the subscriber has muted notifications, false otherwise.
- * @param response The servlet response object.
- * @return a json object with the generated key to the new favorite entity.
- * @throws IOException
- */
- private static JsonObject addFavorite(
- User user, String test, boolean muteNotifications, HttpServletResponse response)
- throws IOException {
- DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
- Key addedTestKey = KeyFactory.createKey(TestEntity.KIND, test);
- // Filter the tests that exist from the set of tests to add
- try {
- datastore.get(addedTestKey);
- } catch (EntityNotFoundException e) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return null;
- }
-
- Filter userFilter =
- new FilterPredicate(UserFavoriteEntity.USER, FilterOperator.EQUAL, user);
- Filter testFilter =
- new FilterPredicate(
- UserFavoriteEntity.TEST_KEY, FilterOperator.EQUAL, addedTestKey);
- Query q =
- new Query(UserFavoriteEntity.KIND)
- .setFilter(CompositeFilterOperator.and(userFilter, testFilter))
- .setKeysOnly();
-
- Key favoriteKey = null;
-
- Transaction txn = datastore.beginTransaction();
- try {
- for (Entity e : datastore.prepare(q).asIterable()) {
- favoriteKey = e.getKey();
- break;
- }
- if (favoriteKey == null) {
- UserFavoriteEntity favorite =
- new UserFavoriteEntity(user, addedTestKey, muteNotifications);
- Entity entity = favorite.toEntity();
- datastore.put(entity);
- favoriteKey = entity.getKey();
- }
- txn.commit();
- } finally {
- if (txn.isActive()) {
- logger.log(
- Level.WARNING,
- "Transaction rollback forced for favorite creation: " + test);
- txn.rollback();
- }
- }
- JsonObject json = new JsonObject();
- json.add("key", new JsonPrimitive(KeyFactory.keyToString(favoriteKey)));
- return json;
- }
-
- /**
- * @param user The user for which to add a favorite.
- * @param favoriteKey The database key to the favorite entity to update.
- * @param muteNotifications True if the subscriber has muted notifications, false otherwise.
- * @param response The servlet response object.
- * @return a json object with the generated key to the new favorite entity.
- * @throws IOException
- */
- private static JsonObject updateFavorite(
- User user, Key favoriteKey, boolean muteNotifications, HttpServletResponse response)
- throws IOException {
- DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
- Entity favoriteEntity;
- try {
- favoriteEntity = datastore.get(favoriteKey);
- } catch (EntityNotFoundException e) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return null;
- }
- UserFavoriteEntity favorite = UserFavoriteEntity.fromEntity(favoriteEntity);
- if (favorite.user.getUserId() == user.getUserId()) {
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- return null;
- }
- if (favorite.muteNotifications != muteNotifications) {
- Transaction txn = datastore.beginTransaction();
- try {
- favorite.muteNotifications = muteNotifications;
- datastore.put(favorite.toEntity());
- txn.commit();
- } finally {
- if (txn.isActive()) {
- logger.log(
- Level.WARNING,
- "Transaction rollback forced for favorite update: " + favoriteKey);
- txn.rollback();
- }
- }
- }
- JsonObject json = new JsonObject();
- json.add("key", new JsonPrimitive(KeyFactory.keyToString(favoriteKey)));
- return json;
- }
-
- /** Add a test to the user's favorites. */
- @Override
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- UserService userService = UserServiceFactory.getUserService();
- User currentUser = userService.getCurrentUser();
-
- boolean muteNotifications = false;
- if (request.getParameter(UserFavoriteEntity.MUTE_NOTIFICATIONS) != null) {
- muteNotifications =
- Boolean.parseBoolean(
- request.getParameter(UserFavoriteEntity.MUTE_NOTIFICATIONS));
- }
-
- String userFavoritesKeyString = request.getParameter("userFavoritesKey");
- String testName = request.getParameter("testName");
-
- JsonObject returnData = null;
- if (userFavoritesKeyString != null) {
- Key userFavoritesKey = KeyFactory.stringToKey(userFavoritesKeyString);
- returnData = updateFavorite(currentUser, userFavoritesKey, muteNotifications, response);
- } else if (testName != null) {
- returnData = addFavorite(currentUser, testName, muteNotifications, response);
- }
-
- if (returnData != null) {
- response.setContentType("application/json");
- PrintWriter writer = response.getWriter();
- writer.print(new Gson().toJson(returnData));
- writer.flush();
- }
- }
-
- /** Remove a test from the user's favorites. */
- @Override
- public void doDelete(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
- String stringKey = request.getPathInfo();
- if (stringKey == null) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- if (stringKey.startsWith("/")) {
- stringKey = stringKey.substring(1);
- }
- datastore.delete(KeyFactory.stringToKey(stringKey));
- response.setStatus(HttpServletResponse.SC_OK);
- }
-}