summaryrefslogtreecommitdiffstats
path: root/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java')
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java373
1 files changed, 328 insertions, 45 deletions
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
index 3e65f03..a857e68 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
@@ -25,92 +25,375 @@ import android.content.Intent;
import android.util.Log;
import android.view.KeyEvent;
+import android.webkit.WebSettings;
import android.os.Bundle;
import android.os.Message;
-import android.test.ActivityInstrumentationTestCase;
+import android.test.ActivityInstrumentationTestCase2;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
-import com.android.dumprendertree.HTMLHostActivity;
+import com.android.dumprendertree.TestShellActivity;
import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.FileReader;
import java.io.IOException;
+import java.util.Vector;
+
+//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 MyTestRecorder {
+ private BufferedOutputStream mBufferedOutputPassedStream;
+ private BufferedOutputStream mBufferedOutputFailedStream;
+ private BufferedOutputStream mBufferedOutputNoresultStream;
+
+ public void passed(String layout_file) {
+ try {
+ mBufferedOutputPassedStream.write(layout_file.getBytes());
+ mBufferedOutputPassedStream.write('\n');
+ mBufferedOutputPassedStream.flush();
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void failed(String layout_file) {
+ try {
+ mBufferedOutputFailedStream.write(layout_file.getBytes());
+ mBufferedOutputFailedStream.write('\n');
+ mBufferedOutputFailedStream.flush();
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void noresult(String layout_file) {
+ try {
+ mBufferedOutputNoresultStream.write(layout_file.getBytes());
+ mBufferedOutputNoresultStream.write('\n');
+ mBufferedOutputNoresultStream.flush();
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public MyTestRecorder(boolean resume) {
+ try {
+ File resultsPassedFile = new File("/sdcard/layout_tests_passed.txt");
+ File resultsFailedFile = new File("/sdcard/layout_tests_failed.txt");
+ File noExpectedResultFile = new File("/sdcard/layout_tests_nontext.txt");
+
+ mBufferedOutputPassedStream =
+ new BufferedOutputStream(new FileOutputStream(resultsPassedFile, resume));
+ mBufferedOutputFailedStream =
+ new BufferedOutputStream(new FileOutputStream(resultsFailedFile, resume));
+ mBufferedOutputNoresultStream =
+ new BufferedOutputStream(new FileOutputStream(noExpectedResultFile, resume));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void close() {
+ try {
+ mBufferedOutputPassedStream.close();
+ mBufferedOutputFailedStream.close();
+ mBufferedOutputNoresultStream.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
-public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase<Menu> {
- private final static String LOGTAG = "LayoutTests";
- private final static int DEFAULT_TIMEOUT_IN_MILLIS = 6000;
- private static String layoutTestDir = null;
- private static int mTimeoutInMillis = 0;
+public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestShellActivity> {
+
+ private static final String LOGTAG = "LayoutTests";
+ static final int DEFAULT_TIMEOUT_IN_MILLIS = 5000;
+
+ static final String LAYOUT_TESTS_ROOT = "/sdcard/android/layout_tests/";
+ static final String LAYOUT_TESTS_RESULT_DIR = "/sdcard/android/layout_tests_results/";
+ static final String ANDROID_EXPECTED_RESULT_DIR = "/sdcard/android/expected_results/";
+ static final String LAYOUT_TESTS_LIST_FILE = "/sdcard/android/layout_tests_list.txt";
+ static final String TEST_STATUS_FILE = "/sdcard/android/running_test.txt";
+
+ private MyTestRecorder mResultRecorder;
+ private Vector<String> mTestList;
+ private boolean mRebaselineResults;
+ private String mTestPathPrefix;
public LayoutTestsAutoTest() {
- super("com.android.dumprendertree", Menu.class);
+ super("com.android.dumprendertree", TestShellActivity.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) {
+ private void passOrFailCallback(String file, boolean result) {
Instrumentation inst = getInstrumentation();
Bundle bundle = new Bundle();
bundle.putBoolean(file, result);
inst.sendStatus(0, bundle);
}
+
+ 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);
+ }
+ }
+
+ private String getResultFile(String test) {
+ String shortName = test.substring(0, test.lastIndexOf('.'));
+ // Write actual results to result directory.
+ return shortName.replaceFirst(LAYOUT_TESTS_ROOT, LAYOUT_TESTS_RESULT_DIR) + "-result.txt";
+ }
+
+ private String getExpectedResultFile(String test) {
+ String shortName = test.substring(0, test.lastIndexOf('.'));
+ return shortName + "-expected.txt";
+ }
+
+ private String getAndroidExpectedResultFile(String expectedResultFile) {
+ return expectedResultFile.replaceFirst(LAYOUT_TESTS_ROOT, ANDROID_EXPECTED_RESULT_DIR);
+ }
+
+ // Wrap up
+ private void failedCase(String file) {
+ Log.w("Layout test: ", file + " failed");
+ mResultRecorder.failed(file);
+ }
- public static void setTimeoutInMillis(int millis) {
- mTimeoutInMillis = (millis > 0) ? millis : DEFAULT_TIMEOUT_IN_MILLIS;
+ private void passedCase(String file) {
+ Log.v("Layout test:", file + " passed");
+ mResultRecorder.passed(file);
}
- 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);
+ private void noresultCase(String file) {
+ Log.v("Layout test:", file + " no expected result");
+ mResultRecorder.noresult(file);
}
+
+ private void processResult(String testFile, String actualResultFile, String expectedResultFile) {
+ Log.v(LOGTAG, " Processing result: " + testFile);
+ File actual = new File(actualResultFile);
+ File expected = new File(expectedResultFile);
+ if (actual.exists() && expected.exists()) {
+ try {
+ boolean passing = true;
+ BufferedReader fr = new BufferedReader(new FileReader(actual));
+ BufferedReader fe = new BufferedReader(new FileReader(expected));
+ while (true) {
+ String s1 = fr.readLine();
+ String s2 = fe.readLine();
+ if (s1 == null && s2 == null)
+ break; // both files are the same
+ if (s1 == null || s2 == null || !s1.equals(s2)) {
+ passing = false;
+ break;
+ }
+ }
+
+ if (passing) {
+ passedCase(testFile);
+ } else {
+ failedCase(testFile);
+ }
+
+ fe.close();
+ fr.close();
+ } catch (FileNotFoundException ex) {
+ Log.e(LOGTAG, "File not found : " + ex.getMessage());
+ } catch (IOException ex) {
+ Log.e(LOGTAG, "IO Error : " + ex.getMessage());
+ }
+ return;
+ }
+
+ if (!expected.exists()) {
+ noresultCase(testFile);
+ }
+ }
+
+ private void runTestAndWaitUntilDone(TestShellActivity activity, String test, int timeout) {
+ activity.setCallback(new TestShellCallback() {
+ public void finished() {
+ synchronized (LayoutTestsAutoTest.this) {
+ LayoutTestsAutoTest.this.notifyAll();
+ }
+ }
+ });
+
+ String resultFile = getResultFile(test);
+ if (mRebaselineResults) {
+ String expectedResultFile = getExpectedResultFile(test);
+ File f = new File(expectedResultFile);
+ if (f.exists()) {
+ return; // don't run test and don't overwrite default tests.
+ }
+
+ resultFile = getAndroidExpectedResultFile(expectedResultFile);
+ }
+
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setClass(activity, TestShellActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ intent.putExtra(TestShellActivity.TEST_URL, "file://" + test);
+ intent.putExtra(TestShellActivity.RESULT_FILE, resultFile);
+ intent.putExtra(TestShellActivity.TIMEOUT_IN_MILLIS, timeout);
+ activity.startActivity(intent);
+
+ // Wait until done.
+ synchronized (this) {
+ try {
+ this.wait();
+ } catch (InterruptedException e) { }
+ }
+
+ if (!mRebaselineResults) {
+ String expectedResultFile = getExpectedResultFile(test);
+ File f = new File(expectedResultFile);
+ if (!f.exists()) {
+ expectedResultFile = getAndroidExpectedResultFile(expectedResultFile);
+ }
+
+ processResult(test, resultFile, expectedResultFile);
+ }
+ }
+
// Invokes running of layout tests
// and waits till it has finished running.
public void executeLayoutTests(boolean resume) {
- Instrumentation inst = getInstrumentation();
-
- {
- 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);
- }
+ LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner) getInstrumentation();
+ // A convenient method to be called by another activity.
+
+ if (runner.mTestPath == null) {
+ Log.e(LOGTAG, "No test specified");
+ return;
+ }
+
+ this.mTestList = new Vector<String>();
- ActivityMonitor htmlHostActivityMonitor =
- inst.addMonitor("com.android.dumprendertree.HTMLHostActivity", null, false);
+ // Read settings
+ try {
+ this.mTestPathPrefix =
+ (new File(LAYOUT_TESTS_ROOT + runner.mTestPath)).getCanonicalPath();
+ } catch (IOException e) {
+ Log.e(LOGTAG, "Cannot find test path prefix: " + e.getMessage());
+ return;
+ }
+
+ this.mRebaselineResults = runner.mRebaseline;
+
+ int timeout = runner.mTimeoutInMillis;
+ if (timeout <= 0) {
+ timeout = DEFAULT_TIMEOUT_IN_MILLIS;
+ }
+
+ this.mResultRecorder = new MyTestRecorder(resume);
+
+ if (!resume)
+ clearTestStatus();
+
+ getTestList();
+ if (resume)
+ resumeTestList();
+
+ TestShellActivity activity = (TestShellActivity) getActivity();
- HTMLHostActivity activity =
- (HTMLHostActivity) htmlHostActivityMonitor.waitForActivity();
+ // Run tests.
+ for (int i = 0; i < mTestList.size(); i++) {
+ String s = mTestList.elementAt(i);
+ updateTestStatus(s);
+ // Run tests
+ runTestAndWaitUntilDone(activity, s, runner.mTimeoutInMillis);
+ }
- while (!activity.hasFinishedRunning()) {
- // Poll every 5 seconds to determine if the layout
- // tests have finished running
- try {Thread.sleep(5000); } catch(Exception e){}
- }
+ updateTestStatus("#DONE");
+
+ activity.finish();
+ }
- // Wait few more seconds so that results are
- // flushed to the /sdcard
- try {Thread.sleep(5000); } catch(Exception e){}
- // Clean up the HTMLHostActivity activity
- activity.finish();
+ private String getTestPath() {
+ LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner) getInstrumentation();
+
+ String test_path = LAYOUT_TESTS_ROOT;
+ if (runner.mTestPath != null) {
+ test_path += runner.mTestPath;
+ }
+ try {
+ test_path = new File(test_path).getCanonicalPath();
+ } catch (IOException e) {
+ Log.e("LayoutTestsAutoTest", "Cannot get cannonical path " + e.getMessage());
+ }
+ Log.v("LayoutTestsAutoTest", " Test path : " + test_path);
+
+ return test_path;
}
public void generateTestList() {
try {
- File tests_list = new File(HTMLHostActivity.LAYOUT_TESTS_LIST_FILE);
+ File tests_list = new File(LAYOUT_TESTS_LIST_FILE);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tests_list, false));
- findTestsRecursively(bos, layoutTestDir);
+ findTestsRecursively(bos, getTestPath());
bos.flush();
bos.close();
} catch (Exception e) {
@@ -156,7 +439,7 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase<Menu> {
// in chunks.
public void startLayoutTests() {
try {
- File tests_list = new File(HTMLHostActivity.LAYOUT_TESTS_LIST_FILE);
+ File tests_list = new File(LAYOUT_TESTS_LIST_FILE);
if (!tests_list.exists())
generateTestList();
} catch (Exception e) {