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