1 /* 2 * Copyright (c) 2017 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you 5 * may not use this file except in compliance with the License. You may 6 * obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 * implied. See the License for the specific language governing 14 * permissions and limitations under the License. 15 */ 16 17 package com.android.vts.api; 18 19 import com.android.vts.entity.TestCaseRunEntity; 20 import com.android.vts.entity.TestEntity; 21 import com.android.vts.entity.TestRunEntity; 22 import com.android.vts.util.TestRunDetails; 23 import com.google.gson.Gson; 24 import java.io.IOException; 25 import java.io.PrintWriter; 26 import java.util.ArrayList; 27 import java.util.List; 28 import java.util.Map; 29 import java.util.Objects; 30 import java.util.logging.Logger; 31 import javax.servlet.http.HttpServletRequest; 32 import javax.servlet.http.HttpServletResponse; 33 34 import static com.googlecode.objectify.ObjectifyService.ofy; 35 36 /** Servlet for handling requests to fetch test case results. */ 37 public class TestRunRestServlet extends BaseApiServlet { 38 private static final String LATEST = "latest"; 39 protected static final Logger logger = Logger.getLogger(TestRunRestServlet.class.getName()); 40 41 /** 42 * Get the test case results for the specified run of the specified test. 43 * 44 * @param test The test whose test cases to get. 45 * @param timeString The string representation of the test run timestamp (in microseconds). 46 * @return A TestRunDetails object with the test case details for the specified run. 47 */ getTestRunDetails(String test, String timeString)48 private TestRunDetails getTestRunDetails(String test, String timeString) { 49 long timestamp; 50 try { 51 timestamp = Long.parseLong(timeString); 52 if (timestamp <= 0) throw new NumberFormatException(); 53 timestamp = timestamp > 0 ? timestamp : null; 54 } catch (NumberFormatException e) { 55 return null; 56 } 57 58 TestRunEntity testRunEntity = TestRunEntity.getByTestNameId(test, timestamp); 59 60 return getTestRunDetails(testRunEntity); 61 } 62 63 /** 64 * Get the test case results for the latest run of the specified test. 65 * 66 * @param testName The test whose test cases to get. 67 * @return A TestRunDetails object with the test case details for the latest run. 68 */ getLatestTestRunDetails(String testName)69 private TestRunDetails getLatestTestRunDetails(String testName) { 70 com.googlecode.objectify.Key testKey = 71 com.googlecode.objectify.Key.create( 72 TestEntity.class, testName); 73 74 TestRunEntity testRun = ofy().load().type(TestRunEntity.class).ancestor(testKey) 75 .filter("type", 2).orderKey(true).first().now(); 76 77 if (testRun == null) return null; 78 79 return getTestRunDetails(testRun); 80 } 81 82 /** 83 * Get TestRunDetails instance from codeCoverageEntity instance. 84 * 85 * @param testRunEntity The TestRunEntity to access testCaseId. 86 * @return A TestRunDetails object with the test case details for the latest run. 87 */ getTestRunDetails(TestRunEntity testRunEntity)88 private TestRunDetails getTestRunDetails(TestRunEntity testRunEntity) { 89 TestRunDetails details = new TestRunDetails(); 90 List<com.googlecode.objectify.Key<TestCaseRunEntity>> testCaseKeyList = new ArrayList<>(); 91 if ( Objects.isNull(testRunEntity.getTestCaseIds()) ) { 92 return details; 93 } else { 94 for (long testCaseId : testRunEntity.getTestCaseIds()) { 95 testCaseKeyList.add( 96 com.googlecode.objectify.Key.create(TestCaseRunEntity.class, testCaseId)); 97 } 98 Map<com.googlecode.objectify.Key<TestCaseRunEntity>, TestCaseRunEntity> 99 testCaseRunEntityKeyMap = ofy().load().keys(() -> testCaseKeyList.iterator()); 100 testCaseRunEntityKeyMap.forEach((key, value) -> details.addTestCase(value)); 101 } 102 return details; 103 } 104 105 /** 106 * Get the test case details for a test run. 107 * 108 * Expected format: (1) /api/test_run?test=[test name]×tamp=[timestamp] to the details 109 * for a specific run, or (2) /api/test_run?test=[test name]×tamp=latest -- the details for 110 * the latest test run. 111 */ 112 @Override doGet(HttpServletRequest request, HttpServletResponse response)113 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { 114 String test = request.getParameter("test"); 115 String timeString = request.getParameter("timestamp"); 116 TestRunDetails details = null; 117 118 if (timeString != null && timeString.equals(LATEST)) { 119 details = getLatestTestRunDetails(test); 120 } else if (timeString != null) { 121 details = getTestRunDetails(test, timeString); 122 } 123 124 if (details == null) { 125 response.setStatus(HttpServletResponse.SC_BAD_REQUEST); 126 } else { 127 response.setStatus(HttpServletResponse.SC_OK); 128 response.setContentType("application/json"); 129 PrintWriter writer = response.getWriter(); 130 writer.print(new Gson().toJson(details.toJson())); 131 writer.flush(); 132 } 133 } 134 } 135