Title: [225047] trunk/Tools
Revision
225047
Author
[email protected]
Date
2017-11-20 03:03:26 -0800 (Mon, 20 Nov 2017)

Log Message

[WPE] Add run-wpe-tests script to run WPE glib API tests
https://bugs.webkit.org/show_bug.cgi?id=173772

Reviewed by Michael Catanzaro.

Move common code from run-gtk-tests to api_test_runner.py, to be shared by both run-gtk-tests and un-wpe-tests.

* Scripts/run-gtk-tests:
(GtkTestRunner):
(GtkTestRunner.__init__):
(GtkTestRunner._start_accessibility_daemons):
(GtkTestRunner._setup_testing_environment):
(GtkTestRunner._tear_down_testing_environment):
(GtkTestRunner.is_glib_test):
(GtkTestRunner.is_google_test):
* Scripts/run-wpe-tests: Added.
(WPETestRunner):
(WPETestRunner.__init__):
(WPETestRunner.is_glib_test):
(WPETestRunner.is_google_test):
* Scripts/webkitpy/port/headlessdriver.py: Added.
(HeadlessDriver):
(HeadlessDriver._setup_environ_for_test):
(HeadlessDriver._start):
* Scripts/webkitpy/port/headlessdriver_unittest.py: Added.
(HeadlessDriverTest):
(HeadlessDriverTest.make_driver):
(HeadlessDriverTest.make_environment):
(HeadlessDriverTest.test_environment_needed_variables):
(HeadlessDriverTest.test_environment_forbidden_variables):
* Scripts/webkitpy/port/wpe.py:
(WPEPort._driver_class):
* WebKitTestRunner/PlatformWebView.h:
* WebKitTestRunner/wpe/PlatformWebViewWPE.cpp:
(WTR::PlatformWebView::windowSnapshotImage):
* glib/api_test_runner.py: Copied from Tools/Scripts/run-gtk-tests.
(SkippedTest):
(SkippedTest.__init__):
(SkippedTest.__str__):
(SkippedTest.skip_entire_suite):
(SkippedTest.skip_for_build_type):
(TestTimeout):
(TestRunner):
(TestRunner.__init__):
(TestRunner._test_programs_base_dir):
(TestRunner._get_tests_from_dir):
(TestRunner._get_tests):
(TestRunner._create_driver):
(TestRunner._setup_testing_environment):
(TestRunner._tear_down_testing_environment):
(TestRunner._test_cases_to_skip):
(TestRunner._should_run_test_program):
(TestRunner._kill_process):
(TestRunner._start_timeout):
(TestRunner._start_timeout._alarm_handler):
(TestRunner._stop_timeout):
(TestRunner._waitpid):
(TestRunner._run_test_glib):
(TestRunner._run_test_glib.parse_line):
(TestRunner._run_test_glib.parse_line.set_test_result):
(TestRunner._get_tests_from_google_test_suite):
(TestRunner._run_google_test):
(TestRunner._run_google_test_suite):
(TestRunner.is_glib_test):
(TestRunner.is_google_test):
(TestRunner._run_test):
(TestRunner.run_tests):
(add_options):
* glib/common.py: Renamed from Tools/gtk/common.py.
(get_build_path.is_valid_build_directory):
* gtk/generate-gtkdoc:
* gtk/jhbuildrc:
* gtk/ycm_extra_conf.py:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Tools/ChangeLog (225046 => 225047)


--- trunk/Tools/ChangeLog	2017-11-20 09:51:07 UTC (rev 225046)
+++ trunk/Tools/ChangeLog	2017-11-20 11:03:26 UTC (rev 225047)
@@ -1,5 +1,81 @@
 2017-11-20  Carlos Garcia Campos  <[email protected]>
 
+        [WPE] Add run-wpe-tests script to run WPE glib API tests
+        https://bugs.webkit.org/show_bug.cgi?id=173772
+
+        Reviewed by Michael Catanzaro.
+
+        Move common code from run-gtk-tests to api_test_runner.py, to be shared by both run-gtk-tests and un-wpe-tests.
+
+        * Scripts/run-gtk-tests:
+        (GtkTestRunner):
+        (GtkTestRunner.__init__):
+        (GtkTestRunner._start_accessibility_daemons):
+        (GtkTestRunner._setup_testing_environment):
+        (GtkTestRunner._tear_down_testing_environment):
+        (GtkTestRunner.is_glib_test):
+        (GtkTestRunner.is_google_test):
+        * Scripts/run-wpe-tests: Added.
+        (WPETestRunner):
+        (WPETestRunner.__init__):
+        (WPETestRunner.is_glib_test):
+        (WPETestRunner.is_google_test):
+        * Scripts/webkitpy/port/headlessdriver.py: Added.
+        (HeadlessDriver):
+        (HeadlessDriver._setup_environ_for_test):
+        (HeadlessDriver._start):
+        * Scripts/webkitpy/port/headlessdriver_unittest.py: Added.
+        (HeadlessDriverTest):
+        (HeadlessDriverTest.make_driver):
+        (HeadlessDriverTest.make_environment):
+        (HeadlessDriverTest.test_environment_needed_variables):
+        (HeadlessDriverTest.test_environment_forbidden_variables):
+        * Scripts/webkitpy/port/wpe.py:
+        (WPEPort._driver_class):
+        * WebKitTestRunner/PlatformWebView.h:
+        * WebKitTestRunner/wpe/PlatformWebViewWPE.cpp:
+        (WTR::PlatformWebView::windowSnapshotImage):
+        * glib/api_test_runner.py: Copied from Tools/Scripts/run-gtk-tests.
+        (SkippedTest):
+        (SkippedTest.__init__):
+        (SkippedTest.__str__):
+        (SkippedTest.skip_entire_suite):
+        (SkippedTest.skip_for_build_type):
+        (TestTimeout):
+        (TestRunner):
+        (TestRunner.__init__):
+        (TestRunner._test_programs_base_dir):
+        (TestRunner._get_tests_from_dir):
+        (TestRunner._get_tests):
+        (TestRunner._create_driver):
+        (TestRunner._setup_testing_environment):
+        (TestRunner._tear_down_testing_environment):
+        (TestRunner._test_cases_to_skip):
+        (TestRunner._should_run_test_program):
+        (TestRunner._kill_process):
+        (TestRunner._start_timeout):
+        (TestRunner._start_timeout._alarm_handler):
+        (TestRunner._stop_timeout):
+        (TestRunner._waitpid):
+        (TestRunner._run_test_glib):
+        (TestRunner._run_test_glib.parse_line):
+        (TestRunner._run_test_glib.parse_line.set_test_result):
+        (TestRunner._get_tests_from_google_test_suite):
+        (TestRunner._run_google_test):
+        (TestRunner._run_google_test_suite):
+        (TestRunner.is_glib_test):
+        (TestRunner.is_google_test):
+        (TestRunner._run_test):
+        (TestRunner.run_tests):
+        (add_options):
+        * glib/common.py: Renamed from Tools/gtk/common.py.
+        (get_build_path.is_valid_build_directory):
+        * gtk/generate-gtkdoc:
+        * gtk/jhbuildrc:
+        * gtk/ycm_extra_conf.py:
+
+2017-11-20  Carlos Garcia Campos  <[email protected]>
+
         [WPE] Build C API tests
         https://bugs.webkit.org/show_bug.cgi?id=179817
 

Modified: trunk/Tools/Scripts/run-gtk-tests (225046 => 225047)


--- trunk/Tools/Scripts/run-gtk-tests	2017-11-20 09:51:07 UTC (rev 225046)
+++ trunk/Tools/Scripts/run-gtk-tests	2017-11-20 11:03:26 UTC (rev 225047)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright (C) 2011, 2012 Igalia S.L.
+# 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
@@ -22,52 +22,19 @@
 import os
 import sys
 import optparse
-import re
-from signal import alarm, signal, SIGALRM, SIGKILL, SIGSEGV
 from gi.repository import Gio, GLib
 
 top_level_directory = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", ".."))
-sys.path.append(os.path.join(top_level_directory, "Tools", "jhbuild"))
-sys.path.append(os.path.join(top_level_directory, "Tools", "gtk"))
+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 webkitpy.common.host import Host
+from api_test_runner import TestRunner, SkippedTest, add_options
 
-class SkippedTest:
-    ENTIRE_SUITE = None
+class GtkTestRunner(TestRunner):
+    TestRunner.TEST_DIRS = [ "WebKit2Gtk", "WebKit", "_javascript_Core", "WTF", "WebCore" ]
 
-    def __init__(self, test, test_case, reason, bug, build_type=None):
-        self.test = test
-        self.test_case = test_case
-        self.reason = reason
-        self.bug = bug
-        self.build_type = build_type
-
-    def __str__(self):
-        skipped_test_str = "%s" % self.test
-
-        if not(self.skip_entire_suite()):
-            skipped_test_str += " [%s]" % self.test_case
-
-        skipped_test_str += ": %s (https://bugs.webkit.org/show_bug.cgi?id=%d)" % (self.reason, self.bug)
-        return skipped_test_str
-
-    def skip_entire_suite(self):
-        return self.test_case == SkippedTest.ENTIRE_SUITE
-
-    def skip_for_build_type(self, build_type):
-        if self.build_type is None:
-            return True;
-
-        return self.build_type == build_type
-
-class TestTimeout(Exception):
-    pass
-
-class TestRunner:
-    TEST_DIRS = [ "WebKit2Gtk", "WebKit", "_javascript_Core", "WTF", "WebCore" ]
-
-    SKIPPED = [
+    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),
@@ -90,7 +57,7 @@
         SkippedTest("WebKit/TestWebKit", "WebKit.GeolocationTransitionToLowAccuracy", "Test causes crash on the next test", 125068),
     ]
 
-    SLOW = [
+    TestRunner.SLOW = [
         "WTF_Lock.ContendedShortSection",
         "WTF_Lock.ContendedLongSection",
         "WTF_WordLock.ContendedShortSection",
@@ -99,54 +66,12 @@
     ]
 
     def __init__(self, options, tests=[]):
-        self._options = options
+        super(GtkTestRunner, self).__init__("gtk", options, tests)
 
-        self._build_type = "Debug" if self._options.debug else "Release"
-        common.set_build_types((self._build_type,))
-        self._port = Host().port_factory.get("gtk")
-        self._driver = self._create_driver()
-
-        self._programs_path = common.binary_build_path()
-        self._tests = self._get_tests(tests)
-        self._skipped_tests = [skipped for skipped in TestRunner.SKIPPED if skipped.skip_for_build_type(self._build_type)]
-        self._disabled_tests = []
-
         # These SPI daemons need to be active for the accessibility tests to work.
         self._spi_registryd = None
         self._spi_bus_launcher = None
 
-    def _test_programs_base_dir(self):
-        return os.path.join(self._programs_path, "TestWebKitAPI")
-
-    def _get_tests_from_dir(self, test_dir):
-        if not os.path.isdir(test_dir):
-            return []
-
-        tests = []
-        for test_file in os.listdir(test_dir):
-            if not test_file.lower().startswith("test"):
-                continue
-            test_path = os.path.join(test_dir, test_file)
-            if os.path.isfile(test_path) and os.access(test_path, os.X_OK):
-                tests.append(test_path)
-        return tests
-
-    def _get_tests(self, initial_tests):
-        tests = []
-        for test in initial_tests:
-            if os.path.isdir(test):
-                tests.extend(self._get_tests_from_dir(test))
-            else:
-                tests.append(test)
-        if tests:
-            return tests
-
-        tests = []
-        for test_dir in self.TEST_DIRS:
-            absolute_test_dir = os.path.join(self._test_programs_base_dir(), test_dir)
-            tests.extend(self._get_tests_from_dir(absolute_test_dir))
-        return tests
-
     def _lookup_atspi2_binary(self, filename):
         exec_prefix = common.pkg_config_file_variable('atspi-2', 'exec_prefix')
         if not exec_prefix:
@@ -208,18 +133,8 @@
 
         return True
 
-    def _create_driver(self, port_options=[]):
-        self._port._display_server = self._options.display_server
-        driver = self._port.create_driver(worker_number=0, no_timeout=True)._make_driver(pixel_tests=False)
-        if not driver.check_driver(self._port):
-            raise RuntimeError("Failed to check driver %s" %driver.__class__.__name__)
-        return driver
-
     def _setup_testing_environment(self):
-        self._test_env = self._driver._setup_environ_for_test()
-        self._test_env["TEST_WEBKIT_API_WEBKIT2_RESOURCES_PATH"] = common.top_level_path("Tools", "TestWebKitAPI", "Tests", "WebKit")
-        self._test_env["TEST_WEBKIT_API_WEBKIT2_INJECTED_BUNDLE_PATH"] = common.library_build_path()
-        self._test_env["WEBKIT_EXEC_PATH"] = self._programs_path
+        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():
@@ -232,277 +147,14 @@
             self._spi_registryd.terminate()
         if self._spi_bus_launcher:
             self._spi_bus_launcher.terminate()
-        if self._driver:
-            self._driver.stop()
+        super(GtkTestRunner, self)._tear_down_testing_environment()
 
-    def _test_cases_to_skip(self, test_program):
-        if self._options.skipped_action != 'skip':
-            return []
+    def is_glib_test(self, test_program):
+        return os.path.basename(os.path.dirname(test_program)) == "WebKit2Gtk"
 
-        test_cases = []
-        for skipped in self._skipped_tests:
-            if test_program.endswith(skipped.test) and not skipped.skip_entire_suite():
-                test_cases.append(skipped.test_case)
-        return test_cases
+    def is_google_test(self, test_program):
+        return os.path.basename(os.path.dirname(test_program)) in ["WebKit", "_javascript_Core", "WTF", "WebCore",  "WebCoreGtk"]
 
-    def _should_run_test_program(self, test_program):
-        for disabled_test in self._disabled_tests:
-            if test_program.endswith(disabled_test):
-                return False
-
-        if self._options.skipped_action != 'skip':
-            return True
-
-        for skipped in self._skipped_tests:
-            if test_program.endswith(skipped.test) and skipped.skip_entire_suite():
-                return False
-        return True
-
-    def _kill_process(self, pid):
-        try:
-            os.kill(pid, SIGKILL)
-        except OSError:
-            # Process already died.
-            pass
-
-    @staticmethod
-    def _start_timeout(timeout):
-        if timeout <= 0:
-            return
-
-        def _alarm_handler(signum, frame):
-            raise TestTimeout
-
-        signal(SIGALRM, _alarm_handler)
-        alarm(timeout)
-
-    @staticmethod
-    def _stop_timeout(timeout):
-        if timeout <= 0:
-            return
-
-        alarm(0)
-
-    def _waitpid(self, pid):
-        while True:
-            try:
-                dummy, status = os.waitpid(pid, 0)
-                if os.WIFSIGNALED(status):
-                    return -os.WTERMSIG(status)
-                if os.WIFEXITED(status):
-                    return os.WEXITSTATUS(status)
-
-                # Should never happen
-                raise RuntimeError("Unknown child exit status!")
-            except (OSError, IOError) as e:
-                if e.errno == errno.EINTR:
-                    continue
-                if e.errno == errno.ECHILD:
-                    # This happens if SIGCLD is set to be ignored or waiting
-                    # for child processes has otherwise been disabled for our
-                    # process.  This child is dead, we can't get the status.
-                    return 0
-                raise
-
-    def _run_test_glib(self, test_program):
-        command = ['gtester', '-k']
-        if self._options.verbose:
-            command.append('--verbose')
-        for test_case in self._test_cases_to_skip(test_program):
-            command.extend(['-s', test_case])
-        command.append(test_program)
-
-        timeout = self._options.timeout
-        test = os.path.join(os.path.basename(os.path.dirname(test_program)), os.path.basename(test_program))
-        if test in TestRunner.SLOW:
-            timeout *= 5
-
-        test_context = { "child-pid" : -1, "did-timeout" : False, "current_test" : None }
-        def parse_line(line, test_context = test_context):
-            if not line:
-                return
-
-            match = re.search(r'\(pid=(?P<child_pid>[0-9]+)\)', line)
-            if match:
-                test_context["child-pid"] = int(match.group('child_pid'))
-                sys.stdout.write(line)
-                return
-
-            def set_test_result(test, result):
-                if result == "FAIL":
-                    if test_context["did-timeout"] and result == "FAIL":
-                        test_context[test] = "TIMEOUT"
-                    else:
-                        test_context[test] = result
-                test_context["did-timeout"] = False
-                test_context["current_test"] = None
-                self._stop_timeout(timeout)
-                self._start_timeout(timeout)
-
-            normalized_line = line.strip().replace(' ', '')
-            if not normalized_line:
-                return
-
-            if normalized_line[0] == '/':
-                test, result = normalized_line.split(':', 1)
-                if result in ["OK", "FAIL"]:
-                    set_test_result(test, result)
-                else:
-                    test_context["current_test"] = test
-            elif normalized_line in ["OK", "FAIL"]:
-                set_test_result(test_context["current_test"], normalized_line)
-
-            sys.stdout.write(line)
-
-        pid, fd = os.forkpty()
-        if pid == 0:
-            os.execvpe(command[0], command, self._test_env)
-            sys.exit(0)
-
-        self._start_timeout(timeout)
-
-        while (True):
-            try:
-                common.parse_output_lines(fd, parse_line)
-                break
-            except TestTimeout:
-                assert test_context["child-pid"] > 0
-                self._kill_process(test_context["child-pid"])
-                test_context["child-pid"] = -1
-                test_context["did-timeout"] = True
-
-        self._stop_timeout(timeout)
-        del test_context["child-pid"]
-        del test_context["did-timeout"]
-        del test_context["current_test"]
-
-        self._waitpid(pid)
-        return test_context
-
-    def _get_tests_from_google_test_suite(self, test_program):
-        try:
-            output = subprocess.check_output([test_program, '--gtest_list_tests'], env=self._test_env)
-        except subprocess.CalledProcessError:
-            sys.stderr.write("ERROR: could not list available tests for binary %s.\n" % (test_program))
-            sys.stderr.flush()
-            return 1
-
-        skipped_test_cases = self._test_cases_to_skip(test_program)
-
-        tests = []
-        prefix = None
-        for line in output.split('\n'):
-            if not line.startswith('  '):
-                prefix = line
-                continue
-            else:
-                test_name = prefix + line.strip()
-                if not test_name in skipped_test_cases:
-                    tests.append(test_name)
-        return tests
-
-    def _run_google_test(self, test_program, subtest):
-        command = [test_program, '--gtest_filter=%s' % (subtest)]
-        timeout = self._options.timeout
-        if subtest in TestRunner.SLOW:
-            timeout *= 5
-
-        pid, fd = os.forkpty()
-        if pid == 0:
-            os.execvpe(command[0], command, self._test_env)
-            sys.exit(0)
-
-        self._start_timeout(timeout)
-        try:
-            common.parse_output_lines(fd, sys.stdout.write)
-            status = self._waitpid(pid)
-        except TestTimeout:
-            self._kill_process(pid)
-            return { subtest : "TIMEOUT" }
-
-        self._stop_timeout(timeout)
-
-        if status == -SIGSEGV:
-            sys.stdout.write("**CRASH** %s\n" % subtest)
-            sys.stdout.flush()
-            return { subtest : "CRASH" }
-
-        if status != 0:
-            return { subtest : "FAIL" }
-
-        return { }
-
-    def _run_google_test_suite(self, test_program):
-        result = { }
-        for subtest in self._get_tests_from_google_test_suite(test_program):
-            result.update(self._run_google_test(test_program, subtest))
-        return result
-
-    def _run_test(self, test_program):
-        basedir = os.path.basename(os.path.dirname(test_program))
-        if basedir in ["WebKit2Gtk", "WebKitGtk"]:
-            return self._run_test_glib(test_program)
-
-        if basedir in ["WebKit", "_javascript_Core", "WTF", "WebCore",  "WebCoreGtk"]:
-            return self._run_google_test_suite(test_program)
-
-        return 1
-
-    def run_tests(self):
-        if not self._tests:
-            sys.stderr.write("ERROR: tests not found in %s.\n" % (self._test_programs_base_dir()))
-            sys.stderr.flush()
-            return 1
-
-        if not self._setup_testing_environment():
-            return 1
-
-        # Remove skipped tests now instead of when we find them, because
-        # some tests might be skipped while setting up the test environment.
-        self._tests = [test for test in self._tests if self._should_run_test_program(test)]
-
-        crashed_tests = {}
-        failed_tests = {}
-        timed_out_tests = {}
-        try:
-            for test in self._tests:
-                results = self._run_test(test)
-                for test_case, result in results.iteritems():
-                    if result == "FAIL":
-                        failed_tests.setdefault(test, []).append(test_case)
-                    elif result == "TIMEOUT":
-                        timed_out_tests.setdefault(test, []).append(test_case)
-                    elif result == "CRASH":
-                        crashed_tests.setdefault(test, []).append(test_case)
-        finally:
-            self._tear_down_testing_environment()
-
-        if failed_tests:
-            sys.stdout.write("\nUnexpected failures (%d)\n" % (sum(len(value) for value in failed_tests.itervalues())))
-            for test in failed_tests:
-                sys.stdout.write("    %s\n" % (test.replace(self._test_programs_base_dir(), '', 1)))
-                for test_case in failed_tests[test]:
-                    sys.stdout.write("        %s\n" % (test_case))
-            sys.stdout.flush()
-
-        if crashed_tests:
-            sys.stdout.write("\nUnexpected crashes (%d)\n" % (sum(len(value) for value in crashed_tests.itervalues())))
-            for test in crashed_tests:
-                sys.stdout.write("    %s\n" % (test.replace(self._test_programs_base_dir(), '', 1)))
-                for test_case in crashed_tests[test]:
-                    sys.stdout.write("        %s\n" % (test_case))
-            sys.stdout.flush()
-
-        if timed_out_tests:
-            sys.stdout.write("\nUnexpected timeouts (%d)\n" % (sum(len(value) for value in timed_out_tests.itervalues())))
-            for test in timed_out_tests:
-                sys.stdout.write("    %s\n" % (test.replace(self._test_programs_base_dir(), '', 1)))
-                for test_case in timed_out_tests[test]:
-                    sys.stdout.write("        %s\n" % (test_case))
-            sys.stdout.flush()
-
-        return len(failed_tests) + len(timed_out_tests)
-
 if __name__ == "__main__":
     if not jhbuildutils.enter_jhbuild_environment_if_available("gtk"):
         print "***"
@@ -510,22 +162,7 @@
         print "***"
 
     option_parser = optparse.OptionParser(usage='usage: %prog [options] [test...]')
-    option_parser.add_option('-r', '--release',
-                             action='', dest='release',
-                             help='Run in Release')
-    option_parser.add_option('-d', '--debug',
-                             action='', dest='debug',
-                             help='Run in Debug')
-    option_parser.add_option('-v', '--verbose',
-                             action='', dest='verbose',
-                             help='Run gtester in verbose mode')
-    option_parser.add_option('--skipped', action='', dest='skipped_action',
-                             choices=['skip', 'ignore', 'only'], default='skip',
-                             metavar='skip|ignore|only',
-                             help='Specifies how to treat the skipped tests')
-    option_parser.add_option('-t', '--timeout',
-                             action='', type='int', dest='timeout', default=10,
-                             help='Time in seconds until a test times out')
+    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.'),
@@ -533,5 +170,5 @@
 
     logging.basicConfig(level=logging.INFO, format="%(message)s")
 
-    runner = TestRunner(options, args)
+    runner = GtkTestRunner(options, args)
     sys.exit(runner.run_tests())

Added: trunk/Tools/Scripts/run-wpe-tests (0 => 225047)


--- trunk/Tools/Scripts/run-wpe-tests	                        (rev 0)
+++ trunk/Tools/Scripts/run-wpe-tests	2017-11-20 11:03:26 UTC (rev 225047)
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 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 os
+import sys
+import optparse
+
+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 jhbuildutils
+from api_test_runner import TestRunner, SkippedTest, add_options
+
+class WPETestRunner(TestRunner):
+    TestRunner.TEST_DIRS = [ "WPE", "WebKit", "_javascript_Core", "WTF", "WebCore" ]
+
+    TestRunner.SLOW = [
+        "WTF_Lock.ContendedShortSection",
+        "WTF_Lock.ContendedLongSection",
+        "WTF_WordLock.ContendedShortSection",
+        "WTF_WordLock.ContendedLongSection",
+    ]
+
+    def __init__(self, options, tests=[]):
+        super(WPETestRunner, self).__init__("wpe", options, tests)
+
+    def is_glib_test(self, test_program):
+        return os.path.basename(os.path.dirname(test_program)) == "WPE"
+
+    def is_google_test(self, test_program):
+        return os.path.basename(os.path.dirname(test_program)) in ["WebKit", "_javascript_Core", "WTF", "WebCore"]
+
+
+if __name__ == "__main__":
+    if not jhbuildutils.enter_jhbuild_environment_if_available("wpe"):
+        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=['headless', 'wayland'], default='headless',
+                             help='"headless": Use headless view backend. "wayland": Use the current wayland session.'),
+    options, args = option_parser.parse_args()
+
+    logging.basicConfig(level=logging.INFO, format="%(message)s")
+
+    runner = WPETestRunner(options, args)
+    sys.exit(runner.run_tests())
Property changes on: trunk/Tools/Scripts/run-wpe-tests
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/Tools/Scripts/webkitpy/port/headlessdriver.py (0 => 225047)


--- trunk/Tools/Scripts/webkitpy/port/headlessdriver.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/port/headlessdriver.py	2017-11-20 11:03:26 UTC (rev 225047)
@@ -0,0 +1,54 @@
+# Copyright (C) 2017 Igalia S.L.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#
+#     * Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import logging
+import os
+
+from webkitpy.port.driver import Driver
+
+_log = logging.getLogger(__name__)
+
+
+class HeadlessDriver(Driver):
+    def _setup_environ_for_test(self):
+        driver_environment = self._port.setup_environ_for_server(self._server_name)
+        driver_environment['WPE_USE_HEADLESS_VIEW_BACKEND'] = "1"
+        driver_environment['LOCAL_RESOURCE_ROOT'] = self._port.layout_tests_dir()
+        driver_environment['DUMPRENDERTREE_TEMP'] = str(self._driver_tempdir)
+        driver_environment['XDG_CACHE_HOME'] = self._port.host.filesystem.join(str(self._driver_tempdir), 'appcache')
+        return driver_environment
+
+    def _start(self, pixel_tests, per_test_args):
+        super(HeadlessDriver, self).stop()
+        self._driver_tempdir = self._port.host.filesystem.mkdtemp(prefix='%s-' % self._server_name)
+        self._crashed_process_name = None
+        self._crashed_pid = None
+        self._server_process = self._port._server_process_constructor(self._port, self._server_name, self.cmd_line(pixel_tests, per_test_args), self._setup_environ_for_test())
+        self._server_process.start()

Added: trunk/Tools/Scripts/webkitpy/port/headlessdriver_unittest.py (0 => 225047)


--- trunk/Tools/Scripts/webkitpy/port/headlessdriver_unittest.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/port/headlessdriver_unittest.py	2017-11-20 11:03:26 UTC (rev 225047)
@@ -0,0 +1,75 @@
+# Copyright (C) 2017 Igalia S.L.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#    * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#    * Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import logging
+import unittest
+
+from webkitpy.common.system.systemhost_mock import MockSystemHost
+from webkitpy.port import Port
+from webkitpy.port.server_process_mock import MockServerProcess
+from webkitpy.port.headlessdriver import HeadlessDriver
+from webkitpy.thirdparty.mock import patch
+from webkitpy.tool.mocktool import MockOptions
+
+_log = logging.getLogger(__name__)
+
+
+class HeadlessDriverTest(unittest.TestCase):
+    def make_driver(self, worker_number=0, xorg_running=False, executive=None):
+        port = Port(MockSystemHost(log_executive=True, executive=executive), 'headlessdrivertestport', options=MockOptions(configuration='Release'))
+        port._config.build_directory = lambda configuration: '/mock-build'
+        port._server_process_constructor = MockServerProcess
+        driver = HeadlessDriver(port, worker_number=worker_number, pixel_tests=True)
+        driver._startup_delay_secs = 0
+        driver._environment = port.setup_environ_for_server(port.driver_name())
+        return driver
+
+    def make_environment(self):
+        environment_user = {'DISPLAY': ':0.0',
+                           'XAUTHORITY': '/home/igalia/.Xauthority',
+                           'WAYLAND_DISPLAY': 'wayland-0',
+                           'WAYLAND_SOCKET': 'wayland-0'}
+        return environment_user
+
+    def test_environment_needed_variables(self):
+        driver = self.make_driver()
+        environment_user = self.make_environment()
+        with patch('os.environ', environment_user):
+            driver_environment = driver._setup_environ_for_test()
+            self.assertIn('WPE_USE_HEADLESS_VIEW_BACKEND', driver_environment)
+            self.assertEqual(driver_environment['WPE_USE_HEADLESS_VIEW_BACKEND'], '1')
+
+    def test_environment_forbidden_variables(self):
+        driver = self.make_driver()
+        environment_user = self.make_environment()
+        with patch('os.environ', environment_user):
+            driver_environment = driver._setup_environ_for_test()
+            self.assertNotIn('DISPLAY', driver_environment)
+            self.assertNotIn('XAUTHORITY', driver_environment)
+            self.assertNotIn('WAYLAND_DISPLAY', driver_environment)
+            self.assertNotIn('WAYLAND_SOCKET', driver_environment)

Modified: trunk/Tools/Scripts/webkitpy/port/wpe.py (225046 => 225047)


--- trunk/Tools/Scripts/webkitpy/port/wpe.py	2017-11-20 09:51:07 UTC (rev 225046)
+++ trunk/Tools/Scripts/webkitpy/port/wpe.py	2017-11-20 11:03:26 UTC (rev 225047)
@@ -29,6 +29,7 @@
 from webkitpy.common.memoized import memoized
 from webkitpy.layout_tests.models.test_configuration import TestConfiguration
 from webkitpy.port.base import Port
+from webkitpy.port.headlessdriver import HeadlessDriver
 from webkitpy.port.linux_get_crash_log import GDBCrashLogGenerator
 from webkitpy.port.waylanddriver import WaylandDriver
 
@@ -67,7 +68,7 @@
     def _driver_class(self):
         if self._display_server == "wayland":
             return WaylandDriver
-        return super(WPEPort, self)._driver_class()
+        return HeadlessDriver
 
     def setup_environ_for_server(self, server_name=None):
         environment = super(WPEPort, self).setup_environ_for_server(server_name)

Modified: trunk/Tools/WebKitTestRunner/PlatformWebView.h (225046 => 225047)


--- trunk/Tools/WebKitTestRunner/PlatformWebView.h	2017-11-20 09:51:07 UTC (rev 225046)
+++ trunk/Tools/WebKitTestRunner/PlatformWebView.h	2017-11-20 11:03:26 UTC (rev 225047)
@@ -51,9 +51,8 @@
 typedef GtkWidget* PlatformWindow;
 typedef cairo_surface_t *PlatformImage;
 #elif PLATFORM(WPE)
-class HeadlessViewBackend;
 typedef WKViewRef PlatformWKView;
-typedef HeadlessViewBackend* PlatformWindow;
+typedef void* PlatformWindow;
 typedef cairo_surface_t* PlatformImage;
 #endif
 

Modified: trunk/Tools/WebKitTestRunner/wpe/PlatformWebViewWPE.cpp (225046 => 225047)


--- trunk/Tools/WebKitTestRunner/wpe/PlatformWebViewWPE.cpp	2017-11-20 09:51:07 UTC (rev 225046)
+++ trunk/Tools/WebKitTestRunner/wpe/PlatformWebViewWPE.cpp	2017-11-20 11:03:26 UTC (rev 225047)
@@ -26,7 +26,6 @@
 #include "config.h"
 #include "PlatformWebView.h"
 
-#include "HeadlessViewBackend.h"
 #include <WebKit/WKImageCairo.h>
 #include <cairo.h>
 #include <cstdio>
@@ -116,8 +115,7 @@
         RunLoop::main().run();
     }
 
-    cairo_surface_t* imageSurface = m_window->createSnapshot();
-    return imageSurface;
+    return WKViewCreateSnapshot(m_view);
 }
 
 void PlatformWebView::changeWindowScaleIfNeeded(float)

Copied: trunk/Tools/glib/api_test_runner.py (from rev 225046, trunk/Tools/Scripts/run-gtk-tests) (0 => 225047)


--- trunk/Tools/glib/api_test_runner.py	                        (rev 0)
+++ trunk/Tools/glib/api_test_runner.py	2017-11-20 11:03:26 UTC (rev 225047)
@@ -0,0 +1,426 @@
+#!/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 subprocess
+import os
+import errno
+import sys
+import re
+from signal import alarm, signal, SIGALRM, SIGKILL, SIGSEGV
+
+top_level_directory = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", ".."))
+sys.path.insert(0, os.path.join(top_level_directory, "Tools", "glib"))
+import common
+from webkitpy.common.host import Host
+
+
+class SkippedTest:
+    ENTIRE_SUITE = None
+
+    def __init__(self, test, test_case, reason, bug, build_type=None):
+        self.test = test
+        self.test_case = test_case
+        self.reason = reason
+        self.bug = bug
+        self.build_type = build_type
+
+    def __str__(self):
+        skipped_test_str = "%s" % self.test
+
+        if not(self.skip_entire_suite()):
+            skipped_test_str += " [%s]" % self.test_case
+
+        skipped_test_str += ": %s (https://bugs.webkit.org/show_bug.cgi?id=%d)" % (self.reason, self.bug)
+        return skipped_test_str
+
+    def skip_entire_suite(self):
+        return self.test_case == SkippedTest.ENTIRE_SUITE
+
+    def skip_for_build_type(self, build_type):
+        if self.build_type is None:
+            return True
+
+        return self.build_type == build_type
+
+
+class TestTimeout(Exception):
+    pass
+
+
+class TestRunner(object):
+    TEST_DIRS = []
+    SKIPPED = []
+    SLOW = []
+
+    def __init__(self, port, options, tests=[]):
+        self._options = options
+
+        self._build_type = "Debug" if self._options.debug else "Release"
+        common.set_build_types((self._build_type,))
+        self._port = Host().port_factory.get(port)
+        self._driver = self._create_driver()
+
+        self._programs_path = common.binary_build_path()
+        self._tests = self._get_tests(tests)
+        self._skipped_tests = [skipped for skipped in TestRunner.SKIPPED if skipped.skip_for_build_type(self._build_type)]
+        self._disabled_tests = []
+
+    def _test_programs_base_dir(self):
+        return os.path.join(self._programs_path, "TestWebKitAPI")
+
+    def _get_tests_from_dir(self, test_dir):
+        if not os.path.isdir(test_dir):
+            return []
+
+        tests = []
+        for test_file in os.listdir(test_dir):
+            if not test_file.lower().startswith("test"):
+                continue
+            test_path = os.path.join(test_dir, test_file)
+            if os.path.isfile(test_path) and os.access(test_path, os.X_OK):
+                tests.append(test_path)
+        return tests
+
+    def _get_tests(self, initial_tests):
+        tests = []
+        for test in initial_tests:
+            if os.path.isdir(test):
+                tests.extend(self._get_tests_from_dir(test))
+            else:
+                tests.append(test)
+        if tests:
+            return tests
+
+        tests = []
+        for test_dir in self.TEST_DIRS:
+            absolute_test_dir = os.path.join(self._test_programs_base_dir(), test_dir)
+            tests.extend(self._get_tests_from_dir(absolute_test_dir))
+        return tests
+
+    def _create_driver(self, port_options=[]):
+        self._port._display_server = self._options.display_server
+        driver = self._port.create_driver(worker_number=0, no_timeout=True)._make_driver(pixel_tests=False)
+        if not driver.check_driver(self._port):
+            raise RuntimeError("Failed to check driver %s" % driver.__class__.__name__)
+        return driver
+
+    def _setup_testing_environment(self):
+        self._test_env = self._driver._setup_environ_for_test()
+        self._test_env["TEST_WEBKIT_API_WEBKIT2_RESOURCES_PATH"] = common.top_level_path("Tools", "TestWebKitAPI", "Tests", "WebKit")
+        self._test_env["TEST_WEBKIT_API_WEBKIT2_INJECTED_BUNDLE_PATH"] = common.library_build_path()
+        self._test_env["WEBKIT_EXEC_PATH"] = self._programs_path
+
+        return True
+
+    def _tear_down_testing_environment(self):
+        if self._driver:
+            self._driver.stop()
+
+    def _test_cases_to_skip(self, test_program):
+        if self._options.skipped_action != 'skip':
+            return []
+
+        test_cases = []
+        for skipped in self._skipped_tests:
+            if test_program.endswith(skipped.test) and not skipped.skip_entire_suite():
+                test_cases.append(skipped.test_case)
+        return test_cases
+
+    def _should_run_test_program(self, test_program):
+        for disabled_test in self._disabled_tests:
+            if test_program.endswith(disabled_test):
+                return False
+
+        if self._options.skipped_action != 'skip':
+            return True
+
+        for skipped in self._skipped_tests:
+            if test_program.endswith(skipped.test) and skipped.skip_entire_suite():
+                return False
+        return True
+
+    def _kill_process(self, pid):
+        try:
+            os.kill(pid, SIGKILL)
+        except OSError:
+            # Process already died.
+            pass
+
+    @staticmethod
+    def _start_timeout(timeout):
+        if timeout <= 0:
+            return
+
+        def _alarm_handler(signum, frame):
+            raise TestTimeout
+
+        signal(SIGALRM, _alarm_handler)
+        alarm(timeout)
+
+    @staticmethod
+    def _stop_timeout(timeout):
+        if timeout <= 0:
+            return
+
+        alarm(0)
+
+    def _waitpid(self, pid):
+        while True:
+            try:
+                dummy, status = os.waitpid(pid, 0)
+                if os.WIFSIGNALED(status):
+                    return -os.WTERMSIG(status)
+                if os.WIFEXITED(status):
+                    return os.WEXITSTATUS(status)
+
+                # Should never happen
+                raise RuntimeError("Unknown child exit status!")
+            except (OSError, IOError) as e:
+                if e.errno == errno.EINTR:
+                    continue
+                if e.errno == errno.ECHILD:
+                    # This happens if SIGCLD is set to be ignored or waiting
+                    # for child processes has otherwise been disabled for our
+                    # process.  This child is dead, we can't get the status.
+                    return 0
+                raise
+
+    def _run_test_glib(self, test_program):
+        command = ['gtester', '-k']
+        if self._options.verbose:
+            command.append('--verbose')
+        for test_case in self._test_cases_to_skip(test_program):
+            command.extend(['-s', test_case])
+        command.append(test_program)
+
+        timeout = self._options.timeout
+        test = os.path.join(os.path.basename(os.path.dirname(test_program)), os.path.basename(test_program))
+        if test in TestRunner.SLOW:
+            timeout *= 5
+
+        test_context = {"child-pid": -1, "did-timeout": False, "current_test": None}
+
+        def parse_line(line, test_context=test_context):
+            if not line:
+                return
+
+            match = re.search(r'\(pid=(?P<child_pid>[0-9]+)\)', line)
+            if match:
+                test_context["child-pid"] = int(match.group('child_pid'))
+                sys.stdout.write(line)
+                return
+
+            def set_test_result(test, result):
+                if result == "FAIL":
+                    if test_context["did-timeout"] and result == "FAIL":
+                        test_context[test] = "TIMEOUT"
+                    else:
+                        test_context[test] = result
+                test_context["did-timeout"] = False
+                test_context["current_test"] = None
+                self._stop_timeout(timeout)
+                self._start_timeout(timeout)
+
+            normalized_line = line.strip().replace(' ', '')
+            if not normalized_line:
+                return
+
+            if normalized_line[0] == '/':
+                test, result = normalized_line.split(':', 1)
+                if result in ["OK", "FAIL"]:
+                    set_test_result(test, result)
+                else:
+                    test_context["current_test"] = test
+            elif normalized_line in ["OK", "FAIL"]:
+                set_test_result(test_context["current_test"], normalized_line)
+
+            sys.stdout.write(line)
+
+        pid, fd = os.forkpty()
+        if pid == 0:
+            os.execvpe(command[0], command, self._test_env)
+            sys.exit(0)
+
+        self._start_timeout(timeout)
+
+        while (True):
+            try:
+                common.parse_output_lines(fd, parse_line)
+                break
+            except TestTimeout:
+                assert test_context["child-pid"] > 0
+                self._kill_process(test_context["child-pid"])
+                test_context["child-pid"] = -1
+                test_context["did-timeout"] = True
+
+        self._stop_timeout(timeout)
+        del test_context["child-pid"]
+        del test_context["did-timeout"]
+        del test_context["current_test"]
+
+        self._waitpid(pid)
+        return test_context
+
+    def _get_tests_from_google_test_suite(self, test_program):
+        try:
+            output = subprocess.check_output([test_program, '--gtest_list_tests'], env=self._test_env)
+        except subprocess.CalledProcessError:
+            sys.stderr.write("ERROR: could not list available tests for binary %s.\n" % (test_program))
+            sys.stderr.flush()
+            return 1
+
+        skipped_test_cases = self._test_cases_to_skip(test_program)
+
+        tests = []
+        prefix = None
+        for line in output.split('\n'):
+            if not line.startswith('  '):
+                prefix = line
+                continue
+            else:
+                test_name = prefix + line.strip()
+                if not test_name in skipped_test_cases:
+                    tests.append(test_name)
+        return tests
+
+    def _run_google_test(self, test_program, subtest):
+        command = [test_program, '--gtest_filter=%s' % (subtest)]
+        timeout = self._options.timeout
+        if subtest in TestRunner.SLOW:
+            timeout *= 5
+
+        pid, fd = os.forkpty()
+        if pid == 0:
+            os.execvpe(command[0], command, self._test_env)
+            sys.exit(0)
+
+        self._start_timeout(timeout)
+        try:
+            common.parse_output_lines(fd, sys.stdout.write)
+            status = self._waitpid(pid)
+        except TestTimeout:
+            self._kill_process(pid)
+            return {subtest: "TIMEOUT"}
+
+        self._stop_timeout(timeout)
+
+        if status == -SIGSEGV:
+            sys.stdout.write("**CRASH** %s\n" % subtest)
+            sys.stdout.flush()
+            return {subtest: "CRASH"}
+
+        if status != 0:
+            return {subtest: "FAIL"}
+
+        return {}
+
+    def _run_google_test_suite(self, test_program):
+        result = {}
+        for subtest in self._get_tests_from_google_test_suite(test_program):
+            result.update(self._run_google_test(test_program, subtest))
+        return result
+
+    def is_glib_test(self, test_program):
+        raise NotImplementedError
+
+    def is_google_test(self, test_program):
+        raise NotImplementedError
+
+    def _run_test(self, test_program):
+        if self.is_glib_test(test_program):
+            return self._run_test_glib(test_program)
+
+        if self.is_google_test(test_program):
+            return self._run_google_test_suite(test_program)
+
+        return {}
+
+    def run_tests(self):
+        if not self._tests:
+            sys.stderr.write("ERROR: tests not found in %s.\n" % (self._test_programs_base_dir()))
+            sys.stderr.flush()
+            return 1
+
+        if not self._setup_testing_environment():
+            return 1
+
+        # Remove skipped tests now instead of when we find them, because
+        # some tests might be skipped while setting up the test environment.
+        self._tests = [test for test in self._tests if self._should_run_test_program(test)]
+
+        crashed_tests = {}
+        failed_tests = {}
+        timed_out_tests = {}
+        try:
+            for test in self._tests:
+                results = self._run_test(test)
+                for test_case, result in results.iteritems():
+                    if result == "FAIL":
+                        failed_tests.setdefault(test, []).append(test_case)
+                    elif result == "TIMEOUT":
+                        timed_out_tests.setdefault(test, []).append(test_case)
+                    elif result == "CRASH":
+                        crashed_tests.setdefault(test, []).append(test_case)
+        finally:
+            self._tear_down_testing_environment()
+
+        if failed_tests:
+            sys.stdout.write("\nUnexpected failures (%d)\n" % (sum(len(value) for value in failed_tests.itervalues())))
+            for test in failed_tests:
+                sys.stdout.write("    %s\n" % (test.replace(self._test_programs_base_dir(), '', 1)))
+                for test_case in failed_tests[test]:
+                    sys.stdout.write("        %s\n" % (test_case))
+            sys.stdout.flush()
+
+        if crashed_tests:
+            sys.stdout.write("\nUnexpected crashes (%d)\n" % (sum(len(value) for value in crashed_tests.itervalues())))
+            for test in crashed_tests:
+                sys.stdout.write("    %s\n" % (test.replace(self._test_programs_base_dir(), '', 1)))
+                for test_case in crashed_tests[test]:
+                    sys.stdout.write("        %s\n" % (test_case))
+            sys.stdout.flush()
+
+        if timed_out_tests:
+            sys.stdout.write("\nUnexpected timeouts (%d)\n" % (sum(len(value) for value in timed_out_tests.itervalues())))
+            for test in timed_out_tests:
+                sys.stdout.write("    %s\n" % (test.replace(self._test_programs_base_dir(), '', 1)))
+                for test_case in timed_out_tests[test]:
+                    sys.stdout.write("        %s\n" % (test_case))
+            sys.stdout.flush()
+
+        return len(failed_tests) + len(timed_out_tests)
+
+
+def add_options(option_parser):
+    option_parser.add_option('-r', '--release',
+                             action='', dest='release',
+                             help='Run in Release')
+    option_parser.add_option('-d', '--debug',
+                             action='', dest='debug',
+                             help='Run in Debug')
+    option_parser.add_option('-v', '--verbose',
+                             action='', dest='verbose',
+                             help='Run gtester in verbose mode')
+    option_parser.add_option('--skipped', action='', dest='skipped_action',
+                             choices=['skip', 'ignore', 'only'], default='skip',
+                             metavar='skip|ignore|only',
+                             help='Specifies how to treat the skipped tests')
+    option_parser.add_option('-t', '--timeout',
+                             action='', type='int', dest='timeout', default=10,
+                             help='Time in seconds until a test times out')

Copied: trunk/Tools/glib/common.py (from rev 225046, trunk/Tools/gtk/common.py) (0 => 225047)


--- trunk/Tools/glib/common.py	                        (rev 0)
+++ trunk/Tools/glib/common.py	2017-11-20 11:03:26 UTC (rev 225047)
@@ -0,0 +1,150 @@
+#!/usr/bin/env python
+# Copyright (C) 2011 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 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+import errno
+import os
+import select
+import subprocess
+import sys
+
+top_level_dir = None
+build_dir = None
+library_build_dir = None
+binary_build_dir = None
+build_types = ('Release', 'Debug')
+
+
+def top_level_path(*args):
+    global top_level_dir
+    if not top_level_dir:
+        top_level_dir = os.path.join(os.path.dirname(__file__), '..', '..')
+    return os.path.join(*(top_level_dir,) + args)
+
+
+def set_build_types(new_build_types):
+    global build_types
+    build_types = new_build_types
+
+
+def library_build_path(*args):
+    global library_build_dir
+    if not library_build_dir:
+        library_build_dir = build_path('lib', *args)
+    return library_build_dir
+
+
+def binary_build_path(*args):
+    global binary_build_dir
+    if not binary_build_dir:
+        binary_build_dir = build_path('bin', *args)
+    return binary_build_dir
+
+
+def get_build_path(fatal=True):
+    global build_dir
+    if build_dir:
+        return build_dir
+
+    def is_valid_build_directory(path):
+        return os.path.exists(os.path.join(path, 'CMakeCache.txt')) or \
+            os.path.exists(os.path.join(path, 'bin/WebKitTestRunner'))
+
+    if len(sys.argv[1:]) > 1 and os.path.exists(sys.argv[-1]) and is_valid_build_directory(sys.argv[-1]):
+        return sys.argv[-1]
+
+    # Debian and Ubuntu build both flavours of the library (with gtk2
+    # and with gtk3); they use directories build-2.0 and build-3.0 for
+    # that, which is not handled by the above cases; we check that the
+    # directory where we are called from is a valid build directory,
+    # which should handle pretty much all other non-standard cases.
+    build_dir = os.getcwd()
+    if is_valid_build_directory(build_dir):
+        return build_dir
+
+    global build_types
+    for build_type in build_types:
+        build_dir = top_level_path('WebKitBuild', build_type)
+        if is_valid_build_directory(build_dir):
+            return build_dir
+
+    # distcheck builds in a directory named _build in the top-level path.
+    build_dir = top_level_path("_build")
+    if is_valid_build_directory(build_dir):
+        return build_dir
+
+    build_dir = top_level_path()
+    if is_valid_build_directory(build_dir):
+        return build_dir
+
+    build_dir = top_level_path("WebKitBuild")
+    if is_valid_build_directory(build_dir):
+        return build_dir
+
+    print('Could not determine build directory.')
+    if fatal:
+        sys.exit(1)
+
+
+def build_path(*args):
+    return os.path.join(*(get_build_path(),) + args)
+
+
+def pkg_config_file_variable(package, variable):
+    process = subprocess.Popen(['pkg-config', '--variable=%s' % variable, package],
+                               stdout=subprocess.PIPE)
+    stdout = process.communicate()[0].decode("utf-8")
+    if process.returncode:
+        return None
+    return stdout.strip()
+
+
+def prefix_of_pkg_config_file(package):
+    return pkg_config_file_variable(package, 'prefix')
+
+
+def parse_output_lines(fd, parse_line_callback):
+    output = ''
+    read_set = [fd]
+    while read_set:
+        try:
+            rlist, wlist, xlist = select.select(read_set, [], [])
+        except select.error as e:
+            parse_line_callback("WARNING: error while waiting for fd %d to become readable\n" % fd)
+            parse_line_callback("    error code: %d, error message: %s\n" % (e[0], e[1]))
+            continue
+
+        if fd in rlist:
+            try:
+                chunk = os.read(fd, 1024)
+            except OSError as e:
+                if e.errno == errno.EIO:
+                    # Child process finished.
+                    chunk = ''
+                else:
+                    raise e
+            if not chunk:
+                read_set.remove(fd)
+
+            output += chunk
+            while '\n' in output:
+                pos = output.find('\n')
+                parse_line_callback(output[:pos + 1])
+                output = output[pos + 1:]
+
+            if not chunk and output:
+                parse_line_callback(output)
+                output = ''

Deleted: trunk/Tools/gtk/common.py (225046 => 225047)


--- trunk/Tools/gtk/common.py	2017-11-20 09:51:07 UTC (rev 225046)
+++ trunk/Tools/gtk/common.py	2017-11-20 11:03:26 UTC (rev 225047)
@@ -1,150 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2011 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 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
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-import errno
-import os
-import select
-import subprocess
-import sys
-
-top_level_dir = None
-build_dir = None
-library_build_dir = None
-binary_build_dir = None
-build_types = ('Release', 'Debug')
-
-
-def top_level_path(*args):
-    global top_level_dir
-    if not top_level_dir:
-        top_level_dir = os.path.join(os.path.dirname(__file__), '..', '..')
-    return os.path.join(*(top_level_dir,) + args)
-
-
-def set_build_types(new_build_types):
-    global build_types
-    build_types = new_build_types
-
-
-def library_build_path(*args):
-    global library_build_dir
-    if not library_build_dir:
-        library_build_dir = build_path('lib', *args)
-    return library_build_dir
-
-
-def binary_build_path(*args):
-    global binary_build_dir
-    if not binary_build_dir:
-        binary_build_dir = build_path('bin', *args)
-    return binary_build_dir
-
-
-def get_build_path(fatal=True):
-    global build_dir
-    if build_dir:
-        return build_dir
-
-    def is_valid_build_directory(path):
-        return os.path.exists(os.path.join(path, 'CMakeCache.txt')) or \
-            os.path.exists(os.path.join(path, 'bin/MiniBrowser'))
-
-    if len(sys.argv[1:]) > 1 and os.path.exists(sys.argv[-1]) and is_valid_build_directory(sys.argv[-1]):
-        return sys.argv[-1]
-
-    # Debian and Ubuntu build both flavours of the library (with gtk2
-    # and with gtk3); they use directories build-2.0 and build-3.0 for
-    # that, which is not handled by the above cases; we check that the
-    # directory where we are called from is a valid build directory,
-    # which should handle pretty much all other non-standard cases.
-    build_dir = os.getcwd()
-    if is_valid_build_directory(build_dir):
-        return build_dir
-
-    global build_types
-    for build_type in build_types:
-        build_dir = top_level_path('WebKitBuild', build_type)
-        if is_valid_build_directory(build_dir):
-            return build_dir
-
-    # distcheck builds in a directory named _build in the top-level path.
-    build_dir = top_level_path("_build")
-    if is_valid_build_directory(build_dir):
-        return build_dir
-
-    build_dir = top_level_path()
-    if is_valid_build_directory(build_dir):
-        return build_dir
-
-    build_dir = top_level_path("WebKitBuild")
-    if is_valid_build_directory(build_dir):
-        return build_dir
-
-    print('Could not determine build directory.')
-    if fatal:
-        sys.exit(1)
-
-
-def build_path(*args):
-    return os.path.join(*(get_build_path(),) + args)
-
-
-def pkg_config_file_variable(package, variable):
-    process = subprocess.Popen(['pkg-config', '--variable=%s' % variable, package],
-                               stdout=subprocess.PIPE)
-    stdout = process.communicate()[0].decode("utf-8")
-    if process.returncode:
-        return None
-    return stdout.strip()
-
-
-def prefix_of_pkg_config_file(package):
-    return pkg_config_file_variable(package, 'prefix')
-
-
-def parse_output_lines(fd, parse_line_callback):
-    output = ''
-    read_set = [fd]
-    while read_set:
-        try:
-            rlist, wlist, xlist = select.select(read_set, [], [])
-        except select.error as e:
-            parse_line_callback("WARNING: error while waiting for fd %d to become readable\n" % fd)
-            parse_line_callback("    error code: %d, error message: %s\n" % (e[0], e[1]))
-            continue
-
-        if fd in rlist:
-            try:
-                chunk = os.read(fd, 1024)
-            except OSError as e:
-                if e.errno == errno.EIO:
-                    # Child process finished.
-                    chunk = ''
-                else:
-                    raise e
-            if not chunk:
-                read_set.remove(fd)
-
-            output += chunk
-            while '\n' in output:
-                pos = output.find('\n')
-                parse_line_callback(output[:pos + 1])
-                output = output[pos + 1:]
-
-            if not chunk and output:
-                parse_line_callback(output)
-                output = ''

Modified: trunk/Tools/gtk/generate-gtkdoc (225046 => 225047)


--- trunk/Tools/gtk/generate-gtkdoc	2017-11-20 09:51:07 UTC (rev 225046)
+++ trunk/Tools/gtk/generate-gtkdoc	2017-11-20 11:03:26 UTC (rev 225047)
@@ -20,7 +20,6 @@
 
 import argparse
 import codecs
-import common
 import glob
 import gtkdoc
 import logging
@@ -27,6 +26,10 @@
 import os.path
 import sys
 
+top_level_directory = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', '..'))
+sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'glib'))
+import common
+
 sys.stdout = codecs.getwriter("utf-8")(sys.stdout)
 sys.stderr = codecs.getwriter("utf-8")(sys.stderr)
 

Modified: trunk/Tools/gtk/jhbuildrc (225046 => 225047)


--- trunk/Tools/gtk/jhbuildrc	2017-11-20 09:51:07 UTC (rev 225046)
+++ trunk/Tools/gtk/jhbuildrc	2017-11-20 11:03:26 UTC (rev 225047)
@@ -22,8 +22,8 @@
 import jhbuildrc_common
 jhbuildrc_common.init(globals(), "gtk")
 
-__gtk_tools_directory = os.path.abspath(os.path.dirname(__file__))
-sys.path = [__gtk_tools_directory] + sys.path
+top_level_directory = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', '..'))
+sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'glib'))
 import common
 
 # LLVM requires that builddir != srcdir, and it's not possible to do that in jhbuild only

Modified: trunk/Tools/gtk/ycm_extra_conf.py (225046 => 225047)


--- trunk/Tools/gtk/ycm_extra_conf.py	2017-11-20 09:51:07 UTC (rev 225046)
+++ trunk/Tools/gtk/ycm_extra_conf.py	2017-11-20 11:03:26 UTC (rev 225047)
@@ -31,7 +31,8 @@
 else:
     __tools_directory = os.path.dirname(original_file)
 
-sys.path.insert(0, os.path.abspath(__tools_directory))
+top_level_directory = os.path.normpath(os.path.join(os.path.abspath(__tools_directory), '..', '..'))
+sys.path.insert(0, os.path.join(top_level_directory, 'Tools', 'glib'))
 import common
 
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to