Home | History | Annotate | Download | only in coretests
      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