summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorMaksymilian Osowski <maxosowski@google.com>2010-07-22 17:33:53 +0100
committerMaksymilian Osowski <maxosowski@google.com>2010-07-26 10:37:41 +0100
commit7ddc0b7a72aa66d699fecce3d855a6c70f844647 (patch)
tree7fbb9ed72fdf2b29395be51d26f84908e37e2ab5 /tests
parent650893b6761612c8ac763483bcdbdb6c6da3b10d (diff)
downloadframeworks_base-7ddc0b7a72aa66d699fecce3d855a6c70f844647.zip
frameworks_base-7ddc0b7a72aa66d699fecce3d855a6c70f844647.tar.gz
frameworks_base-7ddc0b7a72aa66d699fecce3d855a6c70f844647.tar.bz2
First stage of refactoring the code to handle crashes gracefully.
There is a new activity (LayoutTestsExecuter) added that is responsible for acutally running the tests and sending the actual results to the new ManagerService class. This class will take over most of the functionality of the current LayoutTestsRunnerThread. At the moment LayoutTestsRunnerThread is changed so that after computing the tests' list it sends the list to LayoutTestsExecuter. The rest of the code is never called. It will be shifted to the service. Current implementation of ManagerService only prints the log message on receiving the bundle with actual results from LayoutTestsExecuter. Change-Id: I5adcbc20bb18ebf24324974bc66e4b31c4b81902
Diffstat (limited to 'tests')
-rw-r--r--tests/DumpRenderTree2/AndroidManifest.xml8
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java9
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTest.java13
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecuter.java240
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsRunnerThread.java14
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java60
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java29
7 files changed, 365 insertions, 8 deletions
diff --git a/tests/DumpRenderTree2/AndroidManifest.xml b/tests/DumpRenderTree2/AndroidManifest.xml
index a5199e7..14df611 100644
--- a/tests/DumpRenderTree2/AndroidManifest.xml
+++ b/tests/DumpRenderTree2/AndroidManifest.xml
@@ -28,6 +28,14 @@ limitations under the License.
<activity android:name=".LayoutTestsRunner"
android:label="Layout tests' runner">
</activity>
+
+ <activity android:name=".LayoutTestsExecuter"
+ android:label="Layout tests' executer"
+ android:process=":executer">
+ </activity>
+
+ <service android:name="ManagerService">
+ </service>
</application>
<uses-permission android:name="android.permission.INTERNET" />
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
index 880a5cb..3c7dee2 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
@@ -16,6 +16,7 @@
package com.android.dumprendertree2;
+import android.os.Bundle;
import android.os.Message;
import android.webkit.WebView;
@@ -50,15 +51,15 @@ public abstract class AbstractResult {
}
/**
- * Makes the result object obtain the result of the test from the webview
- * and store it in the format that suits itself bests. This method is asynchronous.
+ * 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.
* The message passed as a parameter is a message that should be sent to its target
* when the result finishes obtaining the result.
*
* @param webview
* @param resultObtainedMsg
*/
- public abstract void obtainActualResult(WebView webview, Message resultObtainedMsg);
+ public abstract void obtainActualResults(WebView webview, Message resultObtainedMsg);
public abstract void setExpectedImageResult(byte[] expectedResult);
@@ -108,4 +109,6 @@ public abstract class AbstractResult {
* a piece of HTML code with a visual diff between the result and the expected result
*/
public abstract String getDiffAsHtml();
+
+ public abstract Bundle getBundle();
} \ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTest.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTest.java
index aa505b7..1312ef9 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTest.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTest.java
@@ -54,8 +54,10 @@ public class LayoutTest {
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_ACTUAL_RESULT_OBTAINED) {
- mResult.setExpectedTextResult(LayoutTestsRunnerThread.getExpectedTextResult(mRelativePath));
- mResult.setExpectedImageResult(LayoutTestsRunnerThread.getExpectedImageResult(mRelativePath));
+ mResult.setExpectedTextResult(LayoutTestsRunnerThread
+ .getExpectedTextResult(mRelativePath));
+ mResult.setExpectedImageResult(LayoutTestsRunnerThread
+ .getExpectedImageResult(mRelativePath));
mTestFinishedMsg.sendToTarget();
}
}
@@ -114,6 +116,11 @@ public class LayoutTest {
mActivity = activity;
}
+ public LayoutTest(AbstractResult result, String relativePath) {
+ mResult = result;
+ mRelativePath = relativePath;
+ }
+
public void run() {
mWebView = new WebView(mActivity);
mActivity.setContentView(mWebView);
@@ -143,7 +150,7 @@ public class LayoutTest {
/** TODO: Implement waitUntilDone */
- mResult.obtainActualResult(mWebView,
+ mResult.obtainActualResults(mWebView,
mResultHandler.obtainMessage(MSG_ACTUAL_RESULT_OBTAINED));
}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecuter.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecuter.java
new file mode 100644
index 0000000..6fd3085
--- /dev/null
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecuter.java
@@ -0,0 +1,240 @@
+/*
+ * 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.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+import android.webkit.JsPromptResult;
+import android.webkit.JsResult;
+import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.webkit.WebStorage.QuotaUpdater;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * This activity executes the test. It contains WebView and logic of LayoutTestController
+ * functions. It runs in a separate process and sends the results of running the test
+ * to ManagerService. The reason why is to handle crashing (test that crashes brings down
+ * whole process with it).
+ */
+public class LayoutTestsExecuter extends Activity {
+
+ /** TODO: make it a setting */
+ static final String TESTS_ROOT_DIR_PATH =
+ Environment.getExternalStorageDirectory() +
+ File.separator + "android" +
+ File.separator + "LayoutTests";
+
+ private static final String LOG_TAG = "LayoutTestExecuter";
+
+ public static final String EXTRA_TESTS_LIST = "TestsList";
+
+ private static final int MSG_ACTUAL_RESULT_OBTAINED = 0;
+
+ private List<String> mTestsList;
+ private int mCurrentTestCount = 0;
+
+ private WebView mCurrentWebView;
+ private String mCurrentTestRelativePath;
+ private String mCurrentTestUri;
+
+ private boolean mOnTestFinishedCalled;
+ private AbstractResult mCurrentResult;
+
+ /** COMMUNICATION WITH ManagerService */
+
+ private Messenger mManagerServiceMessenger;
+
+ private ServiceConnection mServiceConnection = new ServiceConnection() {
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ mManagerServiceMessenger = new Messenger(service);
+ runNextTest();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ /** TODO */
+ }
+ };
+
+ private final Handler mResultHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_ACTUAL_RESULT_OBTAINED) {
+ reportResultToService();
+ runNextTest();
+ }
+ }
+ };
+
+ /** WEBVIEW CONFIGURATION */
+
+ private WebViewClient mWebViewClient = new WebViewClient() {
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ /** Some tests fire up many page loads, we don't want to detect them */
+ if (!url.equals(mCurrentTestUri)) {
+ return;
+ }
+
+ /** TODO: Implement waitUntilDone */
+ onTestFinished();
+ }
+ };
+
+ private WebChromeClient mWebChromeClient = new WebChromeClient() {
+ @Override
+ public void onExceededDatabaseQuota(String url, String databaseIdentifier,
+ long currentQuota, long estimatedSize, long totalUsedQuota,
+ QuotaUpdater quotaUpdater) {
+ /** TODO: This should be recorded as part of the text result */
+ quotaUpdater.updateQuota(currentQuota + 5 * 1024 * 1024);
+ }
+
+ @Override
+ public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
+ /** TODO: Alerts should be recorded as part of text result */
+ result.confirm();
+ return true;
+ }
+
+ @Override
+ public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
+ /** TODO: Alerts should be recorded as part of text result */
+ result.confirm();
+ return true;
+ }
+
+ @Override
+ public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
+ JsPromptResult result) {
+ /** TODO: Alerts should be recorded as part of text result */
+ result.confirm();
+ return true;
+ }
+
+ };
+
+ /** IMPLEMENTATION */
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent intent = getIntent();
+ mTestsList = intent.getStringArrayListExtra(EXTRA_TESTS_LIST);
+
+ bindService(new Intent(this, ManagerService.class), mServiceConnection,
+ Context.BIND_AUTO_CREATE);
+ }
+
+ private void reset() {
+ mOnTestFinishedCalled = false;
+ mCurrentResult = null;
+
+ mCurrentWebView = new WebView(this);
+ mCurrentWebView.setWebViewClient(mWebViewClient);
+ mCurrentWebView.setWebChromeClient(mWebChromeClient);
+
+ WebSettings webViewSettings = mCurrentWebView.getSettings();
+ webViewSettings.setAppCacheEnabled(true);
+ webViewSettings.setAppCachePath(getApplicationContext().getCacheDir().getPath());
+ webViewSettings.setAppCacheMaxSize(Long.MAX_VALUE);
+ webViewSettings.setJavaScriptEnabled(true);
+ webViewSettings.setJavaScriptCanOpenWindowsAutomatically(true);
+ webViewSettings.setSupportMultipleWindows(true);
+ webViewSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
+ webViewSettings.setDatabaseEnabled(true);
+ webViewSettings.setDatabasePath(getDir("databases", 0).getAbsolutePath());
+ webViewSettings.setDomStorageEnabled(true);
+ webViewSettings.setWorkersEnabled(false);
+ webViewSettings.setXSSAuditorEnabled(false);
+
+ setContentView(mCurrentWebView);
+ }
+
+ private void runNextTest() {
+ if (mTestsList.isEmpty()) {
+ onAllTestsFinished();
+ return;
+ }
+
+ mCurrentTestCount++;
+ mCurrentTestRelativePath = mTestsList.remove(0);
+ mCurrentTestUri =
+ Uri.fromFile(new File(TESTS_ROOT_DIR_PATH, mCurrentTestRelativePath)).toString();
+
+ reset();
+ /** TODO: Implement timeout */
+ mCurrentWebView.loadUrl(mCurrentTestUri);
+ }
+
+ private void onTestFinished() {
+ if (mOnTestFinishedCalled) {
+ return;
+ }
+
+ mOnTestFinishedCalled = true;
+
+ /**
+ * If the result has not been set by the time the test finishes we create
+ * a default type of result.
+ */
+ if (mCurrentResult == null) {
+ /** TODO: Default type should be RenderTreeResult. We don't support it now. */
+ mCurrentResult = new TextResult(mCurrentTestRelativePath);
+ }
+
+ mCurrentResult.obtainActualResults(mCurrentWebView,
+ mResultHandler.obtainMessage(MSG_ACTUAL_RESULT_OBTAINED));
+ }
+
+ private void reportResultToService() {
+ try {
+ Message serviceMsg =
+ Message.obtain(null, ManagerService.MSG_PROCESS_ACTUAL_RESULTS);
+ Bundle bundle = mCurrentResult.getBundle();
+ /** TODO: Add timeout info to bundle */
+ serviceMsg.setData(bundle);
+ mManagerServiceMessenger.send(serviceMsg);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG + "::reportResultToService", e.getMessage());
+ }
+ }
+
+ private void onAllTestsFinished() {
+ Log.d(LOG_TAG + "::onAllTestsFisnihed", "Begin.");
+ }
+} \ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsRunnerThread.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsRunnerThread.java
index 8c72e3b..ac814cb 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsRunnerThread.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsRunnerThread.java
@@ -16,6 +16,7 @@
package com.android.dumprendertree2;
+import android.content.Intent;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
@@ -23,6 +24,7 @@ import android.os.Message;
import android.util.Log;
import java.io.File;
+import java.util.ArrayList;
import java.util.LinkedList;
/**
@@ -154,7 +156,17 @@ public class LayoutTestsRunnerThread extends Thread {
mTotalTestCount = 1;
}
- runNextTest();
+ /**
+ * Instead of running next test here, we send a tests' list to Executer activity.
+ * Rest of the code is never executed and will be gradually moved to the service.
+ */
+ Intent intent = new Intent();
+ intent.setClass(mActivity, LayoutTestsExecuter.class);
+ intent.setAction(Intent.ACTION_RUN);
+ intent.putStringArrayListExtra(LayoutTestsExecuter.EXTRA_TESTS_LIST,
+ new ArrayList<String>(mTestsList));
+ mActivity.startActivity(intent);
+
Looper.loop();
}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
new file mode 100644
index 0000000..e452a38
--- /dev/null
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
@@ -0,0 +1,60 @@
+/*
+ * 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.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.util.Log;
+
+/**
+ * A service that handles managing the results of tests, informing of crashes, generating
+ * summaries, etc.
+ */
+public class ManagerService extends Service {
+
+ private static final String LOG_TAG = "ManagerService";
+
+ static final int MSG_PROCESS_ACTUAL_RESULTS = 0;
+
+ private Handler mIncomingHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_PROCESS_ACTUAL_RESULTS:
+ Log.d(LOG_TAG + ".mIncomingHandler", msg.getData().getString("relativePath"));
+ break;
+ }
+ }
+ };
+
+ private Messenger mMessenger = new Messenger(mIncomingHandler);
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ /** TODO: */
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mMessenger.getBinder();
+ }
+} \ 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 e3dcef0..7bab4ae 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
@@ -16,6 +16,7 @@
package com.android.dumprendertree2;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.webkit.WebView;
@@ -50,6 +51,19 @@ public class TextResult extends AbstractResult {
mRelativePath = relativePath;
}
+ /**
+ * Used to recreate the Result when received by the service.
+ *
+ * @param bundle
+ * bundle with data used to recreate the result
+ */
+ public TextResult(Bundle bundle) {
+ mExpectedResult = bundle.getString("expectedTextualResult");
+ mActualResult = bundle.getString("actualTextualResult");
+ mRelativePath = bundle.getString("relativePath");
+ mResultCode = ResultCode.valueOf(bundle.getString("resultCode"));
+ }
+
@Override
public ResultCode getResultCode() {
if (mResultCode != null) {
@@ -141,7 +155,7 @@ public class TextResult extends AbstractResult {
}
@Override
- public void obtainActualResult(WebView webview, Message resultObtainedMsg) {
+ public void obtainActualResults(WebView webview, Message resultObtainedMsg) {
mResultObtainedMsg = resultObtainedMsg;
Message msg = mHandler.obtainMessage(MSG_DOCUMENT_AS_TEXT);
@@ -150,4 +164,17 @@ public class TextResult extends AbstractResult {
msg.arg2 = 0;
webview.documentAsText(msg);
}
+
+ @Override
+ public Bundle getBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putString("expectedTextualResult", mExpectedResult);
+ bundle.putString("actualTextualResult", mActualResult);
+ bundle.putString("relativePath", mRelativePath);
+ if (mResultCode != null) {
+ bundle.putString("resultCode", mResultCode.name());
+ }
+ bundle.putString("type", getType().name());
+ return bundle;
+ }
} \ No newline at end of file