summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2018-11-07 04:50:31 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-11-07 04:50:31 +0000
commitf2d725478cc452a365c1544b2986f6bdaabb9170 (patch)
tree71812e2a46fd982c76e34588ba6813a5377b9c21 /src
parentb2e44195bfe8cd179b33f51f0987c107a55690be (diff)
parent36c1ab52b47c095e438cbe3273b09fe32455a9be (diff)
downloaddashboard-f2d725478cc452a365c1544b2986f6bdaabb9170.tar.gz
Merge changes from topic "hal-api-entity"
* changes: Updating util classes, listener and job servlet for HalApiEntity Updating datastore API for HalApiEntity Adding HalApiEntity and implementing interface logic for the consistent data insertion on datastore.
Diffstat (limited to 'src')
-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();
}
}