1 /* 2 * Copyright (C) 2008 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 17 package com.google.coretests; 18 19 import dalvik.system.VMDebug; 20 21 import junit.framework.AssertionFailedError; 22 import junit.framework.Test; 23 import junit.framework.TestListener; 24 25 import java.io.PrintStream; 26 import java.util.ArrayList; 27 import java.util.Iterator; 28 29 public class PerfStatCollector implements TestListener { 30 31 public boolean listAll = false; 32 public boolean listBad = false; 33 public long thresholdDuration = 3600 * 1000; // in milliseconds 34 public boolean twoLines = true; 35 public boolean bigMarking = true; 36 37 private static boolean havePreciseTime = 38 VMDebug.threadCpuTimeNanos() != -1; 39 40 public class Item { 41 Test test; 42 long startTime, duration; 43 int res; 44 public boolean existsInStore; 45 public int id; 46 public int bestRes; 47 public long lastBestAt; 48 public int lastRes; 49 public long lastDuration; 50 public int statCount; 51 public double statAvgDuration; 52 public long statMinDuration; 53 public long statMaxDuration; 54 int adhocRelevance; 55 public int histRelevance; 56 public boolean isTransition; 57 boolean printed = false; 58 59 void update(boolean rBad, long rthDurat) { 60 // AdHoc Evaluation: 61 if (rBad && (res != 0)) { 62 // no success: 63 adhocRelevance = 2; 64 } 65 else if (duration >= rthDurat) { 66 // long duration: 67 adhocRelevance = 1; 68 } 69 else { 70 adhocRelevance = 0; 71 } 72 73 StatsStore.use1(this); 74 } 75 76 void print1(PrintStream out, boolean bigMarking) { 77 switch (histRelevance) { 78 case -4: 79 if (bigMarking) { 80 out.println(); 81 out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); 82 out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); 83 out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); 84 out.println("Test ran SUCCESSFULLY once, but NOT this time!!!!"); 85 out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); 86 out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); 87 out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); 88 } 89 out.print("-4 VBAD"); break; 90 case 4: out.print(" 4 Good"); break; 91 case 3: out.print(" 3 good"); break; 92 case -2: out.print("-2 SLOW"); break; 93 case 2: out.print(" 2 Fast"); break; 94 case 1: out.print(" 1 fast"); break; 95 case -3: 96 if (res == -2) out.print("-3 FAIL"); 97 else out.print("-3 ERR "); 98 break; 99 default: 100 if (res == 0) out.print(" "); 101 else if (res == -2) out.print(" fail"); 102 else out.print(" err "); 103 } 104 if (isTransition) out.print("! "); 105 else out.print(" "); 106 out.print(test.toString()); 107 out.format(": %d# %d(%d) [%d..%d] %.1f ms", 108 statCount, duration, lastDuration, 109 statMinDuration, statMaxDuration, statAvgDuration); 110 out.println(); 111 printed = true; 112 } 113 114 void print2(PrintStream out, boolean bigMarking) { 115 out.format("%5d. ", id); 116 117 out.println(test.toString()); 118 out.print(" "); 119 120 switch (histRelevance) { 121 case -4: out.print("FAIL"); break; 122 case 4: out.print("PASS"); break; 123 case 3: out.print("PASS"); break; 124 case -2: out.print("SLOW"); break; 125 case 2: out.print("FAST"); break; 126 case 1: out.print("PASS"); break; 127 case -3: 128 if (res == -2) out.print("FAIL"); 129 else out.print("ERR "); 130 break; 131 default: 132 if (res == 0) out.print("PASS"); 133 else if (res == -2) out.print("FAIL"); 134 else out.print("XCPT"); 135 } 136 137 out.format(" %d ms (min %d ms, max %d ms, avg %#.1f ms, %d runs)", 138 duration, 139 statMinDuration, statMaxDuration, statAvgDuration, 140 statCount); 141 out.println(); 142 143 printed = true; 144 } 145 146 void print(PrintStream out, boolean bigMarking) { 147 if (twoLines) print2(out, bigMarking); 148 else print1(out, bigMarking); 149 } 150 151 boolean checkPrint(PrintStream out) { 152 if (printed) return false; 153 print(out, false); 154 return true; 155 } 156 } 157 158 ArrayList<Item> items; 159 Item current; 160 161 PrintStream fWriter; 162 int fColumn= 0; 163 164 public PerfStatCollector(PrintStream writer) { 165 fWriter= writer; 166 items = new ArrayList(); 167 } 168 169 synchronized void digest() { 170 int totalCnt = 0; 171 int adhocRelevantCnt = 0; 172 int histRelevantCnt = 0; 173 long evalStartTime = System.currentTimeMillis(); 174 PrintStream out = fWriter; 175 out.println("Failure and Performance Statistics:"); 176 Iterator<Item> r = items.iterator(); 177 while (r.hasNext()) { 178 Item item = r.next(); 179 item.update(listBad, thresholdDuration); 180 if (item.histRelevance != 0) { 181 item.print(out, bigMarking); 182 histRelevantCnt++; 183 } 184 if (item.adhocRelevance != 0) { 185 if (item.checkPrint(out)) 186 adhocRelevantCnt++; 187 } 188 if (listAll) item.checkPrint(out); 189 totalCnt++; 190 } 191 long evalDuration = System.currentTimeMillis() - evalStartTime; 192 out.println(); 193 out.print(totalCnt); out.println(" tests run totally."); 194 out.print(histRelevantCnt); 195 out.println(" tests listed due to historical relevance."); 196 // out.print(adhocRelevantCnt); 197 // out.println(" tests listed due to ad-hoc-relevance."); 198 // out.print(totalCnt - histRelevantCnt - adhocRelevantCnt); 199 // out.println(" tests NOT listed due to relevance."); 200 out.println(); 201 out.print("Time used in Statistics Acquisition: "); 202 out.print(evalDuration); 203 out.print("ms"); 204 out.println(); 205 } 206 207 208 public PrintStream getWriter() { 209 return fWriter; 210 } 211 212 /** 213 * @see junit.framework.TestListener#addError(Test, Throwable) 214 */ 215 public void addError(Test test, Throwable t) { 216 current.res = -1; 217 } 218 219 /** 220 * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError) 221 */ 222 public void addFailure(Test test, AssertionFailedError t) { 223 current.res = -2; 224 } 225 226 /** 227 * @see junit.framework.TestListener#startTest(Test) 228 */ 229 public void startTest(Test test) { 230 System.gc(); 231 current = new Item(); 232 current.test = test; 233 current.startTime = currentTimeMillis(); 234 items.add(current); 235 } 236 237 /** 238 * @see junit.framework.TestListener#endTest(Test) 239 */ 240 public void endTest(Test test) { 241 current.duration = currentTimeMillis() - current.startTime; 242 } 243 244 /* 245 * Returns a "current time" in ms. Depending on the environment, this is 246 * either the actual CPU time out current thread has used so far, or the 247 * wall clock time of the system. 248 */ 249 private long currentTimeMillis() { 250 if (havePreciseTime) { 251 return VMDebug.threadCpuTimeNanos() / 1000; 252 } else { 253 return System.currentTimeMillis(); 254 } 255 } 256 257 } 258