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.entity; 18 19 import com.google.appengine.api.datastore.Entity; 20 import com.google.appengine.api.datastore.Key; 21 import com.google.appengine.api.datastore.KeyFactory; 22 import java.util.List; 23 import java.util.logging.Level; 24 import java.util.logging.Logger; 25 26 /** Entity describing test run information. */ 27 public class TestRunEntity implements DashboardEntity { 28 protected static final Logger logger = Logger.getLogger(TestRunEntity.class.getName()); 29 30 /** Enum for classifying test run types. */ 31 public enum TestRunType { 32 OTHER(0), 33 PRESUBMIT(1), 34 POSTSUBMIT(2); 35 36 private final int value; 37 TestRunType(int value)38 private TestRunType(int value) { 39 this.value = value; 40 } 41 42 /** 43 * Get the ordinal representation of the type. 44 * 45 * @return The value associated with the test run type. 46 */ getNumber()47 public int getNumber() { 48 return value; 49 } 50 51 /** 52 * Convert an ordinal value to a TestRunType. 53 * 54 * @param value The orginal value to parse. 55 * @return a TestRunType value. 56 */ fromNumber(int value)57 public static TestRunType fromNumber(int value) { 58 if (value == 1) { 59 return TestRunType.PRESUBMIT; 60 } else if (value == 2) { 61 return TestRunType.POSTSUBMIT; 62 } else { 63 return TestRunType.OTHER; 64 } 65 } 66 } 67 68 public static final String KIND = "TestRun"; 69 70 // Property keys 71 public static final String TYPE = "type"; 72 public static final String START_TIMESTAMP = "startTimestamp"; 73 public static final String END_TIMESTAMP = "endTimestamp"; 74 public static final String TEST_BUILD_ID = "testBuildId"; 75 public static final String HOST_NAME = "hostName"; 76 public static final String PASS_COUNT = "passCount"; 77 public static final String FAIL_COUNT = "failCount"; 78 public static final String TEST_CASE_IDS = "testCaseIds"; 79 public static final String LOG_LINKS = "logLinks"; 80 public static final String TOTAL_LINE_COUNT = "totalLineCount"; 81 public static final String COVERED_LINE_COUNT = "coveredLineCount"; 82 83 public final Key key; 84 public final TestRunType type; 85 public final long startTimestamp; 86 public final long endTimestamp; 87 public final String testBuildId; 88 public final String hostName; 89 public final long passCount; 90 public final long failCount; 91 public final long coveredLineCount; 92 public final long totalLineCount; 93 public final List<Long> testCaseIds; 94 public final List<String> logLinks; 95 96 /** 97 * Create a TestRunEntity object describing a test run. 98 * 99 * @param parentKey The key to the parent TestEntity. 100 * @param type The test run type (e.g. presubmit, postsubmit, other) 101 * @param startTimestamp The time in microseconds when the test run started. 102 * @param endTimestamp The time in microseconds when the test run ended. 103 * @param testBuildId The build ID of the VTS test build. 104 * @param hostName The name of host machine. 105 * @param passCount The number of passing test cases in the run. 106 * @param failCount The number of failing test cases in the run. 107 * @param testCaseIds A list of key IDs to the TestCaseRunEntity objects for the test run. 108 * @param logLinks A list of links to log files for the test run, or null if there aren't any. 109 * @param coveredLineCount The number of lines covered by the test run. 110 * @param totalLineCount The total number of executable lines by the test in the test run. 111 */ TestRunEntity(Key parentKey, TestRunType type, long startTimestamp, long endTimestamp, String testBuildId, String hostName, long passCount, long failCount, List<Long> testCaseIds, List<String> logLinks, long coveredLineCount, long totalLineCount)112 public TestRunEntity(Key parentKey, TestRunType type, long startTimestamp, long endTimestamp, 113 String testBuildId, String hostName, long passCount, long failCount, 114 List<Long> testCaseIds, List<String> logLinks, long coveredLineCount, 115 long totalLineCount) { 116 this.key = KeyFactory.createKey(parentKey, KIND, startTimestamp); 117 this.type = type; 118 this.startTimestamp = startTimestamp; 119 this.endTimestamp = endTimestamp; 120 this.testBuildId = testBuildId; 121 this.hostName = hostName; 122 this.passCount = passCount; 123 this.failCount = failCount; 124 this.testCaseIds = testCaseIds; 125 this.logLinks = logLinks; 126 this.coveredLineCount = coveredLineCount; 127 this.totalLineCount = totalLineCount; 128 } 129 130 /** 131 * Create a TestRunEntity object describing a test run. 132 * 133 * @param parentKey The key to the parent TestEntity. 134 * @param type The test run type (e.g. presubmit, postsubmit, other) 135 * @param startTimestamp The time in microseconds when the test run started. 136 * @param endTimestamp The time in microseconds when the test run ended. 137 * @param testBuildId The build ID of the VTS test build. 138 * @param hostName The name of host machine. 139 * @param passCount The number of passing test cases in the run. 140 * @param failCount The number of failing test cases in the run. 141 * @param testCaseIds A list of key IDs to the TestCaseRunEntity objects for the test run. 142 * @param logLinks A list of links to log files for the test run, or null if there aren't any. 143 */ TestRunEntity(Key parentKey, TestRunType type, long startTimestamp, long endTimestamp, String testBuildId, String hostName, long passCount, long failCount, List<Long> testCaseIds, List<String> logLinks)144 public TestRunEntity(Key parentKey, TestRunType type, long startTimestamp, long endTimestamp, 145 String testBuildId, String hostName, long passCount, long failCount, 146 List<Long> testCaseIds, List<String> logLinks) { 147 this(parentKey, type, startTimestamp, endTimestamp, testBuildId, hostName, passCount, 148 failCount, testCaseIds, logLinks, 0, 0); 149 } 150 151 @Override toEntity()152 public Entity toEntity() { 153 Entity testRunEntity = new Entity(this.key); 154 testRunEntity.setProperty(TYPE, this.type.getNumber()); 155 testRunEntity.setProperty(START_TIMESTAMP, this.startTimestamp); 156 testRunEntity.setUnindexedProperty(END_TIMESTAMP, this.endTimestamp); 157 testRunEntity.setProperty(TEST_BUILD_ID, this.testBuildId.toLowerCase()); 158 testRunEntity.setProperty(HOST_NAME, this.hostName.toLowerCase()); 159 testRunEntity.setProperty(PASS_COUNT, this.passCount); 160 testRunEntity.setProperty(FAIL_COUNT, this.failCount); 161 testRunEntity.setProperty(TEST_CASE_IDS, this.testCaseIds); 162 if (this.totalLineCount > 0 && this.coveredLineCount >= 0) { 163 testRunEntity.setProperty(COVERED_LINE_COUNT, this.coveredLineCount); 164 testRunEntity.setProperty(TOTAL_LINE_COUNT, this.totalLineCount); 165 } 166 if (this.logLinks != null && this.logLinks.size() > 0) { 167 testRunEntity.setProperty(LOG_LINKS, this.logLinks); 168 } 169 return testRunEntity; 170 } 171 172 /** 173 * Convert an Entity object to a TestRunEntity. 174 * 175 * @param e The entity to process. 176 * @return TestRunEntity object with the properties from e processed, or null if incompatible. 177 */ 178 @SuppressWarnings("unchecked") fromEntity(Entity e)179 public static TestRunEntity fromEntity(Entity e) { 180 if (!e.getKind().equals(KIND) || !e.hasProperty(TYPE) || !e.hasProperty(START_TIMESTAMP) 181 || !e.hasProperty(END_TIMESTAMP) || !e.hasProperty(TEST_BUILD_ID) 182 || !e.hasProperty(HOST_NAME) || !e.hasProperty(PASS_COUNT) 183 || !e.hasProperty(FAIL_COUNT) || !e.hasProperty(TEST_CASE_IDS)) { 184 logger.log(Level.WARNING, "Missing test run attributes in entity: " + e.toString()); 185 return null; 186 } 187 try { 188 TestRunType type = TestRunType.fromNumber((int) (long) e.getProperty(TYPE)); 189 long startTimestamp = (long) e.getProperty(START_TIMESTAMP); 190 long endTimestamp = (long) e.getProperty(END_TIMESTAMP); 191 String testBuildId = (String) e.getProperty(TEST_BUILD_ID); 192 String hostName = (String) e.getProperty(HOST_NAME); 193 long passCount = (long) e.getProperty(PASS_COUNT); 194 long failCount = (long) e.getProperty(FAIL_COUNT); 195 List<Long> testCaseIds = (List<Long>) e.getProperty(TEST_CASE_IDS); 196 List<String> logLinks = null; 197 long coveredLineCount = 0; 198 long totalLineCount = 0; 199 if (e.hasProperty(TOTAL_LINE_COUNT) && e.hasProperty(COVERED_LINE_COUNT)) { 200 coveredLineCount = (long) e.getProperty(COVERED_LINE_COUNT); 201 totalLineCount = (long) e.getProperty(TOTAL_LINE_COUNT); 202 } 203 if (e.hasProperty(LOG_LINKS)) { 204 logLinks = (List<String>) e.getProperty(LOG_LINKS); 205 } 206 return new TestRunEntity(e.getKey().getParent(), type, startTimestamp, endTimestamp, 207 testBuildId, hostName, passCount, failCount, testCaseIds, logLinks, 208 coveredLineCount, totalLineCount); 209 } catch (ClassCastException exception) { 210 // Invalid cast 211 logger.log(Level.WARNING, "Error parsing test run entity.", exception); 212 } 213 return null; 214 } 215 } 216