Merge "Time-out mechanism and state machine."
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
index 608b14e..e0d3e37 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
@@ -50,6 +50,18 @@
*/
public class LayoutTestsExecutor extends Activity {
+ private enum CurrentState {
+ IDLE,
+ RENDERING_PAGE,
+ WAITING_FOR_ASYNCHRONOUS_TEST,
+ OBTAINING_RESULT;
+
+ public boolean isRunningState() {
+ return this == CurrentState.RENDERING_PAGE ||
+ this == CurrentState.WAITING_FOR_ASYNCHRONOUS_TEST;
+ }
+ }
+
/** TODO: make it a setting */
static final String TESTS_ROOT_DIR_PATH =
Environment.getExternalStorageDirectory() +
@@ -62,6 +74,9 @@
public static final String EXTRA_TEST_INDEX = "TestIndex";
private static final int MSG_ACTUAL_RESULT_OBTAINED = 0;
+ private static final int MSG_TEST_TIMED_OUT = 1;
+
+ private static final int DEFAULT_TIME_OUT_MS = 15 * 1000;
private List<String> mTestsList;
@@ -77,8 +92,9 @@
private WebView mCurrentWebView;
private String mCurrentTestRelativePath;
private String mCurrentTestUri;
+ private CurrentState mCurrentState = CurrentState.IDLE;
- private boolean mOnTestFinishedCalled;
+ private boolean mCurrentTestTimedOut;
private AbstractResult mCurrentResult;
/** COMMUNICATION WITH ManagerService */
@@ -102,11 +118,17 @@
private final Handler mResultHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- if (msg.what == MSG_ACTUAL_RESULT_OBTAINED) {
- reportResultToService();
- mCurrentTestIndex++;
- updateProgressBar();
- runNextTest();
+ switch (msg.what) {
+ case MSG_ACTUAL_RESULT_OBTAINED:
+ onActualResultsObtained();
+ break;
+
+ case MSG_TEST_TIMED_OUT:
+ onTestTimedOut();
+ break;
+
+ default:
+ break;
}
}
};
@@ -177,7 +199,9 @@
}
private void reset() {
- mOnTestFinishedCalled = false;
+ WebView previousWebView = mCurrentWebView;
+
+ mCurrentTestTimedOut = false;
mCurrentResult = null;
mCurrentWebView = new WebView(this);
@@ -199,9 +223,14 @@
webViewSettings.setXSSAuditorEnabled(false);
setContentView(mCurrentWebView);
+ if (previousWebView != null) {
+ previousWebView.destroy();
+ }
}
private void runNextTest() {
+ assert mCurrentState == CurrentState.IDLE : "mCurrentState = " + mCurrentState.name();
+
if (mTestsList.isEmpty()) {
onAllTestsFinished();
return;
@@ -212,17 +241,34 @@
Uri.fromFile(new File(TESTS_ROOT_DIR_PATH, mCurrentTestRelativePath)).toString();
reset();
- /** TODO: Implement timeout */
+
+ /** Start time-out countdown and the test */
+ mCurrentState = CurrentState.RENDERING_PAGE;
+ mResultHandler.sendEmptyMessageDelayed(MSG_TEST_TIMED_OUT, DEFAULT_TIME_OUT_MS);
mCurrentWebView.loadUrl(mCurrentTestUri);
}
+ private void onTestTimedOut() {
+ assert mCurrentState.isRunningState() : "mCurrentState = " + mCurrentState.name();
+
+ mCurrentTestTimedOut = true;
+
+ /**
+ * While it is theoretically possible that the test times out because
+ * of webview becoming unresponsive, it is very unlikely. Therefore it's
+ * assumed that obtaining results (that calls various webview methods)
+ * will not itself hang.
+ */
+ obtainActualResultsFromWebView();
+ }
+
private void onTestFinished() {
- if (mOnTestFinishedCalled) {
- return;
- }
+ assert mCurrentState.isRunningState() : "mCurrentState = " + mCurrentState.name();
- mOnTestFinishedCalled = true;
+ obtainActualResultsFromWebView();
+ }
+ private void obtainActualResultsFromWebView() {
/**
* If the result has not been set by the time the test finishes we create
* a default type of result.
@@ -232,17 +278,35 @@
mCurrentResult = new TextResult(mCurrentTestRelativePath);
}
+ mCurrentState = CurrentState.OBTAINING_RESULT;
mCurrentResult.obtainActualResults(mCurrentWebView,
mResultHandler.obtainMessage(MSG_ACTUAL_RESULT_OBTAINED));
}
+ private void onActualResultsObtained() {
+ assert mCurrentState == CurrentState.OBTAINING_RESULT
+ : "mCurrentState = " + mCurrentState.name();
+
+ mCurrentState = CurrentState.IDLE;
+
+ mResultHandler.removeMessages(MSG_TEST_TIMED_OUT);
+ reportResultToService();
+ mCurrentTestIndex++;
+ updateProgressBar();
+ runNextTest();
+ }
+
private void reportResultToService() {
try {
Message serviceMsg =
Message.obtain(null, ManagerService.MSG_PROCESS_ACTUAL_RESULTS);
+
Bundle bundle = mCurrentResult.getBundle();
bundle.putInt("testIndex", mCurrentTestIndex);
- /** TODO: Add timeout info to bundle */
+ if (mCurrentTestTimedOut) {
+ bundle.putString("resultCode", AbstractResult.ResultCode.FAIL_TIMED_OUT.name());
+ }
+
serviceMsg.setData(bundle);
mManagerServiceMessenger.send(serviceMsg);
} catch (RemoteException e) {