| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.google.coretests; |
| |
| import dalvik.system.VMDebug; |
| |
| import junit.framework.AssertionFailedError; |
| import junit.framework.Test; |
| import junit.framework.TestListener; |
| |
| import java.io.PrintStream; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| |
| public class PerfStatCollector implements TestListener { |
| |
| public boolean listAll = false; |
| public boolean listBad = false; |
| public long thresholdDuration = 3600 * 1000; // in milliseconds |
| public boolean twoLines = true; |
| public boolean bigMarking = true; |
| |
| private static boolean havePreciseTime = |
| VMDebug.threadCpuTimeNanos() != -1; |
| |
| public class Item { |
| Test test; |
| long startTime, duration; |
| int res; |
| public boolean existsInStore; |
| public int id; |
| public int bestRes; |
| public long lastBestAt; |
| public int lastRes; |
| public long lastDuration; |
| public int statCount; |
| public double statAvgDuration; |
| public long statMinDuration; |
| public long statMaxDuration; |
| int adhocRelevance; |
| public int histRelevance; |
| public boolean isTransition; |
| boolean printed = false; |
| |
| void update(boolean rBad, long rthDurat) { |
| // AdHoc Evaluation: |
| if (rBad && (res != 0)) { |
| // no success: |
| adhocRelevance = 2; |
| } |
| else if (duration >= rthDurat) { |
| // long duration: |
| adhocRelevance = 1; |
| } |
| else { |
| adhocRelevance = 0; |
| } |
| |
| StatsStore.use1(this); |
| } |
| |
| void print1(PrintStream out, boolean bigMarking) { |
| switch (histRelevance) { |
| case -4: |
| if (bigMarking) { |
| out.println(); |
| out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); |
| out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); |
| out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); |
| out.println("Test ran SUCCESSFULLY once, but NOT this time!!!!"); |
| out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); |
| out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); |
| out.println("*** *** *** *** *** ATTENTION *** *** *** *** ***"); |
| } |
| out.print("-4 VBAD"); break; |
| case 4: out.print(" 4 Good"); break; |
| case 3: out.print(" 3 good"); break; |
| case -2: out.print("-2 SLOW"); break; |
| case 2: out.print(" 2 Fast"); break; |
| case 1: out.print(" 1 fast"); break; |
| case -3: |
| if (res == -2) out.print("-3 FAIL"); |
| else out.print("-3 ERR "); |
| break; |
| default: |
| if (res == 0) out.print(" "); |
| else if (res == -2) out.print(" fail"); |
| else out.print(" err "); |
| } |
| if (isTransition) out.print("! "); |
| else out.print(" "); |
| out.print(test.toString()); |
| out.format(": %d# %d(%d) [%d..%d] %.1f ms", |
| statCount, duration, lastDuration, |
| statMinDuration, statMaxDuration, statAvgDuration); |
| out.println(); |
| printed = true; |
| } |
| |
| void print2(PrintStream out, boolean bigMarking) { |
| out.format("%5d. ", id); |
| |
| out.println(test.toString()); |
| out.print(" "); |
| |
| switch (histRelevance) { |
| case -4: out.print("FAIL"); break; |
| case 4: out.print("PASS"); break; |
| case 3: out.print("PASS"); break; |
| case -2: out.print("SLOW"); break; |
| case 2: out.print("FAST"); break; |
| case 1: out.print("PASS"); break; |
| case -3: |
| if (res == -2) out.print("FAIL"); |
| else out.print("ERR "); |
| break; |
| default: |
| if (res == 0) out.print("PASS"); |
| else if (res == -2) out.print("FAIL"); |
| else out.print("XCPT"); |
| } |
| |
| out.format(" %d ms (min %d ms, max %d ms, avg %#.1f ms, %d runs)", |
| duration, |
| statMinDuration, statMaxDuration, statAvgDuration, |
| statCount); |
| out.println(); |
| |
| printed = true; |
| } |
| |
| void print(PrintStream out, boolean bigMarking) { |
| if (twoLines) print2(out, bigMarking); |
| else print1(out, bigMarking); |
| } |
| |
| boolean checkPrint(PrintStream out) { |
| if (printed) return false; |
| print(out, false); |
| return true; |
| } |
| } |
| |
| ArrayList<Item> items; |
| Item current; |
| |
| PrintStream fWriter; |
| int fColumn= 0; |
| |
| public PerfStatCollector(PrintStream writer) { |
| fWriter= writer; |
| items = new ArrayList(); |
| } |
| |
| synchronized void digest() { |
| int totalCnt = 0; |
| int adhocRelevantCnt = 0; |
| int histRelevantCnt = 0; |
| long evalStartTime = System.currentTimeMillis(); |
| PrintStream out = fWriter; |
| out.println("Failure and Performance Statistics:"); |
| Iterator<Item> r = items.iterator(); |
| while (r.hasNext()) { |
| Item item = r.next(); |
| item.update(listBad, thresholdDuration); |
| if (item.histRelevance != 0) { |
| item.print(out, bigMarking); |
| histRelevantCnt++; |
| } |
| if (item.adhocRelevance != 0) { |
| if (item.checkPrint(out)) |
| adhocRelevantCnt++; |
| } |
| if (listAll) item.checkPrint(out); |
| totalCnt++; |
| } |
| long evalDuration = System.currentTimeMillis() - evalStartTime; |
| out.println(); |
| out.print(totalCnt); out.println(" tests run totally."); |
| out.print(histRelevantCnt); |
| out.println(" tests listed due to historical relevance."); |
| // out.print(adhocRelevantCnt); |
| // out.println(" tests listed due to ad-hoc-relevance."); |
| // out.print(totalCnt - histRelevantCnt - adhocRelevantCnt); |
| // out.println(" tests NOT listed due to relevance."); |
| out.println(); |
| out.print("Time used in Statistics Acquisition: "); |
| out.print(evalDuration); |
| out.print("ms"); |
| out.println(); |
| } |
| |
| |
| public PrintStream getWriter() { |
| return fWriter; |
| } |
| |
| /** |
| * @see junit.framework.TestListener#addError(Test, Throwable) |
| */ |
| public void addError(Test test, Throwable t) { |
| current.res = -1; |
| } |
| |
| /** |
| * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError) |
| */ |
| public void addFailure(Test test, AssertionFailedError t) { |
| current.res = -2; |
| } |
| |
| /** |
| * @see junit.framework.TestListener#startTest(Test) |
| */ |
| public void startTest(Test test) { |
| System.gc(); |
| current = new Item(); |
| current.test = test; |
| current.startTime = currentTimeMillis(); |
| items.add(current); |
| } |
| |
| /** |
| * @see junit.framework.TestListener#endTest(Test) |
| */ |
| public void endTest(Test test) { |
| current.duration = currentTimeMillis() - current.startTime; |
| } |
| |
| /* |
| * Returns a "current time" in ms. Depending on the environment, this is |
| * either the actual CPU time out current thread has used so far, or the |
| * wall clock time of the system. |
| */ |
| private long currentTimeMillis() { |
| if (havePreciseTime) { |
| return VMDebug.threadCpuTimeNanos() / 1000; |
| } else { |
| return System.currentTimeMillis(); |
| } |
| } |
| |
| } |