diff options
Diffstat (limited to 'tests/DumpRenderTree/src')
6 files changed, 525 insertions, 361 deletions
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java index 91597d5..9be33db 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java @@ -24,13 +24,19 @@ public class FileFilter { public static boolean ignoreTest(String file) { // treat files like directories for the time being. - int size = ignoreTestList.length; - for (int i = 0; i < size; i ++) { - if (file.startsWith(ignoreTestList[i])) { + for (int i = 0; i < ignoreTestList.length; i ++) { + if (file.endsWith(ignoreTestList[i])) { Log.e("FileFilter", "File path in IgnoreTest: " + file); return true; } } + for (int i = 0; i < ignoreTestDirs.length; i++) { + if (file.endsWith(ignoreTestDirs[i])) { + Log.e("FileFilter", "File path in ignore list: " + file); + return true; + } + } + return false; } @@ -64,8 +70,8 @@ public class FileFilter { fillIgnoreResultSet(); fillBugTable(); } - - static final String [] ignoreTestList = { + + static final String[] ignoreTestDirs = { ".", // ignore hidden directories and files "resources", // ignore resource directories "AppleScript", // AppleScript not supported @@ -73,13 +79,16 @@ public class FileFilter { "xsl", //xsl requires libxml2 & libxslt, not sup. "kde", // don't run kde tests. ".svn", // don't run anything under .svn folder - "gradients", //known crash + "gradients", // known crash + "profiler" // profiler is not supported + }; + + static final String [] ignoreTestList = { "toString-stack-overflow.html", // Crashes #606688 "frame-limit.html", // generates too many GREFs "css-insert-import-rule.html", // Crashes, #717414 "input-text-enter.html", // Crashes. #735088 "text-shadow-extreme-value.html", // Crashes #571671 - "001.html", "reflection-masks.html", "frame-creation-removal.html", "large-expressions.html", @@ -203,6 +212,8 @@ public class FileFilter { ignoreResultList.add("fast/loader/local-iFrame-source-from-local.html"); // extra spacing because iFrames rendered next to each other on Apple ignoreResultList.add("fast/loader/opaque-base-url.html"); + // RegExp is too large, causing OOM + ignoreResultList.add("fast/js/regexp-charclass-crash.html"); ignoreResultList.add("fast/text/plain-text-line-breaks.html"); diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java index 8b33d16..d685f5d 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java @@ -117,9 +117,14 @@ public abstract class FileList extends ListActivity { Map map = (Map) l.getItemAtPosition(position); String path = (String)map.get("path"); - if (path.length() > 0) - processFile(path, true); + if ((new File(path)).isDirectory()) { + mPath = path; + mFocusFile = null; + updateList(); + } else { + processFile(path, false); + } } /* @@ -148,7 +153,7 @@ public abstract class FileList extends ListActivity protected void setupPath() { - mPath = "/sdcard"; + mPath = "/sdcard/android/layout_tests"; mBaseLength = mPath.length(); } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostActivity.java index 9521f80..c77d98a 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostActivity.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostActivity.java @@ -16,14 +16,16 @@ package com.android.dumprendertree; +import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; +import java.io.FileReader; import java.io.IOException; +import java.util.List; import java.util.Vector; -import java.util.Stack; import android.app.Activity; import android.content.Intent; @@ -38,14 +40,12 @@ import android.webkit.WebSettings; import android.webkit.WebView; import android.widget.LinearLayout; import android.os.*; -import android.test.TestRecorder; -// SQLite3 in android has a bunch of bugs which -// is causing TestRecorder to not record the results -// properly. This class is a wrapper around it and records -// results in a file as well. -class TestRecorderV2 extends TestRecorder { - @Override +// TestRecorder creates two files, one for passing tests +// and another for failing tests and writes the paths to +// layout tests one line at a time. TestRecorder does not +// have ability to clear the results. +class TestRecorder { public void passed(String layout_file) { try { mBufferedOutputPassedStream.write(layout_file.getBytes()); @@ -54,72 +54,68 @@ class TestRecorderV2 extends TestRecorder { } catch(Exception e) { e.printStackTrace(); } - super.passed(layout_file); } - @Override public void failed(String layout_file, String reason) { try { mBufferedOutputFailedStream.write(layout_file.getBytes()); + mBufferedOutputFailedStream.write(" : ".getBytes()); + mBufferedOutputFailedStream.write(reason.getBytes()); mBufferedOutputFailedStream.write('\n'); mBufferedOutputFailedStream.flush(); } catch(Exception e) { e.printStackTrace(); } - super.failed(layout_file, reason); } - public TestRecorderV2() { - super(); + public void nontext(String layout_file) { + try { + mBufferedOutputNontextStream.write(layout_file.getBytes()); + mBufferedOutputNontextStream.write('\n'); + mBufferedOutputNontextStream.flush(); + } catch(Exception e) { + e.printStackTrace(); + } + } + + public TestRecorder(boolean resume) { try { - File resultsPassedFile = new File("/sdcard/layout_test_presults.txt"); - File resultsFailedFile = new File("/sdcard/layout_test_fresults.txt"); + File resultsPassedFile = new File("/sdcard/layout_tests_passed.txt"); + File resultsFailedFile = new File("/sdcard/layout_tests_failed.txt"); + File resultsNontextFile = new File("/sdcard/layout_tests_nontext.txt"); mBufferedOutputPassedStream = - new BufferedOutputStream(new FileOutputStream(resultsPassedFile, true)); + new BufferedOutputStream(new FileOutputStream(resultsPassedFile, resume)); mBufferedOutputFailedStream = - new BufferedOutputStream(new FileOutputStream(resultsFailedFile, true)); - + new BufferedOutputStream(new FileOutputStream(resultsFailedFile, resume)); + mBufferedOutputNontextStream = + new BufferedOutputStream(new FileOutputStream(resultsNontextFile, resume)); } catch (Exception e) { e.printStackTrace(); } } - - protected void finalize() throws Throwable { - mBufferedOutputPassedStream.flush(); - mBufferedOutputFailedStream.flush(); - mBufferedOutputPassedStream.close(); - mBufferedOutputFailedStream.close(); - } - private static BufferedOutputStream mBufferedOutputPassedStream; - private static BufferedOutputStream mBufferedOutputFailedStream; + public void close() { + try { + mBufferedOutputPassedStream.close(); + mBufferedOutputFailedStream.close(); + mBufferedOutputNontextStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + private BufferedOutputStream mBufferedOutputPassedStream; + private BufferedOutputStream mBufferedOutputFailedStream; + private BufferedOutputStream mBufferedOutputNontextStream; } public class HTMLHostActivity extends Activity implements LayoutTestController { - - private TestRecorderV2 mResultRecorder = new TestRecorderV2(); - private HTMLHostCallbackInterface mCallback = null; - private CallbackProxy mCallbackProxy; - - public class FileEntry { - public FileEntry(String path, int index) { - mPath = path; mIndex=index; - } - String mPath; - int mIndex; - } public class AsyncHandler extends Handler { @Override public void handleMessage(Message msg) { - if (msg.what == MSG_DUMP) { - this.removeMessages(MSG_TIMEOUT); - mTimedOut = false; - requestWebKitData(); - return; - } else if (msg.what == MSG_TIMEOUT) { + if (msg.what == MSG_TIMEOUT) { mTimedOut = true; requestWebKitData(); return; @@ -127,21 +123,24 @@ public class HTMLHostActivity extends Activity HTMLHostActivity.this.dump(mTimedOut, (String)msg.obj); return; } - + super.handleMessage(msg); } + } - void requestWebKitData() { - Message callback = obtainMessage(MSG_WEBKIT_DATA); - if (dumpAsText) { - mWebView.documentAsText(callback); - } else { - mWebView.externalRepresentation(callback); - } + public void requestWebKitData() { + Message callback = mHandler.obtainMessage(MSG_WEBKIT_DATA); + + if (mRequestedWebKitData) + throw new AssertionError("Requested webkit data twice: " + mWebView.getUrl()); + + mRequestedWebKitData = true; + if (mDumpAsText) { + mWebView.documentAsText(callback); + } else { + mWebView.externalRepresentation(callback); } - } - // Activity methods public void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -153,8 +152,9 @@ public class HTMLHostActivity extends Activity mWebView = new WebView(this); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.setWebChromeClient(mChromeClient); - eventSender = new WebViewEventSender(mWebView); - mCallbackProxy = new CallbackProxy(eventSender, this); + mEventSender = new WebViewEventSender(mWebView); + mCallbackProxy = new CallbackProxy(mEventSender, this); + mFinishedRunning = false; mWebView.addJavascriptInterface(mCallbackProxy, "layoutTestController"); mWebView.addJavascriptInterface(mCallbackProxy, "eventSender"); @@ -168,32 +168,99 @@ public class HTMLHostActivity extends Activity super.onRestoreInstanceState(savedInstanceState); } + private void getTestList() { + // Read test list. + try { + BufferedReader inReader = new BufferedReader(new FileReader(LAYOUT_TESTS_LIST_FILE)); + String line = inReader.readLine(); + while (line != null) { + if (line.startsWith(mTestPathPrefix)) + mTestList.add(line); + line = inReader.readLine(); + } + inReader.close(); + Log.v(LOGTAG, "Test list has " + mTestList.size() + " test(s)."); + } catch (Exception e) { + Log.e(LOGTAG, "Error while reading test list : " + e.getMessage()); + } + } + + private void resumeTestList() { + // read out the test name it stoped last time. + try { + BufferedReader inReader = new BufferedReader(new FileReader(TEST_STATUS_FILE)); + String line = inReader.readLine(); + for (int i = 0; i < mTestList.size(); i++) { + if (mTestList.elementAt(i).equals(line)) { + mTestList = new Vector<String>(mTestList.subList(i+1, mTestList.size())); + break; + } + } + inReader.close(); + } catch (Exception e) { + Log.e(LOGTAG, "Error reading " + TEST_STATUS_FILE); + } + } + + private void clearTestStatus() { + // Delete TEST_STATUS_FILE + try { + File f = new File(TEST_STATUS_FILE); + if (f.delete()) + Log.v(LOGTAG, "Deleted " + TEST_STATUS_FILE); + else + Log.e(LOGTAG, "Fail to delete " + TEST_STATUS_FILE); + } catch (Exception e) { + Log.e(LOGTAG, "Fail to delete " + TEST_STATUS_FILE + " : " + e.getMessage()); + } + } + + private void updateTestStatus(String s) { + // Write TEST_STATUS_FILE + try { + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(TEST_STATUS_FILE)); + bos.write(s.getBytes()); + bos.close(); + } catch (Exception e) { + Log.e(LOGTAG, "Cannot update file " + TEST_STATUS_FILE); + } + } + protected void onResume() { super.onResume(); - if (mProcessStack == null || mProcessStack.isEmpty() ) { - mOutstandingLoads = 0; - dumpAsText = false; - pageComplete = false; - - mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL); - - mFinishedStack = new Stack(); - + if (mTestList == null) + mTestList = new Vector<String>(); + + if (mTestList.isEmpty()) { + // Read settings Intent intent = getIntent(); - if (intent.getData() != null) { - File f = new File(intent.getData().toString()); - - if (f.isDirectory()) { - mProcessStack = new Vector(); - mProcessStack.add(new FileEntry(intent.getData().toString(), 0)); - Log.v(LOGTAG, "Initial dir: "+intent.getData().toString()); - loadNextPage(); - } else { - mCurrentFile = intent.getData().toString(); - mWebView.loadUrl("file://"+intent.getData().toString()); - } + mTestPathPrefix = intent.getStringExtra(TEST_PATH_PREFIX); + mSingleTestMode = intent.getBooleanExtra(SINGLE_TEST_MODE, false); + boolean resume = intent.getBooleanExtra(RESUME_FROM_CRASH, false); + mTimeoutInMillis = intent.getIntExtra(TIMEOUT_IN_MILLIS, 8000); + + mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL); + + if (mTestPathPrefix == null) + throw new AssertionError("mTestPathPrefix cannot be null"); + + Log.v(LOGTAG, "Run tests with prefix: " + mTestPathPrefix); + mResultRecorder = new TestRecorder(resume); + + if (!resume) + clearTestStatus(); + + if (!mSingleTestMode) { + getTestList(); + if (resume) + resumeTestList(); + } else { + mTestList.add(mTestPathPrefix); } + + if (!mTestList.isEmpty()) + runTestAtIndex(0); else mWebView.loadUrl("about:"); } @@ -206,9 +273,17 @@ public class HTMLHostActivity extends Activity protected void onDestroy() { super.onDestroy(); + mResultRecorder.close(); mWebView.destroy(); mWebView = null; } + + public void onLowMemory() { + super.onLowMemory(); + // Simulate a crash + Log.e(LOGTAG, "Low memory, killing self"); + System.exit(1); + } public boolean dispatchKeyEvent(KeyEvent event) { // Log key strokes as they don't seem to be matched @@ -216,82 +291,51 @@ public class HTMLHostActivity extends Activity return super.dispatchKeyEvent(event); } - // Functions - - protected void loadNextPage() { - dumpAsText = false; - pageComplete = false; - dumpTitleChanges = false; - eventSender.resetMouse(); - while (!mProcessStack.isEmpty()) { - FileEntry fe = (FileEntry)mProcessStack.remove(0); - if (fe.mIndex == 0) { - System.out.println(); - System.out.print(fe.mPath); - } - Log.v(LOGTAG, "Processing dir: "+fe.mPath+" size: "+mProcessStack.size()); - File f = new File(fe.mPath); - String [] files = f.list(); - for (int i = fe.mIndex; i < files.length; i++) { - if (FileFilter.ignoreTest(files[i])) { - continue; - } - File c = new File(f.getPath(), files[i]); - if (c.isDirectory()) { - Log.v(LOGTAG, "Adding dir: "+fe.mPath+"/"+files[i]); - mProcessStack.add(new FileEntry(fe.mPath+"/"+files[i], 0)); - } else if (files[i].toLowerCase().endsWith("ml")) { - mProcessStack.add(0, new FileEntry(fe.mPath, i+1)); - mCurrentFile = fe.mPath+"/"+files[i]; - Log.e(LOGTAG, "Processing: "+mCurrentFile); - mWebView.loadUrl("file://"+mCurrentFile); - - // Create a timeout timer - Message m = mHandler.obtainMessage(MSG_TIMEOUT); - // Some tests can take up to 5secs to run. - mHandler.sendMessageDelayed(m, 6000); - return; - } - } - Log.v(LOGTAG, "Finished dir: "+fe.mPath+" size: "+mProcessStack.size()); - } - // If we got to here, then we must have finished completely - finished(); - } - - public void scheduleDump() { - // Only schedule if we really are ready - if (waitToDump || mOutstandingLoads > 0 || mDumpRequested) { + // Run a test at specified index in the test list. + // Stops activity if run out of tests. + protected void runTestAtIndex(int testIndex) { + mTestIndex = testIndex; + + resetTestStatus(); + + if (testIndex == mTestList.size()) { + finished(); return; } - mDumpRequested = true; - mHandler.obtainMessage(MSG_DUMP).sendToTarget(); + String s = mTestList.elementAt(testIndex); + if (!mSingleTestMode) + updateTestStatus(s); + + Log.v(LOGTAG, " Running test: "+s); + mWebView.loadUrl("file://"+s); + + if (!mSingleTestMode) { + // Create a timeout timer + Message m = mHandler.obtainMessage(MSG_TIMEOUT); + mHandler.sendMessageDelayed(m, mTimeoutInMillis); + } } - + // Dump the page public void dump(boolean timeout, String webkitData) { - mDumpRequested = false; - System.out.print('.'); - - // remove the extension - String resultFile = mCurrentFile.substring(0, mCurrentFile.lastIndexOf('.')); - - // store the finished file on the stack so that we can do a diff at the end. - mFinishedStack.push(resultFile); + String currentTest = mTestList.elementAt(mTestIndex); + String resultFile = currentTest.substring(0, currentTest.lastIndexOf('.')); // dumpAsText version can be directly compared to expected results - if (dumpAsText) { + if (mDumpAsText) { resultFile += "-results.txt"; } else { resultFile += "-android-results.txt"; } + try { FileOutputStream os = new FileOutputStream(resultFile); if (timeout) { - Log.i("Layout test: Timeout", resultFile); - os.write("**Test timeout\n".getBytes()); + Log.w("Layout test: Timeout", resultFile); + os.write(TIMEOUT_STR.getBytes()); + os.write('\n'); } - if (dumpTitleChanges) + if (mDumpTitleChanges) os.write(mTitleChanges.toString().getBytes()); if (mDialogStrings != null) os.write(mDialogStrings.toString().getBytes()); @@ -305,18 +349,15 @@ public class HTMLHostActivity extends Activity ex.printStackTrace(); } - if (mProcessStack != null) - loadNextPage(); - else - finished(); + processResult(timeout, currentTest); + runTestAtIndex(mTestIndex + 1); } // Wrap up public void failedCase(String file, String reason) { - Log.i("Layout test:", file + " failed" + reason); + Log.w("Layout test: ", file + " failed " + reason); mResultRecorder.failed(file, reason); - - file = file + ".html"; + String bugNumber = FileFilter.isKnownBug(file); if (bugNumber != null) { System.out.println("FAIL known:"+bugNumber+ " "+file+reason); @@ -327,13 +368,11 @@ public class HTMLHostActivity extends Activity } System.out.println("FAIL: "+file+reason); } - + public void passedCase(String file) { - // Add the result to the sqlite database - Log.i("Layout test:", file + " passed"); + Log.v("Layout test:", file + " passed"); mResultRecorder.passed(file); - file = file + ".html"; String bugNumber = FileFilter.isKnownBug(file); if (bugNumber != null) { System.out.println("Bug Fixed: "+bugNumber+ " "+file); @@ -345,90 +384,105 @@ public class HTMLHostActivity extends Activity return; } } + + public void nontextCase(String file) { + Log.v("Layout test:", file + " nontext"); + mResultRecorder.nontext(file); + } public void setCallback(HTMLHostCallbackInterface callback) { mCallback = callback; } - - public void finished() { - int passed = 0; - while (!mFinishedStack.empty()) { - Log.v(LOGTAG, "Comparing dump and reference"); - String file = (String)mFinishedStack.pop(); - - // Only check results that we can check, ie dumpAsText results - String dumpFile = file + "-results.txt"; - File f = new File(dumpFile); - if (f.exists()) { - try { - FileInputStream fr = new FileInputStream(file+"-results.txt"); - FileInputStream fe = new FileInputStream(file+"-expected.txt"); - - mResultRecorder.started(file); - - // If the length is different then they are different - int diff = fe.available() - fr.available(); - if (diff > 1 || diff < 0) { - failedCase(file, " different length"); - fr.close(); - fe.close(); - - mResultRecorder.finished(file); - continue; - } - byte[] br = new byte[fr.available()]; - byte[] be = new byte[fe.available()]; - fr.read(br); - fe.read(be); - boolean fail = false; - for (int i = 0; i < br.length; i++) { - if (br[i] != be[i]) { - failedCase(file, " @offset: "+i); - fail = true; - break; - } - } - if (br.length != be.length && be[be.length-1] == '\n') { - Log.d(LOGTAG, "Extra new line being ignore:" + file); - } + + public void processResult(boolean timeout, String test_path) { + Log.v(LOGTAG, " Processing result: " + test_path); + // remove the extension + String short_file = test_path.substring(0, test_path.lastIndexOf('.')); + if (timeout) { + failedCase(test_path, "TIMEDOUT"); + return; + } + // Only check results that we can check, ie dumpAsText results + String dumpFile = short_file + "-results.txt"; + File f = new File(dumpFile); + if (f.exists()) { + try { + FileInputStream fr = new FileInputStream(short_file+"-results.txt"); + FileInputStream fe = new FileInputStream(short_file+"-expected.txt"); + + // If the length is different then they are different + int diff = fe.available() - fr.available(); + if (diff > 1 || diff < 0) { + failedCase(test_path, " different length"); fr.close(); fe.close(); - if (!fail) { - passed++; - passedCase(file); + return; + } + byte[] br = new byte[fr.available()]; + byte[] be = new byte[fe.available()]; + fr.read(br); + fe.read(be); + boolean fail = false; + for (int i = 0; i < br.length; i++) { + if (br[i] != be[i]) { + failedCase(test_path, " @offset: "+i); + fr.close(); + fe.close(); + return; } - } catch (FileNotFoundException ex) { - // TODO do something here - } catch (IOException ex) { - // Failed on available() or read() } - mResultRecorder.finished(file); + if (br.length != be.length && be[be.length-1] == '\n') { + Log.d(LOGTAG, "Extra new line being ignore:" + test_path); + } + fr.close(); + fe.close(); + passedCase(test_path); + } catch (FileNotFoundException ex) { + // TODO do something here + } catch (IOException ex) { + // Failed on available() or read() } - } + + return; + } - if (mCallback != null) { + File nontext_result = new File(short_file + "-android-results.txt"); + if (nontext_result.exists()) + mResultRecorder.nontext(test_path); + } + + public void finished() { + if (mCallback != null) { mCallback.waitForFinish(); - } - + } + + mFinishedRunning = true; finish(); } // LayoutTestController Functions public void dumpAsText() { - dumpAsText = true; - String url = mWebView.getUrl(); - Log.v(LOGTAG, "dumpAsText called:"+url); - if (url.length() > 60) - url = url.substring(60); + mDumpAsText = true; + if (mWebView != null) { + String url = mWebView.getUrl(); + Log.v(LOGTAG, "dumpAsText called: "+url); + } } public void waitUntilDone() { - waitToDump = true; + mWaitUntilDone = true; + String url = mWebView.getUrl(); + Log.v(LOGTAG, "waitUntilDone called: " + url); } public void notifyDone() { - waitToDump = false; - mChromeClient.onProgressChanged(mWebView, 100); + String url = mWebView.getUrl(); + Log.v(LOGTAG, "notifyDone called: " + url); + if (mWaitUntilDone) { + mWaitUntilDone = false; + mChromeClient.onProgressChanged(mWebView, 100); + } } + public void display() { mWebView.invalidate(); } @@ -461,18 +515,17 @@ public class HTMLHostActivity extends Activity } public void dumpTitleChanges() { - if (!dumpTitleChanges) { + if (!mDumpTitleChanges) { mTitleChanges = new StringBuffer(); } - dumpTitleChanges = true; + mDumpTitleChanges = true; } public void keepWebHistory() { - if (!keepWebHistory) { + if (!mKeepWebHistory) { mWebHistory = new Vector(); } - keepWebHistory = true; - + mKeepWebHistory = true; } public void queueBackNavigation(int howfar) { @@ -491,7 +544,7 @@ public class HTMLHostActivity extends Activity } public void queueReload() { - mWebView.reload(); + mWebView.reload(); } public void queueScript(String scriptToRunInCurrentContext) { @@ -520,33 +573,36 @@ public class HTMLHostActivity extends Activity } public void testRepaint() { - mWebView.invalidate(); + mWebView.invalidate(); } // Instrumentation calls this to find // if the activity has finished running the layout tests + // TODO(fqian): need to sync on mFinisheRunning public boolean hasFinishedRunning() { - if( mProcessStack == null || mFinishedStack == null) - return false; - - if (mProcessStack.isEmpty() && mFinishedStack.empty()) { - return true; - } - - return false; + return mFinishedRunning; } - + private final WebChromeClient mChromeClient = new WebChromeClient() { @Override public void onProgressChanged(WebView view, int newProgress) { if (newProgress == 100) { - pageComplete = true; - String url = mWebView.getUrl(); - if (url != null) { + if (!mSingleTestMode && !mTimedOut && !mWaitUntilDone && !mRequestedWebKitData) { + String url = mWebView.getUrl(); Log.v(LOGTAG, "Finished: "+ url); - if (url.length() > 60) - url = url.substring(60); - scheduleDump(); + mHandler.removeMessages(MSG_TIMEOUT); + requestWebKitData(); + } else { + String url = mWebView.getUrl(); + if (mSingleTestMode) { + Log.v(LOGTAG, "Single test mode: " + url); + } else if (mTimedOut) { + Log.v(LOGTAG, "Timed out before finishing: " + url); + } else if (mWaitUntilDone) { + Log.v(LOGTAG, "Waiting for notifyDone: " + url); + } else if (mRequestedWebKitData) { + Log.v(LOGTAG, "Requested webkit data ready: " + url); + } } } } @@ -556,7 +612,7 @@ public class HTMLHostActivity extends Activity if (title.length() > 30) title = "..."+title.substring(title.length()-30); setTitle(title); - if (dumpTitleChanges) { + if (mDumpTitleChanges) { mTitleChanges.append("TITLE CHANGED: "); mTitleChanges.append(title); mTitleChanges.append("\n"); @@ -572,36 +628,90 @@ public class HTMLHostActivity extends Activity mDialogStrings.append("ALERT: "); mDialogStrings.append(message); mDialogStrings.append('\n'); - return false; + result.confirm(); + return true; + } + + @Override + public boolean onJsConfirm(WebView view, String url, String message, + JsResult result) { + if (mDialogStrings == null) { + mDialogStrings = new StringBuffer(); + } + mDialogStrings.append("CONFIRM: "); + mDialogStrings.append(message); + mDialogStrings.append('\n'); + result.confirm(); + return true; + } + + @Override + public boolean onJsPrompt(WebView view, String url, String message, + String defaultValue, JsPromptResult result) { + if (mDialogStrings == null) { + mDialogStrings = new StringBuffer(); + } + mDialogStrings.append("PROMPT: "); + mDialogStrings.append(message); + mDialogStrings.append(", default text: "); + mDialogStrings.append(defaultValue); + mDialogStrings.append('\n'); + result.confirm(); + return true; } }; - + + private void resetTestStatus() { + mWaitUntilDone = false; + mDumpAsText = false; + mTimedOut = false; + mDumpTitleChanges = false; + mRequestedWebKitData = false; + mEventSender.resetMouse(); + } + + private TestRecorder mResultRecorder; + private HTMLHostCallbackInterface mCallback = null; + private CallbackProxy mCallbackProxy; + private WebView mWebView; - private WebViewEventSender eventSender; - private Vector mProcessStack; - private Stack mFinishedStack; - static final String LOGTAG="DumpRenderTree"; - private String mCurrentFile; - private int mOutstandingLoads; - private AsyncHandler mHandler; - private boolean mDumpRequested; + private WebViewEventSender mEventSender; + + private Vector<String> mTestList; + private int mTestIndex; - private boolean dumpAsText; - private boolean waitToDump; - private boolean pageComplete; + private int mTimeoutInMillis; + private String mTestPathPrefix; + private boolean mSingleTestMode; + + private AsyncHandler mHandler; + private boolean mFinishedRunning; - private boolean dumpTitleChanges; + private boolean mTimedOut; + private boolean mRequestedWebKitData; + private boolean mDumpAsText; + private boolean mWaitUntilDone; + private boolean mDumpTitleChanges; + private StringBuffer mTitleChanges; - private StringBuffer mDialogStrings; - private boolean keepWebHistory; + private boolean mKeepWebHistory; private Vector mWebHistory; - private boolean mTimedOut; + static final String TIMEOUT_STR = "**Test timeout"; + + static final int MSG_TIMEOUT = 0; + static final int MSG_WEBKIT_DATA = 1; - static final int MSG_DUMP = 0; - static final int MSG_TIMEOUT = 1; - static final int MSG_WEBKIT_DATA = 2; + static final String LOGTAG="DumpRenderTree"; + static final String LAYOUT_TESTS_ROOT = "/sdcard/android/layout_tests/"; + static final String LAYOUT_TESTS_LIST_FILE = "/sdcard/layout_tests_list.txt"; + static final String TEST_STATUS_FILE = "/sdcard/running_test.txt"; + + static final String RESUME_FROM_CRASH = "ResumeFromCrash"; + static final String TEST_PATH_PREFIX = "TestPathPrefix"; + static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis"; + static final String SINGLE_TEST_MODE = "SingleTestMode"; } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java index e0e535e..1f37405 100755 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java @@ -21,6 +21,9 @@ import com.android.dumprendertree.LayoutTestsAutoTest; import android.test.InstrumentationTestRunner; import android.test.InstrumentationTestSuite; +import android.util.Log; +import android.content.Intent; +import android.os.Bundle; /** @@ -44,5 +47,22 @@ public class LayoutTestsAutoRunner extends InstrumentationTestRunner { public ClassLoader getLoader() { return LayoutTestsAutoRunner.class.getClassLoader(); } + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + String path = (String) icicle.get("path"); + LayoutTestsAutoTest.setLayoutTestDir(path); + String timeout_str = (String) icicle.get("timeout"); + int timeout = 0; // default value + if (timeout_str != null) { + try { + timeout = Integer.parseInt(timeout_str); + } catch (Exception e) { + e.printStackTrace(); + } + } + LayoutTestsAutoTest.setTimeoutInMillis(timeout); + } } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java index f46b263..3e65f03 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java @@ -16,142 +16,157 @@ package com.android.dumprendertree; +import android.app.Activity; import android.app.Instrumentation; import android.app.Instrumentation.ActivityMonitor; import android.content.ContentResolver; import android.content.ContentValues; +import android.content.Intent; + import android.util.Log; import android.view.KeyEvent; +import android.os.Bundle; +import android.os.Message; import android.test.ActivityInstrumentationTestCase; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.LargeTest; import com.android.dumprendertree.HTMLHostActivity; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase<Menu> { private final static String LOGTAG = "LayoutTests"; - private final static String LAYOUT_TESTS_ROOT = "/sdcard/android/layout_tests/"; - + private final static int DEFAULT_TIMEOUT_IN_MILLIS = 6000; + private static String layoutTestDir = null; + private static int mTimeoutInMillis = 0; + public LayoutTestsAutoTest() { super("com.android.dumprendertree", Menu.class); } + // This function writes the result of the layout test to + // Am status so that it can be picked up from a script. + public void passOrFailCallback(String file, boolean result) { + Instrumentation inst = getInstrumentation(); + Bundle bundle = new Bundle(); + bundle.putBoolean(file, result); + inst.sendStatus(0, bundle); + } + + public static void setTimeoutInMillis(int millis) { + mTimeoutInMillis = (millis > 0) ? millis : DEFAULT_TIMEOUT_IN_MILLIS; + } + + public static void setLayoutTestDir(String name) { + if (name == null) + throw new AssertionError("Layout test directory cannot be null."); + layoutTestDir = HTMLHostActivity.LAYOUT_TESTS_ROOT + name; + Log.v("LayoutTestsAutoTest", " Only running the layout tests : " + layoutTestDir); + } + // Invokes running of layout tests // and waits till it has finished running. - public void executeLayoutTests(String folder) { + public void executeLayoutTests(boolean resume) { Instrumentation inst = getInstrumentation(); - getActivity().processFile(folder, true); - + + { + Activity activity = getActivity(); + Intent intent = new Intent(); + intent.setClass(activity, HTMLHostActivity.class); + intent.putExtra(HTMLHostActivity.RESUME_FROM_CRASH, resume); + intent.putExtra(HTMLHostActivity.SINGLE_TEST_MODE, false); + intent.putExtra(HTMLHostActivity.TEST_PATH_PREFIX, layoutTestDir); + intent.putExtra(HTMLHostActivity.TIMEOUT_IN_MILLIS, mTimeoutInMillis); + activity.startActivity(intent); + } + ActivityMonitor htmlHostActivityMonitor = inst.addMonitor("com.android.dumprendertree.HTMLHostActivity", null, false); + HTMLHostActivity activity = - (HTMLHostActivity) htmlHostActivityMonitor.waitForActivityWithTimeout(6000); - + (HTMLHostActivity) htmlHostActivityMonitor.waitForActivity(); + while (!activity.hasFinishedRunning()) { // Poll every 5 seconds to determine if the layout // tests have finished running try {Thread.sleep(5000); } catch(Exception e){} } - + // Wait few more seconds so that results are // flushed to the /sdcard try {Thread.sleep(5000); } catch(Exception e){} - return ; + // Clean up the HTMLHostActivity activity + activity.finish(); + } + + public void generateTestList() { + try { + File tests_list = new File(HTMLHostActivity.LAYOUT_TESTS_LIST_FILE); + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tests_list, false)); + findTestsRecursively(bos, layoutTestDir); + bos.flush(); + bos.close(); + } catch (Exception e) { + Log.e(LOGTAG, "Error when creating test list: " + e.getMessage()); + } + } + + private void findTestsRecursively(BufferedOutputStream bos, String dir) throws IOException { + Log.v(LOGTAG, "Searching tests under " + dir); + + File d = new File(dir); + if (!d.isDirectory()) { + throw new AssertionError("A directory expected, but got " + dir); + } + + String[] files = d.list(); + for (int i = 0; i < files.length; i++) { + String s = dir + "/" + files[i]; + if (FileFilter.ignoreTest(s)) { + Log.v(LOGTAG, " Ignoring: " + s); + continue; + } + if (s.toLowerCase().endsWith(".html") + || s.toLowerCase().endsWith(".xml")) { + bos.write(s.getBytes()); + bos.write('\n'); + continue; + } + + File f = new File(s); + if (f.isDirectory()) { + findTestsRecursively(bos, s); + continue; + } + + Log.v(LOGTAG, "Skipping " + s); + } } // Running all the layout tests at once sometimes // causes the dumprendertree to run out of memory. // So, additional tests are added to run the tests // in chunks. - @LargeTest - public void testAllLayoutTests() { - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast"); - } - - @LargeTest - public void testLayoutSubset1() { - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/backgrounds"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/borders"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/box-shadow"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/box-sizing"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/canvas"); - } - - @LargeTest - public void testLayoutSubset2() { - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/clip"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/compact"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/cookies"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/css"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/css-generated-content"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/doctypes"); - } - - @LargeTest - public void testLayoutSubset3() { - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/dom"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/dynamic"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/encoding"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/events"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/flexbox"); - } - - @LargeTest - public void testLayoutSubset4() { - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/forms"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/frames"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/gradients"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/history"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/html"); - } - - @LargeTest - public void testLayoutSubset5() { - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/images"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/inline"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/inline-block"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/innerHTML"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/invalid"); - } - - @LargeTest - public void testLayoutSubset6() { - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/js"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/layers"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/leaks"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/lists"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/loader"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/media"); - } - - @LargeTest - public void testLayoutSubset7() { - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/multicol"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/overflow"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/parser"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/profiler"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/reflections"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/regex"); - } - - @LargeTest - public void testLayoutSubset8() { - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/repaint"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/replaced"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/runin"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/selectors"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/table"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/text"); + public void startLayoutTests() { + try { + File tests_list = new File(HTMLHostActivity.LAYOUT_TESTS_LIST_FILE); + if (!tests_list.exists()) + generateTestList(); + } catch (Exception e) { + e.printStackTrace(); + } + + executeLayoutTests(false); } - @LargeTest - public void testLayoutSubset9() { - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/tokenizer"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/transforms"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/xpath"); - executeLayoutTests(LAYOUT_TESTS_ROOT + "fast/xsl"); + public void resumeLayoutTests() { + executeLayoutTests(true); } } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java b/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java index 2def8f3..de0da61 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java @@ -43,9 +43,12 @@ public class Menu extends FileList { void processFile(String filename, boolean selection) { - Intent result = new Intent(null, Uri.parse(filename)); + Intent result = new Intent(); result.setClass(this, HTMLHostActivity.class); - result.putExtra("ReturnWhenFinished", selection); + result.putExtra(HTMLHostActivity.RESUME_FROM_CRASH, false); + result.putExtra(HTMLHostActivity.SINGLE_TEST_MODE, true); + result.putExtra(HTMLHostActivity.TEST_PATH_PREFIX, filename); + result.putExtra(HTMLHostActivity.TIMEOUT_IN_MILLIS, 8000); startActivity(result); } |