1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may 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 implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.compatibility.common.util; 17 18 import java.util.ArrayList; 19 import java.util.Collections; 20 import java.util.HashMap; 21 import java.util.List; 22 import java.util.Map; 23 24 /** 25 * Data structure for a Compatibility test module result. 26 */ 27 public class ModuleResult implements IModuleResult { 28 29 private String mId; 30 private long mRuntime = 0; 31 32 /* Variables related to completion of the module */ 33 private boolean mDone = false; 34 private boolean mHaveSetDone = false; 35 private boolean mInProgress = false; 36 private int mExpectedTestRuns = 0; 37 private int mActualTestRuns = 0; 38 private int mNotExecuted = 0; 39 private boolean mIsFailed = false; 40 41 private Map<String, ICaseResult> mResults = new HashMap<>(); 42 43 /** 44 * Creates a {@link ModuleResult} for the given id, created with 45 * {@link AbiUtils#createId(String, String)} 46 */ ModuleResult(String id)47 public ModuleResult(String id) { 48 mId = id; 49 } 50 51 /** 52 * {@inheritDoc} 53 */ 54 @Override isDone()55 public boolean isDone() { 56 // If module is failed, it cannot be marked done. 57 if (isFailed()) { 58 return false; 59 } 60 return mDone && !mInProgress && (mActualTestRuns >= mExpectedTestRuns); 61 } 62 63 /** 64 * {@inheritDoc} 65 */ 66 @Override isDoneSoFar()67 public boolean isDoneSoFar() { 68 return mDone && !mInProgress; 69 } 70 71 /** 72 * {@inheritDoc} 73 */ 74 @Override initializeDone(boolean done)75 public void initializeDone(boolean done) { 76 mDone = done; 77 mHaveSetDone = false; 78 if (mDone) { 79 mNotExecuted = 0; 80 } 81 } 82 83 /** 84 * {@inheritDoc} 85 */ 86 @Override setDone(boolean done)87 public void setDone(boolean done) { 88 if (mHaveSetDone) { 89 mDone &= done; // If we've already set done for this instance, AND the received value 90 } else { 91 mDone = done; // If done has only been initialized, overwrite the existing value 92 } 93 mHaveSetDone = true; 94 if (mDone) { 95 mNotExecuted = 0; 96 } 97 } 98 99 /** 100 * {@inheritDoc} 101 */ 102 @Override inProgress(boolean inProgress)103 public void inProgress(boolean inProgress) { 104 mInProgress = inProgress; 105 } 106 107 /** 108 * {@inheritDoc} 109 */ 110 @Override getExpectedTestRuns()111 public int getExpectedTestRuns() { 112 return mExpectedTestRuns; 113 } 114 115 /** 116 * {@inheritDoc} 117 */ 118 @Override setExpectedTestRuns(int numRuns)119 public void setExpectedTestRuns(int numRuns) { 120 mExpectedTestRuns = numRuns; 121 } 122 123 /** 124 * {@inheritDoc} 125 */ 126 @Override getTestRuns()127 public int getTestRuns() { 128 return mActualTestRuns; 129 } 130 131 /** 132 * {@inheritDoc} 133 */ 134 @Override addTestRun()135 public void addTestRun() { 136 mActualTestRuns++; 137 } 138 139 /** 140 * {@inheritDoc} 141 */ 142 @Override resetTestRuns()143 public void resetTestRuns() { 144 mActualTestRuns = 0; 145 } 146 147 /** 148 * {@inheritDoc} 149 */ 150 @Override getNotExecuted()151 public int getNotExecuted() { 152 return mNotExecuted; 153 } 154 155 /** 156 * {@inheritDoc} 157 */ 158 @Override setNotExecuted(int numTests)159 public void setNotExecuted(int numTests) { 160 mNotExecuted = numTests; 161 } 162 163 /** 164 * {@inheritDoc} 165 */ 166 @Override getId()167 public String getId() { 168 return mId; 169 } 170 171 /** 172 * {@inheritDoc} 173 */ 174 @Override getName()175 public String getName() { 176 return AbiUtils.parseTestName(mId); 177 } 178 179 /** 180 * {@inheritDoc} 181 */ 182 @Override getAbi()183 public String getAbi() { 184 return AbiUtils.parseAbi(mId); 185 } 186 187 /** 188 * {@inheritDoc} 189 */ 190 @Override addRuntime(long elapsedTime)191 public void addRuntime(long elapsedTime) { 192 mRuntime += elapsedTime; 193 } 194 195 /** 196 * {@inheritDoc} 197 */ 198 @Override resetRuntime()199 public void resetRuntime() { 200 mRuntime = 0; 201 } 202 203 /** 204 * {@inheritDoc} 205 */ 206 @Override getRuntime()207 public long getRuntime() { 208 return mRuntime; 209 } 210 211 /** 212 * {@inheritDoc} 213 */ 214 @Override getOrCreateResult(String caseName)215 public ICaseResult getOrCreateResult(String caseName) { 216 ICaseResult result = mResults.get(caseName); 217 if (result == null) { 218 result = new CaseResult(caseName); 219 mResults.put(caseName, result); 220 } 221 return result; 222 } 223 224 /** 225 * {@inheritDoc} 226 */ 227 @Override getResult(String caseName)228 public ICaseResult getResult(String caseName) { 229 return mResults.get(caseName); 230 } 231 232 /** 233 * {@inheritDoc} 234 */ 235 @Override getResults()236 public List<ICaseResult> getResults() { 237 ArrayList<ICaseResult> results = new ArrayList<>(mResults.values()); 238 Collections.sort(results); 239 return results; 240 } 241 242 /** 243 * {@inheritDoc} 244 */ 245 @Override countResults(TestStatus status)246 public int countResults(TestStatus status) { 247 int total = 0; 248 for (ICaseResult result : mResults.values()) { 249 total += result.countResults(status); 250 } 251 return total; 252 } 253 254 /** 255 * {@inheritDoc} 256 */ 257 @Override compareTo(IModuleResult another)258 public int compareTo(IModuleResult another) { 259 return getId().compareTo(another.getId()); 260 } 261 262 @Override setFailed()263 public void setFailed() { 264 mIsFailed = true; 265 } 266 267 @Override isFailed()268 public boolean isFailed() { 269 return mIsFailed; 270 } 271 272 /** 273 * {@inheritDoc} 274 */ 275 @Override mergeFrom(IModuleResult otherModuleResult)276 public void mergeFrom(IModuleResult otherModuleResult) { 277 if (!otherModuleResult.getId().equals(getId())) { 278 throw new IllegalArgumentException(String.format( 279 "Cannot merge module result with mismatched id. Expected %s, Found %s", 280 otherModuleResult.getId(), getId())); 281 } 282 283 this.mRuntime += otherModuleResult.getRuntime(); 284 this.mNotExecuted += otherModuleResult.getNotExecuted(); 285 // Only touch variables related to 'done' status if this module is not already done 286 if (!isDone()) { 287 this.setDone(otherModuleResult.isDoneSoFar()); 288 this.mActualTestRuns += otherModuleResult.getTestRuns(); 289 // expected test runs are the same across shards, except for shards that do not run 290 // this module at least once (for which the value is not yet set). 291 this.mExpectedTestRuns += otherModuleResult.getExpectedTestRuns(); 292 } 293 // If something failed, then the aggregation is failed 294 if (!this.isFailed()) { 295 this.mIsFailed = otherModuleResult.isFailed(); 296 } 297 for (ICaseResult otherCaseResult : otherModuleResult.getResults()) { 298 ICaseResult caseResult = getOrCreateResult(otherCaseResult.getName()); 299 caseResult.mergeFrom(otherCaseResult); 300 } 301 } 302 } 303