From f92bd42a702af7047ac4bd7c95b4a82973b7a79d Mon Sep 17 00:00:00 2001 From: Guang Zhu Date: Mon, 29 Jun 2009 10:40:55 -0700 Subject: [PATCH] Added a new operation mode where user can launch all tests under a folder from test app ui. --- .../com/android/dumprendertree/FileList.java | 73 ++++++--- .../com/android/dumprendertree/FsUtils.java | 80 +++++++++ .../dumprendertree/LayoutTestsAutoTest.java | 55 +------ .../src/com/android/dumprendertree/Menu.java | 42 ++++- .../dumprendertree/ReliabilityTest.java | 35 +--- .../dumprendertree/TestShellActivity.java | 153 +++++++++++++----- 6 files changed, 288 insertions(+), 150 deletions(-) create mode 100644 tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java index 0218317dbcc6a..e741177a90d98 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java @@ -23,7 +23,9 @@ import java.util.List; import java.util.Map; import java.io.File; +import android.app.AlertDialog; import android.app.ListActivity; +import android.content.DialogInterface; import android.view.KeyEvent; import android.view.View; import android.widget.ListView; @@ -31,7 +33,7 @@ import android.widget.SimpleAdapter; import android.os.Bundle; -public abstract class FileList extends ListActivity +public abstract class FileList extends ListActivity { public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) @@ -39,7 +41,7 @@ public abstract class FileList extends ListActivity case KeyEvent.KEYCODE_DPAD_LEFT: if (mPath.length() > mBaseLength) { File f = new File(mPath); - mFocusFile = f.getName(); + mFocusFile = f.getName(); mFocusIndex = 0; f = f.getParentFile(); mPath = f.getPath(); @@ -47,7 +49,7 @@ public abstract class FileList extends ListActivity return true; } break; - + case KeyEvent.KEYCODE_DPAD_RIGHT: { Map map = (Map) getListView().getItemAtPosition(getListView().getSelectedItemPosition()); @@ -61,24 +63,24 @@ public abstract class FileList extends ListActivity } return true; } - + default: break; } return super.onKeyDown(keyCode, event); } - public void onCreate(Bundle icicle) + public void onCreate(Bundle icicle) { super.onCreate(icicle); setupPath(); updateList(); } - + protected List getData() { List myData = new ArrayList(); - + File f = new File(mPath); if (!f.exists()) { addItem(myData, "!LayoutTests path missing!", ""); @@ -103,10 +105,10 @@ public abstract class FileList extends ListActivity addItem(myData, files[i], path); } } - + return myData; } - + protected void addItem(List data, String name, String path) { HashMap temp = new HashMap(); @@ -114,34 +116,58 @@ public abstract class FileList extends ListActivity temp.put("path", path); data.add(temp); } - + protected void onListItemClick(ListView l, View v, int position, long id) { - Map map = (Map) l.getItemAtPosition(position); - String path = (String)map.get("path"); + Map map = (Map) l.getItemAtPosition(position); + final String path = (String)map.get("path"); if ((new File(path)).isDirectory()) { - mPath = path; - mFocusFile = null; - updateList(); + final CharSequence[] items = {"Open", "Run"}; + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Select an Action"); + builder.setSingleChoiceItems(items, -1, + new DialogInterface.OnClickListener(){ + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case OPEN_DIRECTORY: + dialog.dismiss(); + mPath = path; + mFocusFile = null; + updateList(); + break; + case RUN_TESTS: + dialog.dismiss(); + processDirectory(path, false); + break; + } + } + }); + builder.create().show(); } else { processFile(path, false); } } - + + /* + * This function is called when the user has selected a directory in the + * list and wants to perform an action on it instead of navigating into + * the directory. + */ + abstract void processDirectory(String path, boolean selection); /* * This function is called when the user has selected a file in the * file list. The selected file could be a file or a directory. * The flag indicates if this was from a selection or not. */ abstract void processFile(String filename, boolean selection); - + /* * This function is called when the file list is being built. Return * true if the file is to be added to the file list. */ abstract boolean fileFilter(File f); - + protected void updateList() { setListAdapter(new SimpleAdapter(this, getData(), @@ -152,16 +178,19 @@ public abstract class FileList extends ListActivity setTitle(title); getListView().setSelection(mFocusIndex); } - - protected void setupPath() + + protected void setupPath() { mPath = "/sdcard/android/layout_tests"; mBaseLength = mPath.length(); } - + protected String mPath; protected int mBaseLength; protected String mFocusFile; protected int mFocusIndex; - + + private final static int OPEN_DIRECTORY = 0; + private final static int RUN_TESTS = 1; + } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java new file mode 100644 index 0000000000000..cc2f1f5936a77 --- /dev/null +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java @@ -0,0 +1,80 @@ +package com.android.dumprendertree; + +import android.util.Log; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; + +public class FsUtils { + + private static final String LOGTAG = "FsUtils"; + private FsUtils() { + //no creation of instances + } + + public static void findLayoutTestsRecursively(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()) { + findLayoutTestsRecursively(bos, s); + continue; + } + + Log.v(LOGTAG, "Skipping " + s); + } + } + + public static void updateTestStatus(String statusFile, String s) { + try { + BufferedOutputStream bos = new BufferedOutputStream( + new FileOutputStream(statusFile)); + bos.write(s.getBytes()); + bos.close(); + } catch (Exception e) { + Log.e(LOGTAG, "Cannot update file " + statusFile); + } + } + + public static String readTestStatus(String statusFile) { + // read out the test name it stopped last time. + String status = null; + File testStatusFile = new File(statusFile); + if(testStatusFile.exists()) { + try { + BufferedReader inReader = new BufferedReader( + new FileReader(testStatusFile)); + status = inReader.readLine(); + inReader.close(); + } catch (IOException e) { + Log.e(LOGTAG, "Error reading test status.", e); + } + } + return status; + } + +} diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java index f169a2664171f..a03490d8f0410 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java @@ -178,15 +178,13 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2(mTestList.subList(i+1, mTestList.size())); break; } } - inReader.close(); } catch (Exception e) { Log.e(LOGTAG, "Error reading " + TEST_STATUS_FILE); } @@ -204,18 +202,7 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2 0) { // Create a timeout timer Message m = mHandler.obtainMessage(MSG_TIMEOUT); mHandler.sendMessageDelayed(m, mTimeoutInMillis); } } - + + private void beginUiAutoTest() { + try { + mTestListReader = new BufferedReader( + new FileReader(mUiAutoTestPath)); + } catch (IOException ioe) { + Log.e(LOGTAG, "Failed to open test list for read.", ioe); + finishUiAutoTest(); + return; + } + moveToNextTest(); + } + + private void finishUiAutoTest() { + try { + if(mTestListReader != null) + mTestListReader.close(); + } catch (IOException ioe) { + Log.w(LOGTAG, "Failed to close test list file.", ioe); + } + finished(); + } + + private void moveToNextTest() { + String url = null; + try { + url = mTestListReader.readLine(); + } catch (IOException ioe) { + Log.e(LOGTAG, "Failed to read next test.", ioe); + finishUiAutoTest(); + return; + } + if (url == null) { + mUiAutoTestPath = null; + finishUiAutoTest(); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage("All tests finished. Exit?") + .setCancelable(false) + .setPositiveButton("Yes", new OnClickListener(){ + public void onClick(DialogInterface dialog, int which) { + TestShellActivity.this.finish(); + } + }) + .setNegativeButton("No", new OnClickListener(){ + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }); + builder.create().show(); + return; + } + url = "file://" + url; + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + intent.putExtra(TestShellActivity.TEST_URL, url); + intent.putExtra(TIMEOUT_IN_MILLIS, 10000); + executeIntent(intent); + } + @Override protected void onStop() { super.onStop(); mWebView.stopLoading(); } - + @Override protected void onDestroy() { super.onDestroy(); mWebView.destroy(); mWebView = null; } - + @Override public void onLowMemory() { super.onLowMemory(); @@ -199,13 +268,13 @@ public class TestShellActivity extends Activity implements LayoutTestController finished(); return; } - + try { File parentDir = new File(mResultFile).getParentFile(); if (!parentDir.exists()) { parentDir.mkdirs(); } - + FileOutputStream os = new FileOutputStream(mResultFile); if (timeout) { Log.w("Layout test: Timeout", mResultFile); @@ -222,22 +291,27 @@ public class TestShellActivity extends Activity implements LayoutTestController os.flush(); os.close(); } catch (IOException ex) { - Log.e(LOGTAG, "Cannot write to " + mResultFile + ", " + ex.getMessage()); + Log.e(LOGTAG, "Cannot write to " + mResultFile + ", " + ex.getMessage()); } finished(); } - + public void setCallback(TestShellCallback callback) { mCallback = callback; } - + public void finished() { - if (mCallback != null) { - mCallback.finished(); + if (mUiAutoTestPath != null) { + //don't really finish here + moveToNextTest(); + } else { + if (mCallback != null) { + mCallback.finished(); + } } } - + public void setDefaultDumpDataType(DumpDataType defaultDumpDataType) { mDefaultDumpDataType = defaultDumpDataType; } @@ -257,7 +331,7 @@ public class TestShellActivity extends Activity implements LayoutTestController String url = mWebView.getUrl(); Log.v(LOGTAG, "waitUntilDone called: " + url); } - + public void notifyDone() { String url = mWebView.getUrl(); Log.v(LOGTAG, "notifyDone called: " + url); @@ -266,7 +340,7 @@ public class TestShellActivity extends Activity implements LayoutTestController mChromeClient.onProgressChanged(mWebView, 100); } } - + public void display() { mWebView.invalidate(); } @@ -332,7 +406,7 @@ public class TestShellActivity extends Activity implements LayoutTestController } public void queueScript(String scriptToRunInCurrentContext) { - mWebView.loadUrl("javascript:"+scriptToRunInCurrentContext); + mWebView.loadUrl("javascript:"+scriptToRunInCurrentContext); } public void repaintSweepHorizontally() { @@ -359,7 +433,7 @@ public class TestShellActivity extends Activity implements LayoutTestController public void testRepaint() { mWebView.invalidate(); } - + private final WebChromeClient mChromeClient = new WebChromeClient() { @Override public void onProgressChanged(WebView view, int newProgress) { @@ -406,7 +480,7 @@ public class TestShellActivity extends Activity implements LayoutTestController result.confirm(); return true; } - + @Override public boolean onJsConfirm(WebView view, String url, String message, JsResult result) { @@ -419,7 +493,7 @@ public class TestShellActivity extends Activity implements LayoutTestController result.confirm(); return true; } - + @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { @@ -435,7 +509,7 @@ public class TestShellActivity extends Activity implements LayoutTestController return true; } }; - + private void resetTestStatus() { mWaitUntilDone = false; mDumpDataType = mDefaultDumpDataType; @@ -444,17 +518,19 @@ public class TestShellActivity extends Activity implements LayoutTestController mRequestedWebKitData = false; mEventSender.resetMouse(); } - + private WebView mWebView; private WebViewEventSender mEventSender; private AsyncHandler mHandler; private TestShellCallback mCallback; private CallbackProxy mCallbackProxy; - + private String mTestUrl; private String mResultFile; private int mTimeoutInMillis; + private String mUiAutoTestPath; + private BufferedReader mTestListReader; // States private boolean mTimedOut; @@ -472,13 +548,14 @@ public class TestShellActivity extends Activity implements LayoutTestController private Vector mWebHistory; static final String TIMEOUT_STR = "**Test timeout"; - + static final int MSG_TIMEOUT = 0; static final int MSG_WEBKIT_DATA = 1; static final String LOGTAG="TestShell"; - + static final String TEST_URL = "TestUrl"; static final String RESULT_FILE = "ResultFile"; static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis"; + static final String UI_AUTO_TEST = "UiAutoTest"; }