Diff
Modified: trunk/Source/WebKit2/ChangeLog (153326 => 153327)
--- trunk/Source/WebKit2/ChangeLog 2013-07-25 14:26:42 UTC (rev 153326)
+++ trunk/Source/WebKit2/ChangeLog 2013-07-25 16:13:30 UTC (rev 153327)
@@ -1,3 +1,78 @@
+2013-07-25 Carlos Garcia Campos <[email protected]>
+
+ [GTK] Add support for running unit tests in the web process
+ https://bugs.webkit.org/show_bug.cgi?id=118427
+
+ Reviewed by Gustavo Noronha Silva.
+
+ Some tests, like GObject DOM bindings API tests, run entirely in
+ the WebProcess, so we just need to start the test from the UI
+ process and wait until the test finishes running in the
+ WebProcess. Tests are split in two files, one containing the
+ actual test that runs in the WebProcess and another one to add the
+ tests to the glib test system that works as a
+ proxy. WebProcessTestRunner class starts a private DBus session
+ bus and starts the tests sending a message to the WebExtension
+ waiting until it finishes or fails. WebProcess tests are created
+ by defining a class derived from WebProcessTest class and
+ implementing the static create method and the virtual runTest
+ method. The macro REGISTER_TEST is used by the web process tests
+ to register their test cases. This patch includes the migration
+ of the WebKitDOMNode test, all other GObject DOM bindings tests
+ will be migrated in the same way in follow up patches.
+
+ * UIProcess/API/gtk/tests/DOMNodeTest.cpp: Added.
+ (WebKitDOMNodeTest::create): Create a new WebKitDOMNodeTest.
+ (WebKitDOMNodeTest::webPageFromArgs): Get the pageID parameter
+ from the arguments dictionary.
+ (WebKitDOMNodeTest::testHierarchyNavigation):
+ (WebKitDOMNodeTest::testInsertion):
+ (WebKitDOMNodeTest::runTest): Run the given test.
+ (registerTests): Register test cases.
+ * UIProcess/API/gtk/tests/GNUmakefile.am: Add new files to
+ compilation.
+ * UIProcess/API/gtk/tests/TestDOMNode.cpp: Added.
+ (testWebKitDOMNodeHierarchyNavigation):
+ (testWebKitDOMNodeInsertion):
+ (beforeAll):
+ (afterAll):
+ * UIProcess/API/gtk/tests/TestMain.cpp:
+ (main): Unset DBUS_SESSION_BUS_ADDRESS environment variable to
+ make sure that the GLib bus singleton is initialized by the
+ private DBus session bus created by the tests.
+ * UIProcess/API/gtk/tests/WebProcessTest.cpp: Added.
+ (testsMap): Initialize and get the global map of tests.
+ (WebProcessTest::add): Add a new test to the map, keeping a
+ function to create the test.
+ (WebProcessTest::create): Create a test for the given name.
+ (methodCallCallback): Handle RunTest DBus method. It creates and
+ runs the given test.
+ (webkit_web_extension_initialize):Register the DBus service for
+ this WebExtension.
+ * UIProcess/API/gtk/tests/WebProcessTest.h: Added.
+ * UIProcess/API/gtk/tests/WebProcessTestRunner.cpp: Added.
+ (WebProcessTestRunner::WebProcessTestRunner): Start a private DBus
+ session bus and get a connection to it.
+ (WebProcessTestRunner::~WebProcessTestRunner): Stop the private
+ DBus session bus.
+ (WebProcessTestRunner::proxyCreatedCallback):
+ (WebProcessTestRunner::proxy): Create a new proxy to send messages
+ to the WebExtension if it doesn't exists.
+ (WebProcessTestRunner::onNameAppeared): Called when the DBus
+ service has been registered in the WebExtension and it's safe to
+ create a proxy.
+ (WebProcessTestRunner::onNameVanished): Called when the DBus
+ service is unregistered. This happens when the web process crash,
+ so we just exit here, because the g_asserts in the web process
+ have already registered the error message.
+ (WebProcessTestRunner::testFinishedCallback): Called when the
+ WebProcess tests has finished.
+ (WebProcessTestRunner::runTest): Send a message to the
+ WebExtension to start the given test and monitor the service.
+ (WebProcessTestRunner::finishTest): Save the test result and
+ finish the main loop.
+ * UIProcess/API/gtk/tests/WebProcessTestRunner.h: Added.
+
2013-05-05 Geoffrey Garen <[email protected]>
Rolled back in r149527 with crash fixed.
Added: trunk/Source/WebKit2/UIProcess/API/gtk/tests/DOMNodeTest.cpp (0 => 153327)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/DOMNodeTest.cpp (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/DOMNodeTest.cpp 2013-07-25 16:13:30 UTC (rev 153327)
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include "WebProcessTest.h"
+#include <gio/gio.h>
+#include <webkit2/webkit-web-extension.h>
+
+class WebKitDOMNodeTest : public WebProcessTest {
+public:
+ static PassOwnPtr<WebProcessTest> create() { return adoptPtr(new WebKitDOMNodeTest()); }
+
+private:
+ guint64 webPageFromArgs(GVariant* args)
+ {
+ GVariantIter iter;
+ g_variant_iter_init(&iter, args);
+
+ const char* key;
+ GVariant* value;
+ while (g_variant_iter_loop(&iter, "{&sv}", &key, &value)) {
+ if (!strcmp(key, "pageID") && g_variant_classify(value) == G_VARIANT_CLASS_UINT64)
+ return g_variant_get_uint64(value);
+ }
+
+ g_assert_not_reached();
+ return 0;
+ }
+
+ bool testHierarchyNavigation(WebKitWebExtension* extension, GVariant* args)
+ {
+ WebKitWebPage* page = webkit_web_extension_get_page(extension, webPageFromArgs(args));
+ g_assert(WEBKIT_IS_WEB_PAGE(page));
+ WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
+ g_assert(WEBKIT_DOM_IS_DOCUMENT(document));
+
+ WebKitDOMHTMLHeadElement* head = webkit_dom_document_get_head(document);
+ g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(head));
+
+ // Title, head's child.
+ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(head)));
+ GRefPtr<WebKitDOMNodeList> list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(head)));
+ g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
+ g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1);
+ WebKitDOMNode* node = webkit_dom_node_list_item(list.get(), 0);
+ g_assert(WEBKIT_DOM_IS_HTML_TITLE_ELEMENT(node));
+
+ // Body, Head sibling.
+ node = webkit_dom_node_get_next_sibling(WEBKIT_DOM_NODE(head));
+ g_assert(WEBKIT_DOM_IS_HTML_BODY_ELEMENT(node));
+ WebKitDOMHTMLBodyElement* body = WEBKIT_DOM_HTML_BODY_ELEMENT(node);
+
+ // There is no third sibling
+ g_assert(!webkit_dom_node_get_next_sibling(node));
+
+ // Body's previous sibling is Head.
+ node = webkit_dom_node_get_previous_sibling(WEBKIT_DOM_NODE(body));
+ g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(node));
+
+ // Body has 3 children.
+ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
+ list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
+ unsigned long length = webkit_dom_node_list_get_length(list.get());
+ g_assert_cmpint(length, ==, 3);
+
+ // The three of them are P tags.
+ for (unsigned long i = 0; i < length; i++) {
+ node = webkit_dom_node_list_item(list.get(), i);
+ g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(node));
+ }
+
+ // Go backwards
+ unsigned i;
+ for (i = 0; node; node = webkit_dom_node_get_previous_sibling(node), i++) { }
+ g_assert_cmpint(i, ==, 3);
+
+ return true;
+ }
+
+ bool testInsertion(WebKitWebExtension* extension, GVariant* args)
+ {
+ WebKitWebPage* page = webkit_web_extension_get_page(extension, webPageFromArgs(args));
+ g_assert(WEBKIT_IS_WEB_PAGE(page));
+ WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
+ g_assert(WEBKIT_DOM_IS_DOCUMENT(document));
+
+ WebKitDOMHTMLElement* body = webkit_dom_document_get_body(document);
+ g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(body));
+
+ // Body shouldn't have any children at this point.
+ g_assert(!webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
+
+ // Insert one P element.
+ WebKitDOMElement* p = webkit_dom_document_create_element(document, "P", 0);
+ g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(p));
+ webkit_dom_node_append_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(p), 0);
+
+ // Now it should have one, the same that we inserted.
+ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
+ GRefPtr<WebKitDOMNodeList> list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
+ g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
+ g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1);
+ WebKitDOMNode* node = webkit_dom_node_list_item(list.get(), 0);
+ g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node));
+ g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(p), node));
+
+ // Replace the P tag with a DIV tag.
+ WebKitDOMElement* div = webkit_dom_document_create_element(document, "DIV", 0);
+ g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(div));
+ webkit_dom_node_replace_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE(p), 0);
+ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
+ list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
+ g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
+ g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1);
+ node = webkit_dom_node_list_item(list.get(), 0);
+ g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node));
+ g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node));
+
+ // Now remove the tag.
+ webkit_dom_node_remove_child(WEBKIT_DOM_NODE(body), node, 0);
+ list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
+ g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
+ g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 0);
+
+ // Test insert before. If refChild is null, insert newChild as last element of parent.
+ div = webkit_dom_document_create_element(document, "DIV", 0);
+ g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(div));
+ webkit_dom_node_insert_before(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(div), 0, 0);
+ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
+ list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
+ g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
+ g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1);
+ node = webkit_dom_node_list_item(list.get(), 0);
+ g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node));
+ g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node));
+
+ // Now insert a 'p' before 'div'.
+ p = webkit_dom_document_create_element(document, "P", 0);
+ g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(p));
+ webkit_dom_node_insert_before(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(p), WEBKIT_DOM_NODE(div), 0);
+ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
+ list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)));
+ g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get()));
+ g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 2);
+ node = webkit_dom_node_list_item(list.get(), 0);
+ g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node));
+ g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(p), node));
+ node = webkit_dom_node_list_item(list.get(), 1);
+ g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node));
+ g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node));
+
+ return true;
+ }
+
+ virtual bool runTest(const char* testName, WebKitWebExtension* extension, GVariant* args)
+ {
+ if (!strcmp(testName, "hierarchy-navigation"))
+ return testHierarchyNavigation(extension, args);
+ if (!strcmp(testName, "insertion"))
+ return testInsertion(extension, args);
+
+ g_assert_not_reached();
+ return false;
+ }
+};
+
+static void __attribute__((constructor)) registerTests()
+{
+ REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/hierarchy-navigation");
+ REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/insertion");
+}
+
+
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am (153326 => 153327)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am 2013-07-25 14:26:42 UTC (rev 153326)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am 2013-07-25 16:13:30 UTC (rev 153327)
@@ -5,6 +5,7 @@
Programs/WebKit2APITests/TestBackForwardList \
Programs/WebKit2APITests/TestContextMenu \
Programs/WebKit2APITests/TestCookieManager \
+ Programs/WebKit2APITests/TestDOMNode \
Programs/WebKit2APITests/TestDownloads \
Programs/WebKit2APITests/TestInspector \
Programs/WebKit2APITests/TestInspectorServer \
@@ -90,6 +91,8 @@
Source/WebKit2/UIProcess/API/gtk/tests/WebKitTestBus.h \
Source/WebKit2/UIProcess/API/gtk/tests/WebKitTestServer.cpp \
Source/WebKit2/UIProcess/API/gtk/tests/WebKitTestServer.h \
+ Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTestRunner.cpp \
+ Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTestRunner.h \
Source/WebKit2/UIProcess/API/gtk/tests/TestMain.cpp \
Source/WebKit2/UIProcess/API/gtk/tests/TestMain.h \
Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp \
@@ -120,6 +123,32 @@
$(global_cflags)
+noinst_LTLIBRARIES += Libraries/WebExtensions/libWebProcessTest.la
+Libraries_WebExtensions_libWebProcessTest_la_SOURCES = \
+ Source/WebKit2/UIProcess/API/gtk/tests/DOMNodeTest.cpp \
+ Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTest.cpp \
+ Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTest.h
+
+Libraries_WebExtensions_libWebProcessTest_la_LDFLAGS = \
+ -rpath ${shell pwd}/$(top_builddir)/Libraries/WebExtensions/.libs \
+ $(no_undefined) \
+ -avoid-version \
+ -module
+
+Libraries_WebExtensions_libWebProcessTest_la_CPPFLAGS = \
+ -I$(srcdir)/Source/WebKit2/WebProcess/InjectedBundle/API/gtk \
+ -I$(top_builddir)/DerivedSources \
+ -I$(top_builddir)/DerivedSources/WebKit2/webkit2extension/include \
+ -DWEBKIT2_COMPILATION \
+ $(webkit2_tests_cppflags)
+
+Libraries_WebExtensions_libWebProcessTest_la_CXXFLAGS = \
+ $(global_cxxflags)
+
+Libraries_WebExtensions_libWebProcessTest_la_CFLAGS = \
+ $(global_cflags)
+
+
EXTRA_DIST += \
Source/WebKit2/UIProcess/API/gtk/tests/resources/test-cert.pem \
Source/WebKit2/UIProcess/API/gtk/tests/resources/test-key.pem \
@@ -268,4 +297,10 @@
Programs_WebKit2APITests_TestWebKitWebViewGroup_LDADD = $(webkit2_tests_ldadd)
Programs_WebKit2APITests_TestWebKitWebViewGroup_LDFLAGS = $(webkit2_tests_ldflags)
+Programs_WebKit2APITests_TestDOMNode_SOURCES = \
+ Source/WebKit2/UIProcess/API/gtk/tests/TestDOMNode.cpp
+Programs_WebKit2APITests_TestDOMNode_CPPFLAGS = $(webkit2_tests_cppflags)
+Programs_WebKit2APITests_TestDOMNode_LDADD = $(webkit2_tests_ldadd)
+Programs_WebKit2APITests_TestDOMNode_LDFLAGS = $(webkit2_tests_ldflags)
+
endif # ENABLE_WEBKIT2
Added: trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestDOMNode.cpp (0 => 153327)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestDOMNode.cpp (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestDOMNode.cpp 2013-07-25 16:13:30 UTC (rev 153327)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include "WebProcessTestRunner.h"
+#include "WebViewTest.h"
+#include <gtk/gtk.h>
+#include <webkit2/webkit2.h>
+
+static WebProcessTestRunner* testRunner;
+
+static void testWebKitDOMNodeHierarchyNavigation(WebViewTest* test, gconstpointer)
+{
+ static const char* testHTML = "<html><head><title>This is the title</title></head><body><p>1</p><p>2</p><p>3</p></body></html>";
+ test->loadHtml(testHTML, 0);
+ test->waitUntilLoadFinished();
+
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_add(&builder, "{sv}", "pageID", g_variant_new_uint64(webkit_web_view_get_page_id(test->m_webView)));
+ g_assert(testRunner->runTest("WebKitDOMNode", "hierarchy-navigation", g_variant_builder_end(&builder)));
+}
+
+static void testWebKitDOMNodeInsertion(WebViewTest* test, gconstpointer)
+{
+ static const char* testHTML = "<html><body></body></html>";
+ test->loadHtml(testHTML, 0);
+ test->waitUntilLoadFinished();
+
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_add(&builder, "{sv}", "pageID", g_variant_new_uint64(webkit_web_view_get_page_id(test->m_webView)));
+ g_assert(testRunner->runTest("WebKitDOMNode", "insertion", g_variant_builder_end(&builder)));
+}
+
+void beforeAll()
+{
+ testRunner = new WebProcessTestRunner();
+ webkit_web_context_set_web_extensions_directory(webkit_web_context_get_default(), WEBKIT_TEST_WEB_EXTENSIONS_DIR);
+
+ WebViewTest::add("WebKitDOMNode", "hierarchy-navigation", testWebKitDOMNodeHierarchyNavigation);
+ WebViewTest::add("WebKitDOMNode", "insertion", testWebKitDOMNodeInsertion);
+}
+
+void afterAll()
+{
+ delete testRunner;
+}
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestMain.cpp (153326 => 153327)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestMain.cpp 2013-07-25 14:26:42 UTC (rev 153326)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestMain.cpp 2013-07-25 16:13:30 UTC (rev 153327)
@@ -53,6 +53,7 @@
int main(int argc, char** argv)
{
+ g_unsetenv("DBUS_SESSION_BUS_ADDRESS");
gtk_test_init(&argc, &argv, 0);
g_setenv("WEBKIT_EXEC_PATH", WEBKIT_EXEC_PATH, FALSE);
g_setenv("WEBKIT_INJECTED_BUNDLE_PATH", WEBKIT_INJECTED_BUNDLE_PATH, FALSE);
Added: trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTest.cpp (0 => 153327)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTest.cpp (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTest.cpp 2013-07-25 16:13:30 UTC (rev 153327)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WebProcessTest.h"
+
+#include <gio/gio.h>
+#include <wtf/gobject/GOwnPtr.h>
+
+typedef HashMap<String, Function<PassOwnPtr<WebProcessTest>()>> TestsMap;
+static TestsMap& testsMap()
+{
+ DEFINE_STATIC_LOCAL(TestsMap, s_testsMap, ());
+ return s_testsMap;
+}
+
+void WebProcessTest::add(const String& testName, Function<PassOwnPtr<WebProcessTest>()> closure)
+{
+ testsMap().add(testName, closure);
+}
+
+PassOwnPtr<WebProcessTest> WebProcessTest::create(const String& testName)
+{
+ g_assert(testsMap().contains(testName));
+ return testsMap().get(testName)();
+}
+
+static const char introspectionXML[] =
+ "<node>"
+ " <interface name='org.webkit.gtk.WebProcessTest'>"
+ " <method name='RunTest'>"
+ " <arg type='s' name='path' direction='in'/>"
+ " <arg type='a{sv}' name='args' direction='in'/>"
+ " <arg type='b' name='result' direction='out'/>"
+ " </method>"
+ " </interface>"
+ "</node>";
+
+static void methodCallCallback(GDBusConnection* connection, const char* sender, const char* objectPath, const char* interfaceName, const char* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData)
+{
+ if (g_strcmp0(interfaceName, "org.webkit.gtk.WebProcessTest"))
+ return;
+
+ if (!g_strcmp0(methodName, "RunTest")) {
+ const char* testPath;
+ GVariant* args;
+ g_variant_get(parameters, "(&s@a{sv})", &testPath, &args);
+ OwnPtr<WebProcessTest> test = WebProcessTest::create(String::fromUTF8(testPath));
+ bool result = test->runTest(g_strrstr(testPath, "/") + 1, WEBKIT_WEB_EXTENSION(userData), args);
+ g_variant_unref(args);
+
+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", result));
+ } else
+ g_assert_not_reached();
+}
+
+static const GDBusInterfaceVTable interfaceVirtualTable = {
+ methodCallCallback, 0, 0, { 0, }
+};
+
+static void busAcquiredCallback(GDBusConnection* connection, const char* name, gpointer userData)
+{
+ static GDBusNodeInfo *introspectionData = 0;
+ if (!introspectionData)
+ introspectionData = g_dbus_node_info_new_for_xml(introspectionXML, 0);
+
+ GOwnPtr<GError> error;
+ unsigned registrationID = g_dbus_connection_register_object(
+ connection,
+ "/org/webkit/gtk/WebProcessTest",
+ introspectionData->interfaces[0],
+ &interfaceVirtualTable,
+ g_object_ref(userData),
+ static_cast<GDestroyNotify>(g_object_unref),
+ &error.outPtr());
+ if (!registrationID)
+ g_warning("Failed to register object: %s\n", error->message);
+}
+
+extern "C" void webkit_web_extension_initialize(WebKitWebExtension* extension)
+{
+ g_bus_own_name(
+ G_BUS_TYPE_SESSION,
+ "org.webkit.gtk.WebProcessTest",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ busAcquiredCallback,
+ 0, 0,
+ g_object_ref(extension),
+ static_cast<GDestroyNotify>(g_object_unref));
+}
Added: trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTest.h (0 => 153327)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTest.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTest.h 2013-07-25 16:13:30 UTC (rev 153327)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <webkit2/webkit-web-extension.h>
+#include <wtf/Functional.h>
+#include <wtf/HashMap.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/StringHash.h>
+#include <wtf/text/WTFString.h>
+
+class WebProcessTest {
+public:
+ virtual ~WebProcessTest() { }
+ virtual bool runTest(const char* testName, WebKitWebExtension*, GVariant* args) = 0;
+
+ static void add(const String& testName, Function<PassOwnPtr<WebProcessTest>()>);
+ static PassOwnPtr<WebProcessTest> create(const String& testName);
+};
+
+#define REGISTER_TEST(ClassName, TestName) \
+ WebProcessTest::add(String::fromUTF8(TestName), WTF::bind(&ClassName::create))
+
Added: trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTestRunner.cpp (0 => 153327)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTestRunner.cpp (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTestRunner.cpp 2013-07-25 16:13:30 UTC (rev 153327)
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WebProcessTestRunner.h"
+
+#include <wtf/gobject/GOwnPtr.h>
+
+WebProcessTestRunner::WebProcessTestRunner()
+ : m_mainLoop(g_main_loop_new(0, TRUE))
+ , m_bus(adoptGRef(g_test_dbus_new(G_TEST_DBUS_NONE)))
+{
+ g_test_dbus_up(m_bus.get());
+ m_connection = adoptGRef(g_bus_get_sync(G_BUS_TYPE_SESSION, 0, 0));
+}
+
+WebProcessTestRunner::~WebProcessTestRunner()
+{
+ g_main_loop_unref(m_mainLoop);
+
+ // g_test_dbus_down waits until the connection is freed, so release our refs explicitly before calling it.
+ m_connection = 0;
+ m_proxy = 0;
+ g_test_dbus_down(m_bus.get());
+}
+
+void WebProcessTestRunner::proxyCreatedCallback(GObject*, GAsyncResult* result, WebProcessTestRunner* testRunner)
+{
+ testRunner->m_proxy = adoptGRef(g_dbus_proxy_new_finish(result, 0));
+ g_main_loop_quit(testRunner->m_mainLoop);
+}
+
+GDBusProxy* WebProcessTestRunner::proxy()
+{
+ if (m_proxy)
+ return m_proxy.get();
+
+ g_dbus_proxy_new(m_connection.get(), G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, 0,
+ "org.webkit.gtk.WebProcessTest", "/org/webkit/gtk/WebProcessTest", "org.webkit.gtk.WebProcessTest",
+ 0, reinterpret_cast<GAsyncReadyCallback>(WebProcessTestRunner::proxyCreatedCallback), this);
+ g_main_loop_run(m_mainLoop);
+ g_assert(m_proxy.get());
+
+ return m_proxy.get();
+}
+
+void WebProcessTestRunner::onNameAppeared(GDBusConnection*, const char*, const char*, gpointer userData)
+{
+ WebProcessTestRunner* testRunner = static_cast<WebProcessTestRunner*>(userData);
+ g_main_loop_quit(testRunner->m_mainLoop);
+}
+
+void WebProcessTestRunner::onNameVanished(GDBusConnection*, const char* name, gpointer userData)
+{
+ _exit(1);
+}
+
+void WebProcessTestRunner::testFinishedCallback(GDBusProxy* proxy, GAsyncResult* result, WebProcessTestRunner* testRunner)
+{
+ GRefPtr<GVariant> returnValue = adoptGRef(g_dbus_proxy_call_finish(proxy, result, 0));
+ g_assert(returnValue.get());
+ gboolean testResult;
+ g_variant_get(returnValue.get(), "(b)", &testResult);
+ testRunner->finishTest(testResult);
+}
+
+bool WebProcessTestRunner::runTest(const char* suiteName, const char* testName, GVariant* args)
+{
+ g_assert(g_variant_is_of_type(args, G_VARIANT_TYPE_VARDICT));
+
+ unsigned watcherID = g_bus_watch_name_on_connection(m_connection.get(), "org.webkit.gtk.WebProcessTest", G_BUS_NAME_WATCHER_FLAGS_NONE,
+ WebProcessTestRunner::onNameAppeared, WebProcessTestRunner::onNameVanished, this, 0);
+ g_main_loop_run(m_mainLoop);
+
+ m_testResult = false;
+ GOwnPtr<char> testPath(g_strdup_printf("%s/%s", suiteName, testName));
+ g_dbus_proxy_call(
+ proxy(),
+ "RunTest",
+ g_variant_new("(s@a{sv})", testPath.get(), args),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, 0,
+ reinterpret_cast<GAsyncReadyCallback>(WebProcessTestRunner::testFinishedCallback),
+ this);
+ g_main_loop_run(m_mainLoop);
+ g_bus_unwatch_name(watcherID);
+
+ return m_testResult;
+}
+
+void WebProcessTestRunner::finishTest(bool result)
+{
+ m_testResult = result;
+ g_main_loop_quit(m_mainLoop);
+}
Added: trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTestRunner.h (0 => 153327)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTestRunner.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebProcessTestRunner.h 2013-07-25 16:13:30 UTC (rev 153327)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef WebProcessTestRunner_h
+#define WebProcessTestRunner_h
+
+#include <gio/gio.h>
+#include <webkit2/webkit2.h>
+#include <wtf/gobject/GRefPtr.h>
+
+class WebProcessTestRunner {
+public:
+ WebProcessTestRunner();
+ ~WebProcessTestRunner();
+
+ bool runTest(const char* suiteName, const char* testName, GVariant* args);
+
+private:
+ static void proxyCreatedCallback(GObject*, GAsyncResult*, WebProcessTestRunner*);
+ static void onNameAppeared(GDBusConnection*, const char*, const char*, gpointer);
+ static void onNameVanished(GDBusConnection*, const char*, gpointer);
+ static void testFinishedCallback(GDBusProxy*, GAsyncResult*, WebProcessTestRunner*);
+
+ GDBusProxy* proxy();
+ void finishTest(bool result);
+
+ GMainLoop* m_mainLoop;
+ GRefPtr<GTestDBus> m_bus;
+ GRefPtr<GDBusConnection> m_connection;
+ GRefPtr<GDBusProxy> m_proxy;
+ bool m_testResult;
+};
+
+#endif // WebProcessTestRunner_h