#!/usr/bin/env python # # Copyright (C) 2011, 2012, 2017 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. import logging import subprocess import os import sys import optparse from gi.repository import Gio, GLib top_level_directory = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "..")) sys.path.insert(0, os.path.join(top_level_directory, "Tools", "jhbuild")) sys.path.insert(0, os.path.join(top_level_directory, "Tools", "glib")) import common import jhbuildutils from api_test_runner import TestRunner, SkippedTest, add_options class GtkTestRunner(TestRunner): TestRunner.TEST_DIRS = [ "WebKit2Gtk", "WebKit", "JavaScriptCore", "WTF", "WebCore" ] TestRunner.SKIPPED = [ SkippedTest("WebKit2Gtk/TestUIClient", "/webkit2/WebKitWebView/mouse-target", "Test times out after r150890", 117689), SkippedTest("WebKit2Gtk/TestUIClient", "/webkit2/WebKitWebView/usermedia-permission-requests", "Test times out", 158257), SkippedTest("WebKit2Gtk/TestUIClient", "/webkit2/WebKitWebView/audio-usermedia-permission-request", "Test times out", 158257), SkippedTest("WebKit2Gtk/TestCookieManager", "/webkit2/WebKitCookieManager/persistent-storage", "Test is flaky", 134580), SkippedTest("WebKit2Gtk/TestPrinting", "/webkit2/WebKitPrintOperation/custom-widget", "Test is flaky", 168196), SkippedTest("WebKit2Gtk/TestWebViewEditor", "/webkit2/WebKitWebView/editable/editable", "Test hits an assertion in Debug builds", 151654, "Debug"), SkippedTest("WebKit2Gtk/TestWebExtensions", "/webkit2/WebKitWebExtension/form-controls-associated-signal", "Test is flaky", 168194), SkippedTest("WebKit2Gtk/TestWebExtensions", "/webkit2/WebKitWebView/install-missing-plugins-permission-request", "Test times out", 147822), SkippedTest("WebKit/TestWebKit", "WebKit.MouseMoveAfterCrash", "Test is flaky", 85066), SkippedTest("WebKit/TestWebKit", "WebKit.NewFirstVisuallyNonEmptyLayoutForImages", "Test is flaky", 85066), SkippedTest("WebKit/TestWebKit", "WebKit.NewFirstVisuallyNonEmptyLayoutFrames", "Test fails", 85037), SkippedTest("WebKit/TestWebKit", "WebKit.SpacebarScrolling", "Test fails", 84961), SkippedTest("WebKit/TestWebKit", "WebKit.WKConnection", "Tests fail and time out out", 84959), SkippedTest("WebKit/TestWebKit", "WebKit.ForceRepaint", "Test times out", 105532), SkippedTest("WebKit/TestWebKit", "WebKit.ReloadPageAfterCrash", "Test flakily times out", 110129), SkippedTest("WebKit/TestWebKit", "WebKit.DidAssociateFormControls", "Test times out", 120302), SkippedTest("WebKit/TestWebKit", "WebKit.InjectedBundleFrameHitTest", "Test times out", 120303), SkippedTest("WebKit/TestWebKit", "WebKit.TerminateTwice", "Test causes crash on the next test", 121970), SkippedTest("WebKit/TestWebKit", "WebKit.GeolocationTransitionToHighAccuracy", "Test causes crash on the next test", 125068), SkippedTest("WebKit/TestWebKit", "WebKit.GeolocationTransitionToLowAccuracy", "Test causes crash on the next test", 125068), ] TestRunner.SLOW = [ "WTF_Lock.ContendedShortSection", "WTF_Lock.ContendedLongSection", "WTF_WordLock.ContendedShortSection", "WTF_WordLock.ContendedLongSection", "WebKit2Gtk/TestInspectorServer", ] def __init__(self, options, tests=[]): super(GtkTestRunner, self).__init__("gtk", options, tests) # These SPI daemons need to be active for the accessibility tests to work. self._spi_registryd = None self._spi_bus_launcher = None def _lookup_atspi2_binary(self, filename): exec_prefix = common.pkg_config_file_variable('atspi-2', 'exec_prefix') if not exec_prefix: return None for path in ['libexec', 'lib/at-spi2-core', 'lib32/at-spi2-core', 'lib64/at-spi2-core']: filepath = os.path.join(exec_prefix, path, filename) if os.path.isfile(filepath): return filepath return None def _wait_for_accessibility_bus(self): def timeout_accessibility_bus(): self._accessibility_bus_found = False sys.stderr.write("Timeout waiting for the accesibility bus.\n") sys.stderr.flush() loop.quit() # Backup current environment, and temporally set the test one. oldenv = dict(os.environ) os.environ.clear() os.environ.update(self._test_env) # We spin a main loop until the bus name appears on DBus. self._accessibility_bus_found = True loop = GLib.MainLoop() Gio.bus_watch_name(Gio.BusType.SESSION, 'org.a11y.Bus', Gio.BusNameWatcherFlags.NONE, lambda *args: loop.quit(), None) GLib.timeout_add_seconds(5, timeout_accessibility_bus) loop.run() # Restore previous environment. os.environ.clear() os.environ.update(oldenv) return self._accessibility_bus_found def _start_accessibility_daemons(self): spi_bus_launcher_path = self._lookup_atspi2_binary('at-spi-bus-launcher') spi_registryd_path = self._lookup_atspi2_binary('at-spi2-registryd') if not spi_bus_launcher_path or not spi_registryd_path: return False try: self._spi_bus_launcher = subprocess.Popen([spi_bus_launcher_path], env=self._test_env) except: sys.stderr.write("Failed to launch the accessibility bus\n") sys.stderr.flush() return False # We need to wait until the SPI bus is launched before trying to start the SPI registry. if not self._wait_for_accessibility_bus(): sys.stderr.write("Failed checking the accessibility bus within D-Bus\n") sys.stderr.flush() return False try: self._spi_registryd = subprocess.Popen([spi_registryd_path], env=self._test_env) except: sys.stderr.write("Failed to launch the accessibility registry\n") sys.stderr.flush() return False return True def _setup_testing_environment(self): super(GtkTestRunner, self)._setup_testing_environment() # If we cannot start the accessibility daemons, we can just skip the accessibility tests. if not self._start_accessibility_daemons(): print "Could not start accessibility bus, so disabling TestWebKitAccessibility" self._disabled_tests.append("WebKit2APITests/TestWebKitAccessibility") return True def _tear_down_testing_environment(self): if self._spi_registryd: self._spi_registryd.terminate() if self._spi_bus_launcher: self._spi_bus_launcher.terminate() super(GtkTestRunner, self)._tear_down_testing_environment() def is_glib_test(self, test_program): return os.path.basename(os.path.dirname(test_program)) == "WebKit2Gtk" def is_google_test(self, test_program): return os.path.basename(os.path.dirname(test_program)) in ["WebKit", "JavaScriptCore", "WTF", "WebCore", "WebCoreGtk"] if __name__ == "__main__": if not jhbuildutils.enter_jhbuild_environment_if_available("gtk"): print "***" print "*** Warning: jhbuild environment not present. Run update-webkitgtk-libs before build-webkit to ensure proper testing." print "***" option_parser = optparse.OptionParser(usage='usage: %prog [options] [test...]') add_options(option_parser); option_parser.add_option('--display-server', choices=['xvfb', 'xorg', 'weston', 'wayland'], default='xvfb', help='"xvfb": Use a virtualized X11 server. "xorg": Use the current X11 session. ' '"weston": Use a virtualized Weston server. "wayland": Use the current wayland session.'), options, args = option_parser.parse_args() logging.basicConfig(level=logging.INFO, format="%(message)s") runner = GtkTestRunner(options, args) sys.exit(runner.run_tests())