summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoung Gyu Park <younggyu@google.com>2018-08-27 10:41:32 -0700
committerandroid-build-merger <android-build-merger@google.com>2018-08-27 10:41:32 -0700
commitac4a8aa8842c7f149da6785583af48c9d5398eed (patch)
treefacd45ddac28910a417a2b3ea1bfa36e22ab3e73
parent7b05f79fddda31772792c1d1126606d84a188cfb (diff)
parent0e2ea7c3377e534801f9ab89ba3b33317b58b66a (diff)
downloaddashboard-ac4a8aa8842c7f149da6785583af48c9d5398eed.tar.gz
Implementing rest API for API coverage. am: 85586068d3
am: 0e2ea7c337 Change-Id: I953a2a07c862f6af3553e3f024779ce13bd70535
-rw-r--r--build.gradle5
-rw-r--r--src/main/java/com/android/vts/api/CoverageRestServlet.java194
-rw-r--r--src/main/java/com/android/vts/api/TestDataForDevServlet.java7
-rw-r--r--src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java6
-rw-r--r--src/main/java/com/android/vts/config/ObjectifyListener.java16
-rw-r--r--src/main/java/com/android/vts/entity/TestStatusEntity.java56
-rw-r--r--src/main/webapp/js/test_results.js2
-rw-r--r--src/test/java/com/android/vts/api/CoverageRestServletTest.java134
-rw-r--r--src/test/resources/config.properties2
-rwxr-xr-xsrc/test/resources/driver/chromedriver (renamed from src/test/res/driver/chromedriver)bin5503600 -> 5503600 bytes
-rw-r--r--src/test/resources/driver/config.properties (renamed from src/test/res/driver/config.properties)0
-rw-r--r--src/test/resources/servlet/performanceSummary1.html (renamed from src/test/res/servlet/performanceSummary1.html)0
-rw-r--r--src/test/resources/servlet/performanceSummary2.html (renamed from src/test/res/servlet/performanceSummary2.html)0
-rw-r--r--src/test/resources/servlet/performanceSummary3.html (renamed from src/test/res/servlet/performanceSummary3.html)0
-rw-r--r--src/test/resources/servlet/performanceSummary4.html (renamed from src/test/res/servlet/performanceSummary4.html)0
15 files changed, 344 insertions, 78 deletions
diff --git a/build.gradle b/build.gradle
index 6a5d039..279417b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -53,7 +53,7 @@ dependencies {
compile 'jstl:jstl:1.2'
- compile group: 'commons-lang', name: 'commons-lang', version:'2.6'
+ compile group: 'org.apache.commons', name: 'commons-lang3', version:'3.7'
compile group: 'org.apache.commons', name: 'commons-math3', version:'3.6.1'
compile group: 'commons-codec', name: 'commons-codec', version:'1.9'
compile group: 'com.google.cloud', name: 'google-cloud', version: "${googleCloudVersion}"
@@ -69,7 +69,8 @@ dependencies {
compile group: 'com.google.http-client', name: 'google-http-client-protobuf', version: "${googleHttpClientVersion}"
compile group: 'com.google.visualization', name: 'visualization-datasource', version:'1.1.1'
- testCompile group: 'junit', name: 'junit', version:'4.12'
+ testCompile group: 'junit', name: 'junit', version: '4.12'
+ testCompile group: 'org.mockito', name: 'mockito-core', version: '2.21.0'
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version:'5.0.3'
testCompile 'com.google.appengine:appengine-testing:+'
diff --git a/src/main/java/com/android/vts/api/CoverageRestServlet.java b/src/main/java/com/android/vts/api/CoverageRestServlet.java
index 460949e..b2bbe63 100644
--- a/src/main/java/com/android/vts/api/CoverageRestServlet.java
+++ b/src/main/java/com/android/vts/api/CoverageRestServlet.java
@@ -16,77 +16,161 @@
package com.android.vts.api;
+import com.android.vts.entity.ApiCoverageEntity;
import com.android.vts.entity.CoverageEntity;
import com.android.vts.entity.TestCoverageStatusEntity;
-import com.android.vts.entity.TestSuiteFileEntity;
-import com.android.vts.entity.TestSuiteResultEntity;
-import com.android.vts.proto.TestSuiteResultMessageProto.TestSuiteResultMessage;
-import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
-import com.google.api.client.http.javanet.NetHttpTransport;
-import com.google.api.client.json.jackson.JacksonFactory;
-import com.google.api.services.oauth2.Oauth2;
-import com.google.api.services.oauth2.model.Tokeninfo;
+import com.android.vts.entity.TestPlanRunEntity;
import com.google.gson.Gson;
import com.googlecode.objectify.Key;
-import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-import java.util.Properties;
+import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
-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 org.apache.commons.codec.binary.Base64;
-/**
- * REST endpoint for posting test suite data to the Dashboard.
- */
+import static com.googlecode.objectify.ObjectifyService.ofy;
+
+/** REST endpoint for posting test suite data to the Dashboard. */
public class CoverageRestServlet extends BaseApiServlet {
- private static final Logger logger =
- Logger.getLogger(CoverageRestServlet.class.getName());
+ private static final Logger logger = Logger.getLogger(CoverageRestServlet.class.getName());
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ String pathInfo = request.getPathInfo();
+ String json = "";
+ if (Objects.nonNull(pathInfo)) {
+ if (pathInfo.equalsIgnoreCase("/api/data")) {
+ String key = request.getParameter("key");
+ json = apiCoverageData(key);
+ } else {
+ json = "{error: 'true', message: 'unexpected path!!!'}";
+ logger.log(Level.INFO, "Path Info => " + pathInfo);
+ logger.log(Level.WARNING, "Unknown path access!");
+ }
+ } else {
+ json = "{error: 'true', message: 'the path info is not existed!!!'}";
+ }
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.setContentType("application/json");
+ response.setCharacterEncoding("UTF-8");
+ response.getWriter().write(json);
+ }
+
+ private String apiCoverageData(String key) {
+ ApiCoverageEntity apiCoverageEntity = ApiCoverageEntity.getByUrlSafeKey(key);
+ String apiCoverageEntityJson = new Gson().toJson(apiCoverageEntity);
+ return apiCoverageEntityJson;
+ }
+
+ @Override
+ public void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+
+ String pathInfo = request.getPathInfo();
+ String json = "";
+ if (Objects.nonNull(pathInfo)) {
+ if (pathInfo.equalsIgnoreCase("/api/data")) {
+ String cmd = request.getParameter("cmd");
+ String coverageId = request.getParameter("coverageId");
+ String testName = request.getParameter("testName");
+ String testRunId = request.getParameter("testRunId");
+ json = postCoverageData(cmd, coverageId, testName, testRunId);
+ } else if (pathInfo.equalsIgnoreCase("/api/sum")) {
+ String urlSafeKey = request.getParameter("urlSafeKey");
+ json = postCoverageDataSum(urlSafeKey);
+ } else {
+ json = "{error: 'true', message: 'unexpected path!!!'}";
+ }
+ } else {
+ json = "{error: 'true', message: 'the path info is not existed!!!'}";
+ }
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.setContentType("application/json");
+ response.setCharacterEncoding("UTF-8");
+ response.getWriter().write(json);
+ }
+
+ private String postCoverageDataSum(String urlSafeKey) {
+ List<List<String>> allHalApiList = new ArrayList();
+ List<List<String>> allCoveredHalApiList = new ArrayList();
+
+ Key<TestPlanRunEntity> key = Key.create(urlSafeKey);
+ TestPlanRunEntity testPlanRunEntity = ofy().load().key(key).now();
+
+ for (Key testRunKey : testPlanRunEntity.getTestRuns()) {
+ List<ApiCoverageEntity> apiCoverageEntityList =
+ ofy().load().type(ApiCoverageEntity.class).ancestor(testRunKey).list();
+ for (ApiCoverageEntity apiCoverageEntity : apiCoverageEntityList) {
+ allHalApiList.add(apiCoverageEntity.getHalApi());
+ allCoveredHalApiList.add(apiCoverageEntity.getCoveredHalApi());
+ }
+ }
+ long totalHalApiNum = allHalApiList.stream().flatMap(Collection::stream).distinct().count();
+ long totalCoveredHalApiNum =
+ allCoveredHalApiList.stream().flatMap(Collection::stream).distinct().count();
+ testPlanRunEntity.setTotalApiCount(totalHalApiNum);
+ testPlanRunEntity.setCoveredApiCount(totalCoveredHalApiNum);
+ testPlanRunEntity.save();
+
+ Map<String, Long> halApiNumMap =
+ new HashMap<String, Long>() {
+ {
+ put("totalHalApiNum", totalHalApiNum);
+ put("totalCoveredHalApiNum", totalCoveredHalApiNum);
+ }
+ };
+ String json = new Gson().toJson(halApiNumMap);
+ return json;
+ }
+
+ /**
+ * The API to ignore the irrelevant code for calculating ratio
+ *
+ * @param cmd disable or enable command to ignore the code.
+ * @param coverageId the datastore ID for code coverage.
+ * @param testName the test name.
+ * @param testRunId the test run ID from datastore.
+ * @return success json.
+ */
+ private String postCoverageData(
+ String cmd, String coverageId, String testName, String testRunId) {
- @Override
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
+ Boolean isIgnored = false;
+ if (cmd.equals("disable")) {
+ isIgnored = true;
+ }
+ CoverageEntity coverageEntity = CoverageEntity.findById(testName, testRunId, coverageId);
+ coverageEntity.setIsIgnored(isIgnored);
+ coverageEntity.save();
- String cmd = request.getParameter("cmd");
- String coverageId = request.getParameter("coverageId");
- String testName = request.getParameter("testName");
- String testRunId = request.getParameter("testRunId");
+ TestCoverageStatusEntity testCoverageStatusEntity =
+ TestCoverageStatusEntity.findById(testName);
+ Long newCoveredLineCount =
+ cmd.equals("disable")
+ ? testCoverageStatusEntity.getUpdatedCoveredLineCount()
+ - coverageEntity.getCoveredCount()
+ : testCoverageStatusEntity.getUpdatedCoveredLineCount()
+ + coverageEntity.getCoveredCount();
+ Long newTotalLineCount =
+ cmd.equals("disable")
+ ? testCoverageStatusEntity.getUpdatedTotalLineCount()
+ - coverageEntity.getTotalCount()
+ : testCoverageStatusEntity.getUpdatedTotalLineCount()
+ + coverageEntity.getTotalCount();
+ testCoverageStatusEntity.setUpdatedCoveredLineCount(newCoveredLineCount);
+ testCoverageStatusEntity.setUpdatedTotalLineCount(newTotalLineCount);
+ testCoverageStatusEntity.save();
- Boolean isIgnored = false;
- if (cmd.equals("disable")) {
- isIgnored = true;
+ String json = new Gson().toJson("Success!");
+ return json;
}
- CoverageEntity coverageEntity = CoverageEntity.findById(testName, testRunId, coverageId);
- coverageEntity.setIsIgnored(isIgnored);
- coverageEntity.save();
-
- TestCoverageStatusEntity testCoverageStatusEntity = TestCoverageStatusEntity.findById(testName);
- Long newCoveredLineCount =
- cmd.equals("disable") ? testCoverageStatusEntity.getUpdatedCoveredLineCount()
- - coverageEntity.getCoveredCount()
- : testCoverageStatusEntity.getUpdatedCoveredLineCount() + coverageEntity
- .getCoveredCount();
- Long newTotalLineCount =
- cmd.equals("disable") ? testCoverageStatusEntity.getUpdatedTotalLineCount() - coverageEntity
- .getTotalCount()
- : testCoverageStatusEntity.getUpdatedTotalLineCount() + coverageEntity.getTotalCount();
- testCoverageStatusEntity.setUpdatedCoveredLineCount(newCoveredLineCount);
- testCoverageStatusEntity.setUpdatedTotalLineCount(newTotalLineCount);
- testCoverageStatusEntity.save();
-
- String json = new Gson().toJson("Success!");
- response.setStatus(HttpServletResponse.SC_OK);
- response.setContentType("application/json");
- response.setCharacterEncoding("UTF-8");
- response.getWriter().write(json);
- }
}
diff --git a/src/main/java/com/android/vts/api/TestDataForDevServlet.java b/src/main/java/com/android/vts/api/TestDataForDevServlet.java
index 70aa74a..a265b81 100644
--- a/src/main/java/com/android/vts/api/TestDataForDevServlet.java
+++ b/src/main/java/com/android/vts/api/TestDataForDevServlet.java
@@ -278,7 +278,6 @@ public class TestDataForDevServlet extends HttpServlet {
new TestSuiteFileEntity(
pathInfo
.toString());
- newTestSuiteFileEntity.save();
com.googlecode.objectify.Key<
TestSuiteFileEntity>
@@ -289,6 +288,8 @@ public class TestDataForDevServlet extends HttpServlet {
.class,
newTestSuiteFileEntity
.getFilePath());
+
+
TestSuiteResultEntity
testSuiteResultEntity =
new TestSuiteResultEntity(
@@ -342,7 +343,7 @@ public class TestDataForDevServlet extends HttpServlet {
rand.nextInt(),
rand.nextInt());
- testSuiteResultEntity.save();
+ testSuiteResultEntity.save(newTestSuiteFileEntity);
})));
resultMap.put("result", "successfully generated!");
return resultMap;
@@ -626,6 +627,8 @@ public class TestDataForDevServlet extends HttpServlet {
testBuildId,
passCount,
failCount,
+ 0L,
+ 0L,
testRunKeys);
// Create the device infos.
diff --git a/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java b/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java
index 8f52c85..4f2d52e 100644
--- a/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java
+++ b/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java
@@ -88,8 +88,10 @@ public class TestSuiteResultRestServlet extends BaseApiServlet {
Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute();
if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) {
+ String filePath = "suite_result/2019/04/06/132343.bin";
Key<TestSuiteFileEntity> testSuiteFileParent =
- Key.create(TestSuiteFileEntity.class, "suite_result/2019/04/06/132343.bin");
+ Key.create(TestSuiteFileEntity.class, filePath);
+ TestSuiteFileEntity newTestSuiteFileEntity = new TestSuiteFileEntity(filePath);
TestSuiteResultEntity testSuiteResultEntity =
new TestSuiteResultEntity(
testSuiteFileParent,
@@ -114,7 +116,7 @@ public class TestSuiteResultRestServlet extends BaseApiServlet {
testSuiteResultMessage.getPassedTestCaseCount(),
testSuiteResultMessage.getFailedTestCaseCount());
- testSuiteResultEntity.save();
+ testSuiteResultEntity.save(newTestSuiteFileEntity);
resultMap.put("result", "successfully saved!");
} else {
logger.log(Level.WARNING, "service_client_id didn't match!");
diff --git a/src/main/java/com/android/vts/config/ObjectifyListener.java b/src/main/java/com/android/vts/config/ObjectifyListener.java
index a78fd66..2c73e1f 100644
--- a/src/main/java/com/android/vts/config/ObjectifyListener.java
+++ b/src/main/java/com/android/vts/config/ObjectifyListener.java
@@ -16,13 +16,20 @@
package com.android.vts.config;
+import com.android.vts.entity.ApiCoverageEntity;
import com.android.vts.entity.CoverageEntity;
+import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.ProfilingPointEntity;
+import com.android.vts.entity.ProfilingPointRunEntity;
+import com.android.vts.entity.ProfilingPointSummaryEntity;
import com.android.vts.entity.RoleEntity;
+import com.android.vts.entity.TestCaseRunEntity;
import com.android.vts.entity.TestCoverageStatusEntity;
import com.android.vts.entity.TestEntity;
import com.android.vts.entity.TestPlanEntity;
import com.android.vts.entity.TestPlanRunEntity;
import com.android.vts.entity.TestRunEntity;
+import com.android.vts.entity.TestStatusEntity;
import com.android.vts.entity.TestSuiteFileEntity;
import com.android.vts.entity.TestSuiteResultEntity;
import com.android.vts.entity.UserEntity;
@@ -66,12 +73,21 @@ public class ObjectifyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
ObjectifyService.init();
+ ObjectifyService.register(ApiCoverageEntity.class);
ObjectifyService.register(CoverageEntity.class);
+ ObjectifyService.register(DeviceInfoEntity.class);
ObjectifyService.register(TestCoverageStatusEntity.class);
+
+ ObjectifyService.register(ProfilingPointEntity.class);
+ ObjectifyService.register(ProfilingPointRunEntity.class);
+ ObjectifyService.register(ProfilingPointSummaryEntity.class);
+
ObjectifyService.register(TestEntity.class);
ObjectifyService.register(TestPlanEntity.class);
ObjectifyService.register(TestPlanRunEntity.class);
ObjectifyService.register(TestRunEntity.class);
+ ObjectifyService.register(TestCaseRunEntity.class);
+ ObjectifyService.register(TestStatusEntity.class);
ObjectifyService.register(TestSuiteFileEntity.class);
ObjectifyService.register(TestSuiteResultEntity.class);
ObjectifyService.register(RoleEntity.class);
diff --git a/src/main/java/com/android/vts/entity/TestStatusEntity.java b/src/main/java/com/android/vts/entity/TestStatusEntity.java
index 9464352..ec5ee36 100644
--- a/src/main/java/com/android/vts/entity/TestStatusEntity.java
+++ b/src/main/java/com/android/vts/entity/TestStatusEntity.java
@@ -18,13 +18,24 @@ package com.android.vts.entity;
import com.android.vts.entity.TestCaseRunEntity.TestCase;
import com.google.appengine.api.datastore.Entity;
+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;
import java.util.logging.Logger;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+@com.googlecode.objectify.annotation.Entity(name = "TestStatus")
+@Cache
+@Data
+@NoArgsConstructor
/** Entity describing test status. */
-public class TestStatusEntity implements DashboardEntity {
+public class TestStatusEntity implements Serializable {
protected static final Logger logger = Logger.getLogger(TestStatusEntity.class.getName());
public static final String KIND = "TestStatus";
@@ -37,11 +48,25 @@ public class TestStatusEntity implements DashboardEntity {
protected static final String FAILING_IDS = "failingTestcaseIds";
protected static final String FAILING_OFFSETS = "failingTestcaseOffsets";
- public final String testName;
- public final int passCount;
- public final int failCount;
- public final long timestamp;
- public final List<TestCaseReference> failingTestCases;
+ /** ID field */
+ @Id private String testName;
+
+ /** Failing Testcase ID List field */
+ private List<Long> failingTestcaseIds;
+
+ /** Failing Testcase Offsets List field */
+ private List<Integer> failingTestcaseOffsets;
+
+ /** pass count field */
+ @Index private int passCount;
+
+ /** fail count field */
+ @Index private int failCount;
+
+ /** updated timestamp field */
+ @Index private long updatedTimestamp;
+
+ @Ignore private List<TestCaseReference> failingTestCases;
/** Object representing a reference to a test case. */
public static class TestCaseReference {
@@ -79,13 +104,13 @@ public class TestStatusEntity implements DashboardEntity {
* @param failingTestCases The TestCaseReferences of the last observed failing test cases.
*/
public TestStatusEntity(
- String testName,
- long timestamp,
- int passCount,
- int failCount,
- List<TestCaseReference> failingTestCases) {
+ String testName,
+ long timestamp,
+ int passCount,
+ int failCount,
+ List<TestCaseReference> failingTestCases) {
this.testName = testName;
- this.timestamp = timestamp;
+ this.updatedTimestamp = timestamp;
this.passCount = passCount;
this.failCount = failCount;
this.failingTestCases = failingTestCases;
@@ -100,11 +125,10 @@ public class TestStatusEntity implements DashboardEntity {
this(testName, 0, -1, -1, new ArrayList<TestCaseReference>());
}
- @Override
public Entity toEntity() {
Entity testEntity = new Entity(KIND, this.testName);
- if (this.timestamp >= 0 && this.passCount >= 0 && this.failCount >= 0) {
- testEntity.setProperty(UPDATED_TIMESTAMP, this.timestamp);
+ if (this.updatedTimestamp >= 0 && this.passCount >= 0 && this.failCount >= 0) {
+ testEntity.setProperty(UPDATED_TIMESTAMP, this.updatedTimestamp);
testEntity.setProperty(PASS_COUNT, this.passCount);
testEntity.setProperty(FAIL_COUNT, this.failCount);
if (this.failingTestCases.size() > 0) {
@@ -154,7 +178,7 @@ public class TestStatusEntity implements DashboardEntity {
if (ids.size() == offsets.size()) {
for (int i = 0; i < ids.size(); i++) {
failingTestCases.add(
- new TestCaseReference(ids.get(i), offsets.get(i).intValue()));
+ new TestCaseReference(ids.get(i), offsets.get(i).intValue()));
}
}
}
diff --git a/src/main/webapp/js/test_results.js b/src/main/webapp/js/test_results.js
index e00d6ac..45c1de4 100644
--- a/src/main/webapp/js/test_results.js
+++ b/src/main/webapp/js/test_results.js
@@ -264,7 +264,7 @@
var total = metadata.testRun.totalApiCount;
var apiCoverage = ('API Coverage: ' + covered + '/' + total);
createClickableIndicator(
- div, apiCoverage, 'yellow grey-text',
+ div, apiCoverage, 'orange',
function (evt) {
$('#apiCoverageModal').data("urlSafeKeyList", metadata.testRun.apiCoverageKeyList);
$('#apiCoverageModal').modal('open');
diff --git a/src/test/java/com/android/vts/api/CoverageRestServletTest.java b/src/test/java/com/android/vts/api/CoverageRestServletTest.java
new file mode 100644
index 0000000..ed3d0d2
--- /dev/null
+++ b/src/test/java/com/android/vts/api/CoverageRestServletTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+import static com.googlecode.objectify.ObjectifyService.factory;
+
+import com.android.vts.entity.ApiCoverageEntity;
+import com.android.vts.util.ObjectifyTestBase;
+import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
+import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
+import com.google.cloud.datastore.Datastore;
+import com.google.cloud.datastore.DatastoreOptions;
+import com.google.gson.Gson;
+import com.google.gson.internal.LinkedTreeMap;
+import com.googlecode.objectify.ObjectifyFactory;
+import com.googlecode.objectify.ObjectifyService;
+import com.googlecode.objectify.util.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import java.util.Arrays;
+import java.util.Properties;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class CoverageRestServletTest extends ObjectifyTestBase {
+
+ private final LocalServiceTestHelper helper =
+ new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
+
+ protected Closeable session;
+
+ private Gson gson;
+
+ @Mock HttpServletRequest request;
+
+ @Mock HttpServletResponse response;
+
+ @BeforeClass
+ public static void setUpBeforeClass() {}
+
+ @Before
+ public void setUp() throws Exception {
+ InputStream configIs =
+ this.getClass().getClassLoader().getResourceAsStream("config.properties");
+
+ Properties prop = new Properties();
+ prop.load(configIs);
+
+ gson = new Gson();
+
+ MockitoAnnotations.initMocks(this);
+
+ this.helper.setUp();
+
+ Datastore datastore =
+ DatastoreOptions.newBuilder()
+ .setProjectId(prop.getProperty("testProjectID"))
+ .build()
+ .getService();
+
+ ObjectifyService.init(new ObjectifyFactory(datastore));
+ ObjectifyService.register(ApiCoverageEntity.class);
+ ObjectifyService.begin();
+
+ this.session = ObjectifyService.begin();
+ }
+
+ @After
+ public void tearDown() {
+ this.session.close();
+ this.helper.tearDown();
+ }
+
+ @Test
+ public void testApiData() throws IOException, ServletException {
+
+ factory().register(ApiCoverageEntity.class);
+
+ when(request.getPathInfo()).thenReturn("/api/data");
+
+ String key =
+ "partition_id+%7B%0A++project_id%3A+%22android-vts-staging%22%0A%7D%0Apath+%7B%0A"
+ + "++kind%3A+%22Test%22%0A++name%3A+%22VtsHalGraphicsMapperV2_0TargetProfiling"
+ + "%22%0A%7D%0Apath+%7B%0A++kind%3A+%22TestRun%22%0A++id%3A+1534552828906226%0A%7D%0A"
+ + "path+%7B%0A++kind%3A+%22ApiCoverage%22%0A"
+ + "++name%3A+%221f529291-f1c3-4d9b-ba60-48525fe7c376%22%0A%7D%0A";
+ when(request.getParameter("key")).thenReturn(key);
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+
+ when(response.getWriter()).thenReturn(pw);
+
+ CoverageRestServlet coverageRestServlet = new CoverageRestServlet();
+ coverageRestServlet.doGet(request, response);
+ String result = sw.getBuffer().toString().trim();
+
+ LinkedTreeMap resultMap = gson.fromJson(result, LinkedTreeMap.class);
+
+ assertEquals(resultMap.get("id"), "1f529291-f1c3-4d9b-ba60-48525fe7c376");
+ assertEquals(resultMap.get("halInterfaceName"), "IAllocator");
+ assertEquals(resultMap.get("halPackageName"), "android.hardware.graphics.allocator");
+ assertEquals(resultMap.get("halApi"), Arrays.asList("allocate", "dumpDebugInfo"));
+ assertEquals(resultMap.get("coveredHalApi"), Arrays.asList("allocate", "dumpDebugInfo"));
+
+ }
+}
diff --git a/src/test/resources/config.properties b/src/test/resources/config.properties
new file mode 100644
index 0000000..745065b
--- /dev/null
+++ b/src/test/resources/config.properties
@@ -0,0 +1,2 @@
+
+testProjectID= \ No newline at end of file
diff --git a/src/test/res/driver/chromedriver b/src/test/resources/driver/chromedriver
index bbb06c3..bbb06c3 100755
--- a/src/test/res/driver/chromedriver
+++ b/src/test/resources/driver/chromedriver
Binary files differ
diff --git a/src/test/res/driver/config.properties b/src/test/resources/driver/config.properties
index 939fa90..939fa90 100644
--- a/src/test/res/driver/config.properties
+++ b/src/test/resources/driver/config.properties
diff --git a/src/test/res/servlet/performanceSummary1.html b/src/test/resources/servlet/performanceSummary1.html
index 3b01593..3b01593 100644
--- a/src/test/res/servlet/performanceSummary1.html
+++ b/src/test/resources/servlet/performanceSummary1.html
diff --git a/src/test/res/servlet/performanceSummary2.html b/src/test/resources/servlet/performanceSummary2.html
index 3b01593..3b01593 100644
--- a/src/test/res/servlet/performanceSummary2.html
+++ b/src/test/resources/servlet/performanceSummary2.html
diff --git a/src/test/res/servlet/performanceSummary3.html b/src/test/resources/servlet/performanceSummary3.html
index 1ff1028..1ff1028 100644
--- a/src/test/res/servlet/performanceSummary3.html
+++ b/src/test/resources/servlet/performanceSummary3.html
diff --git a/src/test/res/servlet/performanceSummary4.html b/src/test/resources/servlet/performanceSummary4.html
index 8fc8997..8fc8997 100644
--- a/src/test/res/servlet/performanceSummary4.html
+++ b/src/test/resources/servlet/performanceSummary4.html