Home | History | Annotate | Download | only in test
      1 /*
      2  * Copyright (C) 2006 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 android.test;
     18 
     19 import android.content.ContentValues;
     20 import android.database.sqlite.SQLiteDatabase;
     21 import android.os.Environment;
     22 import android.os.FileUtils;
     23 import android.test.TestRunner.IntermediateTime;
     24 import android.util.Log;
     25 import junit.framework.Test;
     26 import junit.framework.TestListener;
     27 
     28 import java.io.File;
     29 import java.io.PrintWriter;
     30 import java.io.StringWriter;
     31 import java.util.HashSet;
     32 import java.util.List;
     33 import java.util.Set;
     34 
     35 /**
     36  * {@hide} Not needed for 1.0 SDK.
     37  */
     38 public class TestRecorder implements TestRunner.Listener, TestListener {
     39     private static final int DATABASE_VERSION = 1;
     40     private static SQLiteDatabase sDb;
     41     private Set<String> mFailedTests = new HashSet<String>();
     42 
     43     private static SQLiteDatabase getDatabase() {
     44         if (sDb == null) {
     45             File dir = new File(Environment.getDataDirectory(), "test_results");
     46 
     47             /* TODO: add a DB version number and bootstrap/upgrade methods
     48             * if the format of the table changes.
     49             */
     50             String dbName = "TestHarness.db";
     51             File file = new File(dir, dbName);
     52             sDb = SQLiteDatabase.openOrCreateDatabase(file.getPath(), null);
     53 
     54             if (sDb.getVersion() == 0) {
     55                 int code = FileUtils.setPermissions(file.getPath(),
     56                         FileUtils.S_IRUSR | FileUtils.S_IWUSR |
     57                                 FileUtils.S_IRGRP | FileUtils.S_IWGRP |
     58                                 FileUtils.S_IROTH | FileUtils.S_IWOTH, -1, -1);
     59 
     60                 if (code != 0) {
     61                     Log.w("TestRecorder",
     62                             "Set permissions for " + file.getPath() + " returned = " + code);
     63                 }
     64 
     65                 try {
     66                     sDb.execSQL("CREATE TABLE IF NOT EXISTS tests (_id INT PRIMARY KEY," +
     67                             "name TEXT," +
     68                             "result TEXT," +
     69                             "exception TEXT," +
     70                             "started INTEGER," +
     71                             "finished INTEGER," +
     72                             "time INTEGER," +
     73                             "iterations INTEGER," +
     74                             "allocations INTEGER," +
     75                             "parent INTEGER);");
     76                     sDb.setVersion(DATABASE_VERSION);
     77                 } catch (Exception e) {
     78                     Log.e("TestRecorder", "failed to create table 'tests'", e);
     79                     sDb = null;
     80                 }
     81             }
     82         }
     83 
     84         return sDb;
     85     }
     86 
     87     public TestRecorder() {
     88     }
     89 
     90     public void started(String className) {
     91         ContentValues map = new ContentValues(2);
     92         map.put("name", className);
     93         map.put("started", System.currentTimeMillis());
     94 
     95         // try to update the row first in case we've ran this test before.
     96         int rowsAffected = getDatabase().update("tests", map, "name = '" + className + "'", null);
     97 
     98         if (rowsAffected == 0) {
     99             getDatabase().insert("tests", null, map);
    100         }
    101     }
    102 
    103     public void finished(String className) {
    104         ContentValues map = new ContentValues(1);
    105         map.put("finished", System.currentTimeMillis());
    106 
    107         getDatabase().update("tests", map, "name = '" + className + "'", null);
    108     }
    109 
    110     public void performance(String className, long itemTimeNS, int iterations, List<IntermediateTime> intermediates) {
    111         ContentValues map = new ContentValues();
    112         map.put("time", itemTimeNS);
    113         map.put("iterations", iterations);
    114 
    115         getDatabase().update("tests", map, "name = '" + className + "'", null);
    116 
    117         if (intermediates != null && intermediates.size() > 0) {
    118             int n = intermediates.size();
    119             for (int i = 0; i < n; i++) {
    120                 TestRunner.IntermediateTime time = intermediates.get(i);
    121 
    122                 getDatabase().execSQL("INSERT INTO tests (name, time, parent) VALUES ('" +
    123                         time.name + "', " + time.timeInNS + ", " +
    124                         "(SELECT _id FROM tests WHERE name = '" + className + "'));");
    125             }
    126         }
    127     }
    128 
    129     public void passed(String className) {
    130         ContentValues map = new ContentValues();
    131         map.put("result", "passed");
    132 
    133         getDatabase().update("tests", map, "name = '" + className + "'", null);
    134     }
    135 
    136     public void failed(String className, Throwable exception) {
    137         StringWriter stringWriter = new StringWriter();
    138         PrintWriter printWriter = new PrintWriter(stringWriter);
    139         try {
    140             exception.printStackTrace(printWriter);
    141         } finally {
    142             printWriter.close();
    143         }
    144         ContentValues map = new ContentValues();
    145         map.put("result", "failed");
    146         map.put("exception", stringWriter.toString());
    147 
    148         getDatabase().update("tests", map, "name = '" + className + "'", null);
    149     }
    150 
    151     /**
    152      * Reports a test case failure.
    153      *
    154      * @param className Name of the class/test.
    155      * @param reason    Reason for failure.
    156      */
    157     public void failed(String className, String reason) {
    158         ContentValues map = new ContentValues();
    159         map.put("result", "failed");
    160         // The reason is put as the exception.
    161         map.put("exception", reason);
    162         getDatabase().update("tests", map, "name = '" + className + "'", null);
    163     }
    164 
    165     public void addError(Test test, Throwable t) {
    166         mFailedTests.add(test.toString());
    167         failed(test.toString(), t);
    168     }
    169 
    170     public void addFailure(Test test, junit.framework.AssertionFailedError t) {
    171         mFailedTests.add(test.toString());
    172         failed(test.toString(), t.getMessage());
    173     }
    174 
    175     public void endTest(Test test) {
    176         finished(test.toString());
    177         if (!mFailedTests.contains(test.toString())) {
    178             passed(test.toString());
    179         }
    180         mFailedTests.remove(test.toString());
    181     }
    182 
    183     public void startTest(Test test) {
    184         started(test.toString());
    185     }
    186 }
    187