summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoung Gyu Park <younggyu@google.com>2018-11-06 21:15:57 -0800
committerandroid-build-merger <android-build-merger@google.com>2018-11-06 21:15:57 -0800
commitb88f2be166fcadb439eb13aed98722f50267fa4f (patch)
tree71812e2a46fd982c76e34588ba6813a5377b9c21
parent27280d64d11bce6eb011751a4b2034b16ccb83b0 (diff)
parenta079fb0eaad5da782d23230908e2e987afa2d0d7 (diff)
downloaddashboard-b88f2be166fcadb439eb13aed98722f50267fa4f.tar.gz
Merge changes from topic "hal-api-entity" am: f2d725478c am: a9ef3c7d09
am: a079fb0eaa Change-Id: I8752303bfa845febe777731d89c19c2b1f6d10e3
-rw-r--r--src/main/java/com/android/vts/api/BaseApiServlet.java72
-rw-r--r--src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java1
-rw-r--r--src/main/java/com/android/vts/api/CoverageRestServlet.java8
-rw-r--r--src/main/java/com/android/vts/api/DatastoreRestServlet.java509
-rw-r--r--src/main/java/com/android/vts/api/TestDataForDevServlet.java11
-rw-r--r--src/main/java/com/android/vts/config/ObjectifyListener.java6
-rw-r--r--src/main/java/com/android/vts/entity/ApiCoverageEntity.java272
-rw-r--r--src/main/java/com/android/vts/entity/ApiCoverageExcludedEntity.java45
-rw-r--r--src/main/java/com/android/vts/entity/BranchEntity.java13
-rw-r--r--src/main/java/com/android/vts/entity/BuildTargetEntity.java12
-rw-r--r--src/main/java/com/android/vts/entity/CodeCoverageEntity.java25
-rw-r--r--src/main/java/com/android/vts/entity/CodeCoverageFileEntity.java10
-rw-r--r--src/main/java/com/android/vts/entity/CoverageEntity.java482
-rw-r--r--src/main/java/com/android/vts/entity/DashboardEntity.java37
-rw-r--r--src/main/java/com/android/vts/entity/DeviceInfoEntity.java28
-rw-r--r--src/main/java/com/android/vts/entity/HalApiEntity.java105
-rw-r--r--src/main/java/com/android/vts/entity/ProfilingPointEntity.java13
-rw-r--r--src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java56
-rw-r--r--src/main/java/com/android/vts/entity/ProfilingPointSummaryEntity.java13
-rw-r--r--src/main/java/com/android/vts/entity/RoleEntity.java63
-rw-r--r--src/main/java/com/android/vts/entity/TestAcknowledgmentEntity.java68
-rw-r--r--src/main/java/com/android/vts/entity/TestCaseRunEntity.java31
-rw-r--r--src/main/java/com/android/vts/entity/TestCoverageStatusEntity.java8
-rw-r--r--src/main/java/com/android/vts/entity/TestEntity.java30
-rw-r--r--src/main/java/com/android/vts/entity/TestPlanEntity.java17
-rw-r--r--src/main/java/com/android/vts/entity/TestPlanRunEntity.java72
-rw-r--r--src/main/java/com/android/vts/entity/TestRunEntity.java17
-rw-r--r--src/main/java/com/android/vts/entity/TestStatusEntity.java11
-rw-r--r--src/main/java/com/android/vts/entity/TestSuiteFileEntity.java10
-rw-r--r--src/main/java/com/android/vts/entity/TestSuiteResultEntity.java13
-rw-r--r--src/main/java/com/android/vts/entity/UserEntity.java7
-rw-r--r--src/main/java/com/android/vts/entity/UserFavoriteEntity.java33
-rw-r--r--src/main/java/com/android/vts/job/BaseJobServlet.java27
-rw-r--r--src/main/java/com/android/vts/job/VtsAlertJobServlet.java13
-rw-r--r--src/main/java/com/android/vts/job/VtsSpreadSheetSyncServlet.java3
-rw-r--r--src/main/java/com/android/vts/servlet/BaseServlet.java357
-rw-r--r--src/main/java/com/android/vts/util/DatastoreHelper.java154
37 files changed, 1665 insertions, 987 deletions
diff --git a/src/main/java/com/android/vts/api/BaseApiServlet.java b/src/main/java/com/android/vts/api/BaseApiServlet.java
index 1ad0237..b7384a7 100644
--- a/src/main/java/com/android/vts/api/BaseApiServlet.java
+++ b/src/main/java/com/android/vts/api/BaseApiServlet.java
@@ -17,61 +17,51 @@
package com.android.vts.api;
import com.google.apphosting.api.ApiProxy;
-import com.google.gson.Gson;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-/**
- * An abstract class to be subclassed to create API Servlet
- */
+/** 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());
+ private static final Logger logger = Logger.getLogger(BaseApiServlet.class.getName());
+
+ /** System Configuration Property class */
+ protected Properties systemConfigProp = new Properties();
- /**
- * System Configuration Property class
- */
- protected Properties systemConfigProp = new Properties();
+ /** Appengine server host name */
+ protected String hostName;
- /**
- * 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);
+ @Override
+ public void init(ServletConfig cfg) throws ServletException {
+ super.init(cfg);
- ApiProxy.Environment env = ApiProxy.getCurrentEnvironment();
- hostName = env.getAttributes().get("com.google.appengine.runtime.default_version_hostname")
- .toString();
- try {
- InputStream defaultInputStream =
- BaseApiServlet.class
- .getClassLoader()
- .getResourceAsStream("config.properties");
- systemConfigProp.load(defaultInputStream);
+ systemConfigProp =
+ Properties.class.cast(cfg.getServletContext().getAttribute("systemConfigProp"));
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
+ 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");
- }
+ 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
index ac69b84..d331d4b 100644
--- a/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java
+++ b/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java
@@ -150,7 +150,6 @@ public class BigtableLegacyJsonServlet extends HttpServlet {
try {
byte[] value = Base64.decodeBase64(payloadJson.getString("value"));
TestReportMessage testReportMessage = TestReportMessage.parseFrom(value);
- DatastoreHelper.insertTestReport(testReportMessage);
} 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
index 217b740..165db8d 100644
--- a/src/main/java/com/android/vts/api/CoverageRestServlet.java
+++ b/src/main/java/com/android/vts/api/CoverageRestServlet.java
@@ -20,8 +20,10 @@ 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;
@@ -104,9 +106,11 @@ public class CoverageRestServlet extends BaseApiServlet {
List<List<String>> allCoveredHalApiList = new ArrayList();
Key<TestPlanRunEntity> key = Key.create(urlSafeKey);
- TestPlanRunEntity testPlanRunEntity = ofy().load().key(key).now();
+ System.out.println("urlSafekey => " + urlSafeKey);
+ TestPlanRunEntity testPlanRunEntity = ofy().load().key(key).safe();
- for (Key testRunKey : testPlanRunEntity.getTestRuns()) {
+ System.out.println("testPlanRunEntity => " + testPlanRunEntity);
+ for (Key<TestRunEntity> testRunKey : testPlanRunEntity.getTestRuns()) {
List<ApiCoverageEntity> apiCoverageEntityList =
ofy().load().type(ApiCoverageEntity.class).ancestor(testRunKey).list();
for (ApiCoverageEntity apiCoverageEntity : apiCoverageEntityList) {
diff --git a/src/main/java/com/android/vts/api/DatastoreRestServlet.java b/src/main/java/com/android/vts/api/DatastoreRestServlet.java
index 42d7a60..5ddf18d 100644
--- a/src/main/java/com/android/vts/api/DatastoreRestServlet.java
+++ b/src/main/java/com/android/vts/api/DatastoreRestServlet.java
@@ -16,58 +16,60 @@
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.android.vts.servlet.BaseServlet;
-import com.android.vts.util.DatastoreHelper;
-import com.android.vts.util.EmailHelper;
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.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+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.HttpServlet;
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 HttpServlet {
+public class DatastoreRestServlet extends BaseApiServlet {
private static String SERVICE_CLIENT_ID;
private static final String SERVICE_NAME = "VTS Dashboard";
- private static final Logger logger = Logger.getLogger(DatastoreRestServlet.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 =
- DatastoreRestServlet.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();
- }
+ SERVICE_CLIENT_ID = this.systemConfigProp.getProperty("appengine.serviceClientID");
}
@Override
@@ -81,14 +83,15 @@ public class DatastoreRestServlet extends HttpServlet {
postMessage = DashboardPostMessage.parseFrom(value);
} catch (IOException e) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- logger.log(Level.WARNING, "Invalid proto: " + e.getLocalizedMessage());
+ log.error("Invalid proto: " + e.getLocalizedMessage());
return;
}
// Verify service account access token.
if (postMessage.hasAccessToken()) {
String accessToken = postMessage.getAccessToken();
- logger.log(Level.INFO, "accessToken => " + accessToken);
+ log.debug("accessToken => " + accessToken);
+
GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
Oauth2 oauth2 =
new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credential)
@@ -97,23 +100,461 @@ public class DatastoreRestServlet extends HttpServlet {
Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute();
if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) {
for (TestReportMessage testReportMessage : postMessage.getTestReportList()) {
- DatastoreHelper.insertTestReport(testReportMessage);
+ this.insertTestReport(testReportMessage);
}
for (TestPlanReportMessage planReportMessage :
postMessage.getTestPlanReportList()) {
- DatastoreHelper.insertTestPlanReport(planReportMessage);
+ this.insertTestPlanReport(planReportMessage);
}
response.setStatus(HttpServletResponse.SC_OK);
} else {
- logger.log(Level.WARNING, "service_client_id didn't match!");
- logger.log(Level.INFO, "SERVICE_CLIENT_ID => " + tokenInfo.getIssuedTo());
+ log.warn("service_client_id didn't match!");
+ log.debug("SERVICE_CLIENT_ID => " + tokenInfo.getIssuedTo());
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
} else {
- logger.log(Level.WARNING, "postMessage do not contain any accessToken!");
+ log.error("postMessage do not contain any accessToken!");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}
+
+ /**
+ * 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) {
+ List<TestCaseRunEntity> dashboardEntityList =
+ (List<TestCaseRunEntity>) entity;
+ Map<
+ com.googlecode.objectify.Key<
+ TestCaseRunEntity>,
+ TestCaseRunEntity>
+ testCaseRunEntityMap =
+ DashboardEntity.saveAll(
+ dashboardEntityList,
+ 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) {
+ List<TestRunEntity> dashboardEntityList =
+ (List<TestRunEntity>) entity;
+ dashboardEntityList.get(0).setTestCaseIds(testCaseIds);
+ DashboardEntity.saveAll(
+ dashboardEntityList,
+ 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());
+
+ testRunKeyList.forEach(
+ (v) -> {
+ log.debug("TestRunEntity key value => " + v);
+ });
+ log.debug("testRunEntityMap value => " + testRunEntityMap.values());
+ log.debug("testRunEntityMap keySet => " + testRunEntityMap.keySet());
+
+ 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/TestDataForDevServlet.java b/src/main/java/com/android/vts/api/TestDataForDevServlet.java
index 7fc067f..2ed387b 100644
--- a/src/main/java/com/android/vts/api/TestDataForDevServlet.java
+++ b/src/main/java/com/android/vts/api/TestDataForDevServlet.java
@@ -490,14 +490,14 @@ public class TestDataForDevServlet extends HttpServlet {
BuildTargetEntity buildTargetEntity =
new BuildTargetEntity(
buildTarget.targetName);
- datastore.put(buildTargetEntity.toEntity());
+ buildTargetEntity.save();
});
testRun.branchList.forEach(
branch -> {
BranchEntity branchEntity =
new BranchEntity(branch.branchName);
- datastore.put(branchEntity.toEntity());
+ branchEntity.save();
});
boolean hasCodeCoverage =
@@ -630,13 +630,14 @@ public class TestDataForDevServlet extends HttpServlet {
testBuildId,
passCount,
failCount,
- 0L,
- 0L,
+ 0L,
+ 0L,
testRunKeys);
// Create the device infos.
for (DeviceInfoEntity device : devices) {
- datastore.put(device.copyWithParent(testPlanRun.key).toEntity());
+ datastore.put(
+ device.copyWithParent(testPlanRun.getOfyKey()).toEntity());
}
datastore.put(testPlanRun.toEntity());
diff --git a/src/main/java/com/android/vts/config/ObjectifyListener.java b/src/main/java/com/android/vts/config/ObjectifyListener.java
index 9c4a705..5f35abd 100644
--- a/src/main/java/com/android/vts/config/ObjectifyListener.java
+++ b/src/main/java/com/android/vts/config/ObjectifyListener.java
@@ -23,6 +23,7 @@ import com.android.vts.entity.ApiCoverageExcludedEntity;
import com.android.vts.entity.CodeCoverageEntity;
import com.android.vts.entity.CoverageEntity;
import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.HalApiEntity;
import com.android.vts.entity.ProfilingPointEntity;
import com.android.vts.entity.ProfilingPointRunEntity;
import com.android.vts.entity.ProfilingPointSummaryEntity;
@@ -87,6 +88,7 @@ public class ObjectifyListener implements ServletContextListener {
ObjectifyService.register(BranchEntity.class);
ObjectifyService.register(BuildTargetEntity.class);
+ ObjectifyService.register(HalApiEntity.class);
ObjectifyService.register(ApiCoverageEntity.class);
ObjectifyService.register(ApiCoverageExcludedEntity.class);
ObjectifyService.register(CodeCoverageEntity.class);
@@ -106,6 +108,7 @@ public class ObjectifyListener implements ServletContextListener {
ObjectifyService.register(TestStatusEntity.class);
ObjectifyService.register(TestSuiteFileEntity.class);
ObjectifyService.register(TestSuiteResultEntity.class);
+ ObjectifyService.register(TestAcknowledgmentEntity.class);
ObjectifyService.register(RoleEntity.class);
ObjectifyService.register(UserEntity.class);
ObjectifyService.begin();
@@ -123,6 +126,9 @@ public class ObjectifyListener implements ServletContextListener {
servletContextEvent
.getServletContext()
+ .setAttribute("systemConfigProp", systemConfigProp);
+ servletContextEvent
+ .getServletContext()
.setAttribute("dataStoreFactory", DATA_STORE_FACTORY);
servletContextEvent
.getServletContext()
diff --git a/src/main/java/com/android/vts/entity/ApiCoverageEntity.java b/src/main/java/com/android/vts/entity/ApiCoverageEntity.java
index 0a41743..9c74032 100644
--- a/src/main/java/com/android/vts/entity/ApiCoverageEntity.java
+++ b/src/main/java/com/android/vts/entity/ApiCoverageEntity.java
@@ -35,167 +35,125 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
-/**
- * Entity Class for ApiCoverageEntity
- */
+/** Entity Class for ApiCoverageEntity */
@Cache
@Entity(name = "ApiCoverage")
@EqualsAndHashCode(of = "id")
@NoArgsConstructor
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
@JsonIgnoreProperties({"id", "parent"})
-public class ApiCoverageEntity {
-
- /**
- * ApiCoverageEntity id field
- */
- @Id
- @Getter
- @Setter
- String id;
-
- @Parent
- @Getter
- Key<?> parent;
-
- /**
- * HAL package name. e.g. android.hardware.foo.
- */
- @Index
- @Getter
- @Setter
- String halPackageName;
-
- /**
- * HAL (major) version. e.g. 1.
- */
- @Index
- @Getter
- @Setter
- int halMajorVersion;
-
- /**
- * HAL (minor) version. e.g. 0.
- */
- @Index
- @Getter
- @Setter
- int halMinorVersion;
-
- /**
- * HAL interface name. e.g. IFoo.
- */
- @Index
- @Getter
- @Setter
- String halInterfaceName;
-
- /**
- * List of HAL API
- */
- @Getter
- @Setter
- List<String> halApi;
-
- /**
- * List of HAL covered API
- */
- @Getter
- @Setter
- List<String> coveredHalApi;
-
- /**
- * When this record was created or updated
- */
- @Index
- Date updated;
-
- /**
- * Constructor function for ApiCoverageEntity Class
- */
- public ApiCoverageEntity(com.google.appengine.api.datastore.Key testRunKey, String halPackageName,
- int halVersionMajor, int halVersionMinor, String halInterfaceName, List<String> halApi,
- List<String> coveredHalApi) {
-
- this.parent = getParentKey(testRunKey);
-
- this.halPackageName = halPackageName;
- this.halMajorVersion = halVersionMajor;
- this.halMinorVersion = halVersionMinor;
- this.halInterfaceName = halInterfaceName;
- this.halApi = halApi;
- this.coveredHalApi = coveredHalApi;
- }
-
- /**
- * Constructor function for ApiCoverageEntity Class with objectify Key.
- */
- public ApiCoverageEntity(Key testRunKey, String halPackageName,
- int halVersionMajor, int halVersionMinor, String halInterfaceName,
- List<String> halApi, List<String> coveredHalApi) {
- this.parent = testRunKey;
-
- this.halPackageName = halPackageName;
- this.halMajorVersion = halVersionMajor;
- this.halMinorVersion = halVersionMinor;
- this.halInterfaceName = halInterfaceName;
- this.halApi = halApi;
- this.coveredHalApi = coveredHalApi;
- }
-
- /**
- * Get objectify Key from datastore Key type
- */
- private Key getParentKey(com.google.appengine.api.datastore.Key testRunKey) {
- Key testParentKey = Key.create(TestEntity.class, testRunKey.getParent().getName());
- return Key.create(testParentKey, TestRunEntity.class, testRunKey.getId());
- }
-
- /**
- * Get UrlSafeKey from ApiCoverageEntity Information
- */
- public String getUrlSafeKey() {
- Key uuidKey = Key.create(this.parent, ApiCoverageEntity.class, this.id);
- return uuidKey.toUrlSafe();
- }
-
- /**
- * Saving function for the instance of this class
- */
- public Key<ApiCoverageEntity> save() {
- this.id = UUID.randomUUID().toString();
- this.updated = new Date();
- return ofy().save().entity(this).now();
- }
-
- /**
- * Get List of ApiCoverageEntity by HAL interface name
- */
- public static ApiCoverageEntity getByUrlSafeKey(String urlSafeKey) {
- return ofy().load()
- .type(ApiCoverageEntity.class)
- .filterKey(com.google.cloud.datastore.Key.fromUrlSafe(urlSafeKey))
- .first()
- .now();
- }
-
- /**
- * Get List of ApiCoverageEntity by HAL interface name
- */
- public static List<ApiCoverageEntity> getByInterfaceNameList(String halInterfaceName) {
- return ofy().load()
- .type(ApiCoverageEntity.class)
- .filter("halInterfaceName", halInterfaceName)
- .list();
- }
-
- /**
- * Get List of ApiCoverageEntity by HAL package name
- */
- public static List<ApiCoverageEntity> getByPackageNameList(String packageName) {
- return ofy().load()
- .type(ApiCoverageEntity.class)
- .filter("halPackageName", packageName)
- .list();
- }
+public class ApiCoverageEntity implements DashboardEntity {
+
+ /** ApiCoverageEntity id field */
+ @Id @Getter @Setter String id;
+
+ @Parent @Getter Key<?> parent;
+
+ /** HAL package name. e.g. android.hardware.foo. */
+ @Index @Getter @Setter String halPackageName;
+
+ /** HAL (major) version. e.g. 1. */
+ @Index @Getter @Setter int halMajorVersion;
+
+ /** HAL (minor) version. e.g. 0. */
+ @Index @Getter @Setter int halMinorVersion;
+
+ /** HAL interface name. e.g. IFoo. */
+ @Index @Getter @Setter String halInterfaceName;
+
+ /** List of HAL API */
+ @Getter @Setter List<String> halApi;
+
+ /** List of HAL covered API */
+ @Getter @Setter List<String> coveredHalApi;
+
+ /** When this record was created or updated */
+ @Index Date updated;
+
+ /** Constructor function for ApiCoverageEntity Class */
+ public ApiCoverageEntity(
+ com.google.appengine.api.datastore.Key testRunKey,
+ String halPackageName,
+ int halVersionMajor,
+ int halVersionMinor,
+ String halInterfaceName,
+ List<String> halApi,
+ List<String> coveredHalApi) {
+ this.id = UUID.randomUUID().toString();
+ this.parent = getParentKey(testRunKey);
+
+ this.halPackageName = halPackageName;
+ this.halMajorVersion = halVersionMajor;
+ this.halMinorVersion = halVersionMinor;
+ this.halInterfaceName = halInterfaceName;
+ this.halApi = halApi;
+ this.coveredHalApi = coveredHalApi;
+ this.updated = new Date();
+ }
+
+ /** Constructor function for ApiCoverageEntity Class with objectify Key. */
+ public ApiCoverageEntity(
+ Key testRunKey,
+ String halPackageName,
+ int halVersionMajor,
+ int halVersionMinor,
+ String halInterfaceName,
+ List<String> halApi,
+ List<String> coveredHalApi) {
+ this.id = UUID.randomUUID().toString();
+ this.parent = testRunKey;
+
+ this.halPackageName = halPackageName;
+ this.halMajorVersion = halVersionMajor;
+ this.halMinorVersion = halVersionMinor;
+ this.halInterfaceName = halInterfaceName;
+ this.halApi = halApi;
+ this.coveredHalApi = coveredHalApi;
+ this.updated = new Date();
+ }
+
+ /** Get objectify Key from datastore Key type */
+ private Key getParentKey(com.google.appengine.api.datastore.Key testRunKey) {
+ Key testParentKey = Key.create(TestEntity.class, testRunKey.getParent().getName());
+ return Key.create(testParentKey, TestRunEntity.class, testRunKey.getId());
+ }
+
+ /** Get UrlSafeKey from ApiCoverageEntity Information */
+ public String getUrlSafeKey() {
+ Key uuidKey = Key.create(this.parent, ApiCoverageEntity.class, this.id);
+ return uuidKey.toUrlSafe();
+ }
+
+ /** Saving function for the instance of this class */
+ @Override
+ public Key<ApiCoverageEntity> save() {
+ this.id = UUID.randomUUID().toString();
+ this.updated = new Date();
+ return ofy().save().entity(this).now();
+ }
+
+ /** Get List of ApiCoverageEntity by HAL interface name */
+ public static ApiCoverageEntity getByUrlSafeKey(String urlSafeKey) {
+ return ofy().load()
+ .type(ApiCoverageEntity.class)
+ .filterKey(com.google.cloud.datastore.Key.fromUrlSafe(urlSafeKey))
+ .first()
+ .now();
+ }
+
+ /** Get List of ApiCoverageEntity by HAL interface name */
+ public static List<ApiCoverageEntity> getByInterfaceNameList(String halInterfaceName) {
+ return ofy().load()
+ .type(ApiCoverageEntity.class)
+ .filter("halInterfaceName", halInterfaceName)
+ .list();
+ }
+
+ /** Get List of ApiCoverageEntity by HAL package name */
+ public static List<ApiCoverageEntity> getByPackageNameList(String packageName) {
+ return ofy().load()
+ .type(ApiCoverageEntity.class)
+ .filter("halPackageName", packageName)
+ .list();
+ }
}
diff --git a/src/main/java/com/android/vts/entity/ApiCoverageExcludedEntity.java b/src/main/java/com/android/vts/entity/ApiCoverageExcludedEntity.java
index 834f8cc..61bd6a7 100644
--- a/src/main/java/com/android/vts/entity/ApiCoverageExcludedEntity.java
+++ b/src/main/java/com/android/vts/entity/ApiCoverageExcludedEntity.java
@@ -28,11 +28,8 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
-import java.util.Collection;
import java.util.Date;
import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
import static com.googlecode.objectify.ObjectifyService.ofy;
@@ -46,10 +43,7 @@ import static com.googlecode.objectify.ObjectifyService.ofy;
@NoArgsConstructor
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
@JsonIgnoreProperties({"id", "parent"})
-public class ApiCoverageExcludedEntity {
-
- // The maximum number of entity list size to insert datastore
- private static final int maxNumEntitySize = 500;
+public class ApiCoverageExcludedEntity implements DashboardEntity {
/** ApiCoverageEntity id field */
@Id @Getter @Setter private String id;
@@ -82,11 +76,12 @@ public class ApiCoverageExcludedEntity {
String interfaceName,
String apiName,
String comment) {
-
+ this.id = this.getObjectifyId();
this.packageName = packageName;
this.interfaceName = interfaceName;
this.apiName = apiName;
this.comment = comment;
+ this.updated = new Date();
this.setVersions(version);
}
@@ -125,44 +120,14 @@ public class ApiCoverageExcludedEntity {
}
/** Saving function for the instance of this class */
+ @Override
public Key<ApiCoverageExcludedEntity> save() {
- this.id = this.getObjectifyId();
- this.updated = new Date();
return ofy().save().entity(this).now();
}
- /** Spliting a list based on a given size */
- public static <T> Collection<List<T>> partitionBasedOnSize(List<T> inputList, int size) {
- final AtomicInteger counter = new AtomicInteger(0);
- return inputList
- .stream()
- .collect(Collectors.groupingBy(s -> counter.getAndIncrement() / size))
- .values();
- }
-
- /** Saving function with parameter of this entity List */
- public static void saveAll(List<ApiCoverageExcludedEntity> apiCoverageExcludedEntityList) {
- List<ApiCoverageExcludedEntity> entityWithIdList =
- apiCoverageExcludedEntityList
- .stream()
- .map(
- entity -> {
- entity.setId(entity.getObjectifyId());
- entity.setUpdated(new Date());
- return entity;
- })
- .collect(Collectors.toList());
-
- partitionBasedOnSize(entityWithIdList, maxNumEntitySize)
- .stream()
- .forEach(
- entityList -> {
- ofy().save().entities(entityList).now();
- });
- }
-
/** Get All Key List of ApiCoverageExcludedEntity */
public static List<Key<ApiCoverageExcludedEntity>> getAllKeyList() {
return ofy().load().type(ApiCoverageExcludedEntity.class).keys().list();
}
+
}
diff --git a/src/main/java/com/android/vts/entity/BranchEntity.java b/src/main/java/com/android/vts/entity/BranchEntity.java
index fa3f7a5..1c9ea52 100644
--- a/src/main/java/com/android/vts/entity/BranchEntity.java
+++ b/src/main/java/com/android/vts/entity/BranchEntity.java
@@ -41,8 +41,6 @@ public class BranchEntity implements DashboardEntity {
public static final String KIND = "Branch"; // The entity kind.
- public Key key; // The key for the entity in the database.
-
@Id private String name;
/**
@@ -51,7 +49,11 @@ public class BranchEntity implements DashboardEntity {
* @param branchName The name of the branch.
*/
public BranchEntity(String branchName) {
- this.key = KeyFactory.createKey(KIND, branchName);
+ this.name = branchName;
+ }
+
+ public Key getKey() {
+ return KeyFactory.createKey(KIND, this.name);
}
/** find by branch name */
@@ -86,9 +88,10 @@ public class BranchEntity implements DashboardEntity {
}
}
+ /** Saving function for the instance of this class */
@Override
- public Entity toEntity() {
- return new Entity(this.key);
+ public com.googlecode.objectify.Key<BranchEntity> save() {
+ return ofy().save().entity(this).now();
}
/**
diff --git a/src/main/java/com/android/vts/entity/BuildTargetEntity.java b/src/main/java/com/android/vts/entity/BuildTargetEntity.java
index b204d0c..4180213 100644
--- a/src/main/java/com/android/vts/entity/BuildTargetEntity.java
+++ b/src/main/java/com/android/vts/entity/BuildTargetEntity.java
@@ -41,8 +41,6 @@ public class BuildTargetEntity implements DashboardEntity {
public static final String KIND = "BuildTarget"; // The entity kind.
- public Key key; // The key for the entity in the database.
-
@Id private String name;
/**
@@ -51,12 +49,16 @@ public class BuildTargetEntity implements DashboardEntity {
* @param targetName The name of the build target.
*/
public BuildTargetEntity(String targetName) {
- this.key = KeyFactory.createKey(KIND, targetName);
+ this.name = targetName;
}
+ public Key getKey() {
+ return KeyFactory.createKey(KIND, this.name);
+ }
+ /** Saving function for the instance of this class */
@Override
- public Entity toEntity() {
- return new Entity(this.key);
+ public com.googlecode.objectify.Key<BuildTargetEntity> save() {
+ return ofy().save().entity(this).now();
}
/** find by Build Target Name */
diff --git a/src/main/java/com/android/vts/entity/CodeCoverageEntity.java b/src/main/java/com/android/vts/entity/CodeCoverageEntity.java
index 63034ef..2a46b1f 100644
--- a/src/main/java/com/android/vts/entity/CodeCoverageEntity.java
+++ b/src/main/java/com/android/vts/entity/CodeCoverageEntity.java
@@ -16,13 +16,10 @@
package com.android.vts.entity;
-import com.android.vts.util.UrlUtil;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.google.appengine.api.datastore.KeyFactory;
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Cache;
@@ -35,10 +32,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
-import java.util.ArrayList;
import java.util.Date;
-import java.util.List;
-import java.util.logging.Level;
import java.util.logging.Logger;
import static com.googlecode.objectify.ObjectifyService.ofy;
@@ -50,7 +44,7 @@ import static com.googlecode.objectify.ObjectifyService.ofy;
@NoArgsConstructor
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
@JsonIgnoreProperties({"id", "parent"})
-public class CodeCoverageEntity {
+public class CodeCoverageEntity implements DashboardEntity {
protected static final Logger logger = Logger.getLogger(CodeCoverageEntity.class.getName());
public static final String KIND = "CodeCoverage";
@@ -59,7 +53,7 @@ public class CodeCoverageEntity {
public static final String TOTAL_LINE_COUNT = "totalLineCount";
/** CodeCoverageEntity id field */
- @Id @Getter @Setter long id;
+ @Id @Getter @Setter Long id;
@Parent @Getter Key<?> parent;
@@ -82,6 +76,20 @@ public class CodeCoverageEntity {
this.totalLineCount = totalLineCount;
}
+ /** Constructor function for ApiCoverageEntity Class */
+ public CodeCoverageEntity(
+ long id,
+ com.google.appengine.api.datastore.Key testRunKey,
+ long coveredLineCount,
+ long totalLineCount) {
+ this.id = id;
+
+ this.parent = getParentKey(testRunKey);
+
+ this.coveredLineCount = coveredLineCount;
+ this.totalLineCount = totalLineCount;
+ }
+
/** Constructor function for ApiCoverageEntity Class with objectify key*/
public CodeCoverageEntity(Key testRunKey, long coveredLineCount, long totalLineCount) {
this.parent = testRunKey;
@@ -102,6 +110,7 @@ public class CodeCoverageEntity {
}
/** Saving function for the instance of this class */
+ @Override
public Key<CodeCoverageEntity> save() {
this.id = this.getParent().getId();
this.updated = new Date();
diff --git a/src/main/java/com/android/vts/entity/CodeCoverageFileEntity.java b/src/main/java/com/android/vts/entity/CodeCoverageFileEntity.java
index cb6d06c..fe4e8a0 100644
--- a/src/main/java/com/android/vts/entity/CodeCoverageFileEntity.java
+++ b/src/main/java/com/android/vts/entity/CodeCoverageFileEntity.java
@@ -37,11 +37,10 @@ import static com.googlecode.objectify.ObjectifyService.ofy;
@Entity(name = "CodeCoverageFile")
@EqualsAndHashCode(of = "id")
@NoArgsConstructor
-public class CodeCoverageFileEntity {
+public class CodeCoverageFileEntity implements DashboardEntity {
/** CodeCoverageFileEntity testName field */
- @Id
- @Getter @Setter long id;
+ @Id @Getter @Setter Long id;
@Parent
@Getter @Setter private Key<?> coverageParent;
@@ -94,8 +93,9 @@ public class CodeCoverageFileEntity {
}
/** Saving function for the instance of this class */
- public void save() {
+ @Override
+ public Key<CodeCoverageFileEntity> save() {
this.isIgnored = false;
- ofy().save().entity(this).now();
+ return ofy().save().entity(this).now();
}
}
diff --git a/src/main/java/com/android/vts/entity/CoverageEntity.java b/src/main/java/com/android/vts/entity/CoverageEntity.java
index 82b6690..50d2f4e 100644
--- a/src/main/java/com/android/vts/entity/CoverageEntity.java
+++ b/src/main/java/com/android/vts/entity/CoverageEntity.java
@@ -21,14 +21,11 @@ import static com.googlecode.objectify.ObjectifyService.ofy;
import com.android.vts.proto.VtsReportMessage.CoverageReportMessage;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
-import com.google.cloud.datastore.PathElement;
-import com.googlecode.objectify.LoadResult;
import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.Parent;
-import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
@@ -48,231 +45,268 @@ import lombok.Setter;
@Data
@NoArgsConstructor
/** Object describing coverage data gathered for a file. */
-public class CoverageEntity implements Serializable {
-
- protected static final Logger logger = Logger.getLogger(CoverageEntity.class.getName());
-
- public static final String KIND = "Coverage";
-
- public static String GERRIT_URI;
-
- // Property keys
- public static final String GROUP = "group";
- public static final String COVERED_LINE_COUNT = "coveredCount";
- public static final String TOTAL_LINE_COUNT = "totalCount";
- public static final String FILE_PATH = "filePath";
- public static final String PROJECT_NAME = "projectName";
- public static final String PROJECT_VERSION = "projectVersion";
- public static final String LINE_COVERAGE = "lineCoverage";
-
- @Ignore
- @Getter
- @Setter
- private Key parentKey;
-
- @Id
- @Getter
- @Setter
- private Long id;
-
- @Parent
- @Getter
- @Setter
- private com.googlecode.objectify.Key<?> testParent;
-
- @Index
- @Getter
- @Setter
- private String group;
-
- @Getter
- @Setter
- private long coveredCount;
-
- @Getter
- @Setter
- private long totalCount;
-
- @Index
- @Getter
- @Setter
- private String filePath;
-
- @Getter
- @Setter
- private String projectName;
-
- @Getter
- @Setter
- private String projectVersion;
-
- @Getter
- @Setter
- private List<Long> lineCoverage;
-
- /**
- * CoverageEntity isIgnored field
- */
- @Index
- @Getter
- @Setter
- Boolean isIgnored;
-
- /**
- * Create a CoverageEntity object for a file.
- *
- * @param parentKey The key to the parent TestRunEntity object in the database.
- * @param group The group within the test run describing the coverage.
- * @param coveredLineCount The total number of covered lines in the file.
- * @param totalLineCount The total number of uncovered executable lines in the file.
- * @param filePath The path to the file.
- * @param projectName The name of the git project.
- * @param projectVersion The commit hash of the project at the time the test was executed.
- * @param lineCoverage List of coverage counts per executable line in the file.
- */
- public CoverageEntity(Key parentKey, String group, long coveredLineCount, long totalLineCount,
- String filePath, String projectName, String projectVersion, List<Long> lineCoverage) {
- this.parentKey = parentKey;
- this.group = group;
- this.coveredCount = coveredLineCount;
- this.totalCount = totalLineCount;
- this.filePath = filePath;
- this.projectName = projectName;
- this.projectVersion = projectVersion;
- this.lineCoverage = lineCoverage;
- }
-
- /**
- * find coverage entity by ID
- */
- public static CoverageEntity findById(String testName, String testRunId, String id) {
- com.googlecode.objectify.Key testKey = com.googlecode.objectify.Key
- .create(TestEntity.class, testName);
- com.googlecode.objectify.Key testRunKey = com.googlecode.objectify.Key
- .create(testKey, TestRunEntity.class, Long.parseLong(testRunId));
- return ofy().load().type(CoverageEntity.class).parent(testRunKey).id(Long.parseLong(id)).now();
- }
-
- public static void setPropertyValues(Properties newSystemConfigProp) {
- GERRIT_URI = newSystemConfigProp.getProperty("gerrit.uri");
- }
-
- /**
- * Saving function for the instance of this class
- */
- public void save() {
- ofy().save().entity(this).now();
- }
-
- /**
- * Get percentage from calculating coveredCount and totalCount values
- */
- public Double getPercentage() {
- return Math.round(coveredCount * 10000d / totalCount) / 100d;
- }
-
- /**
- * Get Gerrit Url function from the attributes of this class
- */
- public String getGerritUrl() throws UnsupportedEncodingException {
- String gerritPath = GERRIT_URI + "/projects/" +
- URLEncoder.encode(projectName, "UTF-8") + "/commits/" +
- URLEncoder.encode(projectVersion, "UTF-8") + "/files/" +
- URLEncoder.encode(filePath, "UTF-8") + "/content";
- return gerritPath;
- }
-
- /* Comparator for sorting the list by isIgnored field */
- public static Comparator<CoverageEntity> isIgnoredComparator = new Comparator<CoverageEntity>() {
-
- public int compare(CoverageEntity coverageEntity1, CoverageEntity coverageEntity2) {
- Boolean isIgnored1 =
- Objects.isNull(coverageEntity1.getIsIgnored()) ? false : coverageEntity1.getIsIgnored();
- Boolean isIgnored2 =
- Objects.isNull(coverageEntity2.getIsIgnored()) ? false : coverageEntity2.getIsIgnored();
-
- // ascending order
- return isIgnored1.compareTo(isIgnored2);
+public class CoverageEntity implements DashboardEntity {
+
+ protected static final Logger logger = Logger.getLogger(CoverageEntity.class.getName());
+
+ public static final String KIND = "Coverage";
+
+ public static String GERRIT_URI;
+
+ // Property keys
+ public static final String GROUP = "group";
+ public static final String COVERED_LINE_COUNT = "coveredCount";
+ public static final String TOTAL_LINE_COUNT = "totalCount";
+ public static final String FILE_PATH = "filePath";
+ public static final String PROJECT_NAME = "projectName";
+ public static final String PROJECT_VERSION = "projectVersion";
+ public static final String LINE_COVERAGE = "lineCoverage";
+
+ @Ignore @Getter @Setter private Key parentKey;
+
+ @Id @Getter @Setter private Long id;
+
+ @Parent @Getter @Setter private com.googlecode.objectify.Key<?> testParent;
+
+ @Index @Getter @Setter private String group;
+
+ @Getter @Setter private long coveredCount;
+
+ @Getter @Setter private long totalCount;
+
+ @Index @Getter @Setter private String filePath;
+
+ @Getter @Setter private String projectName;
+
+ @Getter @Setter private String projectVersion;
+
+ @Getter @Setter private List<Long> lineCoverage;
+
+ /** CoverageEntity isIgnored field */
+ @Index @Getter @Setter Boolean isIgnored;
+
+ /**
+ * Create a CoverageEntity object for a file.
+ *
+ * @param parentKey The key to the parent TestRunEntity object in the database.
+ * @param group The group within the test run describing the coverage.
+ * @param coveredLineCount The total number of covered lines in the file.
+ * @param totalLineCount The total number of uncovered executable lines in the file.
+ * @param filePath The path to the file.
+ * @param projectName The name of the git project.
+ * @param projectVersion The commit hash of the project at the time the test was executed.
+ * @param lineCoverage List of coverage counts per executable line in the file.
+ */
+ public CoverageEntity(
+ Key parentKey,
+ String group,
+ long coveredLineCount,
+ long totalLineCount,
+ String filePath,
+ String projectName,
+ String projectVersion,
+ List<Long> lineCoverage) {
+ this.parentKey = parentKey;
+ this.group = group;
+ this.coveredCount = coveredLineCount;
+ this.totalCount = totalLineCount;
+ this.filePath = filePath;
+ this.projectName = projectName;
+ this.projectVersion = projectVersion;
+ this.lineCoverage = lineCoverage;
}
- };
-
- public Entity toEntity() {
- Entity coverageEntity = new Entity(KIND, parentKey);
- coverageEntity.setProperty(GROUP, group);
- coverageEntity.setUnindexedProperty(COVERED_LINE_COUNT, coveredCount);
- coverageEntity.setUnindexedProperty(TOTAL_LINE_COUNT, totalCount);
- coverageEntity.setProperty(FILE_PATH, filePath);
- coverageEntity.setUnindexedProperty(PROJECT_NAME, projectName);
- coverageEntity.setUnindexedProperty(PROJECT_VERSION, projectVersion);
- if (lineCoverage != null && lineCoverage.size() > 0) {
- coverageEntity.setUnindexedProperty(LINE_COVERAGE, lineCoverage);
+
+ /**
+ * Create a CoverageEntity object for a file.
+ *
+ * @param testParent The objectify key to the parent TestRunEntity object in the database.
+ * @param group The group within the test run describing the coverage.
+ * @param coveredLineCount The total number of covered lines in the file.
+ * @param totalLineCount The total number of uncovered executable lines in the file.
+ * @param filePath The path to the file.
+ * @param projectName The name of the git project.
+ * @param projectVersion The commit hash of the project at the time the test was executed.
+ * @param lineCoverage List of coverage counts per executable line in the file.
+ */
+ public CoverageEntity(
+ com.googlecode.objectify.Key testParent,
+ String group,
+ long coveredLineCount,
+ long totalLineCount,
+ String filePath,
+ String projectName,
+ String projectVersion,
+ List<Long> lineCoverage) {
+ this.testParent = testParent;
+ this.group = group;
+ this.coveredCount = coveredLineCount;
+ this.totalCount = totalLineCount;
+ this.filePath = filePath;
+ this.projectName = projectName;
+ this.projectVersion = projectVersion;
+ this.lineCoverage = lineCoverage;
+ }
+
+ /** find coverage entity by ID */
+ public static CoverageEntity findById(String testName, String testRunId, String id) {
+ com.googlecode.objectify.Key testKey =
+ com.googlecode.objectify.Key.create(TestEntity.class, testName);
+ com.googlecode.objectify.Key testRunKey =
+ com.googlecode.objectify.Key.create(
+ testKey, TestRunEntity.class, Long.parseLong(testRunId));
+ return ofy().load()
+ .type(CoverageEntity.class)
+ .parent(testRunKey)
+ .id(Long.parseLong(id))
+ .now();
+ }
+
+ public static void setPropertyValues(Properties newSystemConfigProp) {
+ GERRIT_URI = newSystemConfigProp.getProperty("gerrit.uri");
+ }
+
+ /** Saving function for the instance of this class */
+ @Override
+ public com.googlecode.objectify.Key<CoverageEntity> save() {
+ return ofy().save().entity(this).now();
+ }
+
+ /** Get percentage from calculating coveredCount and totalCount values */
+ public Double getPercentage() {
+ return Math.round(coveredCount * 10000d / totalCount) / 100d;
}
- return coverageEntity;
- }
-
- /**
- * Convert an Entity object to a CoverageEntity.
- *
- * @param e The entity to process.
- * @return CoverageEntity object with the properties from e, or null if incompatible.
- */
- @SuppressWarnings("unchecked")
- public static CoverageEntity fromEntity(Entity e) {
- if (!e.getKind().equals(KIND) || !e.hasProperty(GROUP) || !e.hasProperty(COVERED_LINE_COUNT)
- || !e.hasProperty(TOTAL_LINE_COUNT) || !e.hasProperty(FILE_PATH)
- || !e.hasProperty(PROJECT_NAME) || !e.hasProperty(PROJECT_VERSION)) {
- logger.log(Level.WARNING, "Missing coverage attributes in entity: " + e.toString());
- return null;
+
+ /** Get Gerrit Url function from the attributes of this class */
+ public String getGerritUrl() throws UnsupportedEncodingException {
+ String gerritPath =
+ GERRIT_URI
+ + "/projects/"
+ + URLEncoder.encode(projectName, "UTF-8")
+ + "/commits/"
+ + URLEncoder.encode(projectVersion, "UTF-8")
+ + "/files/"
+ + URLEncoder.encode(filePath, "UTF-8")
+ + "/content";
+ return gerritPath;
}
- try {
- String group = (String) e.getProperty(GROUP);
- long coveredLineCount = (long) e.getProperty(COVERED_LINE_COUNT);
- long totalLineCount = (long) e.getProperty(TOTAL_LINE_COUNT);
- String filePath = (String) e.getProperty(FILE_PATH);
- String projectName = (String) e.getProperty(PROJECT_NAME);
- String projectVersion = (String) e.getProperty(PROJECT_VERSION);
- List<Long> lineCoverage;
- if (e.hasProperty(LINE_COVERAGE)) {
- lineCoverage = (List<Long>) e.getProperty(LINE_COVERAGE);
- } else {
- lineCoverage = new ArrayList<>();
- }
- return new CoverageEntity(e.getKey().getParent(), group, coveredLineCount,
- totalLineCount, filePath, projectName, projectVersion, lineCoverage);
- } catch (ClassCastException exception) {
- // Invalid contents or null values
- logger.log(Level.WARNING, "Error parsing coverage entity.", exception);
+
+ /* Comparator for sorting the list by isIgnored field */
+ public static Comparator<CoverageEntity> isIgnoredComparator =
+ new Comparator<CoverageEntity>() {
+
+ public int compare(CoverageEntity coverageEntity1, CoverageEntity coverageEntity2) {
+ Boolean isIgnored1 =
+ Objects.isNull(coverageEntity1.getIsIgnored())
+ ? false
+ : coverageEntity1.getIsIgnored();
+ Boolean isIgnored2 =
+ Objects.isNull(coverageEntity2.getIsIgnored())
+ ? false
+ : coverageEntity2.getIsIgnored();
+
+ // ascending order
+ return isIgnored1.compareTo(isIgnored2);
+ }
+ };
+
+ public Entity toEntity() {
+ Entity coverageEntity = new Entity(KIND, parentKey);
+ coverageEntity.setProperty(GROUP, group);
+ coverageEntity.setUnindexedProperty(COVERED_LINE_COUNT, coveredCount);
+ coverageEntity.setUnindexedProperty(TOTAL_LINE_COUNT, totalCount);
+ coverageEntity.setProperty(FILE_PATH, filePath);
+ coverageEntity.setUnindexedProperty(PROJECT_NAME, projectName);
+ coverageEntity.setUnindexedProperty(PROJECT_VERSION, projectVersion);
+ if (lineCoverage != null && lineCoverage.size() > 0) {
+ coverageEntity.setUnindexedProperty(LINE_COVERAGE, lineCoverage);
+ }
+ return coverageEntity;
}
- return null;
- }
-
- /**
- * Convert a coverage report to a CoverageEntity.
- *
- * @param parentKey The ancestor key for the coverage entity.
- * @param group The group to display the coverage report with.
- * @param coverage The coverage report containing coverage data.
- * @return The CoverageEntity for the coverage report message, or null if not compatible.
- */
- public static CoverageEntity fromCoverageReport(
- Key parentKey, String group, CoverageReportMessage coverage) {
- if (!coverage.hasFilePath() || !coverage.hasProjectName() || !coverage.hasRevision()
- || !coverage.hasTotalLineCount() || !coverage.hasCoveredLineCount()) {
- return null; // invalid coverage report;
+
+ /**
+ * Convert an Entity object to a CoverageEntity.
+ *
+ * @param e The entity to process.
+ * @return CoverageEntity object with the properties from e, or null if incompatible.
+ */
+ @SuppressWarnings("unchecked")
+ public static CoverageEntity fromEntity(Entity e) {
+ if (!e.getKind().equals(KIND)
+ || !e.hasProperty(GROUP)
+ || !e.hasProperty(COVERED_LINE_COUNT)
+ || !e.hasProperty(TOTAL_LINE_COUNT)
+ || !e.hasProperty(FILE_PATH)
+ || !e.hasProperty(PROJECT_NAME)
+ || !e.hasProperty(PROJECT_VERSION)) {
+ logger.log(Level.WARNING, "Missing coverage attributes in entity: " + e.toString());
+ return null;
+ }
+ try {
+ String group = (String) e.getProperty(GROUP);
+ long coveredLineCount = (long) e.getProperty(COVERED_LINE_COUNT);
+ long totalLineCount = (long) e.getProperty(TOTAL_LINE_COUNT);
+ String filePath = (String) e.getProperty(FILE_PATH);
+ String projectName = (String) e.getProperty(PROJECT_NAME);
+ String projectVersion = (String) e.getProperty(PROJECT_VERSION);
+ List<Long> lineCoverage;
+ if (e.hasProperty(LINE_COVERAGE)) {
+ lineCoverage = (List<Long>) e.getProperty(LINE_COVERAGE);
+ } else {
+ lineCoverage = new ArrayList<>();
+ }
+ return new CoverageEntity(
+ e.getKey().getParent(),
+ group,
+ coveredLineCount,
+ totalLineCount,
+ filePath,
+ projectName,
+ projectVersion,
+ lineCoverage);
+ } catch (ClassCastException exception) {
+ // Invalid contents or null values
+ logger.log(Level.WARNING, "Error parsing coverage entity.", exception);
+ }
+ return null;
}
- long coveredLineCount = coverage.getCoveredLineCount();
- long totalLineCount = coverage.getTotalLineCount();
- String filePath = coverage.getFilePath().toStringUtf8();
- String projectName = coverage.getProjectName().toStringUtf8();
- String projectVersion = coverage.getRevision().toStringUtf8();
- List<Long> lineCoverage = null;
- if (coverage.getLineCoverageVectorCount() > 0) {
- lineCoverage = new ArrayList<>();
- for (long count : coverage.getLineCoverageVectorList()) {
- lineCoverage.add(count);
- }
+
+ /**
+ * Convert a coverage report to a CoverageEntity.
+ *
+ * @param parentKey The ancestor key for the coverage entity.
+ * @param group The group to display the coverage report with.
+ * @param coverage The coverage report containing coverage data.
+ * @return The CoverageEntity for the coverage report message, or null if not compatible.
+ */
+ public static CoverageEntity fromCoverageReport(
+ com.googlecode.objectify.Key parentKey, String group, CoverageReportMessage coverage) {
+ if (!coverage.hasFilePath()
+ || !coverage.hasProjectName()
+ || !coverage.hasRevision()
+ || !coverage.hasTotalLineCount()
+ || !coverage.hasCoveredLineCount()) {
+ return null; // invalid coverage report;
+ }
+ long coveredLineCount = coverage.getCoveredLineCount();
+ long totalLineCount = coverage.getTotalLineCount();
+ String filePath = coverage.getFilePath().toStringUtf8();
+ String projectName = coverage.getProjectName().toStringUtf8();
+ String projectVersion = coverage.getRevision().toStringUtf8();
+ List<Long> lineCoverage = null;
+ if (coverage.getLineCoverageVectorCount() > 0) {
+ lineCoverage = new ArrayList<>();
+ for (long count : coverage.getLineCoverageVectorList()) {
+ lineCoverage.add(count);
+ }
+ }
+ return new CoverageEntity(
+ parentKey,
+ group,
+ coveredLineCount,
+ totalLineCount,
+ filePath,
+ projectName,
+ projectVersion,
+ lineCoverage);
}
- return new CoverageEntity(parentKey, group, coveredLineCount, totalLineCount, filePath,
- projectName, projectVersion, lineCoverage);
- }
}
diff --git a/src/main/java/com/android/vts/entity/DashboardEntity.java b/src/main/java/com/android/vts/entity/DashboardEntity.java
index 402a1e5..a42c1eb 100644
--- a/src/main/java/com/android/vts/entity/DashboardEntity.java
+++ b/src/main/java/com/android/vts/entity/DashboardEntity.java
@@ -16,14 +16,41 @@
package com.android.vts.entity;
-import com.google.appengine.api.datastore.Entity;
+import com.google.common.collect.Lists;
+import com.googlecode.objectify.Key;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static com.googlecode.objectify.ObjectifyService.ofy;
/** Interface for interacting with VTS Dashboard entities in Cloud Datastore. */
-public interface DashboardEntity {
+public interface DashboardEntity extends Serializable {
/**
- * Serialize the DashboardEntity to an Entity object.
+ * Save the Entity to the datastore.
*
- * @return Entity object representing the properties defined in the DashboardEntity.
+ * @return The saved entity's key value.
*/
- public Entity toEntity();
+ <T> Key<T> save();
+
+ /** Save List of entity through objectify entities method. */
+ static <T> Map<Key<T>, T> saveAll(List<T> entityList, int maxEntitySize) {
+ return ofy().transact(
+ () -> {
+ List<List<T>> partitionedList =
+ Lists.partition(entityList, maxEntitySize);
+ return partitionedList
+ .stream()
+ .map(
+ subEntityList ->
+ ofy().save().entities(subEntityList).now())
+ .flatMap(m -> m.entrySet().stream())
+ .collect(
+ Collectors.toMap(
+ entry -> entry.getKey(),
+ entry -> entry.getValue()));
+ });
+ }
}
diff --git a/src/main/java/com/android/vts/entity/DeviceInfoEntity.java b/src/main/java/com/android/vts/entity/DeviceInfoEntity.java
index d0c3d00..2b98355 100644
--- a/src/main/java/com/android/vts/entity/DeviceInfoEntity.java
+++ b/src/main/java/com/android/vts/entity/DeviceInfoEntity.java
@@ -27,7 +27,6 @@ import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.Parent;
-import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
@@ -44,7 +43,7 @@ import static com.googlecode.objectify.ObjectifyService.ofy;
@Data
@NoArgsConstructor
/** Class describing a device used for a test run. */
-public class DeviceInfoEntity implements Serializable {
+public class DeviceInfoEntity implements DashboardEntity {
protected static final Logger logger = Logger.getLogger(DeviceInfoEntity.class.getName());
/** This is the instance of App Engine memcache service java library */
@@ -64,8 +63,7 @@ public class DeviceInfoEntity implements Serializable {
private Key parentKey;
/** ID field using start timestamp */
- @Id
- private long id;
+ @Id private Long id;
/** parent field based on Test and TestRun key */
@Parent
@@ -87,15 +85,6 @@ public class DeviceInfoEntity implements Serializable {
private String abiName;
- /*
- public final String branch;
- public final String product;
- public final String buildFlavor;
- public final String buildId;
- public final String abiBitness;
- public final String abiName;
- */
-
/**
* Create a DeviceInfoEntity object.
*
@@ -215,8 +204,8 @@ public class DeviceInfoEntity implements Serializable {
}
/** Saving function for the instance of this class */
- public void save() {
- ofy().save().entity(this).now();
+ public com.googlecode.objectify.Key<DeviceInfoEntity> save() {
+ return ofy().save().entity(this).now();
}
public Entity toEntity() {
@@ -270,12 +259,12 @@ public class DeviceInfoEntity implements Serializable {
/**
* Convert a device info message to a DeviceInfoEntity.
*
- * @param parentKey The ancestor key for the device entity.
+ * @param parent The ancestor key for the device entity.
* @param device The device info report describing the target Android device.
* @return The DeviceInfoEntity for the target device, or null if incompatible
*/
public static DeviceInfoEntity fromDeviceInfoMessage(
- Key parentKey, AndroidDeviceInfoMessage device) {
+ com.googlecode.objectify.Key parent, AndroidDeviceInfoMessage device) {
if (!device.hasBuildAlias() || !device.hasBuildFlavor() || !device.hasProductVariant()
|| !device.hasBuildId()) {
return null;
@@ -287,7 +276,7 @@ public class DeviceInfoEntity implements Serializable {
String abiBitness = device.getAbiBitness().toStringUtf8();
String abiName = device.getAbiName().toStringUtf8();
return new DeviceInfoEntity(
- parentKey, branch, product, buildFlavor, buildId, abiBitness, abiName);
+ parent, branch, product, buildFlavor, buildId, abiBitness, abiName);
}
@Override
@@ -312,10 +301,11 @@ public class DeviceInfoEntity implements Serializable {
/**
* Create a copy of the device info under a near parent.
+ *
* @param parentKey The new parent key.
* @return A copy of the DeviceInfoEntity with the specified parent.
*/
- public DeviceInfoEntity copyWithParent(Key parentKey) {
+ public DeviceInfoEntity copyWithParent(com.googlecode.objectify.Key parentKey) {
return new DeviceInfoEntity(parentKey, this.branch, this.product, this.buildFlavor,
this.buildId, this.abiBitness, this.abiName);
}
diff --git a/src/main/java/com/android/vts/entity/HalApiEntity.java b/src/main/java/com/android/vts/entity/HalApiEntity.java
new file mode 100644
index 0000000..158a4ca
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/HalApiEntity.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2018 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.entity;
+
+import static com.googlecode.objectify.ObjectifyService.ofy;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.googlecode.objectify.Key;
+import com.googlecode.objectify.annotation.Cache;
+import com.googlecode.objectify.annotation.Entity;
+import com.googlecode.objectify.annotation.Id;
+import com.googlecode.objectify.annotation.Index;
+import com.googlecode.objectify.annotation.Parent;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/** Entity Class for HalApiEntity */
+@Cache
+@Entity(name = "HalApiEntity")
+@EqualsAndHashCode(of = "id")
+@NoArgsConstructor
+@JsonAutoDetect(fieldVisibility = Visibility.ANY)
+@JsonIgnoreProperties({"id", "parent"})
+public class HalApiEntity implements DashboardEntity {
+
+ /** HalApiEntity id field */
+ @Id @Getter @Setter String id;
+
+ @Parent @Getter Key<?> parent;
+
+ /** HAL Api Release Level. e.g. */
+ @Index @Getter @Setter String halApiReleaseLevel;
+
+ /** HAL package name. e.g. android.hardware.foo. */
+ @Index @Getter @Setter String halPackageName;
+
+ /** HAL (major) version. e.g. 1. */
+ @Index @Getter @Setter int halVersionMajor;
+
+ /** HAL (minor) version. e.g. 0. */
+ @Index @Getter @Setter int halVersionMinor;
+
+ /** HAL interface name. e.g. IFoo. */
+ @Index @Getter @Setter String halInterfaceName;
+
+ /** List of HAL API */
+ @Getter @Setter List<String> halApi;
+
+ /** List of HAL covered API */
+ @Getter @Setter List<String> coveredHalApi;
+
+ /** When this record was created or updated */
+ @Index Date updated;
+
+ /** Constructor function for HalApiEntity Class */
+ public HalApiEntity(
+ com.googlecode.objectify.Key testRunKey,
+ String halApiReleaseLevel,
+ String halPackageName,
+ int halVersionMajor,
+ int halVersionMinor,
+ String halInterfaceName,
+ List<String> halApi,
+ List<String> coveredHalApi) {
+
+ this.id = UUID.randomUUID().toString();
+ this.parent = testRunKey;
+
+ this.halApiReleaseLevel = halApiReleaseLevel;
+ this.halPackageName = halPackageName;
+ this.halVersionMajor = halVersionMajor;
+ this.halVersionMinor = halVersionMinor;
+ this.halInterfaceName = halInterfaceName;
+ this.halApi = halApi;
+ this.coveredHalApi = coveredHalApi;
+ this.updated = new Date();
+ }
+
+ /** Saving function for the instance of this class */
+ @Override
+ public Key<HalApiEntity> save() {
+ return ofy().save().entity(this).now();
+ }
+}
diff --git a/src/main/java/com/android/vts/entity/ProfilingPointEntity.java b/src/main/java/com/android/vts/entity/ProfilingPointEntity.java
index 741a5a7..ac2994c 100644
--- a/src/main/java/com/android/vts/entity/ProfilingPointEntity.java
+++ b/src/main/java/com/android/vts/entity/ProfilingPointEntity.java
@@ -25,21 +25,20 @@ import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Index;
-import java.io.Serializable;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import lombok.Data;
-import lombok.Getter;
import lombok.NoArgsConstructor;
-import lombok.Setter;
+
+import static com.googlecode.objectify.ObjectifyService.ofy;
@com.googlecode.objectify.annotation.Entity(name = "ProfilingPoint")
@Cache
@Data
@NoArgsConstructor
/** Entity describing a profiling point. */
-public class ProfilingPointEntity implements Serializable {
+public class ProfilingPointEntity implements DashboardEntity {
protected static final Logger logger = Logger.getLogger(ProfilingPointEntity.class.getName());
protected static final String DELIMITER = "#";
@@ -141,6 +140,12 @@ public class ProfilingPointEntity implements Serializable {
return KeyFactory.createKey(KIND, testName + DELIMITER + profilingPointName);
}
+ /** Saving function for the instance of this class */
+ @Override
+ public com.googlecode.objectify.Key<ProfilingPointEntity> save() {
+ return ofy().save().entity(this).now();
+ }
+
public Entity toEntity() {
Entity profilingPoint = new Entity(key);
profilingPoint.setIndexedProperty(TEST_NAME, this.testName);
diff --git a/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java b/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java
index 2010971..48df727 100644
--- a/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java
+++ b/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java
@@ -27,22 +27,21 @@ import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Parent;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import lombok.Data;
-import lombok.Getter;
import lombok.NoArgsConstructor;
-import lombok.Setter;
+
+import static com.googlecode.objectify.ObjectifyService.ofy;
@com.googlecode.objectify.annotation.Entity(name = "ProfilingPointRun")
@Cache
@Data
@NoArgsConstructor
/** Entity describing a profiling point execution. */
-public class ProfilingPointRunEntity implements Serializable {
+public class ProfilingPointRunEntity implements DashboardEntity {
protected static final Logger logger =
Logger.getLogger(ProfilingPointRunEntity.class.getName());
@@ -94,7 +93,7 @@ public class ProfilingPointRunEntity implements Serializable {
/**
* Create a ProfilingPointRunEntity object.
*
- * @param parentKey The Key object for the parent TestRunEntity in the database.
+ * @param parentKey The Key object for the parent TestRunEntity in datastore.
* @param name The name of the profiling point.
* @param type The (number) type of the profiling point data.
* @param regressionMode The (number) mode to use for detecting regression.
@@ -125,6 +124,41 @@ public class ProfilingPointRunEntity implements Serializable {
this.options = options;
}
+
+ /**
+ * Create a ProfilingPointRunEntity object.
+ *
+ * @param parent The objectify Key for the parent TestRunEntity in datastore.
+ * @param name The name of the profiling point.
+ * @param type The (number) type of the profiling point data.
+ * @param regressionMode The (number) mode to use for detecting regression.
+ * @param labels List of data labels, or null if the data is unlabeled.
+ * @param values List of data values.
+ * @param xLabel The x axis label.
+ * @param yLabel The y axis label.
+ * @param options The list of key=value options for the profiling point run.
+ */
+ public ProfilingPointRunEntity(
+ com.googlecode.objectify.Key parent,
+ String name,
+ int type,
+ int regressionMode,
+ List<String> labels,
+ List<Long> values,
+ String xLabel,
+ String yLabel,
+ List<String> options) {
+ this.parent = parent;
+ this.name = name;
+ this.type = type;
+ this.regressionMode = regressionMode;
+ this.labels = labels == null ? null : new ArrayList<>(labels);
+ this.values = new ArrayList<>(values);
+ this.xLabel = xLabel;
+ this.yLabel = yLabel;
+ this.options = options;
+ }
+
/**
* Get VtsProfilingType from int value.
*
@@ -143,6 +177,12 @@ public class ProfilingPointRunEntity implements Serializable {
return VtsProfilingRegressionMode.forNumber(regressionMode);
}
+ /** Saving function for the instance of this class */
+ @Override
+ public com.googlecode.objectify.Key<ProfilingPointRunEntity> save() {
+ return ofy().save().entity(this).now();
+ }
+
public Entity toEntity() {
Entity profilingRun = new Entity(this.key);
profilingRun.setUnindexedProperty(TYPE, this.type);
@@ -207,12 +247,12 @@ public class ProfilingPointRunEntity implements Serializable {
/**
* Convert a coverage report to a CoverageEntity.
*
- * @param parentKey The ancestor key for the coverage entity.
+ * @param parent The ancestor objectify key for the coverage entity.
* @param profilingReport The profiling report containing profiling data.
* @return The ProfilingPointRunEntity for the profiling report message, or null if incompatible
*/
public static ProfilingPointRunEntity fromProfilingReport(
- Key parentKey, ProfilingReportMessage profilingReport) {
+ com.googlecode.objectify.Key parent, ProfilingReportMessage profilingReport) {
if (!profilingReport.hasName()
|| !profilingReport.hasType()
|| profilingReport.getType() == VtsProfilingType.UNKNOWN_VTS_PROFILING_TYPE
@@ -265,7 +305,7 @@ public class ProfilingPointRunEntity implements Serializable {
}
}
return new ProfilingPointRunEntity(
- parentKey,
+ parent,
name,
type.getNumber(),
regressionMode.getNumber(),
diff --git a/src/main/java/com/android/vts/entity/ProfilingPointSummaryEntity.java b/src/main/java/com/android/vts/entity/ProfilingPointSummaryEntity.java
index f426707..e4a1911 100644
--- a/src/main/java/com/android/vts/entity/ProfilingPointSummaryEntity.java
+++ b/src/main/java/com/android/vts/entity/ProfilingPointSummaryEntity.java
@@ -25,7 +25,6 @@ import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Index;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -33,16 +32,16 @@ import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import lombok.Data;
-import lombok.Getter;
import lombok.NoArgsConstructor;
-import lombok.Setter;
+
+import static com.googlecode.objectify.ObjectifyService.ofy;
@com.googlecode.objectify.annotation.Entity(name = "ProfilingPointSummary")
@Cache
@Data
@NoArgsConstructor
/** Entity describing a profiling point summary. */
-public class ProfilingPointSummaryEntity implements Serializable {
+public class ProfilingPointSummaryEntity implements DashboardEntity {
protected static final Logger logger =
Logger.getLogger(ProfilingPointSummaryEntity.class.getName());
protected static final String DELIMITER = "#";
@@ -237,6 +236,12 @@ public class ProfilingPointSummaryEntity implements Serializable {
}
}
+ /** Saving function for the instance of this class */
+ @Override
+ public com.googlecode.objectify.Key<ProfilingPointSummaryEntity> save() {
+ return ofy().save().entity(this).now();
+ }
+
public Entity toEntity() {
Entity profilingSummary;
profilingSummary = new Entity(this.key);
diff --git a/src/main/java/com/android/vts/entity/RoleEntity.java b/src/main/java/com/android/vts/entity/RoleEntity.java
index d001cfa..508a9ca 100644
--- a/src/main/java/com/android/vts/entity/RoleEntity.java
+++ b/src/main/java/com/android/vts/entity/RoleEntity.java
@@ -6,49 +6,38 @@ import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
-import com.googlecode.objectify.annotation.Index;
-import com.googlecode.objectify.annotation.Load;
-import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Date;
-import java.util.List;
-import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
-
@Cache
@Entity
@EqualsAndHashCode(of = "role")
@NoArgsConstructor
-public class RoleEntity implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- @Id
- private String role;
-
- /** When this record was created or updated */
- @Getter
- Date updated;
-
- /** Construction function for UserEntity Class */
- public RoleEntity(String roleName) {
- this.role = roleName;
- }
-
- /** Get role by email */
- public static RoleEntity getRole(String role) {
- return ofy().load()
- .type(RoleEntity.class)
- .id(role)
- .now();
- }
-
- /** Saving function for the instance of this class */
- public void save() {
- this.updated = new Date();
- ofy().save().entity(this).now();
- }
-} \ No newline at end of file
+public class RoleEntity implements DashboardEntity {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id private String role;
+
+ /** When this record was created or updated */
+ @Getter Date updated;
+
+ /** Construction function for UserEntity Class */
+ public RoleEntity(String roleName) {
+ this.role = roleName;
+ }
+
+ /** Get role by email */
+ public static RoleEntity getRole(String role) {
+ return ofy().load().type(RoleEntity.class).id(role).now();
+ }
+
+ /** Saving function for the instance of this class */
+ @Override
+ public Key<RoleEntity> save() {
+ this.updated = new Date();
+ return ofy().save().entity(this).now();
+ }
+}
diff --git a/src/main/java/com/android/vts/entity/TestAcknowledgmentEntity.java b/src/main/java/com/android/vts/entity/TestAcknowledgmentEntity.java
index 66b56b8..a594f85 100644
--- a/src/main/java/com/android/vts/entity/TestAcknowledgmentEntity.java
+++ b/src/main/java/com/android/vts/entity/TestAcknowledgmentEntity.java
@@ -26,6 +26,12 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.reflect.TypeToken;
+import com.googlecode.objectify.annotation.Cache;
+import com.googlecode.objectify.annotation.Id;
+import com.googlecode.objectify.annotation.Ignore;
+import com.googlecode.objectify.annotation.Index;
+import lombok.Data;
+
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashSet;
@@ -35,6 +41,11 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
+import static com.googlecode.objectify.ObjectifyService.ofy;
+
+@com.googlecode.objectify.annotation.Entity(name = "TestAcknowledgment")
+@Cache
+@Data
/** Entity describing a test failure acknowledgment. */
public class TestAcknowledgmentEntity implements DashboardEntity {
protected static final Logger logger =
@@ -44,21 +55,27 @@ public class TestAcknowledgmentEntity implements DashboardEntity {
public static final String KEY = "key";
public static final String TEST_KEY = "testKey";
public static final String TEST_NAME = "testName";
- public static final String USER = "user";
+ public static final String USER_OBJ = "userObj";
public static final String CREATED = "created";
public static final String BRANCHES = "branches";
public static final String DEVICES = "devices";
public static final String TEST_CASE_NAMES = "testCaseNames";
public static final String NOTE = "note";
- private final Key key;
- private final long created;
- public final Key test;
- public final User user;
- public final Set<String> branches;
- public final Set<String> devices;
- public final Set<String> testCaseNames;
- public final String note;
+ @Ignore private final Key key;
+ @Ignore public final Key test;
+ @Ignore public final User userObj;
+
+ @Id private Long id;
+
+ private com.googlecode.objectify.Key testKey;
+ private Set<String> branches;
+ private Set<String> devices;
+ private Set<String> testCaseNames;
+ private String note;
+ private String user;
+
+ @Index private final long created;
/**
* Create a AcknowledgmentEntity object.
@@ -66,11 +83,11 @@ public class TestAcknowledgmentEntity implements DashboardEntity {
* @param key The key of the AcknowledgmentEntity in the database.
* @param created The timestamp when the entity was created (in microseconds).
* @param test The key of the test.
- * @param user The user who created or last modified the entity.
+ * @param userObj The user who created or last modified the entity.
* @param branches The list of branch names for which the acknowledgment applies (or null if
* all).
- * @param devices The list of device build flavors for which the acknowledgment applies (or
- * null if all).
+ * @param devices The list of device build flavors for which the acknowledgment applies (or null
+ * if all).
* @param testCaseNames The list of test case names known to fail (or null if all).
* @param note A text blob with details about the failure (or null if all).
*/
@@ -78,13 +95,13 @@ public class TestAcknowledgmentEntity implements DashboardEntity {
Key key,
long created,
Key test,
- User user,
+ User userObj,
List<String> branches,
List<String> devices,
List<String> testCaseNames,
Text note) {
this.test = test;
- this.user = user;
+ this.userObj = userObj;
if (branches != null) this.branches = new HashSet(branches);
else this.branches = new HashSet<>();
@@ -105,32 +122,37 @@ public class TestAcknowledgmentEntity implements DashboardEntity {
* Create a AcknowledgmentEntity object.
*
* @param test The key of the test.
- * @param user The user who created or last modified the entity.
+ * @param userObj The user who created or last modified the entity.
* @param branches The list of branch names for which the acknowledgment applies (or null if
* all).
- * @param devices The list of device build flavors for which the acknowledgment applies (or
- * null if all).
+ * @param devices The list of device build flavors for which the acknowledgment applies (or null
+ * if all).
* @param testCaseNames The list of test case names known to fail (or null if all).
* @param note A text blob with details about the failure (or null if all).
*/
public TestAcknowledgmentEntity(
Key test,
- User user,
+ User userObj,
List<String> branches,
List<String> devices,
List<String> testCaseNames,
Text note) {
- this(null, -1, test, user, branches, devices, testCaseNames, note);
+ this(null, -1, test, userObj, branches, devices, testCaseNames, note);
}
+ /** Saving function for the instance of this class */
@Override
+ public com.googlecode.objectify.Key<TestAcknowledgmentEntity> save() {
+ return ofy().save().entity(this).now();
+ }
+
public Entity toEntity() {
Entity ackEntity;
if (this.key == null) ackEntity = new Entity(KIND);
else ackEntity = new Entity(key);
ackEntity.setProperty(TEST_KEY, this.test);
- ackEntity.setProperty(USER, this.user);
+ ackEntity.setProperty(USER_OBJ, this.userObj);
long created = this.created;
if (created < 0) created = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
@@ -159,7 +181,7 @@ public class TestAcknowledgmentEntity implements DashboardEntity {
public static TestAcknowledgmentEntity fromEntity(Entity e) {
if (!e.getKind().equals(KIND)
|| !e.hasProperty(TEST_KEY)
- || !e.hasProperty(USER)
+ || !e.hasProperty(USER_OBJ)
|| !e.hasProperty(CREATED)) {
logger.log(
Level.WARNING, "Missing attributes in acknowledgment entity: " + e.toString());
@@ -167,7 +189,7 @@ public class TestAcknowledgmentEntity implements DashboardEntity {
}
try {
Key test = (Key) e.getProperty(TEST_KEY);
- User user = (User) e.getProperty(USER);
+ User user = (User) e.getProperty(USER_OBJ);
long created = (long) e.getProperty(CREATED);
List<String> branches;
@@ -247,7 +269,7 @@ public class TestAcknowledgmentEntity implements DashboardEntity {
JsonObject json = new JsonObject();
json.add(KEY, new JsonPrimitive(KeyFactory.keyToString(this.key)));
json.add(TEST_NAME, new JsonPrimitive(this.test.getName()));
- json.add(USER, new JsonPrimitive(this.user.getEmail()));
+ json.add(USER_OBJ, new JsonPrimitive(this.userObj.getEmail()));
json.add(CREATED, new JsonPrimitive(this.created));
List<JsonElement> branches = new ArrayList<>();
diff --git a/src/main/java/com/android/vts/entity/TestCaseRunEntity.java b/src/main/java/com/android/vts/entity/TestCaseRunEntity.java
index 6d3ba83..30776d4 100644
--- a/src/main/java/com/android/vts/entity/TestCaseRunEntity.java
+++ b/src/main/java/com/android/vts/entity/TestCaseRunEntity.java
@@ -24,17 +24,17 @@ import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.OnLoad;
import java.util.ArrayList;
import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import lombok.Data;
-import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import static com.googlecode.objectify.ObjectifyService.ofy;
@com.googlecode.objectify.annotation.Entity(name = "TestCaseRun")
@Cache
@Data
+@Slf4j
/** Entity describing the execution of a test case. */
public class TestCaseRunEntity implements DashboardEntity {
- protected static final Logger logger = Logger.getLogger(TestCaseRunEntity.class.getName());
public static final String KIND = "TestCaseRun";
@@ -89,7 +89,8 @@ public class TestCaseRunEntity implements DashboardEntity {
* Create a TestCaseRunEntity.
*/
public TestCaseRunEntity() {
- this.id = -1L;
+ this.results = new ArrayList<>();
+ this.testCaseNames = new ArrayList<>();
this.testCases = new ArrayList<>();
this.systraceUrl = null;
}
@@ -100,6 +101,8 @@ public class TestCaseRunEntity implements DashboardEntity {
*/
public TestCaseRunEntity(long id) {
this.id = id;
+ this.results = new ArrayList<>();
+ this.testCaseNames = new ArrayList<>();
this.testCases = new ArrayList<>();
this.systraceUrl = null;
}
@@ -147,13 +150,21 @@ public class TestCaseRunEntity implements DashboardEntity {
* @return true if added, false otherwise.
*/
public boolean addTestCase(String name, int result) {
- if (isFull())
+ if (this.isFull()) {
return false;
- this.testCases.add(new TestCase(this.id, this.testCases.size(), name, result));
- return true;
+ } else {
+ this.testCaseNames.add(name);
+ this.results.add(result);
+ return true;
+ }
}
+ /** Saving function for the instance of this class */
@Override
+ public com.googlecode.objectify.Key<TestCaseRunEntity> save() {
+ return ofy().save().entity(this).now();
+ }
+
public Entity toEntity() {
Entity testCaseRunEntity;
if (this.id >= 0) {
@@ -188,7 +199,7 @@ public class TestCaseRunEntity implements DashboardEntity {
@SuppressWarnings("unchecked")
public static TestCaseRunEntity fromEntity(Entity e) {
if (!e.getKind().equals(KIND)) {
- logger.log(Level.WARNING, "Wrong kind: " + e.getKey());
+ log.warn("Wrong kind: " + e.getKey());
return null;
}
try {
@@ -213,7 +224,7 @@ public class TestCaseRunEntity implements DashboardEntity {
return testCaseRun;
} catch (ClassCastException exception) {
// Invalid cast
- logger.log(Level.WARNING, "Error parsing test case run entity.", exception);
+ log.warn("Error parsing test case run entity.", exception);
}
return null;
}
diff --git a/src/main/java/com/android/vts/entity/TestCoverageStatusEntity.java b/src/main/java/com/android/vts/entity/TestCoverageStatusEntity.java
index cc630c3..1156cc7 100644
--- a/src/main/java/com/android/vts/entity/TestCoverageStatusEntity.java
+++ b/src/main/java/com/android/vts/entity/TestCoverageStatusEntity.java
@@ -23,7 +23,6 @@ import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index;
-import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
@@ -42,7 +41,7 @@ import lombok.Setter;
@Cache
@NoArgsConstructor
/** Entity describing test coverage status. */
-public class TestCoverageStatusEntity implements Serializable {
+public class TestCoverageStatusEntity implements DashboardEntity {
protected static final Logger logger =
Logger.getLogger(TestCoverageStatusEntity.class.getName());
@@ -190,9 +189,10 @@ public class TestCoverageStatusEntity implements Serializable {
}
/** Saving function for the instance of this class */
- public void save() {
+ @Override
+ public Key<TestCoverageStatusEntity> save() {
this.updatedDate = new Date();
- ofy().save().entity(this).now();
+ return ofy().save().entity(this).now();
}
public Entity toEntity() {
diff --git a/src/main/java/com/android/vts/entity/TestEntity.java b/src/main/java/com/android/vts/entity/TestEntity.java
index e48d759..4df7fb0 100644
--- a/src/main/java/com/android/vts/entity/TestEntity.java
+++ b/src/main/java/com/android/vts/entity/TestEntity.java
@@ -24,7 +24,6 @@ import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index;
-import java.io.Serializable;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -34,12 +33,12 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
-@Entity(name="Test")
+@Entity(name = "Test")
@Cache
@Data
@NoArgsConstructor
/** Entity describing test metadata. */
-public class TestEntity implements Serializable {
+public class TestEntity implements DashboardEntity {
protected static final Logger logger = Logger.getLogger(TestEntity.class.getName());
public static final String KIND = "Test";
@@ -75,6 +74,12 @@ public class TestEntity implements Serializable {
this(testName, false);
}
+ /** Saving function for the instance of this class */
+ @Override
+ public com.googlecode.objectify.Key<TestEntity> save() {
+ return ofy().save().entity(this).now();
+ }
+
public com.google.appengine.api.datastore.Entity toEntity() {
com.google.appengine.api.datastore.Entity testEntity = new com.google.appengine.api.datastore.Entity(this.getOldKey());
testEntity.setProperty(HAS_PROFILING_DATA, this.hasProfilingData);
@@ -82,6 +87,19 @@ public class TestEntity implements Serializable {
}
/**
+ * Get objectify TestRun Entity's key.
+ *
+ * @param startTimestamp test start timestamp
+ */
+ public com.googlecode.objectify.Key getTestRunKey(long startTimestamp) {
+ com.googlecode.objectify.Key testKey =
+ com.googlecode.objectify.Key.create(TestEntity.class, this.getTestName());
+ com.googlecode.objectify.Key testRunKey =
+ com.googlecode.objectify.Key.create(testKey, TestRunEntity.class, startTimestamp);
+ return testRunKey;
+ }
+
+ /**
* Get key info from appengine based library.
*/
public Key getOldKey() {
@@ -130,10 +148,4 @@ public class TestEntity implements Serializable {
}
return new TestEntity(testName, hasProfilingData);
}
-
- /** Saving function for the instance of this class */
- public void save() {
- ofy().save().entity(this).now();
- }
-
}
diff --git a/src/main/java/com/android/vts/entity/TestPlanEntity.java b/src/main/java/com/android/vts/entity/TestPlanEntity.java
index 805c3cd..590db46 100644
--- a/src/main/java/com/android/vts/entity/TestPlanEntity.java
+++ b/src/main/java/com/android/vts/entity/TestPlanEntity.java
@@ -19,21 +19,20 @@ package com.android.vts.entity;
import static com.googlecode.objectify.ObjectifyService.ofy;
import com.google.appengine.api.datastore.Entity;
+import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Id;
-import java.io.Serializable;
-import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import lombok.Data;
import lombok.NoArgsConstructor;
-@com.googlecode.objectify.annotation.Entity(name="TestPlan")
+@com.googlecode.objectify.annotation.Entity(name = "TestPlan")
@Cache
@Data
@NoArgsConstructor
/** Entity describing test plan metadata. */
-public class TestPlanEntity implements Serializable {
+public class TestPlanEntity implements DashboardEntity {
protected static final Logger logger = Logger.getLogger(TestPlanEntity.class.getName());
public static final String KIND = "TestPlan";
@@ -58,6 +57,11 @@ public class TestPlanEntity implements Serializable {
return planEntity;
}
+ public Key getKey() {
+ Key key = Key.create(TestPlanEntity.class, this.testPlanName);
+ return key;
+ }
+
/**
* Convert an Entity object to a TestEntity.
*
@@ -76,7 +80,8 @@ public class TestPlanEntity implements Serializable {
}
/** Saving function for the instance of this class */
- public void save() {
- ofy().save().entity(this).now();
+ @Override
+ public com.googlecode.objectify.Key<TestPlanEntity> save() {
+ return ofy().save().entity(this).now();
}
}
diff --git a/src/main/java/com/android/vts/entity/TestPlanRunEntity.java b/src/main/java/com/android/vts/entity/TestPlanRunEntity.java
index 7dbb0dc..de2e505 100644
--- a/src/main/java/com/android/vts/entity/TestPlanRunEntity.java
+++ b/src/main/java/com/android/vts/entity/TestPlanRunEntity.java
@@ -18,7 +18,6 @@ package com.android.vts.entity;
import static com.googlecode.objectify.ObjectifyService.ofy;
-import com.android.vts.entity.TestRunEntity.TestRunType;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
@@ -32,25 +31,21 @@ import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.Parent;
-import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Objects;
-import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import lombok.Data;
-import lombok.Getter;
import lombok.NoArgsConstructor;
-import lombok.Setter;
@com.googlecode.objectify.annotation.Entity(name = "TestPlanRun")
@Cache
@Data
@NoArgsConstructor
/** Entity describing test plan run information. */
-public class TestPlanRunEntity implements Serializable {
+public class TestPlanRunEntity implements DashboardEntity {
protected static final Logger logger = Logger.getLogger(TestPlanRunEntity.class.getName());
@@ -76,7 +71,7 @@ public class TestPlanRunEntity implements Serializable {
@Id private Long id;
- @Parent private com.googlecode.objectify.Key<TestPlanEntity> testParent;
+ @Parent private com.googlecode.objectify.Key<TestPlanEntity> parent;
@Index private String testPlanName;
@@ -98,7 +93,7 @@ public class TestPlanRunEntity implements Serializable {
@Ignore private List<Key> oldTestRuns;
- private List<com.googlecode.objectify.Key<?>> testRuns;
+ private List<com.googlecode.objectify.Key<TestRunEntity>> testRuns;
/** When this record was created or updated */
@Index Date updated;
@@ -106,7 +101,7 @@ public class TestPlanRunEntity implements Serializable {
/**
* Create a TestPlanRunEntity object describing a test plan run.
*
- * @param parentKey The key for the parent entity in the database.
+ * @param testPlanKey The key for the parent entity in the database.
* @param type The test run type (e.g. presubmit, postsubmit, other)
* @param startTimestamp The time in microseconds when the test plan run started.
* @param endTimestamp The time in microseconds when the test plan run ended.
@@ -116,7 +111,7 @@ public class TestPlanRunEntity implements Serializable {
* @param testRuns A list of keys to the TestRunEntity objects for the plan run run.
*/
public TestPlanRunEntity(
- Key parentKey,
+ Key testPlanKey,
String testPlanName,
long type,
long startTimestamp,
@@ -127,7 +122,8 @@ public class TestPlanRunEntity implements Serializable {
long totalApiCount,
long coveredApiCount,
List<Key> testRuns) {
- this.key = KeyFactory.createKey(parentKey, KIND, startTimestamp);
+ this.id = startTimestamp;
+ this.key = KeyFactory.createKey(testPlanKey, KIND, startTimestamp);
this.testPlanName = testPlanName;
this.type = type;
this.startTimestamp = startTimestamp;
@@ -152,6 +148,44 @@ public class TestPlanRunEntity implements Serializable {
.collect(Collectors.toList());
}
+ /**
+ * Create a TestPlanRunEntity object describing a test plan run.
+ *
+ * @param testPlanKey The key for the parent entity in the database.
+ * @param type The test run type (e.g. presubmit, postsubmit, other)
+ * @param startTimestamp The time in microseconds when the test plan run started.
+ * @param endTimestamp The time in microseconds when the test plan run ended.
+ * @param testBuildId The build ID of the VTS test build.
+ * @param passCount The number of passing test cases in the run.
+ * @param failCount The number of failing test cases in the run.
+ * @param testRuns A list of keys to the TestRunEntity objects for the plan run run.
+ */
+ public TestPlanRunEntity(
+ com.googlecode.objectify.Key<TestPlanEntity> testPlanKey,
+ String testPlanName,
+ long type,
+ long startTimestamp,
+ long endTimestamp,
+ String testBuildId,
+ long passCount,
+ long failCount,
+ long totalApiCount,
+ long coveredApiCount,
+ List<com.googlecode.objectify.Key<TestRunEntity>> testRuns) {
+ this.id = startTimestamp;
+ this.parent = testPlanKey;
+ this.testPlanName = testPlanName;
+ this.type = type;
+ this.startTimestamp = startTimestamp;
+ this.endTimestamp = endTimestamp;
+ this.testBuildId = testBuildId;
+ this.passCount = passCount;
+ this.failCount = failCount;
+ this.totalApiCount = totalApiCount;
+ this.coveredApiCount = coveredApiCount;
+ this.testRuns = testRuns;
+ }
+
public Entity toEntity() {
Entity planRun = new Entity(this.key);
planRun.setProperty(TEST_PLAN_NAME, this.testPlanName);
@@ -168,6 +202,7 @@ public class TestPlanRunEntity implements Serializable {
}
/** Saving function for the instance of this class */
+ @Override
public com.googlecode.objectify.Key<TestPlanRunEntity> save() {
this.updated = new Date();
return ofy().save().entity(this).now();
@@ -175,12 +210,7 @@ public class TestPlanRunEntity implements Serializable {
/** Get UrlSafeKey from this class */
public String getUrlSafeKey() {
- com.googlecode.objectify.Key testPlanKey =
- com.googlecode.objectify.Key.create(TestPlanEntity.class, this.testPlanName);
- com.googlecode.objectify.Key idKey =
- com.googlecode.objectify.Key.create(
- testPlanKey, TestPlanRunEntity.class, this.startTimestamp);
- return idKey.toUrlSafe();
+ return this.getOfyKey().toUrlSafe();
}
/** Add a task to calculate the total number of coverage API */
@@ -191,7 +221,7 @@ public class TestPlanRunEntity implements Serializable {
Queue queue = QueueFactory.getQueue(QUEUE_NAME);
queue.add(
TaskOptions.Builder.withUrl(COVERAGE_API_URL)
- .param("urlSafeKey", String.valueOf(this.getUrlSafeKey()))
+ .param("urlSafeKey", this.getUrlSafeKey())
.method(TaskOptions.Method.POST));
}
}
@@ -205,6 +235,12 @@ public class TestPlanRunEntity implements Serializable {
return KeyFactory.createKey(parentKey, KIND, startTimestamp);
}
+ /** Get key info from objecitfy library. */
+ public com.googlecode.objectify.Key getOfyKey() {
+ return com.googlecode.objectify.Key.create(
+ this.parent, TestPlanRunEntity.class, this.startTimestamp);
+ }
+
/**
* Convert an Entity object to a TestPlanRunEntity.
*
diff --git a/src/main/java/com/android/vts/entity/TestRunEntity.java b/src/main/java/com/android/vts/entity/TestRunEntity.java
index bdd0ac8..0d5f1ec 100644
--- a/src/main/java/com/android/vts/entity/TestRunEntity.java
+++ b/src/main/java/com/android/vts/entity/TestRunEntity.java
@@ -35,9 +35,7 @@ import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.OnLoad;
import com.googlecode.objectify.annotation.Parent;
-import java.io.Serializable;
import java.util.ArrayList;
-import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -45,20 +43,17 @@ import java.util.Optional;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
-import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.lang3.math.NumberUtils;
-import org.json.JSONArray;
@com.googlecode.objectify.annotation.Entity(name = "TestRun")
@Cache
@NoArgsConstructor
/** Entity describing test run information. */
-public class TestRunEntity implements Serializable {
+public class TestRunEntity implements DashboardEntity {
protected static final Logger logger = Logger.getLogger(TestRunEntity.class.getName());
/** Enum for classifying test run types. */
@@ -168,7 +163,7 @@ public class TestRunEntity implements Serializable {
@Index @Getter @Setter private boolean hasCodeCoverage;
- private com.googlecode.objectify.Key<CodeCoverageEntity> codeCoverageEntityKey;
+ @Ignore private com.googlecode.objectify.Key<CodeCoverageEntity> codeCoverageEntityKey;
@Index @Getter @Setter private long coveredLineCount;
@@ -202,6 +197,7 @@ public class TestRunEntity implements Serializable {
boolean hasCodeCoverage,
List<Long> testCaseIds,
List<String> logLinks) {
+ this.id = startTimestamp;
this.key = KeyFactory.createKey(parentKey, KIND, startTimestamp);
this.type = type;
this.startTimestamp = startTimestamp;
@@ -212,9 +208,11 @@ public class TestRunEntity implements Serializable {
this.failCount = failCount;
this.hasCodeCoverage = hasCodeCoverage;
this.testName = parentKey.getName();
- this.codeCoverageEntityKey = getCodeCoverageEntityKey();
this.testCaseIds = testCaseIds;
this.logLinks = logLinks;
+
+ this.testRunParent = com.googlecode.objectify.Key.create(TestEntity.class, testName);
+ this.codeCoverageEntityKey = getCodeCoverageEntityKey();
}
/**
@@ -247,6 +245,7 @@ public class TestRunEntity implements Serializable {
}
/** Saving function for the instance of this class */
+ @Override
public com.googlecode.objectify.Key<TestRunEntity> save() {
return ofy().save().entity(this).now();
}
@@ -289,7 +288,7 @@ public class TestRunEntity implements Serializable {
}
/** Get ApiCoverageEntity Key from the parent key */
- private com.googlecode.objectify.Key getOfyKey() {
+ public com.googlecode.objectify.Key getOfyKey() {
com.googlecode.objectify.Key testKey =
com.googlecode.objectify.Key.create(
TestEntity.class, this.testName);
diff --git a/src/main/java/com/android/vts/entity/TestStatusEntity.java b/src/main/java/com/android/vts/entity/TestStatusEntity.java
index ec5ee36..b703c64 100644
--- a/src/main/java/com/android/vts/entity/TestStatusEntity.java
+++ b/src/main/java/com/android/vts/entity/TestStatusEntity.java
@@ -22,7 +22,6 @@ import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Index;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
@@ -30,12 +29,14 @@ import java.util.logging.Logger;
import lombok.Data;
import lombok.NoArgsConstructor;
+import static com.googlecode.objectify.ObjectifyService.ofy;
+
@com.googlecode.objectify.annotation.Entity(name = "TestStatus")
@Cache
@Data
@NoArgsConstructor
/** Entity describing test status. */
-public class TestStatusEntity implements Serializable {
+public class TestStatusEntity implements DashboardEntity {
protected static final Logger logger = Logger.getLogger(TestStatusEntity.class.getName());
public static final String KIND = "TestStatus";
@@ -125,6 +126,12 @@ public class TestStatusEntity implements Serializable {
this(testName, 0, -1, -1, new ArrayList<TestCaseReference>());
}
+ /** Saving function for the instance of this class */
+ @Override
+ public com.googlecode.objectify.Key<TestStatusEntity> save() {
+ return ofy().save().entity(this).now();
+ }
+
public Entity toEntity() {
Entity testEntity = new Entity(KIND, this.testName);
if (this.updatedTimestamp >= 0 && this.passCount >= 0 && this.failCount >= 0) {
diff --git a/src/main/java/com/android/vts/entity/TestSuiteFileEntity.java b/src/main/java/com/android/vts/entity/TestSuiteFileEntity.java
index 2331e42..c68f2ec 100644
--- a/src/main/java/com/android/vts/entity/TestSuiteFileEntity.java
+++ b/src/main/java/com/android/vts/entity/TestSuiteFileEntity.java
@@ -16,6 +16,7 @@
package com.android.vts.entity;
+import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
@@ -25,11 +26,9 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
-import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
-import java.util.List;
import static com.googlecode.objectify.ObjectifyService.ofy;
@@ -38,7 +37,7 @@ import static com.googlecode.objectify.ObjectifyService.ofy;
@Entity
@EqualsAndHashCode(of = "id")
@NoArgsConstructor
-public class TestSuiteFileEntity {
+public class TestSuiteFileEntity implements DashboardEntity {
/** Test Suite full file path field */
@Id @Getter @Setter String filePath;
@@ -71,8 +70,9 @@ public class TestSuiteFileEntity {
}
/** Saving function for the instance of this class */
- public void save() {
+ @Override
+ public Key<TestSuiteFileEntity> save() {
this.updated = new Date();
- ofy().save().entity(this).now();
+ return ofy().save().entity(this).now();
}
}
diff --git a/src/main/java/com/android/vts/entity/TestSuiteResultEntity.java b/src/main/java/com/android/vts/entity/TestSuiteResultEntity.java
index 2e12f54..95ba5c8 100644
--- a/src/main/java/com/android/vts/entity/TestSuiteResultEntity.java
+++ b/src/main/java/com/android/vts/entity/TestSuiteResultEntity.java
@@ -38,18 +38,13 @@ import org.apache.http.client.utils.URIUtils;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
-import javax.servlet.ServletContext;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
-import java.math.RoundingMode;
import java.net.URI;
import java.net.URISyntaxException;
-import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
-import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
@@ -126,7 +121,7 @@ class TestTypeIndex {
@Entity
@EqualsAndHashCode(of = "id")
@NoArgsConstructor
-public class TestSuiteResultEntity {
+public class TestSuiteResultEntity implements DashboardEntity {
private static final Logger logger = Logger.getLogger(TestSuiteResultEntity.class.getName());
@@ -316,6 +311,12 @@ public class TestSuiteResultEntity {
}
}
+ /** Saving function for the instance of this class */
+ @Override
+ public Key<TestSuiteResultEntity> save() {
+ return ofy().save().entity(this).now();
+ }
+
public static void setPropertyValues(Properties newSystemConfigProp) {
systemConfigProp = newSystemConfigProp;
bugTrackingSystemProp = getBugTrackingSystemProp(newSystemConfigProp);
diff --git a/src/main/java/com/android/vts/entity/UserEntity.java b/src/main/java/com/android/vts/entity/UserEntity.java
index a686efb..43b5edd 100644
--- a/src/main/java/com/android/vts/entity/UserEntity.java
+++ b/src/main/java/com/android/vts/entity/UserEntity.java
@@ -38,7 +38,7 @@ import static com.googlecode.objectify.ObjectifyService.ofy;
@Entity
@EqualsAndHashCode(of = "email")
@NoArgsConstructor
-public class UserEntity {
+public class UserEntity implements DashboardEntity {
/** User email field */
@Id @Getter @Setter String email;
@@ -79,9 +79,10 @@ public class UserEntity {
}
/** Saving function for the instance of this class */
- public void save() {
+ @Override
+ public Key<UserEntity> save() {
this.updated = new Date();
- ofy().save().entity(this).now();
+ return ofy().save().entity(this).now();
}
/** Get admin user list by admin email */
diff --git a/src/main/java/com/android/vts/entity/UserFavoriteEntity.java b/src/main/java/com/android/vts/entity/UserFavoriteEntity.java
index 132d9b4..2548042 100644
--- a/src/main/java/com/android/vts/entity/UserFavoriteEntity.java
+++ b/src/main/java/com/android/vts/entity/UserFavoriteEntity.java
@@ -19,9 +19,22 @@ package com.android.vts.entity;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.users.User;
+import com.googlecode.objectify.annotation.Cache;
+import com.googlecode.objectify.annotation.Ignore;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
import java.util.logging.Level;
import java.util.logging.Logger;
+import static com.googlecode.objectify.ObjectifyService.ofy;
+
+@Cache
+@com.googlecode.objectify.annotation.Entity(name = "UserFavorite")
+@EqualsAndHashCode(of = "email")
+@NoArgsConstructor
/** Entity describing subscriptions between a user and a test. */
public class UserFavoriteEntity implements DashboardEntity {
protected static final Logger logger = Logger.getLogger(UserFavoriteEntity.class.getName());
@@ -33,10 +46,17 @@ public class UserFavoriteEntity implements DashboardEntity {
public static final String TEST_KEY = "testKey";
public static final String MUTE_NOTIFICATIONS = "muteNotifications";
- private final Key key;
- public final User user;
- public final Key testKey;
- public boolean muteNotifications;
+ @Ignore private Key key = null;
+
+ @Ignore public User user = null;
+
+ @Ignore public Key testKey = null;
+
+ @Getter @Setter private com.googlecode.objectify.Key<TestEntity> test;
+
+ @Getter @Setter private String userEmail;
+
+ @Getter @Setter public boolean muteNotifications;
/**
* Create a user favorite relationship.
@@ -64,7 +84,12 @@ public class UserFavoriteEntity implements DashboardEntity {
this(null, user, testKey, muteNotifications);
}
+ /** Saving function for the instance of this class */
@Override
+ public com.googlecode.objectify.Key<UserFavoriteEntity> save() {
+ return ofy().save().entity(this).now();
+ }
+
public Entity toEntity() {
Entity favoriteEntity;
if (this.key != null) {
diff --git a/src/main/java/com/android/vts/job/BaseJobServlet.java b/src/main/java/com/android/vts/job/BaseJobServlet.java
index 3d6232b..18a1d24 100644
--- a/src/main/java/com/android/vts/job/BaseJobServlet.java
+++ b/src/main/java/com/android/vts/job/BaseJobServlet.java
@@ -16,15 +16,10 @@
package com.android.vts.job;
-import com.android.vts.servlet.BaseServlet;
-import com.android.vts.util.EmailHelper;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.Properties;
/**
@@ -37,20 +32,20 @@ public abstract class BaseJobServlet extends HttpServlet {
*/
protected static Properties systemConfigProp = new Properties();
+ /**
+ * 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);
- try {
- InputStream defaultInputStream =
- BaseServlet.class.getClassLoader().getResourceAsStream("config.properties");
- systemConfigProp.load(defaultInputStream);
-
- EmailHelper.setPropertyValues(systemConfigProp);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
+ systemConfigProp =
+ Properties.class.cast(cfg.getServletContext().getAttribute("systemConfigProp"));
+
+ this.MAX_ENTITY_SIZE_PER_TRANSACTION =
+ Integer.parseInt(systemConfigProp.getProperty("datastore.maxEntitySize"));
}
}
diff --git a/src/main/java/com/android/vts/job/VtsAlertJobServlet.java b/src/main/java/com/android/vts/job/VtsAlertJobServlet.java
index 3336c85..be23982 100644
--- a/src/main/java/com/android/vts/job/VtsAlertJobServlet.java
+++ b/src/main/java/com/android/vts/job/VtsAlertJobServlet.java
@@ -179,29 +179,30 @@ public class VtsAlertJobServlet extends BaseJobServlet {
List<TestAcknowledgmentEntity> acks) {
Set<String> acknowledged = new HashSet<>();
for (TestAcknowledgmentEntity ack : acks) {
- boolean allDevices = ack.devices == null || ack.devices.size() == 0;
- boolean allBranches = ack.branches == null || ack.branches.size() == 0;
+ boolean allDevices = ack.getDevices() == null || ack.getDevices().size() == 0;
+ boolean allBranches = ack.getBranches() == null || ack.getBranches().size() == 0;
boolean isRelevant = allDevices && allBranches;
// Determine if the acknowledgment is relevant to the devices.
if (!isRelevant) {
for (DeviceInfoEntity device : devices) {
boolean deviceAcknowledged =
- allDevices || ack.devices.contains(device.getBuildFlavor());
+ allDevices || ack.getDevices().contains(device.getBuildFlavor());
boolean branchAcknowledged =
- allBranches || ack.branches.contains(device.getBranch());
+ allBranches || ack.getBranches().contains(device.getBranch());
if (deviceAcknowledged && branchAcknowledged) isRelevant = true;
}
}
if (isRelevant) {
// Separate the test cases
- boolean allTestCases = ack.testCaseNames == null || ack.testCaseNames.size() == 0;
+ boolean allTestCases =
+ ack.getTestCaseNames() == null || ack.getTestCaseNames().size() == 0;
if (allTestCases) {
acknowledged.addAll(testCases);
testCases.removeAll(acknowledged);
} else {
- for (String testCase : ack.testCaseNames) {
+ for (String testCase : ack.getTestCaseNames()) {
if (testCases.contains(testCase)) {
acknowledged.add(testCase);
testCases.remove(testCase);
diff --git a/src/main/java/com/android/vts/job/VtsSpreadSheetSyncServlet.java b/src/main/java/com/android/vts/job/VtsSpreadSheetSyncServlet.java
index 0f1bfbc..45726d9 100644
--- a/src/main/java/com/android/vts/job/VtsSpreadSheetSyncServlet.java
+++ b/src/main/java/com/android/vts/job/VtsSpreadSheetSyncServlet.java
@@ -17,6 +17,7 @@
package com.android.vts.job;
import com.android.vts.entity.ApiCoverageExcludedEntity;
+import com.android.vts.entity.DashboardEntity;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.appengine.datastore.AppEngineDataStoreFactory;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
@@ -162,7 +163,7 @@ public class VtsSpreadSheetSyncServlet extends BaseJobServlet {
}
}
- ApiCoverageExcludedEntity.saveAll(apiCoverageExcludedEntities);
+ DashboardEntity.saveAll(apiCoverageExcludedEntities, MAX_ENTITY_SIZE_PER_TRANSACTION);
} catch (GeneralSecurityException gse) {
logger.log(Level.SEVERE, gse.getMessage());
diff --git a/src/main/java/com/android/vts/servlet/BaseServlet.java b/src/main/java/com/android/vts/servlet/BaseServlet.java
index 96ba561..5319ee1 100644
--- a/src/main/java/com/android/vts/servlet/BaseServlet.java
+++ b/src/main/java/com/android/vts/servlet/BaseServlet.java
@@ -26,9 +26,7 @@ import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gson.Gson;
-import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -45,200 +43,191 @@ import javax.servlet.http.HttpSession;
public abstract class BaseServlet extends HttpServlet {
- protected final Logger logger = Logger.getLogger(getClass().getName());
-
- protected String ERROR_MESSAGE_JSP = "WEB-INF/jsp/error_msg.jsp";
-
- // Environment variables
- protected static String GERRIT_URI;
- protected static String GERRIT_SCOPE;
- protected static String CLIENT_ID;
- protected static String ANALYTICS_ID;
-
- protected static final String TREE_DEFAULT_PARAM = "treeDefault";
-
- public enum PageType {
- TOT("Test", "/"),
- RELEASE("Release", "/show_release"),
- COVERAGE_OVERVIEW("Coverage", "/show_coverage_overview"),
- PROFILING_LIST("Profiling", "/show_profiling_list"),
- TABLE("", "/show_table"),
- TREE("", "/show_tree"),
- GRAPH("Profiling", "/show_graph"),
- COVERAGE("Coverage", "/show_coverage"),
- PERFORMANCE_DIGEST("Performance Digest", "/show_performance_digest"),
- PLAN_RELEASE("", "/show_plan_release"),
- PLAN_RUN("Plan Run", "/show_plan_run"),
- PROFILING_OVERVIEW("", "/show_profiling_overview");
-
- public final String defaultName;
- public final String defaultUrl;
-
- PageType(String defaultName, String defaultUrl) {
- this.defaultName = defaultName;
- this.defaultUrl = defaultUrl;
+ protected final Logger logger = Logger.getLogger(getClass().getName());
+
+ protected String ERROR_MESSAGE_JSP = "WEB-INF/jsp/error_msg.jsp";
+
+ // Environment variables
+ protected static String GERRIT_URI;
+ protected static String GERRIT_SCOPE;
+ protected static String CLIENT_ID;
+ protected static String ANALYTICS_ID;
+
+ protected static final String TREE_DEFAULT_PARAM = "treeDefault";
+
+ public enum PageType {
+ TOT("Test", "/"),
+ RELEASE("Release", "/show_release"),
+ COVERAGE_OVERVIEW("Coverage", "/show_coverage_overview"),
+ PROFILING_LIST("Profiling", "/show_profiling_list"),
+ TABLE("", "/show_table"),
+ TREE("", "/show_tree"),
+ GRAPH("Profiling", "/show_graph"),
+ COVERAGE("Coverage", "/show_coverage"),
+ PERFORMANCE_DIGEST("Performance Digest", "/show_performance_digest"),
+ PLAN_RELEASE("", "/show_plan_release"),
+ PLAN_RUN("Plan Run", "/show_plan_run"),
+ PROFILING_OVERVIEW("", "/show_profiling_overview");
+
+ public final String defaultName;
+ public final String defaultUrl;
+
+ PageType(String defaultName, String defaultUrl) {
+ this.defaultName = defaultName;
+ this.defaultUrl = defaultUrl;
+ }
}
- }
- public static class Page {
+ public static class Page {
- private final PageType type;
- private final String name;
- private final String url;
+ private final PageType type;
+ private final String name;
+ private final String url;
- public Page(PageType type) {
- this.type = type;
- this.name = type.defaultName;
- this.url = type.defaultUrl;
- }
+ public Page(PageType type) {
+ this.type = type;
+ this.name = type.defaultName;
+ this.url = type.defaultUrl;
+ }
- public Page(PageType type, String name, String url) {
- this.type = type;
- this.name = type.defaultName + name;
- this.url = type.defaultUrl + url;
- }
+ public Page(PageType type, String name, String url) {
+ this.type = type;
+ this.name = type.defaultName + name;
+ this.url = type.defaultUrl + url;
+ }
- public Page(PageType type, String name, String url, Boolean withoutDefault) {
- this.type = type;
- this.name = name;
- this.url = type.defaultUrl + url;
- }
+ public Page(PageType type, String name, String url, Boolean withoutDefault) {
+ this.type = type;
+ this.name = name;
+ this.url = type.defaultUrl + url;
+ }
- public Page(PageType type, String url) {
- this.type = type;
- this.name = type.defaultName;
- this.url = type.defaultUrl + url;
- }
+ public Page(PageType type, String url) {
+ this.type = type;
+ this.name = type.defaultName;
+ this.url = type.defaultUrl + url;
+ }
+
+ public String getName() {
+ return name;
+ }
- public String getName() {
- return name;
+ public String getUrl() {
+ return url;
+ }
}
- public String getUrl() {
- return url;
+ public static final List<Page> navbarLinks;
+
+ static {
+ List<Page> links = new ArrayList<>();
+ links.add(new Page(PageType.TOT));
+ links.add(new Page(PageType.RELEASE));
+ links.add(new Page(PageType.COVERAGE_OVERVIEW));
+ links.add(new Page(PageType.PROFILING_LIST));
+ navbarLinks = links;
}
- }
-
- public static final List<Page> navbarLinks;
-
- static {
- List<Page> links = new ArrayList<>();
- links.add(new Page(PageType.TOT));
- links.add(new Page(PageType.RELEASE));
- links.add(new Page(PageType.COVERAGE_OVERVIEW));
- links.add(new Page(PageType.PROFILING_LIST));
- navbarLinks = links;
- }
-
- public abstract PageType getNavParentType();
-
- /**
- * Get a list of URL/Display name pairs for the breadcrumb hierarchy.
- *
- * @param request The HttpServletRequest object for the page request.
- * @return a list of Page entries.
- */
- public abstract List<Page> getBreadcrumbLinks(HttpServletRequest request);
-
- /**
- * System Configuration Property class
- */
- protected static Properties systemConfigProp = new Properties();
-
- @Override
- public void init(ServletConfig cfg) throws ServletException {
- super.init(cfg);
-
- try {
- InputStream defaultInputStream =
- BaseServlet.class.getClassLoader().getResourceAsStream("config.properties");
- systemConfigProp.load(defaultInputStream);
-
- GERRIT_URI = systemConfigProp.getProperty("gerrit.uri");
- GERRIT_SCOPE = systemConfigProp.getProperty("gerrit.scope");
- CLIENT_ID = systemConfigProp.getProperty("appengine.clientID");
- ANALYTICS_ID = systemConfigProp.getProperty("analytics.id");
-
- CoverageEntity.setPropertyValues(systemConfigProp);
- TestSuiteResultEntity.setPropertyValues(systemConfigProp);
- EmailHelper.setPropertyValues(systemConfigProp);
- GcsHelper.setGcsProjectId(systemConfigProp.getProperty("gcs.projectID"));
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
+
+ public abstract PageType getNavParentType();
+
+ /**
+ * Get a list of URL/Display name pairs for the breadcrumb hierarchy.
+ *
+ * @param request The HttpServletRequest object for the page request.
+ * @return a list of Page entries.
+ */
+ public abstract List<Page> getBreadcrumbLinks(HttpServletRequest request);
+
+ /** System Configuration Property class */
+ protected static Properties systemConfigProp = new Properties();
+
+ @Override
+ public void init(ServletConfig cfg) throws ServletException {
+ super.init(cfg);
+
+ systemConfigProp =
+ Properties.class.cast(cfg.getServletContext().getAttribute("systemConfigProp"));
+
+ GERRIT_URI = systemConfigProp.getProperty("gerrit.uri");
+ GERRIT_SCOPE = systemConfigProp.getProperty("gerrit.scope");
+ CLIENT_ID = systemConfigProp.getProperty("appengine.clientID");
+ ANALYTICS_ID = systemConfigProp.getProperty("analytics.id");
+
+ CoverageEntity.setPropertyValues(systemConfigProp);
+ TestSuiteResultEntity.setPropertyValues(systemConfigProp);
+ EmailHelper.setPropertyValues(systemConfigProp);
+ GcsHelper.setGcsProjectId(systemConfigProp.getProperty("gcs.projectID"));
}
- }
-
- @Override
- public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
- // If the user is logged out, allow them to log back in and return to the page.
- // Set the logout URL to direct back to a login page that directs to the current request.
- UserService userService = UserServiceFactory.getUserService();
- Optional<User> currentUser = Optional.ofNullable(userService.getCurrentUser());
- String currentUserEmail =
- currentUser.isPresent()
- ? currentUser.map(user -> user.getEmail().trim()).orElse("")
- : "";
- String requestUri = request.getRequestURI();
- String requestArgs = request.getQueryString();
- String loginURI = userService.createLoginURL(requestUri + '?' + requestArgs);
- String logoutURI = userService.createLogoutURL(loginURI);
- if (currentUserEmail != "") {
-
- int activeIndex;
- switch (getNavParentType()) {
- case PROFILING_LIST:
- activeIndex = 3;
- break;
- case COVERAGE_OVERVIEW:
- activeIndex = 2;
- break;
- case RELEASE:
- activeIndex = 1;
- break;
- default:
- activeIndex = 0;
- break;
- }
- if (request.getParameter(TREE_DEFAULT_PARAM) != null) {
- HttpSession session = request.getSession(true);
- boolean treeDefault = request.getParameter(TREE_DEFAULT_PARAM).equals("true");
- session.setAttribute(TREE_DEFAULT_PARAM, treeDefault);
- }
-
- request.setAttribute("serverName", request.getServerName());
- request.setAttribute("logoutURL", logoutURI);
- request.setAttribute("email", currentUserEmail);
- request.setAttribute("analyticsID", new Gson().toJson(ANALYTICS_ID));
- request.setAttribute("breadcrumbLinks", getBreadcrumbLinks(request));
- request.setAttribute("navbarLinks", navbarLinks);
- request.setAttribute("activeIndex", activeIndex);
- response.setContentType("text/html");
-
- if (currentUserEmail.endsWith("@google.com") || UserEntity.getUserList()
- .contains(currentUserEmail)) {
- doGetHandler(request, response);
- } else {
- RequestDispatcher dispatcher =
- request.getRequestDispatcher("WEB-INF/jsp/auth_error.jsp");
- try {
- dispatcher.forward(request, response);
- } catch (ServletException e) {
- logger.log(Level.SEVERE, "Servlet Exception caught : ", e);
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ // If the user is logged out, allow them to log back in and return to the page.
+ // Set the logout URL to direct back to a login page that directs to the current request.
+ UserService userService = UserServiceFactory.getUserService();
+ Optional<User> currentUser = Optional.ofNullable(userService.getCurrentUser());
+ String currentUserEmail =
+ currentUser.isPresent()
+ ? currentUser.map(user -> user.getEmail().trim()).orElse("")
+ : "";
+ String requestUri = request.getRequestURI();
+ String requestArgs = request.getQueryString();
+ String loginURI = userService.createLoginURL(requestUri + '?' + requestArgs);
+ String logoutURI = userService.createLogoutURL(loginURI);
+ if (currentUserEmail != "") {
+
+ int activeIndex;
+ switch (getNavParentType()) {
+ case PROFILING_LIST:
+ activeIndex = 3;
+ break;
+ case COVERAGE_OVERVIEW:
+ activeIndex = 2;
+ break;
+ case RELEASE:
+ activeIndex = 1;
+ break;
+ default:
+ activeIndex = 0;
+ break;
+ }
+ if (request.getParameter(TREE_DEFAULT_PARAM) != null) {
+ HttpSession session = request.getSession(true);
+ boolean treeDefault = request.getParameter(TREE_DEFAULT_PARAM).equals("true");
+ session.setAttribute(TREE_DEFAULT_PARAM, treeDefault);
+ }
+
+ request.setAttribute("serverName", request.getServerName());
+ request.setAttribute("logoutURL", logoutURI);
+ request.setAttribute("email", currentUserEmail);
+ request.setAttribute("analyticsID", new Gson().toJson(ANALYTICS_ID));
+ request.setAttribute("breadcrumbLinks", getBreadcrumbLinks(request));
+ request.setAttribute("navbarLinks", navbarLinks);
+ request.setAttribute("activeIndex", activeIndex);
+ response.setContentType("text/html");
+
+ if (currentUserEmail.endsWith("@google.com")
+ || UserEntity.getUserList().contains(currentUserEmail)) {
+ doGetHandler(request, response);
+ } else {
+ RequestDispatcher dispatcher =
+ request.getRequestDispatcher("WEB-INF/jsp/auth_error.jsp");
+ try {
+ dispatcher.forward(request, response);
+ } catch (ServletException e) {
+ logger.log(Level.SEVERE, "Servlet Exception caught : ", e);
+ }
+ }
+ } else {
+ response.sendRedirect(loginURI);
}
- }
- } else {
- response.sendRedirect(loginURI);
}
- }
-
- /**
- * Implementation of the doGet method to be executed by servlet subclasses.
- *
- * @param request The HttpServletRequest object.
- * @param response The HttpServletResponse object.
- */
- public abstract void doGetHandler(HttpServletRequest request, HttpServletResponse response)
- throws IOException;
+
+ /**
+ * Implementation of the doGet method to be executed by servlet subclasses.
+ *
+ * @param request The HttpServletRequest object.
+ * @param response The HttpServletResponse object.
+ */
+ public abstract void doGetHandler(HttpServletRequest request, HttpServletResponse response)
+ throws IOException;
}
diff --git a/src/main/java/com/android/vts/util/DatastoreHelper.java b/src/main/java/com/android/vts/util/DatastoreHelper.java
index 2dbca37..3764c7a 100644
--- a/src/main/java/com/android/vts/util/DatastoreHelper.java
+++ b/src/main/java/com/android/vts/util/DatastoreHelper.java
@@ -112,8 +112,8 @@ public class DatastoreHelper {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key startKey = KeyFactory.createKey(parentKey, kind, lowerBound);
Filter startFilter =
- new FilterPredicate(
- Entity.KEY_RESERVED_PROPERTY, FilterOperator.GREATER_THAN, startKey);
+ new FilterPredicate(
+ Entity.KEY_RESERVED_PROPERTY, FilterOperator.GREATER_THAN, startKey);
Query q = new Query(kind).setAncestor(parentKey).setFilter(startFilter).setKeysOnly();
return datastore.prepare(q).countEntities(FetchOptions.Builder.withLimit(1)) > 0;
}
@@ -132,7 +132,7 @@ public class DatastoreHelper {
}
Key endKey = KeyFactory.createKey(parentKey, kind, upperBound);
Filter endFilter =
- new FilterPredicate(Entity.KEY_RESERVED_PROPERTY, FilterOperator.LESS_THAN, endKey);
+ new FilterPredicate(Entity.KEY_RESERVED_PROPERTY, FilterOperator.LESS_THAN, endKey);
Query q = new Query(kind).setAncestor(parentKey).setFilter(endFilter).setKeysOnly();
return datastore.prepare(q).countEntities(FetchOptions.Builder.withLimit(1)) > 0;
}
@@ -179,10 +179,10 @@ public class DatastoreHelper {
List<Entity> profilingPointRunEntityList = new ArrayList<>();
if (!report.hasStartTimestamp()
- || !report.hasEndTimestamp()
- || !report.hasTest()
- || !report.hasHostInfo()
- || !report.hasBuildInfo()) {
+ || !report.hasEndTimestamp()
+ || !report.hasTest()
+ || !report.hasHostInfo()
+ || !report.hasBuildInfo()) {
// missing information
return;
}
@@ -195,8 +195,8 @@ public class DatastoreHelper {
TestEntity testEntity = new TestEntity(testName);
Key testRunKey =
- KeyFactory.createKey(
- testEntity.getOldKey(), TestRunEntity.KIND, report.getStartTimestamp());
+ KeyFactory.createKey(
+ testEntity.getOldKey(), TestRunEntity.KIND, report.getStartTimestamp());
long passCount = 0;
long failCount = 0;
@@ -220,7 +220,7 @@ public class DatastoreHelper {
++failCount;
}
if (testCase.getSystraceCount() > 0
- && testCase.getSystraceList().get(0).getUrlCount() > 0) {
+ && testCase.getSystraceList().get(0).getUrlCount() > 0) {
String systraceLink = testCase.getSystraceList().get(0).getUrl(0).toStringUtf8();
links.add(systraceLink);
}
@@ -228,7 +228,7 @@ public class DatastoreHelper {
// Process coverage data for test case
for (CoverageReportMessage coverage : testCase.getCoverageList()) {
CoverageEntity coverageEntity =
- CoverageEntity.fromCoverageReport(testRunKey, testCaseName, coverage);
+ CoverageEntity.fromCoverageReport(testRunKey, testCaseName, coverage);
if (coverageEntity == null) {
logger.log(Level.WARNING, "Invalid coverage report in test run " + testRunKey);
} else {
@@ -241,7 +241,7 @@ public class DatastoreHelper {
// Process profiling data for test case
for (ProfilingReportMessage profiling : testCase.getProfilingList()) {
ProfilingPointRunEntity profilingPointRunEntity =
- ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling);
+ ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling);
if (profilingPointRunEntity == null) {
logger.log(Level.WARNING, "Invalid profiling report in test run " + testRunKey);
} else {
@@ -275,7 +275,7 @@ public class DatastoreHelper {
long testRunType = 0;
for (AndroidDeviceInfoMessage device : report.getDeviceInfoList()) {
DeviceInfoEntity deviceInfoEntity =
- DeviceInfoEntity.fromDeviceInfoMessage(testRunKey, device);
+ DeviceInfoEntity.fromDeviceInfoMessage(testRunKey, device);
if (deviceInfoEntity == null) {
logger.log(Level.WARNING, "Invalid device info in test run " + testRunKey);
} else {
@@ -308,7 +308,7 @@ public class DatastoreHelper {
// Process global coverage data
for (CoverageReportMessage coverage : report.getCoverageList()) {
CoverageEntity coverageEntity =
- CoverageEntity.fromCoverageReport(testRunKey, new String(), coverage);
+ CoverageEntity.fromCoverageReport(testRunKey, new String(), coverage);
if (coverageEntity == null) {
logger.log(Level.WARNING, "Invalid coverage report in test run " + testRunKey);
} else {
@@ -322,19 +322,19 @@ public class DatastoreHelper {
for (ApiCoverageReportMessage apiCoverage : report.getApiCoverageList()) {
HalInterfaceMessage halInterfaceMessage = apiCoverage.getHalInterface();
List<String> halApiList = apiCoverage.getHalApiList().stream().map(h -> h.toStringUtf8())
- .collect(
- Collectors.toList());
+ .collect(
+ Collectors.toList());
List<String> coveredHalApiList = apiCoverage.getCoveredHalApiList().stream()
- .map(h -> h.toStringUtf8()).collect(
- Collectors.toList());
+ .map(h -> h.toStringUtf8()).collect(
+ Collectors.toList());
ApiCoverageEntity apiCoverageEntity = new ApiCoverageEntity(
- testRunKey,
- halInterfaceMessage.getHalPackageName().toStringUtf8(),
- halInterfaceMessage.getHalVersionMajor(),
- halInterfaceMessage.getHalVersionMinor(),
- halInterfaceMessage.getHalInterfaceName().toStringUtf8(),
- halApiList,
- coveredHalApiList
+ testRunKey,
+ halInterfaceMessage.getHalPackageName().toStringUtf8(),
+ halInterfaceMessage.getHalVersionMajor(),
+ halInterfaceMessage.getHalVersionMinor(),
+ halInterfaceMessage.getHalInterfaceName().toStringUtf8(),
+ halApiList,
+ coveredHalApiList
);
com.googlecode.objectify.Key apiCoverageEntityKey = apiCoverageEntity.save();
if (apiCoverageEntityKey == null) {
@@ -345,7 +345,7 @@ public class DatastoreHelper {
// Process global profiling data
for (ProfilingReportMessage profiling : report.getProfilingList()) {
ProfilingPointRunEntity profilingPointRunEntity =
- ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling);
+ ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling);
if (profilingPointRunEntity == null) {
logger.log(Level.WARNING, "Invalid profiling report in test run " + testRunKey);
} else {
@@ -370,18 +370,18 @@ public class DatastoreHelper {
boolean hasCodeCoverage = totalLineCount > 0 && coveredLineCount >= 0;
TestRunEntity testRunEntity =
- new TestRunEntity(
- testEntity.getOldKey(),
- testRunType,
- startTimestamp,
- endTimestamp,
- testBuildId,
- hostName,
- passCount,
- failCount,
- hasCodeCoverage,
- testCaseIds,
- links);
+ new TestRunEntity(
+ testEntity.getOldKey(),
+ testRunType,
+ startTimestamp,
+ endTimestamp,
+ testBuildId,
+ hostName,
+ passCount,
+ failCount,
+ hasCodeCoverage,
+ testCaseIds,
+ links);
testEntityList.add(testRunEntity.toEntity());
CodeCoverageEntity codeCoverageEntity = new CodeCoverageEntity(
@@ -394,11 +394,11 @@ public class DatastoreHelper {
if (datastoreTransactionalRetry(test, testEntityList)) {
List<List<Entity>> auxiliaryEntityList =
- Arrays.asList(
- profilingPointRunEntityList,
- coverageEntityList,
- branchEntityList,
- buildTargetEntityList);
+ Arrays.asList(
+ profilingPointRunEntityList,
+ coverageEntityList,
+ branchEntityList,
+ buildTargetEntityList);
int indexCount = 0;
for (List<Entity> entityList : auxiliaryEntityList) {
switch (indexCount) {
@@ -406,12 +406,12 @@ public class DatastoreHelper {
case 1:
if (entityList.size() > MAX_ENTITY_SIZE_PER_TRANSACTION) {
List<List<Entity>> partitionedList =
- Lists.partition(entityList, MAX_ENTITY_SIZE_PER_TRANSACTION);
+ Lists.partition(entityList, MAX_ENTITY_SIZE_PER_TRANSACTION);
partitionedList.forEach(
- subEntityList -> {
- datastoreTransactionalRetry(
- new Entity(NULL_ENTITY_KIND), subEntityList);
- });
+ subEntityList -> {
+ datastoreTransactionalRetry(
+ new Entity(NULL_ENTITY_KIND), subEntityList);
+ });
} else {
datastoreTransactionalRetry(new Entity(NULL_ENTITY_KIND), entityList);
}
@@ -419,7 +419,7 @@ public class DatastoreHelper {
case 2:
case 3:
datastoreTransactionalRetryWithXG(
- new Entity(NULL_ENTITY_KIND), entityList, true);
+ new Entity(NULL_ENTITY_KIND), entityList, true);
break;
default:
break;
@@ -429,7 +429,7 @@ public class DatastoreHelper {
if (testRunEntity.getType() == TestRunType.POSTSUBMIT.getNumber()) {
VtsAlertJobServlet.addTask(testRunKey);
- if (testRunEntity.getHasCodeCoverage()) {
+ if (testRunEntity.getHasCodeCoverage()) {
VtsCoverageAlertJobServlet.addTask(testRunKey);
}
if (profilingPointKeys.size() > 0) {
@@ -437,9 +437,9 @@ public class DatastoreHelper {
}
} else {
logger.log(
- Level.WARNING,
- "The alert email was not sent as testRunEntity type is not POSTSUBMIT!" +
- " \n " + " testRunEntity type => " + testRunEntity.getType());
+ Level.WARNING,
+ "The alert email was not sent as testRunEntity type is not POSTSUBMIT!" +
+ " \n " + " testRunEntity type => " + testRunEntity.getType());
}
}
}
@@ -506,18 +506,18 @@ public class DatastoreHelper {
return;
}
TestPlanRunEntity testPlanRun =
- new TestPlanRunEntity(
- testPlanEntity.getKey(),
- testPlanName,
- type,
- startTimestamp,
- endTimestamp,
- testBuildId,
- passCount,
- failCount,
- 0L,
- 0L,
- testRunKeys);
+ new TestPlanRunEntity(
+ testPlanEntity.getKey(),
+ testPlanName,
+ type,
+ startTimestamp,
+ endTimestamp,
+ testBuildId,
+ passCount,
+ failCount,
+ 0L,
+ 0L,
+ testRunKeys);
// Create the device infos.
for (DeviceInfoEntity device : deviceInfoEntitySet) {
@@ -549,7 +549,7 @@ public class DatastoreHelper {
* @param entityList The list of entity for using datastore put method.
*/
private static boolean datastoreTransactionalRetryWithXG(
- Entity entity, List<Entity> entityList, boolean withXG) {
+ Entity entity, List<Entity> entityList, boolean withXG) {
int retries = 0;
while (true) {
Transaction txn;
@@ -568,7 +568,7 @@ public class DatastoreHelper {
Entity datastoreEntity = datastore.get(entity.getKey());
TestEntity datastoreTestEntity = TestEntity.fromEntity(datastoreEntity);
if (datastoreTestEntity == null
- || !datastoreTestEntity.equals(entity)) {
+ || !datastoreTestEntity.equals(entity)) {
entityList.add(entity);
}
} else if (entity.getKind().equalsIgnoreCase("TestPlan")) {
@@ -584,25 +584,25 @@ public class DatastoreHelper {
txn.commit();
break;
} catch (ConcurrentModificationException
- | DatastoreFailureException
- | DatastoreTimeoutException e) {
+ | DatastoreFailureException
+ | DatastoreTimeoutException e) {
entityList.remove(entity);
logger.log(
- Level.WARNING,
- "Retrying insert kind: " + entity.getKind() + " key: " + entity.getKey());
+ Level.WARNING,
+ "Retrying insert kind: " + entity.getKind() + " key: " + entity.getKey());
if (retries++ >= MAX_WRITE_RETRIES) {
logger.log(
- Level.SEVERE,
- "Exceeded maximum retries kind: "
- + entity.getKind()
- + " key: "
- + entity.getKey());
+ Level.SEVERE,
+ "Exceeded maximum retries kind: "
+ + entity.getKind()
+ + " key: "
+ + entity.getKey());
return false;
}
} finally {
if (txn.isActive()) {
logger.log(
- Level.WARNING, "Transaction rollback forced for : " + entity.getKind());
+ Level.WARNING, "Transaction rollback forced for : " + entity.getKind());
txn.rollback();
}
}