1 /* 2 * Copyright (c) 2018 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.ApiCoverageEntity; 20 import com.android.vts.entity.CoverageEntity; 21 import com.android.vts.entity.TestCoverageStatusEntity; 22 import com.android.vts.entity.TestPlanRunEntity; 23 import com.android.vts.entity.TestRunEntity; 24 import com.google.gson.Gson; 25 import com.googlecode.objectify.Key; 26 27 import java.io.IOException; 28 import java.util.ArrayList; 29 import java.util.Collection; 30 import java.util.HashMap; 31 import java.util.List; 32 import java.util.Map; 33 import java.util.Objects; 34 import java.util.logging.Level; 35 import java.util.logging.Logger; 36 import javax.servlet.http.HttpServletRequest; 37 import javax.servlet.http.HttpServletResponse; 38 39 import static com.googlecode.objectify.ObjectifyService.ofy; 40 41 /** REST endpoint for posting test suite data to the Dashboard. */ 42 public class CoverageRestServlet extends BaseApiServlet { 43 44 private static final Logger logger = Logger.getLogger(CoverageRestServlet.class.getName()); 45 46 @Override doGet(HttpServletRequest request, HttpServletResponse response)47 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { 48 String pathInfo = request.getPathInfo(); 49 String json = ""; 50 if (Objects.nonNull(pathInfo)) { 51 if (pathInfo.equalsIgnoreCase("/api/data")) { 52 String key = request.getParameter("key"); 53 json = apiCoverageData(key); 54 } else { 55 json = "{error: 'true', message: 'unexpected path!!!'}"; 56 logger.log(Level.INFO, "Path Info => " + pathInfo); 57 logger.log(Level.WARNING, "Unknown path access!"); 58 } 59 } else { 60 json = "{error: 'true', message: 'the path info is not existed!!!'}"; 61 } 62 63 response.setStatus(HttpServletResponse.SC_OK); 64 response.setContentType("application/json"); 65 response.setCharacterEncoding("UTF-8"); 66 response.getWriter().write(json); 67 } 68 apiCoverageData(String key)69 private String apiCoverageData(String key) { 70 ApiCoverageEntity apiCoverageEntity = ApiCoverageEntity.getByUrlSafeKey(key); 71 String apiCoverageEntityJson = new Gson().toJson(apiCoverageEntity); 72 return apiCoverageEntityJson; 73 } 74 75 @Override doPost(HttpServletRequest request, HttpServletResponse response)76 public void doPost(HttpServletRequest request, HttpServletResponse response) 77 throws IOException { 78 79 String pathInfo = request.getPathInfo(); 80 String json = ""; 81 if (Objects.nonNull(pathInfo)) { 82 if (pathInfo.equalsIgnoreCase("/api/data")) { 83 String cmd = request.getParameter("cmd"); 84 String coverageId = request.getParameter("coverageId"); 85 String testName = request.getParameter("testName"); 86 String testRunId = request.getParameter("testRunId"); 87 json = postCoverageData(cmd, coverageId, testName, testRunId); 88 } else if (pathInfo.equalsIgnoreCase("/api/sum")) { 89 String urlSafeKey = request.getParameter("urlSafeKey"); 90 json = postCoverageDataSum(urlSafeKey); 91 } else { 92 json = "{error: 'true', message: 'unexpected path!!!'}"; 93 } 94 } else { 95 json = "{error: 'true', message: 'the path info is not existed!!!'}"; 96 } 97 98 response.setStatus(HttpServletResponse.SC_OK); 99 response.setContentType("application/json"); 100 response.setCharacterEncoding("UTF-8"); 101 response.getWriter().write(json); 102 } 103 postCoverageDataSum(String urlSafeKey)104 private String postCoverageDataSum(String urlSafeKey) { 105 List<List<String>> allHalApiList = new ArrayList(); 106 List<List<String>> allCoveredHalApiList = new ArrayList(); 107 108 Key<TestPlanRunEntity> key = Key.create(urlSafeKey); 109 TestPlanRunEntity testPlanRunEntity = ofy().load().key(key).safe(); 110 111 for (Key<TestRunEntity> testRunKey : testPlanRunEntity.getTestRuns()) { 112 List<ApiCoverageEntity> apiCoverageEntityList = 113 ofy().load().type(ApiCoverageEntity.class).ancestor(testRunKey).list(); 114 for (ApiCoverageEntity apiCoverageEntity : apiCoverageEntityList) { 115 allHalApiList.add(apiCoverageEntity.getHalApi()); 116 allCoveredHalApiList.add(apiCoverageEntity.getCoveredHalApi()); 117 } 118 } 119 long totalHalApiNum = allHalApiList.stream().flatMap(Collection::stream).distinct().count(); 120 long totalCoveredHalApiNum = 121 allCoveredHalApiList.stream().flatMap(Collection::stream).distinct().count(); 122 if (totalHalApiNum > 0) { 123 testPlanRunEntity.setTotalApiCount(totalHalApiNum); 124 if (totalCoveredHalApiNum > 0) { 125 testPlanRunEntity.setCoveredApiCount(totalCoveredHalApiNum); 126 } 127 testPlanRunEntity.save(); 128 } 129 130 Map<String, Long> halApiNumMap = 131 new HashMap<String, Long>() { 132 { 133 put("totalHalApiNum", totalHalApiNum); 134 put("totalCoveredHalApiNum", totalCoveredHalApiNum); 135 } 136 }; 137 String json = new Gson().toJson(halApiNumMap); 138 return json; 139 } 140 141 /** 142 * The API to ignore the irrelevant code for calculating ratio 143 * 144 * @param cmd disable or enable command to ignore the code. 145 * @param coverageId the datastore ID for code coverage. 146 * @param testName the test name. 147 * @param testRunId the test run ID from datastore. 148 * @return success json. 149 */ postCoverageData( String cmd, String coverageId, String testName, String testRunId)150 private String postCoverageData( 151 String cmd, String coverageId, String testName, String testRunId) { 152 153 Boolean isIgnored = false; 154 if (cmd.equals("disable")) { 155 isIgnored = true; 156 } 157 CoverageEntity coverageEntity = CoverageEntity.findById(testName, testRunId, coverageId); 158 coverageEntity.setIsIgnored(isIgnored); 159 coverageEntity.save(); 160 161 TestCoverageStatusEntity testCoverageStatusEntity = 162 TestCoverageStatusEntity.findById(testName); 163 Long newCoveredLineCount = 164 cmd.equals("disable") 165 ? testCoverageStatusEntity.getUpdatedCoveredLineCount() 166 - coverageEntity.getCoveredCount() 167 : testCoverageStatusEntity.getUpdatedCoveredLineCount() 168 + coverageEntity.getCoveredCount(); 169 Long newTotalLineCount = 170 cmd.equals("disable") 171 ? testCoverageStatusEntity.getUpdatedTotalLineCount() 172 - coverageEntity.getTotalCount() 173 : testCoverageStatusEntity.getUpdatedTotalLineCount() 174 + coverageEntity.getTotalCount(); 175 testCoverageStatusEntity.setUpdatedCoveredLineCount(newCoveredLineCount); 176 testCoverageStatusEntity.setUpdatedTotalLineCount(newTotalLineCount); 177 testCoverageStatusEntity.save(); 178 179 String json = new Gson().toJson("Success!"); 180 return json; 181 } 182 } 183