mac_unittest.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. # Copyright (C) 2010 Google Inc. All rights reserved.
  2. #
  3. # Redistribution and use in source and binary forms, with or without
  4. # modification, are permitted provided that the following conditions are
  5. # met:
  6. #
  7. # * Redistributions of source code must retain the above copyright
  8. # notice, this list of conditions and the following disclaimer.
  9. # * Redistributions in binary form must reproduce the above
  10. # copyright notice, this list of conditions and the following disclaimer
  11. # in the documentation and/or other materials provided with the
  12. # distribution.
  13. # * Neither the name of Google Inc. nor the names of its
  14. # contributors may be used to endorse or promote products derived from
  15. # this software without specific prior written permission.
  16. #
  17. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  20. # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  21. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  22. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  23. # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. from webkitpy.port.mac import MacPort
  29. from webkitpy.port import port_testcase
  30. from webkitpy.common.system.filesystem_mock import MockFileSystem
  31. from webkitpy.common.system.outputcapture import OutputCapture
  32. from webkitpy.tool.mocktool import MockOptions
  33. from webkitpy.common.system.executive_mock import MockExecutive, MockExecutive2, MockProcess, ScriptError
  34. from webkitpy.common.system.systemhost_mock import MockSystemHost
  35. class MacTest(port_testcase.PortTestCase):
  36. os_name = 'mac'
  37. os_version = 'lion'
  38. port_name = 'mac-lion'
  39. port_maker = MacPort
  40. def assert_skipped_file_search_paths(self, port_name, expected_paths, use_webkit2=False):
  41. port = self.make_port(port_name=port_name, options=MockOptions(webkit_test_runner=use_webkit2))
  42. self.assertEqual(port._skipped_file_search_paths(), expected_paths)
  43. def test_default_timeout_ms(self):
  44. super(MacTest, self).test_default_timeout_ms()
  45. self.assertEqual(self.make_port(options=MockOptions(guard_malloc=True)).default_timeout_ms(), 350000)
  46. example_skipped_file = u"""
  47. # <rdar://problem/5647952> fast/events/mouseout-on-window.html needs mac DRT to issue mouse out events
  48. fast/events/mouseout-on-window.html
  49. # <rdar://problem/5643675> window.scrollTo scrolls a window with no scrollbars
  50. fast/events/attempt-scroll-with-no-scrollbars.html
  51. # see bug <rdar://problem/5646437> REGRESSION (r28015): svg/batik/text/smallFonts fails
  52. svg/batik/text/smallFonts.svg
  53. # Java tests don't work on WK2
  54. java/
  55. """
  56. example_skipped_tests = [
  57. "fast/events/mouseout-on-window.html",
  58. "fast/events/attempt-scroll-with-no-scrollbars.html",
  59. "svg/batik/text/smallFonts.svg",
  60. "java",
  61. ]
  62. def test_tests_from_skipped_file_contents(self):
  63. port = self.make_port()
  64. self.assertEqual(port._tests_from_skipped_file_contents(self.example_skipped_file), self.example_skipped_tests)
  65. def assert_name(self, port_name, os_version_string, expected):
  66. host = MockSystemHost(os_name='mac', os_version=os_version_string)
  67. port = self.make_port(host=host, port_name=port_name)
  68. self.assertEqual(expected, port.name())
  69. def test_tests_for_other_platforms(self):
  70. platforms = ['mac', 'chromium-linux', 'mac-snowleopard']
  71. port = self.make_port(port_name='mac-snowleopard')
  72. platform_dir_paths = map(port._webkit_baseline_path, platforms)
  73. # Replace our empty mock file system with one which has our expected platform directories.
  74. port._filesystem = MockFileSystem(dirs=platform_dir_paths)
  75. dirs_to_skip = port._tests_for_other_platforms()
  76. self.assertIn('platform/chromium-linux', dirs_to_skip)
  77. self.assertNotIn('platform/mac', dirs_to_skip)
  78. self.assertNotIn('platform/mac-snowleopard', dirs_to_skip)
  79. def test_version(self):
  80. port = self.make_port()
  81. self.assertTrue(port.version())
  82. def test_versions(self):
  83. # Note: these tests don't need to be exhaustive as long as we get path coverage.
  84. self.assert_name('mac', 'snowleopard', 'mac-snowleopard')
  85. self.assert_name('mac-snowleopard', 'leopard', 'mac-snowleopard')
  86. self.assert_name('mac-snowleopard', 'lion', 'mac-snowleopard')
  87. self.assert_name('mac', 'lion', 'mac-lion')
  88. self.assert_name('mac-lion', 'lion', 'mac-lion')
  89. self.assert_name('mac', 'mountainlion', 'mac-mountainlion')
  90. self.assert_name('mac-mountainlion', 'lion', 'mac-mountainlion')
  91. self.assert_name('mac', 'future', 'mac-future')
  92. self.assert_name('mac-future', 'future', 'mac-future')
  93. self.assertRaises(AssertionError, self.assert_name, 'mac-tiger', 'leopard', 'mac-leopard')
  94. def test_setup_environ_for_server(self):
  95. port = self.make_port(options=MockOptions(leaks=True, guard_malloc=True))
  96. env = port.setup_environ_for_server(port.driver_name())
  97. self.assertEqual(env['MallocStackLogging'], '1')
  98. self.assertEqual(env['DYLD_INSERT_LIBRARIES'], '/usr/lib/libgmalloc.dylib:/mock-build/libWebCoreTestShim.dylib')
  99. def _assert_search_path(self, port_name, baseline_path, search_paths, use_webkit2=False):
  100. port = self.make_port(port_name=port_name, options=MockOptions(webkit_test_runner=use_webkit2))
  101. absolute_search_paths = map(port._webkit_baseline_path, search_paths)
  102. self.assertEqual(port.baseline_path(), port._webkit_baseline_path(baseline_path))
  103. self.assertEqual(port.baseline_search_path(), absolute_search_paths)
  104. def test_baseline_search_path(self):
  105. # Note that we don't need total coverage here, just path coverage, since this is all data driven.
  106. self._assert_search_path('mac-snowleopard', 'mac-snowleopard', ['mac-snowleopard', 'mac-lion', 'mac'])
  107. self._assert_search_path('mac-lion', 'mac-lion', ['mac-lion', 'mac'])
  108. self._assert_search_path('mac-mountainlion', 'mac', ['mac'])
  109. self._assert_search_path('mac-future', 'mac', ['mac'])
  110. self._assert_search_path('mac-snowleopard', 'mac-wk2', ['mac-wk2', 'wk2', 'mac-snowleopard', 'mac-lion', 'mac'], use_webkit2=True)
  111. self._assert_search_path('mac-lion', 'mac-wk2', ['mac-wk2', 'wk2', 'mac-lion', 'mac'], use_webkit2=True)
  112. self._assert_search_path('mac-mountainlion', 'mac-wk2', ['mac-wk2', 'wk2', 'mac'], use_webkit2=True)
  113. self._assert_search_path('mac-future', 'mac-wk2', ['mac-wk2', 'wk2', 'mac'], use_webkit2=True)
  114. def test_show_results_html_file(self):
  115. port = self.make_port()
  116. # Delay setting a should_log executive to avoid logging from MacPort.__init__.
  117. port._executive = MockExecutive(should_log=True)
  118. expected_logs = "MOCK popen: ['Tools/Scripts/run-safari', '--release', '--no-saved-state', '-NSOpen', 'test.html'], cwd=/mock-checkout\n"
  119. OutputCapture().assert_outputs(self, port.show_results_html_file, ["test.html"], expected_logs=expected_logs)
  120. def test_operating_system(self):
  121. self.assertEqual('mac', self.make_port().operating_system())
  122. def test_default_child_processes(self):
  123. port = self.make_port(port_name='mac-lion')
  124. # MockPlatformInfo only has 2 mock cores. The important part is that 2 > 1.
  125. self.assertEqual(port.default_child_processes(), 2)
  126. bytes_for_drt = 200 * 1024 * 1024
  127. port.host.platform.total_bytes_memory = lambda: bytes_for_drt
  128. expected_logs = "This machine could support 2 child processes, but only has enough memory for 1.\n"
  129. child_processes = OutputCapture().assert_outputs(self, port.default_child_processes, (), expected_logs=expected_logs)
  130. self.assertEqual(child_processes, 1)
  131. # Make sure that we always use one process, even if we don't have the memory for it.
  132. port.host.platform.total_bytes_memory = lambda: bytes_for_drt - 1
  133. expected_logs = "This machine could support 2 child processes, but only has enough memory for 1.\n"
  134. child_processes = OutputCapture().assert_outputs(self, port.default_child_processes, (), expected_logs=expected_logs)
  135. self.assertEqual(child_processes, 1)
  136. # SnowLeopard has a CFNetwork bug which causes crashes if we execute more than one copy of DRT at once.
  137. port = self.make_port(port_name='mac-snowleopard')
  138. expected_logs = "Cannot run tests in parallel on Snow Leopard due to rdar://problem/10621525.\n"
  139. child_processes = OutputCapture().assert_outputs(self, port.default_child_processes, (), expected_logs=expected_logs)
  140. self.assertEqual(child_processes, 1)
  141. def test_get_crash_log(self):
  142. # Mac crash logs are tested elsewhere, so here we just make sure we don't crash.
  143. def fake_time_cb():
  144. times = [0, 20, 40]
  145. return lambda: times.pop(0)
  146. port = self.make_port(port_name='mac-snowleopard')
  147. port._get_crash_log('DumpRenderTree', 1234, '', '', 0,
  148. time_fn=fake_time_cb(), sleep_fn=lambda delay: None)
  149. def test_helper_starts(self):
  150. host = MockSystemHost(MockExecutive())
  151. port = self.make_port(host)
  152. oc = OutputCapture()
  153. oc.capture_output()
  154. host.executive._proc = MockProcess('ready\n')
  155. port.start_helper()
  156. port.stop_helper()
  157. oc.restore_output()
  158. # make sure trying to stop the helper twice is safe.
  159. port.stop_helper()
  160. def test_helper_fails_to_start(self):
  161. host = MockSystemHost(MockExecutive())
  162. port = self.make_port(host)
  163. oc = OutputCapture()
  164. oc.capture_output()
  165. port.start_helper()
  166. port.stop_helper()
  167. oc.restore_output()
  168. def test_helper_fails_to_stop(self):
  169. host = MockSystemHost(MockExecutive())
  170. host.executive._proc = MockProcess()
  171. def bad_waiter():
  172. raise IOError('failed to wait')
  173. host.executive._proc.wait = bad_waiter
  174. port = self.make_port(host)
  175. oc = OutputCapture()
  176. oc.capture_output()
  177. port.start_helper()
  178. port.stop_helper()
  179. oc.restore_output()
  180. def test_sample_process(self):
  181. def logging_run_command(args):
  182. print args
  183. port = self.make_port()
  184. port._executive = MockExecutive2(run_command_fn=logging_run_command)
  185. expected_stdout = "['/usr/bin/sample', 42, 10, 10, '-file', '/mock-build/layout-test-results/test-42-sample.txt']\n"
  186. OutputCapture().assert_outputs(self, port.sample_process, args=['test', 42], expected_stdout=expected_stdout)
  187. def test_sample_process_throws_exception(self):
  188. def throwing_run_command(args):
  189. raise ScriptError("MOCK script error")
  190. port = self.make_port()
  191. port._executive = MockExecutive2(run_command_fn=throwing_run_command)
  192. OutputCapture().assert_outputs(self, port.sample_process, args=['test', 42])
  193. def test_32bit(self):
  194. port = self.make_port(options=MockOptions(architecture='x86'))
  195. def run_script(script, args=None, env=None):
  196. self.args = args
  197. port._run_script = run_script
  198. self.assertEqual(port.architecture(), 'x86')
  199. port._build_driver()
  200. self.assertEqual(self.args, ['ARCHS=i386'])
  201. def test_64bit(self):
  202. # Apple Mac port is 64-bit by default
  203. port = self.make_port()
  204. self.assertEqual(port.architecture(), 'x86_64')
  205. def run_script(script, args=None, env=None):
  206. self.args = args
  207. port._run_script = run_script
  208. port._build_driver()
  209. self.assertEqual(self.args, [])