# Copyright (C) 2010 Google Inc. All rights reserved. # Copyright (C) 2014-2020 Apple Inc. All rights reserved. # # 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 Google Inc. 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 from webkitcorepy import Version, OutputCapture from webkitpy.port.mac import MacPort from webkitpy.port import darwin_testcase from webkitpy.port import port_testcase from webkitpy.tool.mocktool import MockOptions from webkitpy.common.system.executive_mock import MockExecutive, MockExecutive2, ScriptError from webkitpy.common.system.platforminfo_mock import MockPlatformInfo from webkitpy.common.system.systemhost_mock import MockSystemHost from webkitpy.common.version_name_map import VersionNameMap class MacTest(darwin_testcase.DarwinTest): os_name = 'mac' os_version = Version.from_name('Lion') port_name = 'mac-lion' port_maker = MacPort # 2 minor versions from the current version should always be a future version. FUTURE_VERSION = Version.from_iterable(MacPort.CURRENT_VERSION) FUTURE_VERSION.major += 2 def test_version(self): port = self.make_port() self.assertIsNotNone(port.version_name()) def test_versions(self): # Note: these tests don't need to be exhaustive as long as we get path coverage. self.assert_name('mac', 'snowleopard', 'mac-snowleopard') self.assert_name('mac-snowleopard', 'leopard', 'mac-snowleopard') self.assert_name('mac-snowleopard', 'lion', 'mac-snowleopard') self.assert_name('mac', 'lion', 'mac-lion') self.assert_name('mac-lion', 'lion', 'mac-lion') self.assert_name('mac', 'mountainlion', 'mac-mountainlion') self.assert_name('mac-mountainlion', 'lion', 'mac-mountainlion') self.assert_name('mac', 'mavericks', 'mac-mavericks') self.assert_name('mac-mavericks', 'mountainlion', 'mac-mavericks') self.assert_name('mac', 'yosemite', 'mac-yosemite') self.assert_name('mac-yosemite', 'mavericks', 'mac-yosemite') self.assert_name('mac', 'elcapitan', 'mac-elcapitan') self.assert_name('mac-elcapitan', 'mavericks', 'mac-elcapitan') self.assert_name('mac-elcapitan', 'yosemite', 'mac-elcapitan') self.assert_name('mac', 'sierra', 'mac-sierra') self.assert_name('mac-sierra', 'yosemite', 'mac-sierra') self.assert_name('mac-sierra', 'elcapitan', 'mac-sierra') self.assert_name('mac', 'highsierra', 'mac-highsierra') self.assert_name('mac-highsierra', 'elcapitan', 'mac-highsierra') self.assert_name('mac-highsierra', 'sierra', 'mac-highsierra') self.assert_name('mac', 'mojave', 'mac-mojave') self.assert_name('mac-mojave', 'sierra', 'mac-mojave') self.assert_name('mac-mojave', 'highsierra', 'mac-mojave') self.assertRaises(AssertionError, self.assert_name, 'mac-tiger', 'leopard', 'mac-leopard') def test_setup_environ_for_server(self): port = self.make_port(options=MockOptions(leaks=True, guard_malloc=True)) env = port.setup_environ_for_server(port.driver_name()) self.assertEqual(env['MallocStackLogging'], '1') self.assertEqual(env['MallocScribble'], '1') self.assertEqual(env['DYLD_INSERT_LIBRARIES'], '/usr/lib/libgmalloc.dylib') def test_show_results_html_file(self): port = self.make_port() # Delay setting a should_log executive to avoid logging from MacPort.__init__. port._executive = MockExecutive(should_log=True) with OutputCapture(level=logging.INFO) as captured: port.show_results_html_file('test.html') self.assertEqual( captured.root.log.getvalue(), "MOCK popen: ['Tools/Scripts/run-safari', '--release', '--no-saved-state', '-NSOpen', 'test.html'], cwd=/mock-checkout\n" ) def test_operating_system(self): self.assertEqual('mac', self.make_port().operating_system()) def test_default_child_processes(self): port = self.make_port(port_name='mac-lion') # MockPlatformInfo only has 2 mock cores. The important part is that 2 > 1. self.assertEqual(port.default_child_processes(), 2) bytes_for_drt = 200 * 1024 * 1024 port.host.platform.total_bytes_memory = lambda: bytes_for_drt with OutputCapture(level=logging.INFO) as captured: child_processes = port.default_child_processes() self.assertEqual( captured.root.log.getvalue(), "This machine could support 2 child processes, but only has enough memory for 1.\n" ) self.assertEqual(child_processes, 1) # Make sure that we always use one process, even if we don't have the memory for it. port.host.platform.total_bytes_memory = lambda: bytes_for_drt - 1 with OutputCapture(level=logging.INFO) as captured: child_processes = port.default_child_processes() self.assertEqual( captured.root.log.getvalue(), "This machine could support 2 child processes, but only has enough memory for 1.\n" ) self.assertEqual(child_processes, 1) def test_32bit(self): port = self.make_port(options=MockOptions(architecture='x86')) def run_script(script, args=None, env=None): self.args = args port._run_script = run_script self.assertEqual(port.architecture(), 'x86') port._build_driver() self.assertEqual(self.args, ['ARCHS=i386']) def test_64bit(self): port = self.make_port(options=MockOptions(architecture='x86_64')) self.assertEqual(port.architecture(), 'x86_64') def run_script(script, args=None, env=None): self.args = args port._run_script = run_script port._build_driver() self.assertEqual(self.args, ['ARCHS=x86_64']) def test_arm(self): port = self.make_port(options=MockOptions(architecture='arm64e')) self.assertEqual(port.architecture(), 'arm64') def run_script(script, args=None, env=None): self.args = args port._run_script = run_script port._build_driver() self.assertEqual(self.args, ['ARCHS=arm64']) def test_default(self): port = self.make_port() self.assertEqual(port.architecture(), port.host.platform.architecture()) def run_script(script, args=None, env=None): self.args = args port._run_script = run_script port._build_driver() self.assertEqual(self.args, ['ARCHS={}'.format(port.host.platform.architecture())]) def test_sdk_name(self): port = self.make_port() self.assertEqual(port.SDK, 'macosx') def test_xcrun(self): def throwing_run_command(args): print(args) raise ScriptError("MOCK script error") port = self.make_port() port._executive = MockExecutive2(run_command_fn=throwing_run_command) with OutputCapture() as captured: port.xcrun_find('test', 'falling') self.assertEqual( captured.stdout.getvalue(), "['xcrun', '--sdk', 'macosx', '-find', 'test']\n" ) def test_layout_test_searchpath_with_apple_additions(self): with port_testcase.bind_mock_apple_additions(): search_path = self.make_port().default_baseline_search_path() self.assertEqual(search_path[0], '/additional_testing_path/mac-add-lion-wk1') self.assertEqual(search_path[1], '/mock-checkout/LayoutTests/platform/mac-lion-wk1') self.assertEqual(search_path[2], '/additional_testing_path/mac-add-lion') self.assertEqual(search_path[3], '/mock-checkout/LayoutTests/platform/mac-lion') self.assertEqual(search_path[4], '/additional_testing_path/mac-add-mountainlion-wk1') self.assertEqual(search_path[5], '/mock-checkout/LayoutTests/platform/mac-mountainlion-wk1') def test_monterey_baseline_search_path(self): search_path = self.make_port(port_name='macos-monterey').default_baseline_search_path() self.assertEqual(search_path[0], '/mock-checkout/LayoutTests/platform/mac-monterey-wk1') self.assertEqual(search_path[1], '/mock-checkout/LayoutTests/platform/mac-monterey') self.assertEqual(search_path[2], '/mock-checkout/LayoutTests/platform/mac-wk1') self.assertEqual(search_path[3], '/mock-checkout/LayoutTests/platform/mac') def test_factory_with_future_version(self): port = self.make_port(options=MockOptions(webkit_test_runner=True), os_version=MacTest.FUTURE_VERSION, os_name='mac', port_name='mac') self.assertEqual(port.driver_name(), 'WebKitTestRunner') self.assertEqual(port.version_name(), VersionNameMap().to_name(MacPort.CURRENT_VERSION, platform=MacPort.port_name)) port = self.make_port(options=MockOptions(webkit_test_runner=False), os_version=MacTest.FUTURE_VERSION, os_name='mac', port_name='mac') self.assertEqual(port.driver_name(), 'DumpRenderTree') self.assertEqual(port.version_name(), VersionNameMap().to_name(MacPort.CURRENT_VERSION, platform=MacPort.port_name)) port = self.make_port(options=MockOptions(webkit_test_runner=False), os_version=MacTest.FUTURE_VERSION, os_name='mac', port_name='mac-wk2') self.assertEqual(port.driver_name(), 'WebKitTestRunner') self.assertEqual(port.version_name(), VersionNameMap().to_name(MacPort.CURRENT_VERSION, platform=MacPort.port_name)) port = self.make_port(options=MockOptions(webkit_test_runner=True), os_version=MacTest.FUTURE_VERSION, os_name='mac', port_name='mac-wk2') self.assertEqual(port.driver_name(), 'WebKitTestRunner') self.assertEqual(port.version_name(), VersionNameMap().to_name(MacPort.CURRENT_VERSION, platform=MacPort.port_name)) def test_factory_with_future_version_and_apple_additions(self): with port_testcase.bind_mock_apple_additions(): port = self.make_port(options=MockOptions(webkit_test_runner=True), os_version=MacTest.FUTURE_VERSION, os_name='mac', port_name='mac') self.assertEqual(port.driver_name(), 'WebKitTestRunner') self.assertEqual(port.version_name(), None) port = self.make_port(options=MockOptions(webkit_test_runner=False), os_version=MacTest.FUTURE_VERSION, os_name='mac', port_name='mac') self.assertEqual(port.driver_name(), 'DumpRenderTree') self.assertEqual(port.version_name(), None) port = self.make_port(options=MockOptions(webkit_test_runner=False), os_version=MacTest.FUTURE_VERSION, os_name='mac', port_name='mac-wk2') self.assertEqual(port.driver_name(), 'WebKitTestRunner') self.assertEqual(port.version_name(), None) port = self.make_port(options=MockOptions(webkit_test_runner=True), os_version=MacTest.FUTURE_VERSION, os_name='mac', port_name='mac-wk2') self.assertEqual(port.driver_name(), 'WebKitTestRunner') self.assertEqual(port.version_name(), None) def test_factory_with_portname_version(self): port = self.make_port(options=MockOptions(webkit_test_runner=False), port_name='mac-mountainlion') self.assertEqual(port.driver_name(), 'DumpRenderTree') self.assertEqual(port.version_name(), 'Mountain Lion') port = self.make_port(options=MockOptions(webkit_test_runner=True), port_name='mac-mountainlion') self.assertEqual(port.driver_name(), 'WebKitTestRunner') self.assertEqual(port.version_name(), 'Mountain Lion') port = self.make_port(options=MockOptions(webkit_test_runner=True), port_name='mac-mountainlion-wk2') self.assertEqual(port.driver_name(), 'WebKitTestRunner') self.assertEqual(port.version_name(), 'Mountain Lion') port = self.make_port(options=MockOptions(webkit_test_runner=False), port_name='mac-mountainlion-wk2') self.assertEqual(port.driver_name(), 'WebKitTestRunner') self.assertEqual(port.version_name(), 'Mountain Lion') def test_factory_with_portname_wk2(self): port = self.make_port(options=MockOptions(webkit_test_runner=False), port_name='mac') self.assertEqual(port.driver_name(), 'DumpRenderTree') port = self.make_port(options=MockOptions(webkit_test_runner=True), port_name='mac') self.assertEqual(port.driver_name(), 'WebKitTestRunner') port = self.make_port(options=MockOptions(webkit_test_runner=True), port_name='mac-wk2') self.assertEqual(port.driver_name(), 'WebKitTestRunner') port = self.make_port(options=MockOptions(webkit_test_runner=False), port_name='mac-wk2') self.assertEqual(port.driver_name(), 'WebKitTestRunner') def test_configuration_for_upload(self): port = self.make_port() self.assertEqual( dict( platform='mac', is_simulator=False, architecture='x86_64', version='10.7', version_name='Lion', sdk='17A405', style='release', ), port.configuration_for_upload(), ) def test_rosetta_expectations(self): mock_host = MockSystemHost() mock_host.platform = MockPlatformInfo(architecture='arm64') mock_host.filesystem.write_text_file( '/mock-checkout/LayoutTests/platform/mac/TestExpectationsRosetta', '# FIXME \n', ) port = self.make_port( host=mock_host, options=MockOptions(architecture='x86_64', configuration='Release'), ) self.assertEqual( list(port.expectations_dict().keys())[-1], '/mock-checkout/LayoutTests/platform/mac/TestExpectationsRosetta', )