1# Copyright 2024 The Chromium Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5from __future__ import annotations 6 7import plistlib 8 9from pyfakefs.fake_filesystem import OSType 10 11from crossbench import path as pth 12from tests import test_helper 13from tests.crossbench.mock_helper import MacOsMockPlatform 14from tests.crossbench.plt.helper import BasePosixMockPlatformTestCase 15 16 17class MacOsMockPlatformTestCase(BasePosixMockPlatformTestCase): 18 __test__ = True 19 20 def setUp(self) -> None: 21 super().setUp() 22 self.fs.os = OSType.MACOS 23 24 def mock_platform_setup(self) -> None: 25 self.mock_platform = MacOsMockPlatform() 26 self.platform = self.mock_platform 27 28 def test_name(self): 29 self.assertEqual(self.platform.name, "mock.macos") 30 31 def test_is_macos(self): 32 self.assertTrue(self.platform.is_macos) 33 34 def test_app_version_non_existing(self): 35 app_path = pth.AnyPath("/Applications/Google Chrome.app") 36 self.assertFalse(self.platform.exists(app_path)) 37 with self.assertRaisesRegex(ValueError, "not exist"): 38 self.platform.app_version(app_path) 39 40 def test_app_version_binary(self): 41 app_path = pth.AnyPath("/opt/homebrew/bin/brew") 42 self.fs.create_file(app_path, st_size=100) 43 self.expect_sh(app_path, "--version", result="111.22.3") 44 self.assertEqual(self.platform.app_version(app_path), "111.22.3") 45 46 def test_app_version(self): 47 app_path = pth.LocalPath("/Applications/Google Chrome.app") 48 with self.assertRaisesRegex(ValueError, str(app_path)): 49 self.platform.app_version(app_path) 50 app_path.mkdir(parents=True) 51 with self.assertRaisesRegex(ValueError, str(app_path)): 52 self.platform.app_version(app_path) 53 54 binary_path = app_path / "Contents/MacOS/Google Chrome" 55 binary_path.parent.mkdir(parents=True) 56 with self.assertRaisesRegex(ValueError, "Info.plist"): 57 self.platform.app_version(app_path) 58 59 info_plist = app_path / "Contents/Info.plist" 60 self.fs.create_file(info_plist) 61 with self.assertRaisesRegex(ValueError, "Invalid file"): 62 self.platform.app_version(app_path) 63 64 with info_plist.open("wb") as f: 65 plistlib.dump({}, f) 66 with self.assertRaisesRegex(ValueError, str(app_path)): 67 self.platform.app_version(app_path) 68 69 with info_plist.open("wb") as f: 70 plistlib.dump({"CFBundleShortVersionString": "129.9.6668.103"}, f) 71 self.assertEqual(self.platform.app_version(app_path), "129.9.6668.103") 72 73 def test_app_version_binary_inside_app(self): 74 binary_path = pth.LocalPath("/Applications/Safari Technology Preview.app/" 75 "Contents/MacOS/safaridriver") 76 self.fs.create_file(binary_path, st_size=100) 77 self.expect_sh(binary_path, "--version", result="(Release 203, 19620.1.6)") 78 self.assertEqual( 79 self.platform.app_version(binary_path), "(Release 203, 19620.1.6)") 80 81 def test_search_binary(self): 82 app_path = pth.LocalPath("/Applications/Google Chrome.app") 83 self.assertIsNone(self.platform.search_binary(app_path)) 84 binary_path = app_path / "Contents/MacOS/Google Chrome" 85 self.fs.create_file(binary_path, st_size=100) 86 self.assertEqual(self.platform.search_binary(app_path), binary_path) 87 88 def test_search_binary_custom_bundle_executable(self): 89 app_path = pth.LocalPath("/Applications/Google Chrome.app") 90 self.assertIsNone(self.platform.search_binary(app_path)) 91 binary_path = app_path / "Contents/MacOS/Chrome" 92 binary_path.parent.mkdir(parents=True) 93 with self.assertRaisesRegex(ValueError, "Info.plist"): 94 self.platform.search_binary(app_path) 95 96 info_plist = app_path / "Contents/Info.plist" 97 self.fs.create_file(info_plist) 98 with self.assertRaisesRegex(ValueError, "Invalid file"): 99 self.platform.search_binary(app_path) 100 101 with info_plist.open("wb") as f: 102 plistlib.dump({}, f) 103 with self.assertRaisesRegex(ValueError, str(app_path)): 104 self.platform.search_binary(app_path) 105 106 with info_plist.open("wb") as f: 107 plistlib.dump({"CFBundleExecutable": str(binary_path)}, f) 108 with self.assertRaisesRegex(ValueError, str(app_path)): 109 self.platform.search_binary(app_path) 110 111 self.fs.create_file(binary_path, st_size=100) 112 # Single binary is always resolved directly 113 self.assertEqual(self.platform.search_binary(app_path), binary_path) 114 115 # Adding another binary will still resolve to CFBundleExecutable 116 self.fs.create_file(binary_path.parent / "Other", st_size=100) 117 self.assertEqual(self.platform.search_binary(app_path), binary_path) 118 119 def test_search_binary_single(self): 120 app_path = pth.LocalPath("/Applications/Custom.app") 121 binary_path = app_path / "Contents/MacOS/CustomA" 122 self.fs.create_file(binary_path, st_size=100) 123 self.assertEqual(self.platform.search_binary(app_path), binary_path) 124 125 def test_search_binary_multiple_binaries(self): 126 app_path = pth.LocalPath("/Applications/Custom.app") 127 self.fs.create_file(app_path / "Contents/MacOS/CustomA", st_size=100) 128 self.fs.create_file(app_path / "Contents/MacOS/CustomB", st_size=100) 129 info_plist = app_path / "Contents/Info.plist" 130 with info_plist.open("wb") as f: 131 plistlib.dump({}, f) 132 with self.assertRaisesRegex(ValueError, "binaries"): 133 self.platform.search_binary(app_path) 134 135 136if __name__ == "__main__": 137 test_helper.run_pytest(__file__) 138