blob: 4ef7c03ef311468d083900dde543e056197a1ad3 [file] [log] [blame]
/*
* 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();
}
}
}