From 81d71f56120e4c0b757fe3d153df21da4fa6ed88 Mon Sep 17 00:00:00 2001 From: Young Gyu Park Date: Tue, 14 Aug 2018 11:03:33 +0900 Subject: Adding and updating entities Test: go/vts-web-staging Bug: 111481322 Change-Id: I786a2587f56645e454a22e5846a8fb7890a9ec5a --- .../com/android/vts/entity/ApiCoverageEntity.java | 185 ++++++++++ .../com/android/vts/entity/CoverageEntity.java | 2 +- .../com/android/vts/entity/DeviceInfoEntity.java | 44 ++- .../android/vts/entity/ProfilingPointEntity.java | 81 ++++- .../vts/entity/ProfilingPointRunEntity.java | 83 ++++- .../vts/entity/ProfilingPointSummaryEntity.java | 92 ++++- .../com/android/vts/entity/TestCaseRunEntity.java | 21 +- .../vts/entity/TestCoverageStatusEntity.java | 2 +- .../com/android/vts/entity/TestPlanRunEntity.java | 391 ++++++++++++--------- .../java/com/android/vts/entity/TestRunEntity.java | 257 ++++++++------ .../java/com/android/vts/entity/UserEntity.java | 6 +- 11 files changed, 842 insertions(+), 322 deletions(-) create mode 100644 src/main/java/com/android/vts/entity/ApiCoverageEntity.java (limited to 'src/main') diff --git a/src/main/java/com/android/vts/entity/ApiCoverageEntity.java b/src/main/java/com/android/vts/entity/ApiCoverageEntity.java new file mode 100644 index 0000000..beb772d --- /dev/null +++ b/src/main/java/com/android/vts/entity/ApiCoverageEntity.java @@ -0,0 +1,185 @@ +/* + * 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 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 halApi; + + /** + * List of HAL covered API + */ + @Getter + @Setter + List 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 halApi, + List coveredHalApi) { + + this.parent = getParentKey(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 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 getByInterfaceNameList(String halInterfaceName) { + return ofy().load() + .type(ApiCoverageEntity.class) + .filter("halInterfaceName", halInterfaceName) + .list(); + } + + /** + * Get List of ApiCoverageEntity by HAL package name + */ + public static List getByPackageNameList(String packageName) { + return ofy().load() + .type(ApiCoverageEntity.class) + .filter("halPackageName", packageName) + .list(); + } +} diff --git a/src/main/java/com/android/vts/entity/CoverageEntity.java b/src/main/java/com/android/vts/entity/CoverageEntity.java index bfc7041..04c863c 100644 --- a/src/main/java/com/android/vts/entity/CoverageEntity.java +++ b/src/main/java/com/android/vts/entity/CoverageEntity.java @@ -268,7 +268,7 @@ public class CoverageEntity implements Serializable { List lineCoverage = null; if (coverage.getLineCoverageVectorCount() > 0) { lineCoverage = new ArrayList<>(); - for (Long count : coverage.getLineCoverageVectorList()) { + for (long count : coverage.getLineCoverageVectorList()) { lineCoverage.add(count); } } diff --git a/src/main/java/com/android/vts/entity/DeviceInfoEntity.java b/src/main/java/com/android/vts/entity/DeviceInfoEntity.java index 3225b83..cedb7b7 100644 --- a/src/main/java/com/android/vts/entity/DeviceInfoEntity.java +++ b/src/main/java/com/android/vts/entity/DeviceInfoEntity.java @@ -19,11 +19,23 @@ package com.android.vts.entity; import com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.Key; +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.util.logging.Level; import java.util.logging.Logger; +import lombok.Data; +import lombok.NoArgsConstructor; +@com.googlecode.objectify.annotation.Entity(name = "DeviceInfo") +@Cache +@Data +@NoArgsConstructor /** Class describing a device used for a test run. */ -public class DeviceInfoEntity implements DashboardEntity { +public class DeviceInfoEntity implements Serializable { protected static final Logger logger = Logger.getLogger(DeviceInfoEntity.class.getName()); public static final String KIND = "DeviceInfo"; @@ -36,14 +48,41 @@ public class DeviceInfoEntity implements DashboardEntity { public static final String ABI_BITNESS = "abiBitness"; public static final String ABI_NAME = "abiName"; - private final Key parentKey; + @Ignore + private Key parentKey; + /** ID field using start timestamp */ + @Id + private long id; + + /** parent field based on Test and TestRun key */ + @Parent + private com.googlecode.objectify.Key parent; + + @Index + private String branch; + + @Index + private String product; + + @Index + private String buildFlavor; + + @Index + private String buildId; + + private String abiBitness; + + 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. @@ -67,7 +106,6 @@ public class DeviceInfoEntity implements DashboardEntity { this.abiName = abiName; } - @Override public Entity toEntity() { Entity deviceEntity = new Entity(KIND, this.parentKey); deviceEntity.setProperty(BRANCH, this.branch.toLowerCase()); diff --git a/src/main/java/com/android/vts/entity/ProfilingPointEntity.java b/src/main/java/com/android/vts/entity/ProfilingPointEntity.java index cfe4983..741a5a7 100644 --- a/src/main/java/com/android/vts/entity/ProfilingPointEntity.java +++ b/src/main/java/com/android/vts/entity/ProfilingPointEntity.java @@ -21,11 +21,25 @@ import com.android.vts.proto.VtsReportMessage.VtsProfilingType; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.Key; import com.google.appengine.api.datastore.KeyFactory; +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; +@com.googlecode.objectify.annotation.Entity(name = "ProfilingPoint") +@Cache +@Data +@NoArgsConstructor /** Entity describing a profiling point. */ -public class ProfilingPointEntity implements DashboardEntity { +public class ProfilingPointEntity implements Serializable { protected static final Logger logger = Logger.getLogger(ProfilingPointEntity.class.getName()); protected static final String DELIMITER = "#"; @@ -39,14 +53,38 @@ public class ProfilingPointEntity implements DashboardEntity { public static final String X_LABEL = "xLabel"; public static final String Y_LABEL = "yLabel"; - public final Key key; + @Ignore + private Key key; - public final String testName; - public final String profilingPointName; - public final VtsProfilingType type; - public final VtsProfilingRegressionMode regressionMode; - public final String xLabel; - public final String yLabel; + /** ProfilingPointEntity testName field */ + @Id + private String name; + + /** ProfilingPointEntity profilingPointName field */ + @Index + private String profilingPointName; + + /** ProfilingPointEntity testName field */ + @Index + private String testName; + + /** ProfilingPointEntity type field */ + private int type; + + /** ProfilingPointEntity regressionMode field */ + private int regressionMode; + + /** ProfilingPointEntity xLabel field */ + private String xLabel; + + /** ProfilingPointEntity xLabel field */ + private String yLabel; + + /** + * When this record was created or updated + */ + @Index + Date updated; /** * Create a ProfilingPointEntity object. @@ -68,12 +106,30 @@ public class ProfilingPointEntity implements DashboardEntity { this.key = createKey(testName, profilingPointName); this.testName = testName; this.profilingPointName = profilingPointName; - this.type = VtsProfilingType.valueOf(type); - this.regressionMode = VtsProfilingRegressionMode.valueOf(regressionMode); + this.type = type; + this.regressionMode = regressionMode; this.xLabel = xLabel; this.yLabel = yLabel; } + /** + * Get VtsProfilingType from int value. + * + * @return VtsProfilingType class. + */ + public VtsProfilingType getVtsProfilingType(int type) { + return VtsProfilingType.forNumber(type); + } + + /** + * Get VtsProfilingRegressionMode from int value. + * + * @return VtsProfilingType class. + */ + public VtsProfilingRegressionMode getVtsProfilingRegressionMode(int regressionMode) { + return VtsProfilingRegressionMode.forNumber(regressionMode); + } + /** * Create a key for a ProfilingPointEntity. * @@ -85,13 +141,12 @@ public class ProfilingPointEntity implements DashboardEntity { return KeyFactory.createKey(KIND, testName + DELIMITER + profilingPointName); } - @Override public Entity toEntity() { Entity profilingPoint = new Entity(key); profilingPoint.setIndexedProperty(TEST_NAME, this.testName); profilingPoint.setIndexedProperty(PROFILING_POINT_NAME, this.profilingPointName); - profilingPoint.setUnindexedProperty(TYPE, this.type.getNumber()); - profilingPoint.setUnindexedProperty(REGRESSION_MODE, this.regressionMode.getNumber()); + profilingPoint.setUnindexedProperty(TYPE, this.type); + profilingPoint.setUnindexedProperty(REGRESSION_MODE, this.regressionMode); profilingPoint.setUnindexedProperty(X_LABEL, this.xLabel); profilingPoint.setUnindexedProperty(Y_LABEL, this.yLabel); diff --git a/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java b/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java index 165644f..2010971 100644 --- a/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java +++ b/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java @@ -23,13 +23,26 @@ import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.Key; import com.google.appengine.api.datastore.KeyFactory; import com.google.protobuf.ByteString; +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; +@com.googlecode.objectify.annotation.Entity(name = "ProfilingPointRun") +@Cache +@Data +@NoArgsConstructor /** Entity describing a profiling point execution. */ -public class ProfilingPointRunEntity implements DashboardEntity { +public class ProfilingPointRunEntity implements Serializable { protected static final Logger logger = Logger.getLogger(ProfilingPointRunEntity.class.getName()); @@ -44,16 +57,39 @@ public class ProfilingPointRunEntity implements DashboardEntity { public static final String Y_LABEL = "yLabel"; public static final String OPTIONS = "options"; - public final Key key; + @Ignore + private Key key; - public final String name; - public final VtsProfilingType type; - public final VtsProfilingRegressionMode regressionMode; - public final List labels; - public final List values; - public final String xLabel; - public final String yLabel; - public final List options; + /** ID field using profilingPointName */ + @Id + private String name; + + /** parent field based on Test and TestRun key */ + @Parent + private com.googlecode.objectify.Key parent; + + /** VtsProfilingType in ProfilingPointRunEntity class */ + private int type; + + /** VtsProfilingType in ProfilingPointRunEntity class */ + private int regressionMode; + + /** list of label name */ + private List labels; + + /** list of values */ + private List values; + + /** X axis label name */ + private String xLabel; + + /** Y axis label name */ + private String yLabel; + + /** Test Suite file name field */ + private List options; + + /** When this record was created or updated */ /** * Create a ProfilingPointRunEntity object. @@ -80,8 +116,8 @@ public class ProfilingPointRunEntity implements DashboardEntity { List options) { this.key = KeyFactory.createKey(parentKey, KIND, name); this.name = name; - this.type = VtsProfilingType.valueOf(type); - this.regressionMode = VtsProfilingRegressionMode.valueOf(regressionMode); + this.type = type; + this.regressionMode = regressionMode; this.labels = labels == null ? null : new ArrayList<>(labels); this.values = new ArrayList<>(values); this.xLabel = xLabel; @@ -89,11 +125,28 @@ public class ProfilingPointRunEntity implements DashboardEntity { this.options = options; } - @Override + /** + * Get VtsProfilingType from int value. + * + * @return VtsProfilingType class. + */ + public VtsProfilingType getVtsProfilingType(int type) { + return VtsProfilingType.forNumber(type); + } + + /** + * Get VtsProfilingRegressionMode from int value. + * + * @return VtsProfilingType class. + */ + public VtsProfilingRegressionMode getVtsProfilingRegressionMode(int regressionMode) { + return VtsProfilingRegressionMode.forNumber(regressionMode); + } + public Entity toEntity() { Entity profilingRun = new Entity(this.key); - profilingRun.setUnindexedProperty(TYPE, this.type.getNumber()); - profilingRun.setUnindexedProperty(REGRESSION_MODE, this.regressionMode.getNumber()); + profilingRun.setUnindexedProperty(TYPE, this.type); + profilingRun.setUnindexedProperty(REGRESSION_MODE, this.regressionMode); if (this.labels != null) { profilingRun.setUnindexedProperty(LABELS, this.labels); } diff --git a/src/main/java/com/android/vts/entity/ProfilingPointSummaryEntity.java b/src/main/java/com/android/vts/entity/ProfilingPointSummaryEntity.java index e5f46a9..f426707 100644 --- a/src/main/java/com/android/vts/entity/ProfilingPointSummaryEntity.java +++ b/src/main/java/com/android/vts/entity/ProfilingPointSummaryEntity.java @@ -21,15 +21,28 @@ import com.android.vts.util.StatSummary; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.Key; import com.google.appengine.api.datastore.KeyFactory; +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; 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; +@com.googlecode.objectify.annotation.Entity(name = "ProfilingPointSummary") +@Cache +@Data +@NoArgsConstructor /** Entity describing a profiling point summary. */ -public class ProfilingPointSummaryEntity implements DashboardEntity { +public class ProfilingPointSummaryEntity implements Serializable { protected static final Logger logger = Logger.getLogger(ProfilingPointSummaryEntity.class.getName()); protected static final String DELIMITER = "#"; @@ -54,8 +67,62 @@ public class ProfilingPointSummaryEntity implements DashboardEntity { public static final String BUILD_FLAVOR = "buildFlavor"; public static final String SERIES = "series"; - private final Key key; + @Ignore + private Key key; + /** ID field */ + @Id private String name; + + /** branch field */ + @Index private String branch; + + /** build field */ + @Index private String buildFlavor; + + /** total count */ + @Index private int count; + + /** For each label count field */ + @Index private List labelCounts; + + /** Maximum value for each label */ + private List labelMaxes; + + /** Mean value for each label */ + private List labelMeans; + + /** Minimum value for each label */ + private List labelMins; + + /** Label name for each label point */ + private List labels; + + /** Summation for sequence for each label */ + private List labelSumSqs; + + /** Maximum value for total */ + private Long max; + + /** Mean value for total */ + private Long mean; + + /** Minimum value for total */ + private Long min; + + /** The list of series */ + private String series; + + /** The start time field of the test */ + private Long startTime; + + /** The summation of sequences */ + private Long sumSq; + + @Ignore private StatSummary globalStats; + + @Ignore private Map labelStats; + + /* public final StatSummary globalStats; public final List labels; public final Map labelStats; @@ -63,6 +130,7 @@ public class ProfilingPointSummaryEntity implements DashboardEntity { public final String buildFlavor; public final String series; public final long startTime; + */ /** * Create a ProfilingPointSummaryEntity object. @@ -147,26 +215,28 @@ public class ProfilingPointSummaryEntity implements DashboardEntity { * @param profilingRun The profiling point run entity object containing profiling data. */ public void update(ProfilingPointRunEntity profilingRun) { - if (profilingRun.labels != null - && profilingRun.labels.size() == profilingRun.values.size()) { - for (int i = 0; i < profilingRun.labels.size(); i++) { - String label = profilingRun.labels.get(i); + if (profilingRun.getLabels() != null + && profilingRun.getLabels().size() == profilingRun.getValues().size()) { + for (int i = 0; i < profilingRun.getLabels().size(); i++) { + String label = profilingRun.getLabels().get(i); if (!this.labelStats.containsKey(label)) { - StatSummary summary = new StatSummary(label, profilingRun.regressionMode); + VtsProfilingRegressionMode vtsProfilingRegressionMode = + profilingRun.getVtsProfilingRegressionMode( + profilingRun.getRegressionMode()); + StatSummary summary = new StatSummary(label, vtsProfilingRegressionMode); this.labelStats.put(label, summary); } StatSummary summary = this.labelStats.get(label); - summary.updateStats(profilingRun.values.get(i)); + summary.updateStats(profilingRun.getValues().get(i)); } this.labels.clear(); - this.labels.addAll(profilingRun.labels); + this.labels.addAll(profilingRun.getLabels()); } - for (long value : profilingRun.values) { + for (long value : profilingRun.getValues()) { this.globalStats.updateStats(value); } } - @Override public Entity toEntity() { Entity profilingSummary; profilingSummary = new Entity(this.key); diff --git a/src/main/java/com/android/vts/entity/TestCaseRunEntity.java b/src/main/java/com/android/vts/entity/TestCaseRunEntity.java index 81258d0..b0f16ea 100644 --- a/src/main/java/com/android/vts/entity/TestCaseRunEntity.java +++ b/src/main/java/com/android/vts/entity/TestCaseRunEntity.java @@ -18,11 +18,19 @@ package com.android.vts.entity; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.KeyFactory; +import com.googlecode.objectify.annotation.Cache; +import com.googlecode.objectify.annotation.Id; +import com.googlecode.objectify.annotation.Ignore; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import lombok.Data; +import lombok.NoArgsConstructor; +@com.googlecode.objectify.annotation.Entity(name = "TestCaseRun") +@Cache +@Data /** Entity describing the execution of a test case. */ public class TestCaseRunEntity implements DashboardEntity { protected static final Logger logger = Logger.getLogger(TestCaseRunEntity.class.getName()); @@ -39,8 +47,17 @@ public class TestCaseRunEntity implements DashboardEntity { // Maximum number of test cases in the entity. private static final int SIZE_LIMIT = 500; - public final long id; + @Id + private Long id; + + private List results; + + private List testCaseNames; + + @Ignore public final List testCases; + + @Ignore private String systraceUrl; /** @@ -71,7 +88,7 @@ public class TestCaseRunEntity implements DashboardEntity { * Create a TestCaseRunEntity. */ public TestCaseRunEntity() { - this.id = -1; + this.id = -1L; this.testCases = new ArrayList<>(); this.systraceUrl = null; } diff --git a/src/main/java/com/android/vts/entity/TestCoverageStatusEntity.java b/src/main/java/com/android/vts/entity/TestCoverageStatusEntity.java index a9c8deb..bad5268 100644 --- a/src/main/java/com/android/vts/entity/TestCoverageStatusEntity.java +++ b/src/main/java/com/android/vts/entity/TestCoverageStatusEntity.java @@ -34,9 +34,9 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -@Cache @com.googlecode.objectify.annotation.Entity(name = "TestCoverageStatus") @EqualsAndHashCode(of = "testName") +@Cache @NoArgsConstructor /** Entity describing test coverage status. */ public class TestCoverageStatusEntity implements Serializable { diff --git a/src/main/java/com/android/vts/entity/TestPlanRunEntity.java b/src/main/java/com/android/vts/entity/TestPlanRunEntity.java index e72e454..917ae75 100644 --- a/src/main/java/com/android/vts/entity/TestPlanRunEntity.java +++ b/src/main/java/com/android/vts/entity/TestPlanRunEntity.java @@ -16,10 +16,15 @@ 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; +import com.google.appengine.api.taskqueue.Queue; +import com.google.appengine.api.taskqueue.QueueFactory; +import com.google.appengine.api.taskqueue.TaskOptions; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import com.googlecode.objectify.annotation.Cache; @@ -28,7 +33,9 @@ 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.UUID; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -44,175 +51,223 @@ import lombok.Setter; /** Entity describing test plan run information. */ public class TestPlanRunEntity implements Serializable { - protected static final Logger logger = Logger.getLogger(TestPlanRunEntity.class.getName()); - - public static final String KIND = "TestPlanRun"; - - // Property keys - public static final String TEST_PLAN_NAME = "testPlanName"; - public static final String TYPE = "type"; - public static final String START_TIMESTAMP = "startTimestamp"; - public static final String END_TIMESTAMP = "endTimestamp"; - public static final String TEST_BUILD_ID = "testBuildId"; - public static final String PASS_COUNT = "passCount"; - public static final String FAIL_COUNT = "failCount"; - public static final String TEST_RUNS = "testRuns"; - - @Ignore - public Key key; - - @Id - @Getter - @Setter - private Long ID; - - @Parent - @Getter - @Setter - private com.googlecode.objectify.Key testParent; - - @Index - @Getter - @Setter - private String testPlanName; - - @Index - @Getter - @Setter - private TestRunType type; - - @Index - @Getter - @Setter - private long startTimestamp; - - @Index - @Getter - @Setter - private long endTimestamp; - - @Index - @Getter - @Setter - private String testBuildId; - - @Index - @Getter - @Setter - private long passCount; - - @Index - @Getter - @Setter - private long failCount; - - @Getter - @Setter - private List testRuns; - - @Ignore - @Getter - @Setter - private List> ofyTestRuns; - - /** - * Create a TestPlanRunEntity object describing a test plan run. - * - * @param parentKey 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(Key parentKey, String testPlanName, TestRunType type, - long startTimestamp, long endTimestamp, String testBuildId, long passCount, - long failCount, List testRuns) { - this.key = KeyFactory.createKey(parentKey, KIND, startTimestamp); - this.testPlanName = testPlanName; - this.type = type; - this.startTimestamp = startTimestamp; - this.endTimestamp = endTimestamp; - this.testBuildId = testBuildId; - this.passCount = passCount; - this.failCount = failCount; - this.testRuns = testRuns; - this.ofyTestRuns = testRuns.stream().map(testRun -> { - com.googlecode.objectify.Key testParentKey = com.googlecode.objectify.Key - .create(TestEntity.class, testRun.getParent().getName()); - return com.googlecode.objectify.Key - .create(testParentKey, TestRunEntity.class, testRun.getId()); - }).collect(Collectors.toList()); - - } - - public Entity toEntity() { - Entity planRun = new Entity(this.key); - planRun.setProperty(TEST_PLAN_NAME, this.testPlanName); - planRun.setProperty(TYPE, this.type.getNumber()); - planRun.setProperty(START_TIMESTAMP, this.startTimestamp); - planRun.setProperty(END_TIMESTAMP, this.endTimestamp); - planRun.setProperty(TEST_BUILD_ID, this.testBuildId.toLowerCase()); - planRun.setProperty(PASS_COUNT, this.passCount); - planRun.setProperty(FAIL_COUNT, this.failCount); - if (this.testRuns != null && this.testRuns.size() > 0) { - planRun.setUnindexedProperty(TEST_RUNS, this.testRuns); + protected static final Logger logger = Logger.getLogger(TestPlanRunEntity.class.getName()); + + private final String QUEUE_NAME = "coverageApiQueue"; + + public static final String KIND = "TestPlanRun"; + + private static final String COVERAGE_API_URL = "/api/coverage/api/sum"; + + // Property keys + public static final String TEST_PLAN_NAME = "testPlanName"; + public static final String TYPE = "type"; + public static final String START_TIMESTAMP = "startTimestamp"; + public static final String END_TIMESTAMP = "endTimestamp"; + public static final String TEST_BUILD_ID = "testBuildId"; + public static final String PASS_COUNT = "passCount"; + public static final String FAIL_COUNT = "failCount"; + public static final String TOTAL_API_COUNT = "totalApiCount"; + public static final String TOTAL_COVERED_API_COUNT = "coveredApiCount"; + public static final String TEST_RUNS = "testRuns"; + + @Ignore public Key key; + + @Id private Long id; + + @Parent private com.googlecode.objectify.Key testParent; + + @Index private String testPlanName; + + @Ignore private TestRunType testRunType; + + @Index private long type; + + @Index private long startTimestamp; + + @Index private long endTimestamp; + + @Index private String testBuildId; + + @Index private long passCount; + + @Index private long failCount; + + @Index private long totalApiCount; + + @Index private long coveredApiCount; + + @Ignore private List oldTestRuns; + + private List> testRuns; + + /** When this record was created or updated */ + @Index Date updated; + + /** + * Create a TestPlanRunEntity object describing a test plan run. + * + * @param parentKey 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( + Key parentKey, + String testPlanName, + TestRunType type, + long startTimestamp, + long endTimestamp, + String testBuildId, + long passCount, + long failCount, + long totalApiCount, + long coveredApiCount, + List testRuns) { + this.key = KeyFactory.createKey(parentKey, KIND, startTimestamp); + this.testPlanName = testPlanName; + this.testRunType = type; + this.startTimestamp = startTimestamp; + this.endTimestamp = endTimestamp; + this.testBuildId = testBuildId; + this.passCount = passCount; + this.failCount = failCount; + this.totalApiCount = totalApiCount; + this.coveredApiCount = coveredApiCount; + this.oldTestRuns = testRuns; + this.testRuns = + testRuns.stream() + .map( + testRun -> { + com.googlecode.objectify.Key testParentKey = + com.googlecode.objectify.Key.create( + TestEntity.class, + testRun.getParent().getName()); + return com.googlecode.objectify.Key.create( + testParentKey, TestRunEntity.class, testRun.getId()); + }) + .collect(Collectors.toList()); } - return planRun; - } - - /** - * Get key info from appengine based library. - * - * @param parentKey parent key. - */ - public Key getOldKey(Key parentKey) { - return KeyFactory.createKey(parentKey, KIND, startTimestamp); - } - - /** - * Convert an Entity object to a TestPlanRunEntity. - * - * @param e The entity to process. - * @return TestPlanRunEntity object with the properties from e processed, or null if incompatible. - */ - @SuppressWarnings("unchecked") - public static TestPlanRunEntity fromEntity(Entity e) { - if (!e.getKind().equals(KIND) || !e.hasProperty(TEST_PLAN_NAME) || !e.hasProperty(TYPE) - || !e.hasProperty(START_TIMESTAMP) || !e.hasProperty(END_TIMESTAMP) - || !e.hasProperty(TEST_BUILD_ID) || !e.hasProperty(PASS_COUNT) - || !e.hasProperty(FAIL_COUNT) || !e.hasProperty(TEST_RUNS)) { - logger.log(Level.WARNING, "Missing test run attributes in entity: " + e.toString()); - return null; + + public Entity toEntity() { + Entity planRun = new Entity(this.key); + planRun.setProperty(TEST_PLAN_NAME, this.testPlanName); + planRun.setProperty(TYPE, this.testRunType.getNumber()); + planRun.setProperty(START_TIMESTAMP, this.startTimestamp); + planRun.setProperty(END_TIMESTAMP, this.endTimestamp); + planRun.setProperty(TEST_BUILD_ID, this.testBuildId.toLowerCase()); + planRun.setProperty(PASS_COUNT, this.passCount); + planRun.setProperty(FAIL_COUNT, this.failCount); + if (this.oldTestRuns != null && this.oldTestRuns.size() > 0) { + planRun.setUnindexedProperty(TEST_RUNS, this.oldTestRuns); + } + return planRun; + } + + /** Saving function for the instance of this class */ + public com.googlecode.objectify.Key save() { + this.updated = new Date(); + return ofy().save().entity(this).now(); + } + + /** 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(); } - try { - String testPlanName = (String) e.getProperty(TEST_PLAN_NAME); - TestRunType type = TestRunType.fromNumber((int) (long) e.getProperty(TYPE)); - long startTimestamp = (long) e.getProperty(START_TIMESTAMP); - long endTimestamp = (long) e.getProperty(END_TIMESTAMP); - String testBuildId = (String) e.getProperty(TEST_BUILD_ID); - long passCount = (long) e.getProperty(PASS_COUNT); - long failCount = (long) e.getProperty(FAIL_COUNT); - List testRuns = (List) e.getProperty(TEST_RUNS); - return new TestPlanRunEntity(e.getKey().getParent(), testPlanName, type, startTimestamp, - endTimestamp, testBuildId, passCount, failCount, testRuns); - } catch (ClassCastException exception) { - // Invalid cast - logger.log(Level.WARNING, "Error parsing test plan run entity.", exception); + + /** Add a task to calculate the total number of coverage API */ + public void addCoverageApiTask() { + if (this.totalApiCount > 0) { + Queue queue = QueueFactory.getQueue(QUEUE_NAME); + queue.add( + TaskOptions.Builder.withUrl(COVERAGE_API_URL) + .param("urlSafeKey", String.valueOf(this.getUrlSafeKey())) + .method(TaskOptions.Method.POST)); + } + } + + /** + * Get key info from appengine based library. + * + * @param parentKey parent key. + */ + public Key getOldKey(Key parentKey) { + return KeyFactory.createKey(parentKey, KIND, startTimestamp); + } + + /** + * Convert an Entity object to a TestPlanRunEntity. + * + * @param e The entity to process. + * @return TestPlanRunEntity object with the properties from e processed, or null if + * incompatible. + */ + @SuppressWarnings("unchecked") + public static TestPlanRunEntity fromEntity(Entity e) { + if (!e.getKind().equals(KIND) + || !e.hasProperty(TEST_PLAN_NAME) + || !e.hasProperty(TYPE) + || !e.hasProperty(START_TIMESTAMP) + || !e.hasProperty(END_TIMESTAMP) + || !e.hasProperty(TEST_BUILD_ID) + || !e.hasProperty(PASS_COUNT) + || !e.hasProperty(FAIL_COUNT) + || !e.hasProperty(TEST_RUNS)) { + logger.log(Level.WARNING, "Missing test run attributes in entity: " + e.toString()); + return null; + } + try { + String testPlanName = (String) e.getProperty(TEST_PLAN_NAME); + TestRunType type = TestRunType.fromNumber((int) (long) e.getProperty(TYPE)); + long startTimestamp = (long) e.getProperty(START_TIMESTAMP); + long endTimestamp = (long) e.getProperty(END_TIMESTAMP); + String testBuildId = (String) e.getProperty(TEST_BUILD_ID); + long passCount = (long) e.getProperty(PASS_COUNT); + long failCount = (long) e.getProperty(FAIL_COUNT); + + long totalApiCount = + e.hasProperty(TOTAL_API_COUNT) ? (long) e.getProperty(TOTAL_API_COUNT) : 0L; + long coveredApiCount = + e.hasProperty(TOTAL_COVERED_API_COUNT) + ? (long) e.getProperty(TOTAL_COVERED_API_COUNT) + : 0L; + List oldTestRuns = (List) e.getProperty(TEST_RUNS); + return new TestPlanRunEntity( + e.getKey().getParent(), + testPlanName, + type, + startTimestamp, + endTimestamp, + testBuildId, + passCount, + failCount, + totalApiCount, + coveredApiCount, + oldTestRuns); + } catch (ClassCastException exception) { + // Invalid cast + logger.log(Level.WARNING, "Error parsing test plan run entity.", exception); + } + return null; + } + + public JsonObject toJson() { + JsonObject json = new JsonObject(); + json.add(TEST_PLAN_NAME, new JsonPrimitive(this.testPlanName)); + json.add(TEST_BUILD_ID, new JsonPrimitive(this.testBuildId)); + json.add(PASS_COUNT, new JsonPrimitive(this.passCount)); + json.add(FAIL_COUNT, new JsonPrimitive(this.failCount)); + json.add(START_TIMESTAMP, new JsonPrimitive(this.startTimestamp)); + json.add(END_TIMESTAMP, new JsonPrimitive(this.endTimestamp)); + return json; } - return null; - } - - public JsonObject toJson() { - JsonObject json = new JsonObject(); - json.add(TEST_PLAN_NAME, new JsonPrimitive(this.testPlanName)); - json.add(TEST_BUILD_ID, new JsonPrimitive(this.testBuildId)); - json.add(PASS_COUNT, new JsonPrimitive(this.passCount)); - json.add(FAIL_COUNT, new JsonPrimitive(this.failCount)); - json.add(START_TIMESTAMP, new JsonPrimitive(this.startTimestamp)); - json.add(END_TIMESTAMP, new JsonPrimitive(this.endTimestamp)); - return json; - } } diff --git a/src/main/java/com/android/vts/entity/TestRunEntity.java b/src/main/java/com/android/vts/entity/TestRunEntity.java index 1766363..625fc2c 100644 --- a/src/main/java/com/android/vts/entity/TestRunEntity.java +++ b/src/main/java/com/android/vts/entity/TestRunEntity.java @@ -16,12 +16,15 @@ package com.android.vts.entity; +import static com.googlecode.objectify.ObjectifyService.ofy; + import com.android.vts.util.UrlUtil; import com.android.vts.util.UrlUtil.LinkDisplay; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.Key; import com.google.appengine.api.datastore.KeyFactory; import com.google.gson.Gson; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; @@ -33,14 +36,20 @@ import com.googlecode.objectify.annotation.Parent; import java.io.Serializable; import java.util.ArrayList; import java.util.List; +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") +@com.googlecode.objectify.annotation.Entity(name = "TestRun") @Cache @Data @NoArgsConstructor @@ -88,28 +97,25 @@ public class TestRunEntity implements Serializable { /** * Determine the test run type based on the build ID. * - * Postsubmit runs are expected to have integer build IDs, while presubmit runs are integers - * prefixed by the character P. All other runs (e.g. local builds) are classified as OTHER. + *

Postsubmit runs are expected to have integer build IDs, while presubmit runs are + * integers prefixed by the character P. All other runs (e.g. local builds) are classified + * as OTHER. * * @param buildId The build ID. * @return the TestRunType. */ public static TestRunType fromBuildId(String buildId) { - try { - Integer.parseInt(buildId); - return TestRunType.POSTSUBMIT; - } catch (NumberFormatException e) { - // Not an integer - } - if (Character.toLowerCase(buildId.charAt(0)) == 'p') { - try { - Integer.parseInt(buildId.substring(1)); + if (buildId.toLowerCase().startsWith("p")) { + if (NumberUtils.isParsable(buildId.substring(1))) { return TestRunType.PRESUBMIT; - } catch (NumberFormatException e) { - // Not an integer + } else { + return TestRunType.OTHER; } + } else if (NumberUtils.isParsable(buildId)) { + return TestRunType.POSTSUBMIT; + } else { + return TestRunType.OTHER; } - return TestRunType.OTHER; } } @@ -129,82 +135,41 @@ public class TestRunEntity implements Serializable { public static final String HAS_COVERAGE = "hasCoverage"; public static final String TOTAL_LINE_COUNT = "totalLineCount"; public static final String COVERED_LINE_COUNT = "coveredLineCount"; + public static final String API_COVERAGE_KEY_LIST = "apiCoverageKeyList"; + public static final String TOTAL_API_COUNT = "totalApiCount"; + public static final String COVERED_API_COUNT = "coveredApiCount"; + + @Ignore private Key key; + + @Id @Getter @Setter private Long ID; + + @Parent @Getter @Setter private com.googlecode.objectify.Key testRunParent; + + @Index @Getter @Setter private TestRunType type; + + @Index @Getter @Setter private long startTimestamp; + + @Index @Getter @Setter private long endTimestamp; + + @Index @Getter @Setter private String testBuildId; - @Ignore - private Key key; - - @Id - @Getter - @Setter - private Long ID; - - @Parent - @Getter - @Setter - private com.googlecode.objectify.Key testParent; - - @Index - @Getter - @Setter - private TestRunType type; - - @Index - @Getter - @Setter - private long startTimestamp; - - @Index - @Getter - @Setter - private long endTimestamp; - - @Index - @Getter - @Setter - private String testBuildId; - - @Index - @Getter - @Setter - private String testName; - - @Index - @Getter - @Setter - private String hostName; - - @Index - @Getter - @Setter - private long passCount; - - @Index - @Getter - @Setter - private long failCount; - - @Index - @Getter - @Setter - private boolean hasCoverage; - - @Index - @Getter - @Setter - private long coveredLineCount; - - @Index - @Getter - @Setter - private long totalLineCount; - - @Getter - @Setter - private List testCaseIds; - - @Getter - @Setter - private List links; + @Index @Getter @Setter private String testName; + + @Index @Getter @Setter private String hostName; + + @Index @Getter @Setter private long passCount; + + @Index @Getter @Setter private long failCount; + + @Index @Getter @Setter private boolean hasCoverage; + + @Index @Getter @Setter private long coveredLineCount; + + @Index @Getter @Setter private long totalLineCount; + + @Getter @Setter private List testCaseIds; + + @Getter @Setter private List links; /** * Create a TestRunEntity object describing a test run. @@ -222,9 +187,18 @@ public class TestRunEntity implements Serializable { * @param coveredLineCount The number of lines covered by the test run. * @param totalLineCount The total number of executable lines by the test in the test run. */ - public TestRunEntity(Key parentKey, TestRunType type, long startTimestamp, long endTimestamp, - String testBuildId, String hostName, long passCount, long failCount, - List testCaseIds, List links, long coveredLineCount, + public TestRunEntity( + Key parentKey, + TestRunType type, + long startTimestamp, + long endTimestamp, + String testBuildId, + String hostName, + long passCount, + long failCount, + List testCaseIds, + List links, + long coveredLineCount, long totalLineCount) { this.key = KeyFactory.createKey(parentKey, KIND, startTimestamp); this.type = type; @@ -255,11 +229,30 @@ public class TestRunEntity implements Serializable { * @param testCaseIds A list of key IDs to the TestCaseRunEntity objects for the test run. * @param links A list of links to resource files for the test run, or null if there aren't any. */ - public TestRunEntity(Key parentKey, TestRunType type, long startTimestamp, long endTimestamp, - String testBuildId, String hostName, long passCount, long failCount, - List testCaseIds, List links) { - this(parentKey, type, startTimestamp, endTimestamp, testBuildId, hostName, passCount, - failCount, testCaseIds, links, 0, 0); + public TestRunEntity( + Key parentKey, + TestRunType type, + long startTimestamp, + long endTimestamp, + String testBuildId, + String hostName, + long passCount, + long failCount, + List testCaseIds, + List links) { + this( + parentKey, + type, + startTimestamp, + endTimestamp, + testBuildId, + hostName, + passCount, + failCount, + testCaseIds, + links, + 0, + 0); } public Entity toEntity() { @@ -294,6 +287,19 @@ public class TestRunEntity implements Serializable { return KeyFactory.createKey(parentKey, KIND, startTimestamp); } + /** Get ApiCoverageEntity from key info */ + public Optional> getApiCoverageEntityList() { + com.googlecode.objectify.Key testKey = + com.googlecode.objectify.Key.create( + TestEntity.class, this.key.getParent().getName()); + com.googlecode.objectify.Key apiCoverageKey = + com.googlecode.objectify.Key.create(testKey, TestRunEntity.class, startTimestamp); + + List apiCoverageEntityList = + ofy().load().type(ApiCoverageEntity.class).ancestor(apiCoverageKey).list(); + return Optional.ofNullable(apiCoverageEntityList); + } + /** * Convert an Entity object to a TestRunEntity. * @@ -302,10 +308,15 @@ public class TestRunEntity implements Serializable { */ @SuppressWarnings("unchecked") public static TestRunEntity fromEntity(Entity e) { - if (!e.getKind().equals(KIND) || !e.hasProperty(TYPE) || !e.hasProperty(START_TIMESTAMP) - || !e.hasProperty(END_TIMESTAMP) || !e.hasProperty(TEST_BUILD_ID) - || !e.hasProperty(HOST_NAME) || !e.hasProperty(PASS_COUNT) - || !e.hasProperty(FAIL_COUNT) || !e.hasProperty(TEST_CASE_IDS)) { + if (!e.getKind().equals(KIND) + || !e.hasProperty(TYPE) + || !e.hasProperty(START_TIMESTAMP) + || !e.hasProperty(END_TIMESTAMP) + || !e.hasProperty(TEST_BUILD_ID) + || !e.hasProperty(HOST_NAME) + || !e.hasProperty(PASS_COUNT) + || !e.hasProperty(FAIL_COUNT) + || !e.hasProperty(TEST_CASE_IDS)) { logger.log(Level.WARNING, "Missing test run attributes in entity: " + e.toString()); return null; } @@ -328,9 +339,19 @@ public class TestRunEntity implements Serializable { if (e.hasProperty(LOG_LINKS)) { links = (List) e.getProperty(LOG_LINKS); } - return new TestRunEntity(e.getKey().getParent(), type, startTimestamp, endTimestamp, - testBuildId, hostName, passCount, failCount, testCaseIds, links, - coveredLineCount, totalLineCount); + return new TestRunEntity( + e.getKey().getParent(), + type, + startTimestamp, + endTimestamp, + testBuildId, + hostName, + passCount, + failCount, + testCaseIds, + links, + coveredLineCount, + totalLineCount); } catch (ClassCastException exception) { // Invalid cast logger.log(Level.WARNING, "Error parsing test run entity.", exception); @@ -351,6 +372,32 @@ public class TestRunEntity implements Serializable { json.add(COVERED_LINE_COUNT, new JsonPrimitive(this.coveredLineCount)); json.add(TOTAL_LINE_COUNT, new JsonPrimitive(this.totalLineCount)); } + Optional> apiCoverageEntityOptionList = + this.getApiCoverageEntityList(); + if (apiCoverageEntityOptionList.isPresent()) { + List apiCoverageEntityList = apiCoverageEntityOptionList.get(); + Supplier> apiCoverageStreamSupplier = + () -> apiCoverageEntityList.stream(); + int totalHalApi = + apiCoverageStreamSupplier.get().mapToInt(data -> data.getHalApi().size()).sum(); + if (totalHalApi > 0) { + int coveredHalApi = + apiCoverageStreamSupplier + .get() + .mapToInt(data -> data.getCoveredHalApi().size()) + .sum(); + JsonArray apiCoverageKeyArray = + apiCoverageStreamSupplier + .get() + .map(data -> new JsonPrimitive(data.getUrlSafeKey())) + .collect(JsonArray::new, JsonArray::add, JsonArray::addAll); + + json.add(API_COVERAGE_KEY_LIST, apiCoverageKeyArray); + json.add(COVERED_API_COUNT, new JsonPrimitive(coveredHalApi)); + json.add(TOTAL_API_COUNT, new JsonPrimitive(totalHalApi)); + } + } + if (this.links != null && this.links.size() > 0) { List links = new ArrayList<>(); for (String rawUrl : this.links) { diff --git a/src/main/java/com/android/vts/entity/UserEntity.java b/src/main/java/com/android/vts/entity/UserEntity.java index 66216af..a686efb 100644 --- a/src/main/java/com/android/vts/entity/UserEntity.java +++ b/src/main/java/com/android/vts/entity/UserEntity.java @@ -60,7 +60,7 @@ public class UserEntity { @Load @Getter - List> roles; + List> roles = new ArrayList<>(); /** Constructor function for UserEntity Class */ public UserEntity( @@ -68,14 +68,14 @@ public class UserEntity { String name, String company, String roleName) { - RoleEntity role = ofy().load().type(RoleEntity.class).id(roleName).now(); this.email = email; this.name = name; this.enable = true; this.isAdmin = false; this.company = company; - this.roles.add(Ref.create(role)); + RoleEntity roleEntity = RoleEntity.getRole(roleName); + this.roles.add(Ref.create(roleEntity)); } /** Saving function for the instance of this class */ -- cgit v1.2.3