xcode_util_test.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. #!/usr/bin/env vpython3
  2. # Copyright 2021 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """Unittests for xcode_util.py."""
  6. import logging
  7. import mock
  8. import os
  9. import unittest
  10. import test_runner_errors
  11. import test_runner_test
  12. import xcode_util
  13. _XCODEBUILD_VERSION_OUTPUT_12 = b"""Xcode 12.4
  14. Build version 12D4e
  15. """
  16. _XCODEBUILD_VERSION_OUTPUT_13 = b"""Xcode 13.0
  17. Build version 13A5155e
  18. """
  19. class XcodeUtilTest(test_runner_test.TestCase):
  20. """Test class for xcode_util functions."""
  21. def setUp(self):
  22. super(XcodeUtilTest, self).setUp()
  23. @mock.patch(
  24. 'subprocess.check_output', return_value=_XCODEBUILD_VERSION_OUTPUT_13)
  25. def test_version(self, _):
  26. """Tests xcode_util.version()"""
  27. version, build_version = xcode_util.version()
  28. self.assertEqual(version, '13.0')
  29. self.assertEqual(build_version, '13a5155e')
  30. @mock.patch(
  31. 'subprocess.check_output', return_value=_XCODEBUILD_VERSION_OUTPUT_12)
  32. def test_using_xcode_12(self, _):
  33. """Tests xcode_util.using_xcode_11_or_higher"""
  34. self.assertTrue(xcode_util.using_xcode_11_or_higher())
  35. self.assertFalse(xcode_util.using_xcode_13_or_higher())
  36. @mock.patch(
  37. 'subprocess.check_output', return_value=_XCODEBUILD_VERSION_OUTPUT_13)
  38. def test_using_xcode_13(self, _):
  39. """Tests xcode_util.using_xcode_13_or_higher"""
  40. self.assertTrue(xcode_util.using_xcode_11_or_higher())
  41. self.assertTrue(xcode_util.using_xcode_13_or_higher())
  42. class InstallTest(XcodeUtilTest):
  43. """Test class for xcode_util.install function."""
  44. def setUp(self):
  45. super(InstallTest, self).setUp()
  46. self.mac_toolchain = 'mac_toolchain'
  47. self.xcode_build_version = 'TestXcodeVersion'
  48. self.xcode_app_path = 'test/path/Xcode.app'
  49. self.runtime_cache_folder = 'test/path/Runtime'
  50. self.ios_version = '14.4'
  51. @mock.patch('xcode_util.move_runtime', autospec=True)
  52. @mock.patch('xcode_util._install_runtime', autospec=True)
  53. @mock.patch('xcode_util._install_xcode', autospec=True)
  54. def test_legacy_mactoolchain_new_xcode(self, mock_install_xcode,
  55. mock_install_runtime,
  56. mock_move_runtime):
  57. self.mock(xcode_util, '_using_new_mac_toolchain', lambda cmd: False)
  58. self.mock(xcode_util, '_is_legacy_xcode_package', lambda path: False)
  59. with self.assertRaises(test_runner_errors.XcodeMacToolchainMismatchError):
  60. is_legacy_xcode = xcode_util.install(self.mac_toolchain,
  61. self.xcode_build_version,
  62. self.xcode_app_path)
  63. self.assertTrue(is_legacy_xcode, 'install should return true')
  64. mock_install_xcode.assert_called_with('mac_toolchain', 'TestXcodeVersion',
  65. 'test/path/Xcode.app', False)
  66. self.assertFalse(mock_install_runtime.called,
  67. '_install_runtime shouldn\'t be called')
  68. self.assertFalse(mock_move_runtime.called,
  69. 'move_runtime shouldn\'t be called')
  70. @mock.patch('xcode_util.move_runtime', autospec=True)
  71. @mock.patch('xcode_util._install_runtime', autospec=True)
  72. @mock.patch('xcode_util._install_xcode', autospec=True)
  73. def test_legacy_mactoolchain_legacy_xcode(self, mock_install_xcode,
  74. mock_install_runtime,
  75. mock_move_runtime):
  76. self.mock(xcode_util, '_using_new_mac_toolchain', lambda cmd: False)
  77. self.mock(xcode_util, '_is_legacy_xcode_package', lambda path: True)
  78. is_legacy_xcode = xcode_util.install(self.mac_toolchain,
  79. self.xcode_build_version,
  80. self.xcode_app_path)
  81. self.assertTrue(is_legacy_xcode, 'install_should return true')
  82. mock_install_xcode.assert_called_with('mac_toolchain', 'TestXcodeVersion',
  83. 'test/path/Xcode.app', False)
  84. self.assertFalse(mock_install_runtime.called,
  85. '_install_runtime shouldn\'t be called')
  86. self.assertFalse(mock_move_runtime.called,
  87. 'move_runtime shouldn\'t be called')
  88. @mock.patch('xcode_util.move_runtime', autospec=True)
  89. @mock.patch('xcode_util._install_runtime', autospec=True)
  90. @mock.patch('xcode_util._install_xcode', autospec=True)
  91. def test_new_mactoolchain_legacy_xcode(self, mock_install_xcode,
  92. mock_install_runtime,
  93. mock_move_runtime):
  94. self.mock(xcode_util, '_using_new_mac_toolchain', lambda cmd: True)
  95. self.mock(xcode_util, '_is_legacy_xcode_package', lambda path: True)
  96. is_legacy_xcode = xcode_util.install(self.mac_toolchain,
  97. self.xcode_build_version,
  98. self.xcode_app_path)
  99. self.assertTrue(is_legacy_xcode, 'install should return true')
  100. mock_install_xcode.assert_called_with('mac_toolchain', 'TestXcodeVersion',
  101. 'test/path/Xcode.app', True)
  102. self.assertFalse(mock_install_runtime.called,
  103. '_install_runtime shouldn\'t be called')
  104. self.assertFalse(mock_move_runtime.called,
  105. 'move_runtime shouldn\'t be called')
  106. @mock.patch('xcode_util.move_runtime', autospec=True)
  107. @mock.patch('xcode_util._install_runtime')
  108. @mock.patch('xcode_util._install_xcode')
  109. def test_new_mactoolchain_new_xcode(self, mock_install_xcode,
  110. mock_install_runtime, mock_move_runtime):
  111. self.mock(xcode_util, '_using_new_mac_toolchain', lambda cmd: True)
  112. self.mock(xcode_util, '_is_legacy_xcode_package', lambda path: False)
  113. is_legacy_xcode = xcode_util.install(
  114. self.mac_toolchain,
  115. self.xcode_build_version,
  116. self.xcode_app_path,
  117. runtime_cache_folder=self.runtime_cache_folder,
  118. ios_version=self.ios_version)
  119. self.assertFalse(is_legacy_xcode, 'install should return False')
  120. mock_install_xcode.assert_called_with('mac_toolchain', 'TestXcodeVersion',
  121. 'test/path/Xcode.app', True)
  122. mock_install_runtime.assert_called_with('mac_toolchain',
  123. 'test/path/Runtime',
  124. 'TestXcodeVersion', '14.4')
  125. mock_move_runtime.assert_called_with('test/path/Runtime',
  126. 'test/path/Xcode.app', True)
  127. @mock.patch('xcode_util.move_runtime', autospec=True)
  128. @mock.patch('xcode_util._install_runtime')
  129. @mock.patch('xcode_util._install_xcode')
  130. def test_new_mactoolchain_new_xcode_no_runtime(self, mock_install_xcode,
  131. mock_install_runtime,
  132. mock_move_runtime):
  133. self.mock(xcode_util, '_using_new_mac_toolchain', lambda cmd: True)
  134. self.mock(xcode_util, '_is_legacy_xcode_package', lambda path: False)
  135. is_legacy_xcode = xcode_util.install(
  136. self.mac_toolchain,
  137. self.xcode_build_version,
  138. self.xcode_app_path,
  139. runtime_cache_folder=None,
  140. ios_version=None)
  141. self.assertFalse(is_legacy_xcode, 'install should return False')
  142. mock_install_xcode.assert_called_with('mac_toolchain', 'TestXcodeVersion',
  143. 'test/path/Xcode.app', True)
  144. self.assertFalse(mock_install_runtime.called)
  145. self.assertFalse(mock_move_runtime.called)
  146. class HelperFunctionTests(XcodeUtilTest):
  147. """Test class for xcode_util misc util functions."""
  148. def setUp(self):
  149. super(HelperFunctionTests, self).setUp()
  150. self.xcode_runtime_dir_rel_path = (
  151. 'Contents/Developer/'
  152. 'Platforms/iPhoneOS.platform/Library/Developer/'
  153. 'CoreSimulator/Profiles/Runtimes')
  154. self.xcode_runtime_rel_path = (
  155. 'Contents/Developer/'
  156. 'Platforms/iPhoneOS.platform/Library/Developer/'
  157. 'CoreSimulator/Profiles/Runtimes/iOS.simruntime')
  158. @mock.patch('subprocess.check_output', autospec=True)
  159. def test_using_new_mac_toolchain(self, mock_check_output):
  160. mock_check_output.return_value = b"""
  161. Mac OS / iOS toolchain management
  162. Usage: mac_toolchain [command] [arguments]
  163. Commands:
  164. help prints help about a command
  165. install Installs Xcode.
  166. upload Uploads Xcode CIPD packages.
  167. package Create CIPD packages locally.
  168. install-runtime Installs Runtime.
  169. Use "mac_toolchain help [command]" for more information about a command."""
  170. self.assertTrue(xcode_util._using_new_mac_toolchain('mac_toolchain'))
  171. @mock.patch('subprocess.check_output', autospec=True)
  172. def test_using_new_legacy_toolchain(self, mock_check_output):
  173. mock_check_output.return_value = b"""
  174. Mac OS / iOS toolchain management
  175. Usage: mac_toolchain [command] [arguments]
  176. Commands:
  177. help prints help about a command
  178. install Installs Xcode.
  179. upload Uploads Xcode CIPD packages.
  180. package Create CIPD packages locally.
  181. Use "mac_toolchain help [command]" for more information about a command."""
  182. self.assertFalse(xcode_util._using_new_mac_toolchain('mac_toolchain'))
  183. @mock.patch('shutil.rmtree', autospec=True)
  184. @mock.patch('glob.glob', autospec=True)
  185. def test_is_legacy_xcode_package_legacy(self, mock_glob, mock_rmtree):
  186. test_xcode_path = 'test/path/Xcode.app/'
  187. runtime_names = ['iOS.simruntime', 'iOS 12.4.simruntime']
  188. xcode_runtime_paths = [
  189. os.path.join(test_xcode_path, self.xcode_runtime_dir_rel_path,
  190. runtime_name) for runtime_name in runtime_names
  191. ]
  192. mock_glob.return_value = xcode_runtime_paths
  193. self.assertTrue(xcode_util._is_legacy_xcode_package(test_xcode_path))
  194. mock_glob.assert_called_with(
  195. os.path.join(test_xcode_path, self.xcode_runtime_dir_rel_path,
  196. '*.simruntime'))
  197. self.assertFalse(mock_rmtree.called)
  198. @mock.patch('shutil.rmtree', autospec=True)
  199. @mock.patch('glob.glob', autospec=True)
  200. def test_is_legacy_xcode_package_no_runtime(self, mock_glob, mock_rmtree):
  201. test_xcode_path = 'test/path/Xcode.app/'
  202. xcode_runtime_paths = []
  203. mock_glob.return_value = xcode_runtime_paths
  204. self.assertFalse(xcode_util._is_legacy_xcode_package(test_xcode_path))
  205. mock_glob.assert_called_with(
  206. os.path.join(test_xcode_path, self.xcode_runtime_dir_rel_path,
  207. '*.simruntime'))
  208. self.assertFalse(mock_rmtree.called)
  209. @mock.patch('shutil.rmtree', autospec=True)
  210. @mock.patch('glob.glob', autospec=True)
  211. def test_is_legacy_xcode_package_single_runtime(self, mock_glob, mock_rmtree):
  212. test_xcode_path = 'test/path/Xcode.app/'
  213. runtime_names = ['iOS.simruntime']
  214. xcode_runtime_paths = [
  215. os.path.join(test_xcode_path, self.xcode_runtime_dir_rel_path,
  216. runtime_name) for runtime_name in runtime_names
  217. ]
  218. mock_glob.return_value = xcode_runtime_paths
  219. self.assertFalse(xcode_util._is_legacy_xcode_package(test_xcode_path))
  220. mock_glob.assert_called_with(
  221. os.path.join(test_xcode_path, self.xcode_runtime_dir_rel_path,
  222. '*.simruntime'))
  223. mock_rmtree.assert_called_with(
  224. os.path.join(test_xcode_path, self.xcode_runtime_dir_rel_path,
  225. 'iOS.simruntime'))
  226. class MoveRuntimeTests(XcodeUtilTest):
  227. """Test class for xcode_util.move_runtime function."""
  228. def setUp(self):
  229. super(MoveRuntimeTests, self).setUp()
  230. self.runtime_cache_folder = 'test/path/Runtime'
  231. self.xcode_app_path = 'test/path/Xcode.app'
  232. @mock.patch('shutil.move', autospec=True)
  233. @mock.patch('shutil.rmtree', autospec=True)
  234. @mock.patch('glob.glob', autospec=True)
  235. def test_move_runtime_into_xcode(self, mock_glob, mock_rmtree, mock_move):
  236. mock_glob.side_effect = [['test/path/Runtime/iOS.simruntime'], []]
  237. xcode_util.move_runtime(self.runtime_cache_folder, self.xcode_app_path,
  238. True)
  239. xcode_runtime_path = ('test/path/Xcode.app/Contents/Developer/'
  240. 'Platforms/iPhoneOS.platform/Library/Developer/'
  241. 'CoreSimulator/Profiles/Runtimes/iOS.simruntime')
  242. calls = [
  243. mock.call('test/path/Runtime/*.simruntime'),
  244. mock.call(('test/path/Xcode.app/Contents/Developer/'
  245. 'Platforms/iPhoneOS.platform/Library/Developer/'
  246. 'CoreSimulator/Profiles/Runtimes/*.simruntime'))
  247. ]
  248. mock_glob.assert_has_calls(calls)
  249. self.assertFalse(mock_rmtree.called)
  250. mock_move.assert_called_with('test/path/Runtime/iOS.simruntime',
  251. xcode_runtime_path)
  252. @mock.patch('shutil.move', autospec=True)
  253. @mock.patch('shutil.rmtree', autospec=True)
  254. @mock.patch('glob.glob', autospec=True)
  255. def test_move_runtime_outside_xcode(self, mock_glob, mock_rmtree, mock_move):
  256. xcode_runtime_folder = ('test/path/Xcode.app/Contents/Developer/'
  257. 'Platforms/iPhoneOS.platform/Library/Developer/'
  258. 'CoreSimulator/Profiles/Runtimes')
  259. mock_glob.side_effect = [[xcode_runtime_folder + '/iOS.simruntime'], []]
  260. xcode_util.move_runtime(self.runtime_cache_folder, self.xcode_app_path,
  261. False)
  262. calls = [
  263. mock.call(('test/path/Xcode.app/Contents/Developer/'
  264. 'Platforms/iPhoneOS.platform/Library/Developer/'
  265. 'CoreSimulator/Profiles/Runtimes/*.simruntime')),
  266. mock.call('test/path/Runtime/*.simruntime')
  267. ]
  268. mock_glob.assert_has_calls(calls)
  269. self.assertFalse(mock_rmtree.called)
  270. mock_move.assert_called_with(xcode_runtime_folder + '/iOS.simruntime',
  271. 'test/path/Runtime/iOS.simruntime')
  272. @mock.patch('shutil.move', autospec=True)
  273. @mock.patch('shutil.rmtree', autospec=True)
  274. @mock.patch('glob.glob', autospec=True)
  275. def test_move_runtime_multiple_in_src(self, mock_glob, mock_rmtree,
  276. mock_move):
  277. mock_glob.side_effect = [[
  278. 'test/path/Runtime/iOS.simruntime',
  279. 'test/path/Runtime/iOS 13.4.simruntime'
  280. ], []]
  281. with self.assertRaises(test_runner_errors.IOSRuntimeHandlingError):
  282. xcode_util.move_runtime(self.runtime_cache_folder, self.xcode_app_path,
  283. True)
  284. mock_glob.assert_called_with('test/path/Runtime/*.simruntime')
  285. self.assertFalse(mock_rmtree.called)
  286. self.assertFalse(mock_move.called)
  287. @mock.patch('shutil.move', autospec=True)
  288. @mock.patch('shutil.rmtree', autospec=True)
  289. @mock.patch('glob.glob', autospec=True)
  290. def test_move_runtime_remove_from_dst(self, mock_glob, mock_rmtree,
  291. mock_move):
  292. mock_glob.side_effect = [['test/path/Runtime/iOS.simruntime'],
  293. [('test/path/Xcode.app/Contents/Developer/'
  294. 'Platforms/iPhoneOS.platform/Library/Developer/'
  295. 'CoreSimulator/Profiles/Runtimes/iOS.simruntime')
  296. ]]
  297. xcode_util.move_runtime(self.runtime_cache_folder, self.xcode_app_path,
  298. True)
  299. xcode_runtime_path = ('test/path/Xcode.app/Contents/Developer/'
  300. 'Platforms/iPhoneOS.platform/Library/Developer/'
  301. 'CoreSimulator/Profiles/Runtimes/iOS.simruntime')
  302. calls = [
  303. mock.call('test/path/Runtime/*.simruntime'),
  304. mock.call(('test/path/Xcode.app/Contents/Developer/'
  305. 'Platforms/iPhoneOS.platform/Library/Developer/'
  306. 'CoreSimulator/Profiles/Runtimes/*.simruntime'))
  307. ]
  308. mock_glob.assert_has_calls(calls)
  309. mock_rmtree.assert_called_with(xcode_runtime_path)
  310. mock_move.assert_called_with('test/path/Runtime/iOS.simruntime',
  311. xcode_runtime_path)
  312. @mock.patch('shutil.rmtree', autospec=True)
  313. @mock.patch('glob.glob', autospec=True)
  314. def test_remove_runtimes(self, mock_glob, mock_rmtree):
  315. mock_glob.return_value = [
  316. ('test/path/Xcode.app/Contents/Developer/'
  317. 'Platforms/iPhoneOS.platform/Library/Developer/'
  318. 'CoreSimulator/Profiles/Runtimes/iOS.simruntime'),
  319. ('test/path/Xcode.app/Contents/Developer/'
  320. 'Platforms/iPhoneOS.platform/Library/Developer/'
  321. 'CoreSimulator/Profiles/Runtimes/iOS 15.0.simruntime')
  322. ]
  323. xcode_util.remove_runtimes(self.xcode_app_path)
  324. calls = [
  325. mock.call(('test/path/Xcode.app/Contents/Developer/'
  326. 'Platforms/iPhoneOS.platform/Library/Developer/'
  327. 'CoreSimulator/Profiles/Runtimes/*.simruntime'))
  328. ]
  329. mock_glob.assert_has_calls(calls)
  330. calls = [
  331. mock.call(('test/path/Xcode.app/Contents/Developer/'
  332. 'Platforms/iPhoneOS.platform/Library/Developer/'
  333. 'CoreSimulator/Profiles/Runtimes/iOS.simruntime')),
  334. mock.call(('test/path/Xcode.app/Contents/Developer/'
  335. 'Platforms/iPhoneOS.platform/Library/Developer/'
  336. 'CoreSimulator/Profiles/Runtimes/iOS 15.0.simruntime'))
  337. ]
  338. mock_rmtree.assert_has_calls(calls)
  339. class MacToolchainInvocationTests(XcodeUtilTest):
  340. """Test class for xcode_util functions invoking mac_toolchain."""
  341. def setUp(self):
  342. super(MacToolchainInvocationTests, self).setUp()
  343. self.mac_toolchain = 'mac_toolchain'
  344. self.xcode_build_version = 'TestXcodeVersion'
  345. self.xcode_app_path = 'test/path/Xcode.app'
  346. self.runtime_cache_folder = 'test/path/Runtime'
  347. self.ios_version = '14.4'
  348. @mock.patch('shutil.rmtree', autospec=True)
  349. @mock.patch('os.path.exists', autospec=True)
  350. @mock.patch('glob.glob', autospec=True)
  351. @mock.patch('subprocess.check_call', autospec=True)
  352. def test_install_runtime_no_cache(self, mock_check_output, mock_glob,
  353. mock_exists, mock_rmtree):
  354. mock_glob.return_value = []
  355. mock_exists.return_value = False
  356. xcode_util._install_runtime(self.mac_toolchain, self.runtime_cache_folder,
  357. self.xcode_build_version, self.ios_version)
  358. mock_glob.assert_called_with('test/path/Runtime/*.simruntime')
  359. calls = [
  360. mock.call('test/path/Runtime/.cipd'),
  361. mock.call('test/path/Runtime/.xcode_versions'),
  362. ]
  363. mock_exists.assert_has_calls(calls)
  364. self.assertFalse(mock_rmtree.called)
  365. mock_check_output.assert_called_with([
  366. 'mac_toolchain', 'install-runtime', '-xcode-version',
  367. 'testxcodeversion', '-runtime-version', 'ios-14-4', '-output-dir',
  368. 'test/path/Runtime'
  369. ],
  370. stderr=-2)
  371. @mock.patch('shutil.rmtree', autospec=True)
  372. @mock.patch('os.path.exists', autospec=True)
  373. @mock.patch('glob.glob', autospec=True)
  374. @mock.patch('subprocess.check_call', autospec=True)
  375. def test_install_runtime_has_cache(self, mock_check_output, mock_glob,
  376. mock_exists, mock_rmtree):
  377. mock_glob.return_value = ['test/path/Runtime/iOS.simruntime']
  378. xcode_util._install_runtime(self.mac_toolchain, self.runtime_cache_folder,
  379. self.xcode_build_version, self.ios_version)
  380. mock_glob.assert_called_with('test/path/Runtime/*.simruntime')
  381. self.assertFalse(mock_exists.called)
  382. self.assertFalse(mock_rmtree.called)
  383. mock_check_output.assert_called_with([
  384. 'mac_toolchain', 'install-runtime', '-xcode-version',
  385. 'testxcodeversion', '-runtime-version', 'ios-14-4', '-output-dir',
  386. 'test/path/Runtime'
  387. ],
  388. stderr=-2)
  389. @mock.patch('shutil.rmtree', autospec=True)
  390. @mock.patch('os.path.exists', autospec=True)
  391. @mock.patch('glob.glob', autospec=True)
  392. @mock.patch('subprocess.check_call', autospec=True)
  393. def test_install_runtime_incorrect_cache(self, mock_check_output, mock_glob,
  394. mock_exists, mock_rmtree):
  395. mock_glob.return_value = []
  396. mock_exists.return_value = True
  397. xcode_util._install_runtime(self.mac_toolchain, self.runtime_cache_folder,
  398. self.xcode_build_version, self.ios_version)
  399. mock_glob.assert_called_with('test/path/Runtime/*.simruntime')
  400. calls = [
  401. mock.call('test/path/Runtime/.cipd'),
  402. mock.call('test/path/Runtime/.xcode_versions'),
  403. ]
  404. mock_exists.assert_has_calls(calls)
  405. mock_rmtree.assert_has_calls(calls)
  406. mock_check_output.assert_called_with([
  407. 'mac_toolchain', 'install-runtime', '-xcode-version',
  408. 'testxcodeversion', '-runtime-version', 'ios-14-4', '-output-dir',
  409. 'test/path/Runtime'
  410. ],
  411. stderr=-2)
  412. @mock.patch('subprocess.check_call', autospec=True)
  413. def test_install_xcode_legacy_mac_toolchain(self, mock_check_output):
  414. using_new_mac_toolchain = False
  415. xcode_util._install_xcode(self.mac_toolchain, self.xcode_build_version,
  416. self.xcode_app_path, using_new_mac_toolchain)
  417. mock_check_output.assert_called_with([
  418. 'mac_toolchain', 'install', '-kind', 'ios', '-xcode-version',
  419. 'testxcodeversion', '-output-dir', 'test/path/Xcode.app'
  420. ],
  421. stderr=-2)
  422. @mock.patch('subprocess.check_call', autospec=True)
  423. def test_install_xcode_new_mac_toolchain(self, mock_check_output):
  424. using_new_mac_toolchain = True
  425. xcode_util._install_xcode(self.mac_toolchain, self.xcode_build_version,
  426. self.xcode_app_path, using_new_mac_toolchain)
  427. mock_check_output.assert_called_with([
  428. 'mac_toolchain', 'install', '-kind', 'ios', '-xcode-version',
  429. 'testxcodeversion', '-output-dir', 'test/path/Xcode.app',
  430. '-with-runtime=False'
  431. ],
  432. stderr=-2)
  433. if __name__ == '__main__':
  434. logging.basicConfig(
  435. format='[%(asctime)s:%(levelname)s] %(message)s',
  436. level=logging.DEBUG,
  437. datefmt='%I:%M:%S')
  438. unittest.main()