summaryrefslogtreecommitdiffstats
path: root/tests/DumpRenderTree2/src
diff options
context:
space:
mode:
Diffstat (limited to 'tests/DumpRenderTree2/src')
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java62
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java2
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java123
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/SummarizerDBHelper.java129
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java11
5 files changed, 297 insertions, 30 deletions
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
index 6048338a..96c1e5e 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
@@ -18,8 +18,16 @@ package com.android.dumprendertree2;
import android.os.Bundle;
import android.os.Message;
+import android.util.Log;
import android.webkit.WebView;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
/**
* A class that represent a result of the test. It is responsible for returning the result's
* raw data and generating its own diff in HTML format.
@@ -49,7 +57,7 @@ public abstract class AbstractResult implements Comparable<AbstractResult> {
/**
* A code representing the result of comparing actual and expected results.
*/
- public enum ResultCode {
+ public enum ResultCode implements Serializable {
RESULTS_MATCH("Results match"),
RESULTS_DIFFER("Results differ"),
NO_EXPECTED_RESULT("No expected result"),
@@ -81,6 +89,58 @@ public abstract class AbstractResult implements Comparable<AbstractResult> {
return mAdditionalTextOutputString;
}
+ public byte[] getBytes() {
+ ByteArrayOutputStream baos = null;
+ ObjectOutputStream oos = null;
+ try {
+ try {
+ baos = new ByteArrayOutputStream();
+ oos = new ObjectOutputStream(baos);
+ oos.writeObject(this);
+ } finally {
+ if (baos != null) {
+ baos.close();
+ }
+ if (oos != null) {
+ oos.close();
+ }
+ }
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Unable to serialize result: " + getRelativePath(), e);
+ }
+
+ return baos == null ? null : baos.toByteArray();
+ }
+
+ public static AbstractResult create(byte[] bytes) {
+ ByteArrayInputStream bais = null;
+ ObjectInputStream ois = null;
+ AbstractResult result = null;
+ try {
+ try {
+ bais = new ByteArrayInputStream(bytes);
+ ois = new ObjectInputStream(bais);
+ result = (AbstractResult)ois.readObject();
+ } finally {
+ if (bais != null) {
+ bais.close();
+ }
+ if (ois != null) {
+ ois.close();
+ }
+ }
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Unable to deserialize result!", e);
+ } catch (ClassNotFoundException e) {
+ Log.e(LOG_TAG, "Unable to deserialize result!", e);
+ }
+ return result;
+ }
+
+ public void clearResults() {
+ mAdditionalTextOutputString = null;
+ }
+
/**
* Makes the result object obtain the results of the test from the webview
* and store them in the format that suits itself bests. This method is asynchronous.
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
index d4bb0d38..17e19d0 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
@@ -147,7 +147,7 @@ public class ManagerService extends Service {
super.onCreate();
mFileFilter = new FileFilter();
- mSummarizer = new Summarizer(mFileFilter, RESULTS_ROOT_DIR_PATH);
+ mSummarizer = new Summarizer(mFileFilter, RESULTS_ROOT_DIR_PATH, getApplicationContext());
}
@Override
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java
index ffb3f8f..25c5ad5 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java
@@ -16,9 +16,11 @@
package com.android.dumprendertree2;
+import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.database.Cursor;
import android.os.Build;
import android.os.Message;
import android.util.DisplayMetrics;
@@ -32,7 +34,6 @@ import java.net.URI;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
@@ -189,6 +190,7 @@ public class Summarizer {
private static final String TXT_SUMMARY_RELATIVE_PATH = "summary.txt";
private static final int RESULTS_PER_DUMP = 500;
+ private static final int RESULTS_PER_DB_ACCESS = 50;
private int mCrashedTestsCount = 0;
private List<AbstractResult> mUnexpectedFailures = new ArrayList<AbstractResult>();
@@ -196,16 +198,31 @@ public class Summarizer {
private List<AbstractResult> mExpectedPasses = new ArrayList<AbstractResult>();
private List<AbstractResult> mUnexpectedPasses = new ArrayList<AbstractResult>();
+ private Cursor mUnexpectedFailuresCursor;
+ private Cursor mExpectedFailuresCursor;
+ private Cursor mUnexpectedPassesCursor;
+ private Cursor mExpectedPassesCursor;
+
private FileFilter mFileFilter;
private String mResultsRootDirPath;
private String mTestsRelativePath;
private Date mDate;
private int mResultsSinceLastHtmlDump = 0;
+ private int mResultsSinceLastDbAccess = 0;
+
+ private SummarizerDBHelper mDbHelper;
- public Summarizer(FileFilter fileFilter, String resultsRootDirPath) {
+ public Summarizer(FileFilter fileFilter, String resultsRootDirPath, Context context) {
mFileFilter = fileFilter;
mResultsRootDirPath = resultsRootDirPath;
+
+ /**
+ * We don't run the database I/O in a separate thread to avoid consumer/producer problem
+ * and to simplify code.
+ */
+ mDbHelper = new SummarizerDBHelper(context);
+ mDbHelper.open();
}
public static URI getDetailsUri() {
@@ -221,6 +238,7 @@ public class Summarizer {
}
if (result.didPass()) {
+ result.clearResults();
if (mFileFilter.isFail(relativePath)) {
mUnexpectedPasses.add(result);
} else {
@@ -233,6 +251,32 @@ public class Summarizer {
mUnexpectedFailures.add(result);
}
}
+
+ if (++mResultsSinceLastDbAccess == RESULTS_PER_DB_ACCESS) {
+ persistLists();
+ clearLists();
+ }
+ }
+
+ private void clearLists() {
+ mUnexpectedFailures.clear();
+ mExpectedFailures.clear();
+ mUnexpectedPasses.clear();
+ mExpectedPasses.clear();
+ }
+
+ private void persistLists() {
+ persistListToTable(mUnexpectedFailures, SummarizerDBHelper.UNEXPECTED_FAILURES_TABLE);
+ persistListToTable(mExpectedFailures, SummarizerDBHelper.EXPECTED_FAILURES_TABLE);
+ persistListToTable(mUnexpectedPasses, SummarizerDBHelper.UNEXPECTED_PASSES_TABLE);
+ persistListToTable(mExpectedPasses, SummarizerDBHelper.EXPECTED_PASSES_TABLE);
+ mResultsSinceLastDbAccess = 0;
+ }
+
+ private void persistListToTable(List<AbstractResult> results, String table) {
+ for (AbstractResult abstractResult : results) {
+ mDbHelper.insertAbstractResult(abstractResult, table);
+ }
}
public void setTestsRelativePath(String testsRelativePath) {
@@ -240,17 +284,35 @@ public class Summarizer {
}
public void summarize(Message onFinishMessage) {
+ persistLists();
+ clearLists();
+
+ mUnexpectedFailuresCursor =
+ mDbHelper.getAbstractResults(SummarizerDBHelper.UNEXPECTED_FAILURES_TABLE);
+ mUnexpectedPassesCursor =
+ mDbHelper.getAbstractResults(SummarizerDBHelper.UNEXPECTED_PASSES_TABLE);
+ mExpectedFailuresCursor =
+ mDbHelper.getAbstractResults(SummarizerDBHelper.EXPECTED_FAILURES_TABLE);
+ mExpectedPassesCursor =
+ mDbHelper.getAbstractResults(SummarizerDBHelper.EXPECTED_PASSES_TABLE);
+
String webKitRevision = getWebKitRevision();
createHtmlDetails(webKitRevision);
createTxtSummary(webKitRevision);
+
+ clearLists();
+ mUnexpectedFailuresCursor.close();
+ mUnexpectedPassesCursor.close();
+ mExpectedFailuresCursor.close();
+ mExpectedPassesCursor.close();
+
onFinishMessage.sendToTarget();
}
public void reset() {
mCrashedTestsCount = 0;
- mUnexpectedFailures.clear();
- mExpectedFailures.clear();
- mExpectedPasses.clear();
+ clearLists();
+ mDbHelper.reset();
mDate = new Date();
}
@@ -273,10 +335,10 @@ public class Summarizer {
txt.append("TOTAL: " + getTotalTestCount() + "\n");
txt.append("CRASHED (among all tests): " + mCrashedTestsCount + "\n");
- txt.append("UNEXPECTED FAILURES: " + mUnexpectedFailures.size() + "\n");
- txt.append("UNEXPECTED PASSES: " + mUnexpectedPasses.size() + "\n");
- txt.append("EXPECTED FAILURES: " + mExpectedFailures.size() + "\n");
- txt.append("EXPECTED PASSES: " + mExpectedPasses.size() + "\n");
+ txt.append("UNEXPECTED FAILURES: " + mUnexpectedFailuresCursor.getCount() + "\n");
+ txt.append("UNEXPECTED PASSES: " + mUnexpectedPassesCursor.getCount() + "\n");
+ txt.append("EXPECTED FAILURES: " + mExpectedFailuresCursor.getCount() + "\n");
+ txt.append("EXPECTED PASSES: " + mExpectedPassesCursor.getCount() + "\n");
FsUtils.writeDataToStorage(new File(mResultsRootDirPath, TXT_SUMMARY_RELATIVE_PATH),
txt.toString().getBytes(), false);
@@ -293,20 +355,20 @@ public class Summarizer {
createTopSummaryTable(webKitRevision, html);
dumpHtmlToFile(html, false);
- createResultsList(html, "Unexpected failures", mUnexpectedFailures);
- createResultsList(html, "Unexpected passes", mUnexpectedPasses);
- createResultsList(html, "Expected failures", mExpectedFailures);
- createResultsList(html, "Expected passes", mExpectedPasses);
+ createResultsList(html, "Unexpected failures", mUnexpectedFailuresCursor);
+ createResultsList(html, "Unexpected passes", mUnexpectedPassesCursor);
+ createResultsList(html, "Expected failures", mExpectedFailuresCursor);
+ createResultsList(html, "Expected passes", mExpectedPassesCursor);
html.append("</body></html>");
dumpHtmlToFile(html, true);
}
private int getTotalTestCount() {
- return mUnexpectedFailures.size() +
- mUnexpectedPasses.size() +
- mExpectedPasses.size() +
- mExpectedFailures.size();
+ return mUnexpectedFailuresCursor.getCount() +
+ mUnexpectedPassesCursor.getCount() +
+ mExpectedPassesCursor.getCount() +
+ mExpectedFailuresCursor.getCount();
}
private String getWebKitVersionFromUserAgentString() {
@@ -355,10 +417,10 @@ public class Summarizer {
html.append("<table class=\"summary\">");
createSummaryTableRow(html, "TOTAL", getTotalTestCount());
createSummaryTableRow(html, "CRASHED (among all tests)", mCrashedTestsCount);
- createSummaryTableRow(html, "UNEXPECTED FAILURES", mUnexpectedFailures.size());
- createSummaryTableRow(html, "UNEXPECTED PASSES", mUnexpectedPasses.size());
- createSummaryTableRow(html, "EXPECTED FAILURES", mExpectedFailures.size());
- createSummaryTableRow(html, "EXPECTED PASSES", mExpectedPasses.size());
+ createSummaryTableRow(html, "UNEXPECTED FAILURES", mUnexpectedFailuresCursor.getCount());
+ createSummaryTableRow(html, "UNEXPECTED PASSES", mUnexpectedPassesCursor.getCount());
+ createSummaryTableRow(html, "EXPECTED FAILURES", mExpectedFailuresCursor.getCount());
+ createSummaryTableRow(html, "EXPECTED PASSES", mExpectedPassesCursor.getCount());
html.append("</table>");
}
@@ -370,14 +432,21 @@ public class Summarizer {
}
private void createResultsList(
- StringBuilder html, String title, List<AbstractResult> resultsList) {
+ StringBuilder html, String title, Cursor cursor) {
String relativePath;
String id = "";
AbstractResult.ResultCode resultCode;
- Collections.sort(resultsList);
- html.append("<h2>" + title + " [" + resultsList.size() + "]</h2>");
- for (AbstractResult result : resultsList) {
+ html.append("<h2>" + title + " [" + cursor.getCount() + "]</h2>");
+
+ if (!cursor.moveToFirst()) {
+ return;
+ }
+
+ AbstractResult result;
+ do {
+ result = SummarizerDBHelper.getAbstractResult(cursor);
+
relativePath = result.getRelativePath();
resultCode = result.getResultCode();
@@ -429,7 +498,9 @@ public class Summarizer {
if (++mResultsSinceLastHtmlDump == RESULTS_PER_DUMP) {
dumpHtmlToFile(html, true);
}
- }
+
+ cursor.moveToNext();
+ } while (!cursor.isAfterLast());
}
private void appendTags(StringBuilder html, AbstractResult result) {
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/SummarizerDBHelper.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/SummarizerDBHelper.java
new file mode 100644
index 0000000..23e13ec
--- /dev/null
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/SummarizerDBHelper.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2010 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.android.dumprendertree2;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A basic class that wraps database accesses inside itself and provides functionality to
+ * store and retrieve AbstractResults.
+ */
+public class SummarizerDBHelper {
+ private static final String KEY_ID = "id";
+ private static final String KEY_PATH = "path";
+ private static final String KEY_BYTES = "bytes";
+
+ private static final String DATABASE_NAME = "SummarizerDB";
+ private static final int DATABASE_VERSION = 1;
+
+ static final String EXPECTED_FAILURES_TABLE = "expectedFailures";
+ static final String UNEXPECTED_FAILURES_TABLE = "unexpectedFailures";
+ static final String EXPECTED_PASSES_TABLE = "expextedPasses";
+ static final String UNEXPECTED_PASSES_TABLE = "unexpextedPasses";
+ private static final Set<String> TABLES_NAMES = new HashSet<String>();
+ {
+ TABLES_NAMES.add(EXPECTED_FAILURES_TABLE);
+ TABLES_NAMES.add(EXPECTED_PASSES_TABLE);
+ TABLES_NAMES.add(UNEXPECTED_FAILURES_TABLE);
+ TABLES_NAMES.add(UNEXPECTED_PASSES_TABLE);
+ }
+
+ private static final void createTables(SQLiteDatabase db) {
+ String cmd;
+ for (String tableName : TABLES_NAMES) {
+ cmd = "create table " + tableName + " ("
+ + KEY_ID + " integer primary key autoincrement, "
+ + KEY_PATH + " text not null, "
+ + KEY_BYTES + " blob not null);";
+ db.execSQL(cmd);
+ }
+ }
+
+ private static final void dropTables(SQLiteDatabase db) {
+ for (String tableName : TABLES_NAMES) {
+ db.execSQL("DROP TABLE IF EXISTS " + tableName);
+ }
+ }
+
+ private static class DatabaseHelper extends SQLiteOpenHelper {
+ DatabaseHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ dropTables(db);
+ createTables(db);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ /** NOOP for now, because we will never upgrade the db */
+ }
+
+ public void reset(SQLiteDatabase db) {
+ dropTables(db);
+ createTables(db);
+ }
+ }
+
+ private DatabaseHelper mDbHelper;
+ private SQLiteDatabase mDb;
+
+ private final Context mContext;
+
+ public SummarizerDBHelper(Context ctx) {
+ mContext = ctx;
+ mDbHelper = new DatabaseHelper(mContext);
+ }
+
+ public void reset() {
+ mDbHelper.reset(this.mDb);
+ }
+
+ public void open() throws SQLException {
+ mDb = mDbHelper.getWritableDatabase();
+ }
+
+ public void close() {
+ mDbHelper.close();
+ }
+
+ public void insertAbstractResult(AbstractResult result, String table) {
+ ContentValues cv = new ContentValues();
+ cv.put(KEY_PATH, result.getRelativePath());
+ cv.put(KEY_BYTES, result.getBytes());
+ mDb.insert(table, null, cv);
+ }
+
+ public Cursor getAbstractResults(String table) throws SQLException {
+ return mDb.query(false, table, new String[] {KEY_BYTES}, null, null, null, null,
+ KEY_PATH + " ASC", null);
+ }
+
+ public static AbstractResult getAbstractResult(Cursor cursor) {
+ return AbstractResult.create(cursor.getBlob(cursor.getColumnIndex(KEY_BYTES)));
+ }
+} \ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
index 21e5430..f835b6a 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
@@ -41,11 +41,11 @@ public class TextResult extends AbstractResult {
private String mRelativePath;
private boolean mDidTimeOut;
private ResultCode mResultCode;
- private Message mResultObtainedMsg;
+ transient private Message mResultObtainedMsg;
private boolean mDumpChildFramesAsText;
- private Handler mHandler = new Handler() {
+ transient private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_DOCUMENT_AS_TEXT) {
@@ -79,6 +79,13 @@ public class TextResult extends AbstractResult {
}
@Override
+ public void clearResults() {
+ super.clearResults();
+ mExpectedResult = null;
+ mActualResult = null;
+ }
+
+ @Override
public ResultCode getResultCode() {
if (mResultCode != null) {
return mResultCode;