summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorMaksymilian Osowski <maxosowski@google.com>2010-08-03 07:57:43 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-08-03 07:57:43 -0700
commitfb60226a03d1d4c65b7e26268611b97371b25507 (patch)
tree61d1f410a547b05bdde3ffb641900f2e6fd13acd /tests
parent7768e02973f65d347f4457583e05c82810bd5cb8 (diff)
parentdd4bff62b54033bedc254f517397ae8f954d0dc9 (diff)
downloadframeworks_base-fb60226a03d1d4c65b7e26268611b97371b25507.zip
frameworks_base-fb60226a03d1d4c65b7e26268611b97371b25507.tar.gz
frameworks_base-fb60226a03d1d4c65b7e26268611b97371b25507.tar.bz2
Merge "First batch of layoutTestController functions + some fixes and tweaks."
Diffstat (limited to 'tests')
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java12
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/AdditionalTextOutput.java85
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java76
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java192
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java6
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java24
6 files changed, 380 insertions, 15 deletions
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
index a8c1f4c..d68930c 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
@@ -26,6 +26,8 @@ import android.webkit.WebView;
*/
public abstract class AbstractResult implements Comparable<AbstractResult> {
+ private static final String LOG_TAG = "AbstractResult";
+
public enum TestType {
TEXT {
@Override
@@ -63,10 +65,20 @@ public abstract class AbstractResult implements Comparable<AbstractResult> {
}
}
+ String mAdditionalTextOutputString;
+
public int compareTo(AbstractResult another) {
return getRelativePath().compareTo(another.getRelativePath());
}
+ public void setAdditionalTextOutputString(String additionalTextOutputString) {
+ mAdditionalTextOutputString = additionalTextOutputString;
+ }
+
+ public String getAdditionalTextOutputString() {
+ return mAdditionalTextOutputString;
+ }
+
/**
* 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.
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AdditionalTextOutput.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AdditionalTextOutput.java
new file mode 100644
index 0000000..4e4d824
--- /dev/null
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AdditionalTextOutput.java
@@ -0,0 +1,85 @@
+/*
+ * 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.util.Log;
+import android.webkit.ConsoleMessage;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * A class that stores consoles messages, database callbacks, alert messages, etc.
+ */
+public class AdditionalTextOutput {
+ private static final String LOG_TAG = "AdditionalTextOutput";
+
+ private enum OutputType {
+ EXCEEDED_DB_QUOTA_MESSAGE,
+ CONSOLE_MESSAGE;
+ }
+
+ StringBuilder[] mOutputs = new StringBuilder[OutputType.values().length];
+
+ public void appendExceededDbQuotaMessage(String urlString, String databaseIdentifier) {
+ int index = OutputType.EXCEEDED_DB_QUOTA_MESSAGE.ordinal();
+ if (mOutputs[index] == null) {
+ mOutputs[index] = new StringBuilder();
+ }
+
+ String protocol = "";
+ String host = "";
+ int port = 0;
+
+ try {
+ URL url = new URL(urlString);
+ protocol = url.getProtocol();
+ host = url.getHost();
+ if (url.getPort() > -1) {
+ port = url.getPort();
+ }
+ } catch (MalformedURLException e) {
+ Log.e(LOG_TAG + "::appendDatabaseCallback", e.getMessage());
+ }
+
+ mOutputs[index].append("UI DELEGATE DATABASE CALLBACK: ");
+ mOutputs[index].append("exceededDatabaseQuotaForSecurityOrigin:{");
+ mOutputs[index].append(protocol + ", " + host + ", " + port + "} ");
+ mOutputs[index].append("database:" + databaseIdentifier + "\n");
+ }
+
+ public void appendConsoleMessage(ConsoleMessage consoleMessage) {
+ int index = OutputType.CONSOLE_MESSAGE.ordinal();
+ if (mOutputs[index] == null) {
+ mOutputs[index] = new StringBuilder();
+ }
+
+ mOutputs[index].append("CONSOLE MESSAGE: line " + consoleMessage.lineNumber());
+ mOutputs[index].append(": " + consoleMessage.message() + "\n");
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < mOutputs.length; i++) {
+ if (mOutputs[i] != null) {
+ result.append(mOutputs[i].toString());
+ }
+ }
+ return result.toString();
+ }
+} \ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java
new file mode 100644
index 0000000..35f9d0a
--- /dev/null
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java
@@ -0,0 +1,76 @@
+/*
+ * 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.net.Uri;
+import android.util.Log;
+import android.webkit.WebStorage;
+
+import java.io.File;
+
+/**
+ * A class that is registered as JS interface for webview in LayoutTestExecutor
+ */
+public class LayoutTestController {
+ private static final String LOG_TAG = "LayoutTestController";
+
+ LayoutTestsExecutor mLayoutTestsExecutor;
+
+ public LayoutTestController(LayoutTestsExecutor layoutTestsExecutor) {
+ mLayoutTestsExecutor = layoutTestsExecutor;
+ }
+
+ public void waitUntilDone() {
+ mLayoutTestsExecutor.waitUntilDone();
+ }
+
+ public void notifyDone() {
+ mLayoutTestsExecutor.notifyDone();
+ }
+
+ public void dumpAsText() {
+ dumpAsText(false);
+ }
+
+ public void dumpAsText(boolean enablePixelTest) {
+ mLayoutTestsExecutor.dumpAsText(enablePixelTest);
+ }
+
+ public void dumpChildFramesAsText() {
+ mLayoutTestsExecutor.dumpChildFramesAsText();
+ }
+
+ public void clearAllDatabases() {
+ Log.w(LOG_TAG + "::clearAllDatabases", "called");
+ WebStorage.getInstance().deleteAllData();
+ }
+
+ public void setCanOpenWindows() {
+ mLayoutTestsExecutor.setCanOpenWindows();
+ }
+
+ public void dumpDatabaseCallbacks() {
+ mLayoutTestsExecutor.dumpDatabaseCallbacks();
+ }
+
+ public void setDatabaseQuota(long quota) {
+ /** TODO: Reset this before every test! */
+ Log.w(LOG_TAG + "::setDatabaseQuota", "called with: " + quota);
+ WebStorage.getInstance().setQuotaForOrigin(Uri.fromFile(new File("")).toString(),
+ quota);
+ }
+} \ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
index e0d3e37..73026bc 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
@@ -31,6 +31,7 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.Window;
+import android.webkit.ConsoleMessage;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
@@ -96,6 +97,11 @@ public class LayoutTestsExecutor extends Activity {
private boolean mCurrentTestTimedOut;
private AbstractResult mCurrentResult;
+ private AdditionalTextOutput mCurrentAdditionalTextOutput;
+
+ private LayoutTestController mLayoutTestController = new LayoutTestController(this);
+ private boolean mCanOpenWindows;
+ private boolean mDumpDatabaseCallbacks;
/** COMMUNICATION WITH ManagerService */
@@ -143,8 +149,9 @@ public class LayoutTestsExecutor extends Activity {
return;
}
- /** TODO: Implement waitUntilDone */
- onTestFinished();
+ if (mCurrentState == CurrentState.RENDERING_PAGE) {
+ onTestFinished();
+ }
}
};
@@ -154,6 +161,14 @@ public class LayoutTestsExecutor extends Activity {
long currentQuota, long estimatedSize, long totalUsedQuota,
QuotaUpdater quotaUpdater) {
/** TODO: This should be recorded as part of the text result */
+ /** TODO: The quota should also probably be reset somehow for every test? */
+ if (mDumpDatabaseCallbacks) {
+ if (mCurrentAdditionalTextOutput == null) {
+ mCurrentAdditionalTextOutput = new AdditionalTextOutput();
+ }
+
+ mCurrentAdditionalTextOutput.appendExceededDbQuotaMessage(url, databaseIdentifier);
+ }
quotaUpdater.updateQuota(currentQuota + 5 * 1024 * 1024);
}
@@ -179,6 +194,36 @@ public class LayoutTestsExecutor extends Activity {
return true;
}
+ @Override
+ public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
+ if (mCurrentAdditionalTextOutput == null) {
+ mCurrentAdditionalTextOutput = new AdditionalTextOutput();
+ }
+
+ mCurrentAdditionalTextOutput.appendConsoleMessage(consoleMessage);
+ return true;
+ }
+
+ @Override
+ public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture,
+ Message resultMsg) {
+ WebView.WebViewTransport transport = (WebView.WebViewTransport)resultMsg.obj;
+ /** By default windows cannot be opened, so just send null back. */
+ WebView newWindowWebView = null;
+
+ if (mCanOpenWindows) {
+ /**
+ * We never display the new window, just create the view and allow it's content to
+ * execute and be recorded by the executor.
+ */
+ newWindowWebView = new WebView(LayoutTestsExecutor.this);
+ setupWebView(newWindowWebView);
+ }
+
+ transport.setWebView(newWindowWebView);
+ resultMsg.sendToTarget();
+ return true;
+ }
};
/** IMPLEMENTATION */
@@ -201,14 +246,37 @@ public class LayoutTestsExecutor extends Activity {
private void reset() {
WebView previousWebView = mCurrentWebView;
+ resetLayoutTestController();
+
mCurrentTestTimedOut = false;
mCurrentResult = null;
+ mCurrentAdditionalTextOutput = null;
mCurrentWebView = new WebView(this);
- mCurrentWebView.setWebViewClient(mWebViewClient);
- mCurrentWebView.setWebChromeClient(mWebChromeClient);
+ setupWebView(mCurrentWebView);
- WebSettings webViewSettings = mCurrentWebView.getSettings();
+ setContentView(mCurrentWebView);
+ if (previousWebView != null) {
+ Log.d(LOG_TAG + "::reset", "previousWebView != null");
+ previousWebView.destroy();
+ }
+ }
+
+ private void setupWebView(WebView webView) {
+ webView.setWebViewClient(mWebViewClient);
+ webView.setWebChromeClient(mWebChromeClient);
+ webView.addJavascriptInterface(mLayoutTestController, "layoutTestController");
+
+ /**
+ * Setting a touch interval of -1 effectively disables the optimisation in WebView
+ * that stops repeated touch events flooding WebCore. The Event Sender only sends a
+ * single event rather than a stream of events (like what would generally happen in
+ * a real use of touch events in a WebView) and so if the WebView drops the event,
+ * the test will fail as the test expects one callback for every touch it synthesizes.
+ */
+ webView.setTouchInterval(-1);
+
+ WebSettings webViewSettings = webView.getSettings();
webViewSettings.setAppCacheEnabled(true);
webViewSettings.setAppCachePath(getApplicationContext().getCacheDir().getPath());
webViewSettings.setAppCacheMaxSize(Long.MAX_VALUE);
@@ -221,11 +289,6 @@ public class LayoutTestsExecutor extends Activity {
webViewSettings.setDomStorageEnabled(true);
webViewSettings.setWorkersEnabled(false);
webViewSettings.setXSSAuditorEnabled(false);
-
- setContentView(mCurrentWebView);
- if (previousWebView != null) {
- previousWebView.destroy();
- }
}
private void runNextTest() {
@@ -279,6 +342,7 @@ public class LayoutTestsExecutor extends Activity {
}
mCurrentState = CurrentState.OBTAINING_RESULT;
+
mCurrentResult.obtainActualResults(mCurrentWebView,
mResultHandler.obtainMessage(MSG_ACTUAL_RESULT_OBTAINED));
}
@@ -297,6 +361,10 @@ public class LayoutTestsExecutor extends Activity {
}
private void reportResultToService() {
+ if (mCurrentAdditionalTextOutput != null) {
+ mCurrentResult.setAdditionalTextOutputString(mCurrentAdditionalTextOutput.toString());
+ }
+
try {
Message serviceMsg =
Message.obtain(null, ManagerService.MSG_PROCESS_ACTUAL_RESULTS);
@@ -329,5 +397,109 @@ public class LayoutTestsExecutor extends Activity {
} catch (RemoteException e) {
Log.e(LOG_TAG + "::onAllTestsFinished", e.getMessage());
}
+
+ unbindService(mServiceConnection);
+ }
+
+ /** LAYOUT TEST CONTROLLER */
+
+ private static final int MSG_WAIT_UNTIL_DONE = 0;
+ private static final int MSG_NOTIFY_DONE = 1;
+ private static final int MSG_DUMP_AS_TEXT = 2;
+ private static final int MSG_DUMP_CHILD_FRAMES_AS_TEXT = 3;
+ private static final int MSG_SET_CAN_OPEN_WINDOWS = 4;
+ private static final int MSG_DUMP_DATABASE_CALLBACKS = 5;
+
+ Handler mLayoutTestControllerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ assert mCurrentState.isRunningState()
+ : "mCurrentState = " + mCurrentState.name();
+
+ switch (msg.what) {
+ case MSG_WAIT_UNTIL_DONE:
+ mCurrentState = CurrentState.WAITING_FOR_ASYNCHRONOUS_TEST;
+ break;
+
+ case MSG_NOTIFY_DONE:
+ if (mCurrentState == CurrentState.WAITING_FOR_ASYNCHRONOUS_TEST) {
+ onTestFinished();
+ }
+ break;
+
+ case MSG_DUMP_AS_TEXT:
+ if (mCurrentResult == null) {
+ mCurrentResult = new TextResult(mCurrentTestRelativePath);
+ }
+
+ assert mCurrentResult instanceof TextResult
+ : "mCurrentResult instanceof" + mCurrentResult.getClass().getName();
+
+ break;
+
+ case MSG_DUMP_CHILD_FRAMES_AS_TEXT:
+ /** If dumpAsText was not called we assume that the result should be text */
+ if (mCurrentResult == null) {
+ mCurrentResult = new TextResult(mCurrentTestRelativePath);
+ }
+
+ assert mCurrentResult instanceof TextResult
+ : "mCurrentResult instanceof" + mCurrentResult.getClass().getName();
+
+ ((TextResult)mCurrentResult).setDumpChildFramesAsText(true);
+ break;
+
+ case MSG_SET_CAN_OPEN_WINDOWS:
+ mCanOpenWindows = true;
+ break;
+
+ case MSG_DUMP_DATABASE_CALLBACKS:
+ mDumpDatabaseCallbacks = true;
+ break;
+
+ default:
+ Log.w(LOG_TAG + "::handleMessage", "Message code does not exist: " + msg.what);
+ break;
+ }
+ }
+ };
+
+ private void resetLayoutTestController() {
+ mCanOpenWindows = false;
+ mDumpDatabaseCallbacks = false;
+ }
+
+ public void waitUntilDone() {
+ Log.w(LOG_TAG + "::waitUntilDone", "called");
+ mLayoutTestControllerHandler.sendEmptyMessage(MSG_WAIT_UNTIL_DONE);
+ }
+
+ public void notifyDone() {
+ Log.w(LOG_TAG + "::notifyDone", "called");
+ mLayoutTestControllerHandler.sendEmptyMessage(MSG_NOTIFY_DONE);
+ }
+
+ public void dumpAsText(boolean enablePixelTest) {
+ Log.w(LOG_TAG + "::dumpAsText(" + enablePixelTest + ")", "called");
+ /** TODO: Implement */
+ if (enablePixelTest) {
+ Log.w(LOG_TAG + "::dumpAsText", "enablePixelTest not implemented, switching to false");
+ }
+ mLayoutTestControllerHandler.sendEmptyMessage(MSG_DUMP_AS_TEXT);
+ }
+
+ public void dumpChildFramesAsText() {
+ Log.w(LOG_TAG + "::dumpChildFramesAsText", "called");
+ mLayoutTestControllerHandler.sendEmptyMessage(MSG_DUMP_CHILD_FRAMES_AS_TEXT);
+ }
+
+ public void setCanOpenWindows() {
+ Log.w(LOG_TAG + "::setCanOpenWindows", "called");
+ mLayoutTestControllerHandler.sendEmptyMessage(MSG_SET_CAN_OPEN_WINDOWS);
+ }
+
+ public void dumpDatabaseCallbacks() {
+ Log.w(LOG_TAG + "::dumpDatabaseCallbacks:", "called");
+ mLayoutTestControllerHandler.sendEmptyMessage(MSG_DUMP_DATABASE_CALLBACKS);
}
} \ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
index e32247c..cdc9995 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
@@ -132,7 +132,11 @@ public class ManagerService extends Service {
}
public static String getExpectedTextResult(String relativePath) {
- return new String(getExpectedResult(relativePath, TEXT_RESULT_EXTENSION));
+ byte[] result = getExpectedResult(relativePath, TEXT_RESULT_EXTENSION);
+ if (result != null) {
+ return new String(result);
+ }
+ return null;
}
public static byte[] getExpectedImageResult(String relativePath) {
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
index 4278d54..0f864e5 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
@@ -41,11 +41,13 @@ public class TextResult extends AbstractResult {
private ResultCode mResultCode;
private Message mResultObtainedMsg;
+ private boolean mDumpChildFramesAsText;
+
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_DOCUMENT_AS_TEXT) {
- mActualResult = (String) msg.obj;
+ mActualResult = (String)msg.obj;
mResultObtainedMsg.sendToTarget();
}
}
@@ -55,6 +57,10 @@ public class TextResult extends AbstractResult {
mRelativePath = relativePath;
}
+ public void setDumpChildFramesAsText(boolean dumpChildFramesAsText) {
+ mDumpChildFramesAsText = dumpChildFramesAsText;
+ }
+
/**
* Used to recreate the Result when received by the service.
*
@@ -64,6 +70,7 @@ public class TextResult extends AbstractResult {
public TextResult(Bundle bundle) {
mExpectedResult = bundle.getString("expectedTextualResult");
mActualResult = bundle.getString("actualTextualResult");
+ setAdditionalTextOutputString(bundle.getString("additionalTextOutputString"));
mRelativePath = bundle.getString("relativePath");
String resultCode = bundle.getString("resultCode");
if (resultCode != null) {
@@ -95,6 +102,11 @@ public class TextResult extends AbstractResult {
@Override
public String getActualTextResult() {
+ String additionalTextResultString = getAdditionalTextOutputString();
+ if (additionalTextResultString != null) {
+ return additionalTextResultString+ mActualResult;
+ }
+
return mActualResult;
}
@@ -187,9 +199,12 @@ public class TextResult extends AbstractResult {
mResultObtainedMsg = resultObtainedMsg;
Message msg = mHandler.obtainMessage(MSG_DOCUMENT_AS_TEXT);
- /** TODO: mDumpTopFrameAsText and mDumpChildFramesAsText */
+ /**
+ * arg1 - should dump top frame as text
+ * arg2 - should dump child frames as text
+ */
msg.arg1 = 1;
- msg.arg2 = 0;
+ msg.arg2 = mDumpChildFramesAsText ? 1 : 0;
webview.documentAsText(msg);
}
@@ -197,7 +212,8 @@ public class TextResult extends AbstractResult {
public Bundle getBundle() {
Bundle bundle = new Bundle();
bundle.putString("expectedTextualResult", mExpectedResult);
- bundle.putString("actualTextualResult", mActualResult);
+ bundle.putString("actualTextualResult", getActualTextResult());
+ bundle.putString("additionalTextOutputString", getAdditionalTextOutputString());
bundle.putString("relativePath", mRelativePath);
if (mResultCode != null) {
bundle.putString("resultCode", mResultCode.name());