[GTK] Add llvmpipe (Mesa) to the JHBuild moduleset and force it when running layout...
[WebKit-https.git] / Tools / Scripts / webkitpy / port / gtk.py
1 # Copyright (C) 2010 Google Inc. All rights reserved.
2 # Copyright (C) 2013 Samsung Electronics.  All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7 #
8 #     * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 #     * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following disclaimer
12 # in the documentation and/or other materials provided with the
13 # distribution.
14 #     * Neither the Google name nor the names of its
15 # contributors may be used to endorse or promote products derived from
16 # this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 import os
31 import subprocess
32 import uuid
33
34 from webkitpy.common.memoized import memoized
35 from webkitpy.layout_tests.models.test_configuration import TestConfiguration
36 from webkitpy.port.base import Port
37 from webkitpy.port.pulseaudio_sanitizer import PulseAudioSanitizer
38 from webkitpy.port.xvfbdriver import XvfbDriver
39 from webkitpy.port.westondriver import WestonDriver
40 from webkitpy.port.linux_get_crash_log import GDBCrashLogGenerator
41 from webkitpy.port.leakdetector_valgrind import LeakDetectorValgrind
42
43
44 class GtkPort(Port):
45     port_name = "gtk"
46
47     def __init__(self, *args, **kwargs):
48         super(GtkPort, self).__init__(*args, **kwargs)
49         self._pulseaudio_sanitizer = PulseAudioSanitizer()
50
51         if self.get_option("leaks"):
52             self._leakdetector = LeakDetectorValgrind(self._executive, self._filesystem, self.results_directory())
53             if not self.get_option("wrapper"):
54                 raise ValueError('use --wrapper=\"valgrind\" for memory leak detection on GTK')
55
56     def _built_executables_path(self, *path):
57         return self._build_path(*(('bin',) + path))
58
59     def _built_libraries_path(self, *path):
60         return self._build_path(*(('lib',) + path))
61
62     def warn_if_bug_missing_in_test_expectations(self):
63         return not self.get_option('webkit_test_runner')
64
65     def _port_flag_for_scripts(self):
66         return "--gtk"
67
68     @memoized
69     def _driver_class(self):
70         if os.environ.get("WAYLAND_DISPLAY"):
71             return WestonDriver
72         return XvfbDriver
73
74     def default_timeout_ms(self):
75         # Starting an application under Valgrind takes a lot longer than normal
76         # so increase the timeout (empirically 10x is enough to avoid timeouts).
77         multiplier = 10 if self.get_option("leaks") else 1
78         if self.get_option('configuration') == 'Debug':
79             return multiplier * 12 * 1000
80         return multiplier * 6 * 1000
81
82     def driver_stop_timeout(self):
83         if self.get_option("leaks"):
84             # Wait the default timeout time before killing the process in driver.stop().
85             return self.default_timeout_ms()
86         return super(GtkPort, self).driver_stop_timeout()
87
88     def setup_test_run(self):
89         super(GtkPort, self).setup_test_run()
90         self._pulseaudio_sanitizer.unload_pulseaudio_module()
91
92         if self.get_option("leaks"):
93             self._leakdetector.clean_leaks_files_from_results_directory()
94
95     def clean_up_test_run(self):
96         super(GtkPort, self).clean_up_test_run()
97         self._pulseaudio_sanitizer.restore_pulseaudio_module()
98
99     def setup_environ_for_server(self, server_name=None):
100         environment = super(GtkPort, self).setup_environ_for_server(server_name)
101         environment['GSETTINGS_BACKEND'] = 'memory'
102         environment['LIBOVERLAY_SCROLLBAR'] = '0'
103         environment['TEST_RUNNER_INJECTED_BUNDLE_FILENAME'] = self._build_path('lib', 'libTestRunnerInjectedBundle.so')
104         environment['TEST_RUNNER_TEST_PLUGIN_PATH'] = self._build_path('lib')
105         environment['AUDIO_RESOURCES_PATH'] = self.path_from_webkit_base('Source', 'WebCore', 'platform', 'audio', 'resources')
106
107         llvmpipe_libgl_path = os.environ.get('LLVMPIPE_LIBGL_PATH')
108         if llvmpipe_libgl_path:
109             environment['LD_LIBRARY_PATH'] = '%s:%s' % (llvmpipe_libgl_path, os.environ.get('LD_LIBRARY_PATH', ''))
110
111         self._copy_value_from_environ_if_set(environment, 'WEBKIT_OUTPUTDIR')
112         if self.get_option("leaks"):
113             #  Turn off GLib memory optimisations https://wiki.gnome.org/Valgrind.
114             environment['G_SLICE'] = 'always-malloc'
115             environment['G_DEBUG'] = 'gc-friendly'
116             xmlfilename = "".join(("drt-%p-", uuid.uuid1().hex, "-leaks.xml"))
117             xmlfile = os.path.join(self.results_directory(), xmlfilename)
118             suppressionsfile = self.path_from_webkit_base('Tools', 'Scripts', 'valgrind', 'suppressions.txt')
119             environment['VALGRIND_OPTS'] = \
120                 "--tool=memcheck " \
121                 "--num-callers=40 " \
122                 "--demangle=no " \
123                 "--trace-children=no " \
124                 "--smc-check=all-non-file " \
125                 "--leak-check=yes " \
126                 "--leak-resolution=high " \
127                 "--show-possibly-lost=no " \
128                 "--show-reachable=no " \
129                 "--leak-check=full " \
130                 "--undef-value-errors=no " \
131                 "--gen-suppressions=all " \
132                 "--xml=yes " \
133                 "--xml-file=%s " \
134                 "--suppressions=%s" % (xmlfile, suppressionsfile)
135         return environment
136
137     def _generate_all_test_configurations(self):
138         configurations = []
139         for build_type in self.ALL_BUILD_TYPES:
140             configurations.append(TestConfiguration(version=self._version, architecture='x86', build_type=build_type))
141         return configurations
142
143     def _path_to_driver(self):
144         return self._built_executables_path(self.driver_name())
145
146     def _path_to_image_diff(self):
147         return self._built_executables_path('ImageDiff')
148
149     def _path_to_webcore_library(self):
150         gtk_library_names = [
151             "libwebkitgtk-1.0.so",
152             "libwebkitgtk-3.0.so",
153             "libwebkit2gtk-1.0.so",
154         ]
155
156         for library in gtk_library_names:
157             full_library = self._built_libraries_path(library)
158             if self._filesystem.isfile(full_library):
159                 return full_library
160         return None
161
162     def _search_paths(self):
163         search_paths = []
164         if self.get_option('webkit_test_runner'):
165             search_paths.extend([self.port_name + '-wk2', 'wk2'])
166         else:
167             search_paths.append(self.port_name + '-wk1')
168         search_paths.append(self.port_name)
169         search_paths.extend(self.get_option("additional_platform_directory", []))
170         return search_paths
171
172     def default_baseline_search_path(self):
173         return map(self._webkit_baseline_path, self._search_paths())
174
175     def _port_specific_expectations_files(self):
176         return [self._filesystem.join(self._webkit_baseline_path(p), 'TestExpectations') for p in reversed(self._search_paths())]
177
178     def print_leaks_summary(self):
179         if not self.get_option('leaks'):
180             return
181         # FIXME: This is a hack, but we don't have a better way to get this information from the workers yet
182         # because we're in the manager process.
183         leaks_files = self._leakdetector.leaks_files_in_results_directory()
184         if not leaks_files:
185             return
186         self._leakdetector.parse_and_print_leaks_detail(leaks_files)
187
188     # FIXME: We should find a way to share this implmentation with Gtk,
189     # or teach run-launcher how to call run-safari and move this down to Port.
190     def show_results_html_file(self, results_filename):
191         run_launcher_args = ["file://%s" % results_filename]
192         if self.get_option('webkit_test_runner'):
193             run_launcher_args.append('-2')
194         # FIXME: old-run-webkit-tests also added ["-graphicssystem", "raster", "-style", "windows"]
195         # FIXME: old-run-webkit-tests converted results_filename path for cygwin.
196         self._run_script("run-launcher", run_launcher_args)
197
198     def check_sys_deps(self, needs_http):
199         return super(GtkPort, self).check_sys_deps(needs_http) and self._driver_class().check_driver(self)
200
201     def _get_crash_log(self, name, pid, stdout, stderr, newer_than):
202         return GDBCrashLogGenerator(name, pid, newer_than, self._filesystem, self._path_to_driver).generate_crash_log(stdout, stderr)
203
204     def build_webkit_command(self, build_style=None):
205         command = super(GtkPort, self).build_webkit_command(build_style)
206         command.extend(["--gtk", "--update-gtk"])
207
208         if self.get_option('webkit_test_runner'):
209             command.append("--no-webkit1")
210         else:
211             command.append("--no-webkit2")
212
213         command.append(super(GtkPort, self).make_args())
214         return command
215
216     def run_webkit_tests_command(self):
217         command = super(GtkPort, self).run_webkit_tests_command()
218         command.append("--gtk")
219         if self.get_option('webkit_test_runner'):
220             command.append("-2")
221         return command