test_o3de_multi_test_framework.py 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312
  1. """
  2. Copyright (c) Contributors to the Open 3D Engine Project.
  3. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. SPDX-License-Identifier: Apache-2.0 OR MIT
  5. """
  6. import unittest
  7. import pytest
  8. import unittest.mock as mock
  9. import ly_test_tools
  10. import ly_test_tools.launchers.exceptions
  11. import ly_test_tools.o3de.multi_test_framework as multi_test_framework
  12. from ly_test_tools.o3de.editor_test_utils import prepare_asset_processor
  13. from ly_test_tools.launchers.platforms.linux.launcher import LinuxAtomToolsLauncher, LinuxEditor
  14. from ly_test_tools.launchers.platforms.win.launcher import WinAtomToolsLauncher, WinEditor
  15. pytestmark = pytest.mark.SUITE_smoke
  16. class TestResultType(unittest.TestCase):
  17. class DummySubclass(multi_test_framework.Result.ResultType):
  18. def __str__(self):
  19. return None
  20. def setUp(self):
  21. self.mock_result = TestResultType.DummySubclass()
  22. def test_GetOutputStr_HasOutput_ReturnsCorrectly(self):
  23. self.mock_result.output = 'expected output'
  24. assert self.mock_result.get_output_str() == 'expected output'
  25. def test_GetOutputStr_NoOutput_ReturnsCorrectly(self):
  26. self.mock_result.output = None
  27. assert self.mock_result.get_output_str() == '-- No output --'
  28. def test_GetLogStr_HasOutput_ReturnsCorrectly(self):
  29. self.mock_result.log_output = 'expected log output'
  30. assert self.mock_result.get_log_output_str() == 'expected log output'
  31. def test_GetLogStr_NoOutput_ReturnsCorrectly(self):
  32. self.mock_result.log_output = None
  33. assert self.mock_result.get_log_output_str() == '-- No log found --'
  34. class TestResultPass(unittest.TestCase):
  35. def test_Create_ValidArgs_CorrectAttributes(self):
  36. mock_test_spec = mock.MagicMock()
  37. mock_output = 'mock_output'
  38. mock_log_output = 'mock_log_output'
  39. under_test = multi_test_framework.Result.Pass(mock_test_spec, mock_output, mock_log_output)
  40. assert mock_test_spec == under_test.test_spec
  41. assert mock_output == under_test.output
  42. assert mock_log_output == under_test.log_output
  43. def test_Str_ValidPassString_ReturnsOutput(self):
  44. mock_test_spec = mock.MagicMock()
  45. mock_output = 'mock_output'
  46. mock_log_output = 'mock_log_output'
  47. under_test = multi_test_framework.Result.Pass(mock_test_spec, mock_output, mock_log_output)
  48. assert mock_output in str(under_test)
  49. class TestResultFail(unittest.TestCase):
  50. def test_Create_ValidArgs_CorrectAttributes(self):
  51. mock_test_spec = mock.MagicMock()
  52. mock_output = 'mock_output'
  53. mock_log_output = 'mock_log_output'
  54. under_test = multi_test_framework.Result.Fail(mock_test_spec, mock_output, mock_log_output)
  55. assert mock_test_spec == under_test.test_spec
  56. assert mock_output == under_test.output
  57. assert mock_log_output == under_test.log_output
  58. def test_Str_ValidFailString_ReturnsOutput(self):
  59. mock_test_spec = mock.MagicMock()
  60. mock_output = 'mock_output'
  61. mock_log_output = 'mock_log_output'
  62. under_test = multi_test_framework.Result.Fail(mock_test_spec, mock_output, mock_log_output)
  63. assert mock_output in str(under_test)
  64. assert mock_log_output in str(under_test)
  65. class TestResultCrash(unittest.TestCase):
  66. def test_Create_ValidArgs_CorrectAttributes(self):
  67. mock_test_spec = mock.MagicMock()
  68. mock_output = mock.MagicMock()
  69. mock_return_code = mock.MagicMock()
  70. mock_stacktrace = mock.MagicMock()
  71. mock_log_output = 'mock_log_output'
  72. under_test = multi_test_framework.Result.Crash(
  73. mock_test_spec, mock_output, mock_return_code, mock_stacktrace, mock_log_output)
  74. assert under_test.test_spec == mock_test_spec
  75. assert under_test.output == mock_output
  76. assert under_test.log_output == mock_log_output
  77. assert under_test.ret_code == mock_return_code
  78. assert under_test.stacktrace == mock_stacktrace
  79. def test_Str_ValidCrashString_ReturnsOutput(self):
  80. mock_test_spec = mock.MagicMock()
  81. mock_output = 'mock_output'
  82. mock_log_output = 'mock_log_output'
  83. mock_return_code = 0
  84. mock_stacktrace = 'mock stacktrace'
  85. under_test = multi_test_framework.Result.Crash(
  86. mock_test_spec, mock_output, mock_return_code, mock_stacktrace, mock_log_output)
  87. assert mock_stacktrace in str(under_test)
  88. assert mock_output in str(under_test)
  89. assert str(mock_return_code) in str(under_test)
  90. def test_Str_MissingStackTrace_ReturnsCorrectly(self):
  91. mock_test_spec = mock.MagicMock()
  92. mock_output = 'mock_output'
  93. mock_log_output = 'mock_log_output'
  94. mock_return_code = 0
  95. mock_stacktrace = None
  96. under_test = multi_test_framework.Result.Crash(
  97. mock_test_spec, mock_output, mock_return_code, mock_stacktrace, mock_log_output)
  98. assert mock_output in str(under_test)
  99. assert str(mock_return_code) in str(under_test)
  100. class TestResultTimeout(unittest.TestCase):
  101. def test_Create_ValidArgs_CorrectAttributes(self):
  102. mock_test_spec = mock.MagicMock()
  103. mock_output = mock.MagicMock()
  104. mock_log_output = mock.MagicMock()
  105. mock_timeout = mock.MagicMock()
  106. under_test = multi_test_framework.Result.Timeout(mock_test_spec, mock_output, mock_timeout, mock_log_output)
  107. assert under_test.test_spec == mock_test_spec
  108. assert under_test.output == mock_output
  109. assert under_test.log_output == mock_log_output
  110. assert under_test.time_secs == mock_timeout
  111. def test_Str_ValidTimeoutString_ReturnsOutput(self):
  112. mock_test_spec = mock.MagicMock()
  113. mock_output = 'mock_output'
  114. mock_log_output = 'mock_log_output'
  115. mock_timeout = 0
  116. under_test = multi_test_framework.Result.Timeout(mock_test_spec, mock_output, mock_timeout, mock_log_output)
  117. assert mock_output in str(under_test)
  118. assert str(mock_timeout) in str(under_test)
  119. class TestResultUnknown(unittest.TestCase):
  120. def test_Create_ValidArgs_CorrectAttributes(self):
  121. mock_test_spec = mock.MagicMock()
  122. mock_output = mock.MagicMock()
  123. mock_log_output = mock.MagicMock()
  124. mock_extra_info = mock.MagicMock()
  125. under_test = multi_test_framework.Result.Unknown(mock_test_spec, mock_output, mock_extra_info, mock_log_output)
  126. assert under_test.test_spec == mock_test_spec
  127. assert under_test.output == mock_output
  128. assert under_test.log_output == mock_log_output
  129. assert under_test.extra_info == mock_extra_info
  130. def test_Str_ValidUnknownString_ReturnsOutput(self):
  131. mock_test_spec = mock.MagicMock()
  132. mock_output = 'mock_output'
  133. mock_extra_info = 'mock extra info'
  134. mock_log_output = 'mock_log_output'
  135. under_test = multi_test_framework.Result.Unknown(mock_test_spec, mock_output, mock_extra_info, mock_log_output)
  136. assert mock_output in str(under_test)
  137. assert mock_extra_info in str(under_test)
  138. class TestMultiTestSuite(unittest.TestCase):
  139. @mock.patch('ly_test_tools.o3de.editor_test_utils.kill_all_ly_processes')
  140. def test_TestData_ValidAP_TeardownAPOnce(self, mock_kill_processes):
  141. mock_abstract_test_suite = multi_test_framework.MultiTestSuite()
  142. mock_test_data_generator = mock_abstract_test_suite._collected_test_data(mock.MagicMock())
  143. mock_asset_processor = mock.MagicMock()
  144. for test_data in mock_test_data_generator:
  145. test_data.asset_processor = mock_asset_processor
  146. mock_asset_processor.teardown.assert_called()
  147. assert test_data.asset_processor is None
  148. mock_kill_processes.assert_called_once_with(include_asset_processor=True)
  149. @mock.patch('ly_test_tools.o3de.editor_test_utils.kill_all_ly_processes')
  150. def test_TestData_NoAP_NoTeardownAP(self, mock_kill_processes):
  151. mock_abstract_test_suite = multi_test_framework.MultiTestSuite()
  152. mock_test_data_generator = mock_abstract_test_suite._collected_test_data(mock.MagicMock())
  153. for test_data in mock_test_data_generator:
  154. test_data.asset_processor = None
  155. mock_kill_processes.assert_called_once_with(include_asset_processor=False)
  156. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite.filter_session_shared_tests')
  157. def test_PytestCustomModifyItems_FunctionsMatch_AddsRunners(self, mock_filter_tests):
  158. class MockTestSuite(multi_test_framework.MultiTestSuite):
  159. pass
  160. mock_func_1 = mock.MagicMock()
  161. mock_test = mock.MagicMock()
  162. runner_1 = multi_test_framework.MultiTestSuite.Runner('mock_runner_1', mock_func_1, [mock_test])
  163. mock_run_pytest_func = mock.MagicMock()
  164. runner_1.run_pytestfunc = mock_run_pytest_func
  165. mock_result_pytestfuncs = [mock.MagicMock()]
  166. runner_1.result_pytestfuncs = mock_result_pytestfuncs
  167. mock_items = []
  168. mock_items.extend(mock_result_pytestfuncs)
  169. MockTestSuite._runners = [runner_1]
  170. mock_test_1 = mock.MagicMock()
  171. mock_test_2 = mock.MagicMock()
  172. mock_filter_tests.return_value = [mock_test_1, mock_test_2]
  173. MockTestSuite.pytest_custom_modify_items(mock.MagicMock(), mock_items, mock.MagicMock())
  174. assert mock_items == [mock_run_pytest_func, mock_result_pytestfuncs[0]]
  175. def test_GetSingleTests_NoSingleTests_EmptyList(self):
  176. class MockTestSuite(multi_test_framework.MultiTestSuite):
  177. pass
  178. mock_test_suite = MockTestSuite()
  179. tests = mock_test_suite.get_single_tests()
  180. assert len(tests) == 0
  181. def test_GetSingleTests_OneSingleTests_ReturnsOne(self):
  182. class MockTestSuite(multi_test_framework.MultiTestSuite):
  183. class MockSingleTest(multi_test_framework.SingleTest):
  184. pass
  185. mock_test_suite = MockTestSuite()
  186. tests = mock_test_suite.get_single_tests()
  187. assert len(tests) == 1
  188. assert tests[0].__name__ == "MockSingleTest"
  189. assert issubclass(tests[0], multi_test_framework.SingleTest)
  190. def test_GetSingleTests_AllTests_ReturnsOnlySingles(self):
  191. class MockTestSuite(multi_test_framework.MultiTestSuite):
  192. class MockSingleTest(multi_test_framework.SingleTest):
  193. pass
  194. class MockAnotherSingleTest(multi_test_framework.SingleTest):
  195. pass
  196. class MockNotSingleTest(multi_test_framework.SharedTest):
  197. pass
  198. mock_test_suite = MockTestSuite()
  199. tests = mock_test_suite.get_single_tests()
  200. assert len(tests) == 2
  201. for test in tests:
  202. assert issubclass(test, multi_test_framework.SingleTest)
  203. def test_GetSharedTests_NoSharedTests_EmptyList(self):
  204. class MockTestSuite(multi_test_framework.MultiTestSuite):
  205. pass
  206. mock_test_suite = MockTestSuite()
  207. tests = mock_test_suite.get_shared_tests()
  208. assert len(tests) == 0
  209. def test_GetSharedTests_OneSharedTests_ReturnsOne(self):
  210. class MockTestSuite(multi_test_framework.MultiTestSuite):
  211. class MockSharedTest(multi_test_framework.SharedTest):
  212. pass
  213. mock_test_suite = MockTestSuite()
  214. tests = mock_test_suite.get_shared_tests()
  215. assert len(tests) == 1
  216. assert tests[0].__name__ == 'MockSharedTest'
  217. assert issubclass(tests[0], multi_test_framework.SharedTest)
  218. def test_GetSharedTests_AllTests_ReturnsOnlyShared(self):
  219. class MockTestSuite(multi_test_framework.MultiTestSuite):
  220. class MockSharedTest(multi_test_framework.SharedTest):
  221. pass
  222. class MockAnotherSharedTest(multi_test_framework.SharedTest):
  223. pass
  224. class MockNotSharedTest(multi_test_framework.SingleTest):
  225. pass
  226. mock_test_suite = MockTestSuite()
  227. tests = mock_test_suite.get_shared_tests()
  228. assert len(tests) == 2
  229. for test in tests:
  230. assert issubclass(test, multi_test_framework.SharedTest)
  231. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite.filter_session_shared_tests')
  232. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite.get_shared_tests')
  233. def test_GetSessionSharedTests_Valid_CallsCorrectly(self, mock_get_shared_tests, mock_filter_session):
  234. multi_test_framework.MultiTestSuite.get_session_shared_tests(mock.MagicMock())
  235. assert mock_get_shared_tests.called
  236. assert mock_filter_session.called
  237. @mock.patch('ly_test_tools.o3de.multi_test_framework.skip_pytest_runtest_setup', mock.MagicMock())
  238. def test_FilterSessionSharedTests_OneSharedTest_ReturnsOne(self):
  239. def mock_test():
  240. pass
  241. mock_test.originalname = 'mock_test'
  242. mock_test.__name__ = mock_test.originalname
  243. mock_session_items = [mock_test]
  244. mock_shared_tests = [mock_test]
  245. selected_tests = multi_test_framework.MultiTestSuite.filter_session_shared_tests(mock_session_items, mock_shared_tests)
  246. assert selected_tests == mock_session_items
  247. assert len(selected_tests) == 1
  248. @mock.patch('ly_test_tools.o3de.multi_test_framework.skip_pytest_runtest_setup', mock.MagicMock())
  249. def test_FilterSessionSharedTests_ManyTests_ReturnsCorrectTests(self):
  250. def mock_test():
  251. pass
  252. def mock_test_2():
  253. pass
  254. def mock_test_3():
  255. pass
  256. mock_test.originalname = 'mock_test'
  257. mock_test.__name__ = mock_test.originalname
  258. mock_test_2.originalname = 'mock_test_2'
  259. mock_test_2.__name__ = mock_test_2.originalname
  260. mock_test_3.originalname = 'mock_test_3'
  261. mock_test_3.__name__ = mock_test_3.originalname
  262. mock_session_items = [mock_test, mock_test_2]
  263. mock_shared_tests = [mock_test, mock_test_2, mock_test_3]
  264. selected_tests = multi_test_framework.MultiTestSuite.filter_session_shared_tests(mock_session_items, mock_shared_tests)
  265. assert selected_tests == mock_session_items
  266. @mock.patch('ly_test_tools.o3de.multi_test_framework.skip_pytest_runtest_setup')
  267. def test_FilterSessionSharedTests_SkipOneTest_ReturnsCorrectTests(self, mock_skip):
  268. def mock_test():
  269. pass
  270. def mock_test_2():
  271. pass
  272. def mock_test_3():
  273. pass
  274. mock_skip.side_effect = [True, Exception]
  275. mock_test.originalname = 'mock_test'
  276. mock_test.__name__ = mock_test.originalname
  277. mock_test_2.originalname = 'mock_test_2'
  278. mock_test_2.__name__ = mock_test_2.originalname
  279. mock_test_3.originalname = 'mock_test_3'
  280. mock_test_3.__name__ = mock_test_3.originalname
  281. mock_session_items = [mock_test, mock_test_2]
  282. mock_shared_tests = [mock_test, mock_test_2, mock_test_3]
  283. selected_tests = multi_test_framework.MultiTestSuite.filter_session_shared_tests(mock_session_items, mock_shared_tests)
  284. assert selected_tests == [mock_test]
  285. @mock.patch('ly_test_tools.o3de.multi_test_framework.skip_pytest_runtest_setup', mock.MagicMock(side_effect=Exception))
  286. def test_FilterSessionSharedTests_ExceptionDuringSkipSetup_SkipsAddingTest(self):
  287. def mock_test():
  288. pass
  289. mock_test.originalname = 'mock_test'
  290. mock_test.__name__ = mock_test.originalname
  291. mock_session_items = [mock_test]
  292. mock_shared_tests = [mock_test]
  293. selected_tests = multi_test_framework.MultiTestSuite.filter_session_shared_tests(mock_session_items, mock_shared_tests)
  294. assert len(selected_tests) == 0
  295. def test_FilterSharedTests_TrueParams_ReturnsTrueTests(self):
  296. mock_test = mock.MagicMock()
  297. mock_test.is_batchable = True
  298. mock_test.is_parallelizable = True
  299. mock_test_2 = mock.MagicMock()
  300. mock_test_2.is_batchable = False
  301. mock_test_2.is_parallelizable = False
  302. mock_shared_tests = [mock_test, mock_test_2]
  303. filtered_tests = multi_test_framework.MultiTestSuite.filter_shared_tests(
  304. mock_shared_tests, is_batchable=True, is_parallelizable=True)
  305. assert filtered_tests == [mock_test]
  306. def test_FilterSharedTests_FalseParams_ReturnsFalseTests(self):
  307. mock_test = mock.MagicMock()
  308. mock_test.is_batchable = True
  309. mock_test.is_parallelizable = True
  310. mock_test_2 = mock.MagicMock()
  311. mock_test_2.is_batchable = False
  312. mock_test_2.is_parallelizable = False
  313. mock_shared_tests = [mock_test, mock_test_2]
  314. filtered_tests = multi_test_framework.MultiTestSuite.filter_shared_tests(
  315. mock_shared_tests, is_batchable=False, is_parallelizable=False)
  316. assert filtered_tests == [mock_test_2]
  317. class TestUtils(unittest.TestCase):
  318. @mock.patch('ly_test_tools.o3de.editor_test_utils.kill_all_ly_processes')
  319. def test_PrepareAssetProcessor_APExists_StartsAP(self, mock_kill_processes):
  320. mock_workspace = mock.MagicMock()
  321. mock_collected_test_data = mock.MagicMock()
  322. mock_ap = mock.MagicMock()
  323. mock_collected_test_data.asset_processor = mock_ap
  324. prepare_asset_processor(mock_workspace, mock_collected_test_data)
  325. assert mock_collected_test_data.asset_processor.start.called
  326. assert not mock_kill_processes.called
  327. @mock.patch('ly_test_tools.o3de.asset_processor.AssetProcessor.start')
  328. @mock.patch('ly_test_tools.environment.process_utils.process_exists')
  329. @mock.patch('ly_test_tools.o3de.editor_test_utils.kill_all_ly_processes')
  330. def test_PrepareAssetProcessor_NoAP_KillAndCreateAP(self, mock_kill_processes, mock_proc_exists, mock_start):
  331. mock_workspace = mock.MagicMock()
  332. mock_collected_test_data = mock.MagicMock()
  333. mock_collected_test_data.asset_processor = None
  334. mock_proc_exists.return_value = False
  335. prepare_asset_processor(mock_workspace, mock_collected_test_data)
  336. mock_kill_processes.assert_called_with(include_asset_processor=True)
  337. assert isinstance(mock_collected_test_data.asset_processor, ly_test_tools.o3de.asset_processor.AssetProcessor)
  338. assert mock_start.called
  339. @mock.patch('ly_test_tools.o3de.asset_processor.AssetProcessor.start')
  340. @mock.patch('ly_test_tools.environment.process_utils.process_exists')
  341. @mock.patch('ly_test_tools.o3de.editor_test_utils.kill_all_ly_processes')
  342. def test_PrepareAssetProcessor_NoAPButProcExists_NoKill(self, mock_kill_processes, mock_proc_exists, mock_start):
  343. mock_workspace = mock.MagicMock()
  344. mock_collected_test_data = mock.MagicMock()
  345. mock_collected_test_data.asset_processor = None
  346. mock_proc_exists.return_value = True
  347. prepare_asset_processor(mock_workspace, mock_collected_test_data)
  348. mock_kill_processes.assert_called_with(include_asset_processor=False)
  349. assert not mock_start.called
  350. assert mock_collected_test_data.asset_processor is None
  351. @mock.patch('ly_test_tools.o3de.asset_processor.AssetProcessor.start')
  352. @mock.patch('ly_test_tools.environment.process_utils.process_exists')
  353. @mock.patch('ly_test_tools.o3de.editor_test_utils.kill_all_ly_processes')
  354. def test_PrepareAssetProcessor_NoAPButProcExists_NoKill(self, mock_kill_processes, mock_proc_exists, mock_start):
  355. mock_workspace = mock.MagicMock()
  356. mock_collected_test_data = mock.MagicMock()
  357. mock_collected_test_data.asset_processor = None
  358. mock_proc_exists.return_value = True
  359. prepare_asset_processor(mock_workspace, mock_collected_test_data)
  360. mock_kill_processes.assert_called_with(include_asset_processor=False)
  361. assert not mock_start.called
  362. assert mock_collected_test_data.asset_processor is None
  363. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_module_filename')
  364. def test_GetResultsUsingOutput_ValidJsonSuccess_CreatesPassResult(self, mock_get_module):
  365. mock_get_module.return_value = 'mock_module_name'
  366. mock_test_suite = multi_test_framework.MultiTestSuite()
  367. mock_test = mock.MagicMock()
  368. mock_test.__name__ = 'mock_test_name'
  369. mock_test_list = [mock_test]
  370. mock_output = 'JSON_START(' \
  371. '{"name": "mock_module_name", "output": "mock_std_out", "success": "mock_success_data"}' \
  372. ')JSON_END'
  373. results = mock_test_suite._get_results_using_output(mock_test_list, mock_output, '')
  374. assert len(results) == 1
  375. assert 'mock_test_name' in results.keys()
  376. assert isinstance(results['mock_test_name'], multi_test_framework.Result.Pass)
  377. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_module_filename')
  378. def test_GetResultsUsingOutput_ValidJsonFail_CreatesFailResult(self, mock_get_module):
  379. mock_get_module.return_value = 'mock_module_name'
  380. mock_test_suite = multi_test_framework.MultiTestSuite()
  381. mock_test = mock.MagicMock()
  382. mock_test.__name__ = 'mock_test_name'
  383. mock_test_list = [mock_test]
  384. mock_output = 'JSON_START(' \
  385. '{"name": "mock_module_name", "output": "mock_std_out", "failed": "mock_fail_data", "success": ""}' \
  386. ')JSON_END'
  387. results = mock_test_suite._get_results_using_output(mock_test_list, mock_output, '')
  388. assert len(results) == 1
  389. assert 'mock_test_name' in results.keys()
  390. assert isinstance(results['mock_test_name'], multi_test_framework.Result.Fail)
  391. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_module_filename')
  392. def test_GetResultsUsingOutput_ModuleNotInLog_CreatesUnknownResult(self, mock_get_module):
  393. mock_get_module.return_value = 'different_module_name'
  394. mock_test_suite = multi_test_framework.MultiTestSuite()
  395. mock_test = mock.MagicMock()
  396. mock_test.__name__ = 'mock_test_name'
  397. mock_test_list = [mock_test]
  398. mock_output = 'JSON_START(' \
  399. '{"name": "mock_module_name", "output": "mock_std_out", "failed": "mock_fail_data"}' \
  400. ')JSON_END'
  401. results = mock_test_suite._get_results_using_output(mock_test_list, mock_output, '')
  402. assert len(results) == 1
  403. assert 'mock_test_name' in results.keys()
  404. assert isinstance(results['mock_test_name'], multi_test_framework.Result.Unknown)
  405. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_module_filename')
  406. def test_GetResultsUsingOutput_MultipleTests_CreatesCorrectResults(self, mock_get_module):
  407. mock_get_module.side_effect = ['mock_module_name_pass', 'mock_module_name_fail', 'different_module_name']
  408. mock_test_suite = multi_test_framework.MultiTestSuite()
  409. mock_test_pass = mock.MagicMock()
  410. mock_test_pass.__name__ = 'mock_test_name_pass'
  411. mock_test_fail = mock.MagicMock()
  412. mock_test_fail.__name__ = 'mock_test_name_fail'
  413. mock_test_unknown = mock.MagicMock()
  414. mock_test_unknown.__name__ = 'mock_test_name_unknown'
  415. mock_test_list = [mock_test_pass, mock_test_fail, mock_test_unknown]
  416. mock_output = 'JSON_START(' \
  417. '{"name": "mock_module_name_pass", "output": "mock_std_out", "success": "mock_success_data"}' \
  418. ')JSON_END' \
  419. 'JSON_START(' \
  420. '{"name": "mock_module_name_fail", "output": "mock_std_out", "failed": "mock_fail_data", "success": ""}' \
  421. ')JSON_END' \
  422. 'JSON_START(' \
  423. '{"name": "mock_module_name_unknown", "output": "mock_std_out", "failed": "mock_fail_data", "success": ""}' \
  424. ')JSON_END'
  425. mock_log_output = 'JSON_START(' \
  426. '{"name": "mock_module_name_pass"}' \
  427. ')JSON_END' \
  428. 'JSON_START(' \
  429. '{"name": "mock_module_name_fail"}' \
  430. ')JSON_END'
  431. results = mock_test_suite._get_results_using_output(mock_test_list, mock_output, mock_log_output)
  432. assert len(results) == 3
  433. assert 'mock_test_name_pass' in results.keys()
  434. assert 'mock_test_name_fail' in results.keys()
  435. assert 'mock_test_name_unknown' in results.keys()
  436. assert isinstance(results['mock_test_name_pass'], multi_test_framework.Result.Pass)
  437. assert isinstance(results['mock_test_name_fail'], multi_test_framework.Result.Fail)
  438. assert isinstance(results['mock_test_name_unknown'], multi_test_framework.Result.Unknown)
  439. @mock.patch('builtins.print')
  440. def test_ReportResult_TestPassed_ReportsCorrectly(self, mock_print):
  441. mock_test_name = 'mock name'
  442. mock_test_spec = mock.MagicMock()
  443. mock_output = 'mock_output'
  444. mock_log_output = 'mock_log_output'
  445. mock_pass = ly_test_tools.o3de.multi_test_framework.Result.Pass(mock_test_spec, mock_output, mock_log_output)
  446. ly_test_tools.o3de.multi_test_framework.MultiTestSuite._report_result(mock_test_name, mock_pass)
  447. mock_print.assert_called_with(
  448. f'Test {mock_test_name}:\nTest Passed\n------------\n'
  449. f'| Output |\n------------\n{mock_output}\n')
  450. @mock.patch('pytest.fail')
  451. def test_ReportResult_TestFailed_FailsCorrectly(self, mock_pytest_fail):
  452. mock_test_name = 'mock name'
  453. mock_test_spec = mock.MagicMock()
  454. mock_output = 'mock_output'
  455. mock_log_output = 'mock_log_output'
  456. mock_fail = ly_test_tools.o3de.multi_test_framework.Result.Fail(mock_test_spec, mock_output, mock_log_output)
  457. ly_test_tools.o3de.multi_test_framework.MultiTestSuite._report_result(mock_test_name, mock_fail)
  458. mock_pytest_fail.assert_called_with(
  459. f"Test {mock_test_name}:\n"
  460. "Test FAILED\n"
  461. "------------\n"
  462. f"| Output |\n"
  463. "------------\n"
  464. f"{mock_output}\n"
  465. "----------------------------------------------------\n"
  466. f"| Application log |\n"
  467. "----------------------------------------------------\n"
  468. f"{mock_log_output}\n")
  469. class TestRunningTests(unittest.TestCase):
  470. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_results_using_output')
  471. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_editor_log_content')
  472. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path')
  473. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath')
  474. @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report')
  475. @mock.patch('os.path.join', mock.MagicMock())
  476. def test_ExecSingleTest_TestSucceeds_ReturnsPass(self, mock_cycle_crash, mock_get_testcase_filepath,
  477. mock_retrieve_log, mock_retrieve_editor_log,
  478. mock_get_output_results):
  479. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  480. mock_workspace = mock.MagicMock()
  481. mock_workspace.paths.engine_root.return_value = ""
  482. mock_executable = mock.MagicMock()
  483. mock_test_spec = mock.MagicMock()
  484. mock_test_spec.__name__ = 'mock_test_name'
  485. mock_executable.get_returncode.return_value = 0
  486. mock_get_output_results.return_value = {}
  487. results = mock_test_suite._exec_single_test(
  488. mock.MagicMock(), mock_workspace, mock_executable, 0, 'mock_log_name', mock_test_spec, [])
  489. assert isinstance(results[mock_test_spec.__name__], multi_test_framework.Result.Pass)
  490. assert mock_cycle_crash.called
  491. assert mock_executable.start.called
  492. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_results_using_output')
  493. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_editor_log_content')
  494. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path')
  495. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath')
  496. @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report')
  497. @mock.patch('os.path.join', mock.MagicMock())
  498. def test_ExecSingleTest_TestFails_ReturnsFail(self, mock_cycle_crash, mock_get_testcase_filepath, mock_retrieve_log,
  499. mock_retrieve_editor_log, mock_get_output_results):
  500. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  501. mock_workspace = mock.MagicMock()
  502. mock_workspace.paths.engine_root.return_value = ""
  503. mock_executable = mock.MagicMock()
  504. mock_test_spec = mock.MagicMock()
  505. mock_test_spec.__name__ = 'mock_test_name'
  506. mock_executable.get_returncode.return_value = 15
  507. mock_get_output_results.return_value = {}
  508. results = mock_test_suite._exec_single_test(
  509. mock.MagicMock(), mock_workspace, mock_executable, 0, 'mock_log_name', mock_test_spec, [])
  510. assert isinstance(results[mock_test_spec.__name__], multi_test_framework.Result.Fail)
  511. assert mock_cycle_crash.called
  512. assert mock_executable.start.called
  513. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_crash_output')
  514. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_results_using_output')
  515. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_editor_log_content')
  516. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path')
  517. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath')
  518. @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report')
  519. @mock.patch('os.path.join', mock.MagicMock())
  520. @mock.patch('os.path.basename', mock.MagicMock())
  521. def test_ExecSingleTest_TestCrashes_ReturnsCrash(self, mock_cycle_crash, mock_get_testcase_filepath,
  522. mock_retrieve_log, mock_retrieve_editor_log,
  523. mock_get_output_results, mock_retrieve_crash):
  524. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  525. mock_workspace = mock.MagicMock()
  526. mock_workspace.paths.engine_root.return_value = ""
  527. mock_executable = mock.MagicMock()
  528. mock_test_spec = mock.MagicMock()
  529. mock_test_spec.__name__ = 'mock_test_name'
  530. mock_executable.get_returncode.return_value = 1
  531. mock_get_output_results.return_value = {}
  532. results = mock_test_suite._exec_single_test(
  533. mock.MagicMock(), mock_workspace, mock_executable, 0, 'mock_log_name', mock_test_spec, [])
  534. assert mock_cycle_crash.call_count == 2
  535. assert isinstance(results[mock_test_spec.__name__], multi_test_framework.Result.Crash)
  536. assert mock_executable.start.called
  537. assert mock_retrieve_crash.called
  538. # Save executable log output, crash log, and crash dmp
  539. assert mock_workspace.artifact_manager.save_artifact.call_count == 3
  540. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_results_using_output')
  541. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_editor_log_content')
  542. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path')
  543. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath')
  544. @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report')
  545. def test_ExecSingleTest_TestTimeout_ReturnsTimeout(self, mock_cycle_crash, mock_get_testcase_filepath,
  546. mock_retrieve_log, mock_retrieve_editor_log,
  547. mock_get_output_results):
  548. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  549. mock_workspace = mock.MagicMock()
  550. mock_workspace.paths.engine_root.return_value = ""
  551. mock_executable = mock.MagicMock()
  552. mock_test_spec = mock.MagicMock()
  553. mock_test_spec.__name__ = 'mock_test_name'
  554. mock_executable.wait.side_effect = ly_test_tools.launchers.exceptions.WaitTimeoutError()
  555. mock_get_output_results.return_value = {}
  556. results = mock_test_suite._exec_single_test(
  557. mock.MagicMock(), mock_workspace, mock_executable, 0, 'mock_log_name', mock_test_spec, [])
  558. assert isinstance(results[mock_test_spec.__name__], multi_test_framework.Result.Timeout)
  559. assert mock_cycle_crash.called
  560. assert mock_executable.start.called
  561. assert mock_executable.stop.called
  562. @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report')
  563. @mock.patch('os.unlink', mock.MagicMock())
  564. @mock.patch('tempfile.NamedTemporaryFile', mock.MagicMock())
  565. @mock.patch('os.path.join', mock.MagicMock())
  566. @mock.patch('os.path.splitext', mock.MagicMock())
  567. @mock.patch('os.path.dirname', mock.MagicMock())
  568. def test_ExecMultitest_AllTestsPass_ReturnsPasses(self, mock_cycle_crash):
  569. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  570. mock_workspace = mock.MagicMock()
  571. mock_artifact_manager = mock.MagicMock()
  572. mock_workspace.artifact_manager = mock_artifact_manager
  573. mock_workspace.paths.engine_root.return_value = ""
  574. mock_executable = mock.MagicMock()
  575. mock_executable.args = []
  576. mock_executable.get_returncode.return_value = 0
  577. mock_test_spec = mock.MagicMock()
  578. mock_test_spec.__name__ = 'mock_test_name'
  579. mock_test_spec_2 = mock.MagicMock()
  580. mock_test_spec_2.__name__ = 'mock_test_name_2'
  581. mock_test_spec_list = [mock_test_spec, mock_test_spec_2]
  582. mock_path_exists = mock.MagicMock()
  583. mock_path_exists.return_value = True
  584. with mock.patch('builtins.open', mock.mock_open(read_data="")) as mock_file:
  585. results = mock_test_suite._exec_multitest(
  586. mock.MagicMock(), mock_workspace, mock_executable, 0, 'mock_log_name', mock_test_spec_list, [])
  587. assert len(results) == 2
  588. assert isinstance(results['mock_test_name'], multi_test_framework.Result.Pass)
  589. assert isinstance(results['mock_test_name_2'], multi_test_framework.Result.Pass)
  590. assert mock_cycle_crash.called
  591. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_results_using_output')
  592. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath')
  593. @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report')
  594. @mock.patch('os.unlink', mock.MagicMock())
  595. @mock.patch('tempfile.NamedTemporaryFile', mock.MagicMock())
  596. @mock.patch('os.path.join', mock.MagicMock())
  597. @mock.patch('os.path.splitext', mock.MagicMock())
  598. @mock.patch('os.path.dirname', mock.MagicMock())
  599. def test_ExecMultitest_OneFailure_CallsCorrectFunc(
  600. self, mock_cycle_crash, mock_get_testcase_filepath, mock_get_results):
  601. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  602. mock_workspace = mock.MagicMock()
  603. mock_workspace.paths.engine_root.return_value = ""
  604. mock_executable = mock.MagicMock()
  605. mock_executable.get_returncode.return_value = 15
  606. mock_test_spec = mock.MagicMock()
  607. mock_test_spec_2 = mock.MagicMock()
  608. mock_test_spec_list = [mock_test_spec, mock_test_spec_2]
  609. mock_get_testcase_filepath.side_effect = ['mock_path', 'mock_path_2']
  610. mock_get_results.return_value = {'mock_test_name': mock.MagicMock(), 'mock_test_name_2': mock.MagicMock()}
  611. with mock.patch('builtins.open', mock.mock_open(read_data="")) as mock_file:
  612. results = mock_test_suite._exec_multitest(
  613. mock.MagicMock(), mock_workspace, mock_executable, 0, 'mock_log_name', mock_test_spec_list, [])
  614. assert len(results) == 2
  615. assert mock_cycle_crash.called
  616. assert mock_get_results.called
  617. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_crash_output')
  618. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_results_using_output')
  619. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_editor_log_content')
  620. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path')
  621. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath')
  622. @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report')
  623. @mock.patch('os.unlink', mock.MagicMock())
  624. @mock.patch('tempfile.NamedTemporaryFile', mock.MagicMock())
  625. @mock.patch('os.path.join', mock.MagicMock())
  626. @mock.patch('os.path.basename', mock.MagicMock())
  627. @mock.patch('os.path.dirname', mock.MagicMock())
  628. def test_ExecMultitest_OneCrash_ReportsOnUnknownResult(self, mock_cycle_crash, mock_get_testcase_filepath,
  629. mock_retrieve_log, mock_retrieve_editor_log,
  630. mock_get_results, mock_retrieve_crash):
  631. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  632. mock_workspace = mock.MagicMock()
  633. mock_workspace.paths.engine_root.return_value = ""
  634. mock_executable = mock.MagicMock()
  635. mock_executable.get_returncode.return_value = 1
  636. mock_test_spec = mock.MagicMock()
  637. mock_test_spec.__name__ = 'mock_test_name'
  638. mock_test_spec_2 = mock.MagicMock()
  639. mock_test_spec_2.__name__ = 'mock_test_name_2'
  640. mock_test_spec_list = [mock_test_spec, mock_test_spec_2]
  641. mock_unknown_result = ly_test_tools.o3de.multi_test_framework.Result.Unknown(test_spec=None)
  642. mock_unknown_result.test_spec = mock.MagicMock()
  643. mock_unknown_result.editor_log = mock.MagicMock()
  644. mock_get_testcase_filepath.side_effect = ['mock_path', 'mock_path_2']
  645. mock_get_results.return_value = {mock_test_spec.__name__: mock_unknown_result,
  646. mock_test_spec_2.__name__: mock.MagicMock()}
  647. results = mock_test_suite._exec_multitest(
  648. mock.MagicMock(), mock_workspace, mock_executable, 0, 'mock_log_name', mock_test_spec_list, [])
  649. assert mock_cycle_crash.call_count == 2
  650. assert mock_get_results.called
  651. assert isinstance(results[mock_test_spec.__name__], multi_test_framework.Result.Crash)
  652. # Save executable log output, crash log, and crash dmp
  653. assert mock_workspace.artifact_manager.save_artifact.call_count == 3
  654. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_crash_output')
  655. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_results_using_output')
  656. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_editor_log_content')
  657. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path')
  658. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath')
  659. @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report')
  660. @mock.patch('os.unlink', mock.MagicMock())
  661. @mock.patch('tempfile.NamedTemporaryFile', mock.MagicMock())
  662. @mock.patch('os.path.join', mock.MagicMock())
  663. @mock.patch('os.path.basename', mock.MagicMock())
  664. @mock.patch('os.path.dirname', mock.MagicMock())
  665. def test_ExecMultitest_ManyUnknown_ReportsUnknownResults(self, mock_cycle_crash, mock_get_testcase_filepath,
  666. mock_retrieve_log, mock_retrieve_editor_log,
  667. mock_get_results, mock_retrieve_crash):
  668. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  669. mock_workspace = mock.MagicMock()
  670. mock_workspace.paths.engine_root.return_value = ""
  671. mock_executable = mock.MagicMock()
  672. mock_executable.get_returncode.return_value = 1
  673. mock_test_spec = mock.MagicMock()
  674. mock_test_spec.__name__ = 'mock_test_name'
  675. mock_test_spec_2 = mock.MagicMock()
  676. mock_test_spec_2.__name__ = 'mock_test_name_2'
  677. mock_test_spec_list = [mock_test_spec, mock_test_spec_2]
  678. mock_unknown_result = ly_test_tools.o3de.multi_test_framework.Result.Unknown(test_spec=None)
  679. mock_unknown_result.__name__ = 'mock_test_name'
  680. mock_unknown_result.test_spec = mock.MagicMock()
  681. mock_unknown_result.test_spec.__name__ = 'mock_test_spec_name'
  682. mock_unknown_result.editor_log = mock.MagicMock()
  683. mock_get_testcase_filepath.side_effect = ['mock_path', 'mock_path_2']
  684. mock_get_results.return_value = {mock_test_spec.__name__: mock_unknown_result,
  685. mock_test_spec_2.__name__: mock_unknown_result}
  686. results = mock_test_suite._exec_multitest(
  687. mock.MagicMock(), mock_workspace, mock_executable, 0, 'mock_log_name', mock_test_spec_list, [])
  688. assert mock_cycle_crash.call_count == 2
  689. assert mock_get_results.called
  690. assert isinstance(results[mock_test_spec.__name__], multi_test_framework.Result.Crash)
  691. assert isinstance(results[mock_test_spec_2.__name__], multi_test_framework.Result.Unknown)
  692. assert results[mock_test_spec_2.__name__].extra_info, "Extra info missing from Unknown failure"
  693. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_results_using_output')
  694. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_editor_log_content')
  695. @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path')
  696. @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath')
  697. @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report')
  698. def test_ExecMultitest_EditorTimeout_ReportsCorrectly(self, mock_cycle_crash, mock_get_testcase_filepath,
  699. mock_retrieve_log, mock_retrieve_editor_log, mock_get_results):
  700. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  701. mock_workspace = mock.MagicMock()
  702. mock_workspace.paths.engine_root.return_value = ""
  703. mock_executable = mock.MagicMock()
  704. mock_executable.wait.side_effect = ly_test_tools.launchers.exceptions.WaitTimeoutError()
  705. mock_test_spec = mock.MagicMock()
  706. mock_test_spec.__name__ = 'mock_test_name'
  707. mock_test_spec_2 = mock.MagicMock()
  708. mock_test_spec_2.__name__ = 'mock_test_name_2'
  709. mock_test_spec_list = [mock_test_spec, mock_test_spec_2]
  710. mock_unknown_result = ly_test_tools.o3de.multi_test_framework.Result.Unknown(test_spec=None)
  711. mock_unknown_result.test_spec = mock.MagicMock()
  712. mock_unknown_result.test_spec.__name__ = 'mock_test_spec_name'
  713. mock_unknown_result.output = mock.MagicMock()
  714. mock_unknown_result.editor_log = mock.MagicMock()
  715. mock_get_testcase_filepath.side_effect = ['mock_path', 'mock_path_2']
  716. mock_get_results.return_value = {mock_test_spec.__name__: mock_unknown_result,
  717. mock_test_spec_2.__name__: mock_unknown_result}
  718. results = mock_test_suite._exec_multitest(
  719. mock.MagicMock(), mock_workspace, mock_executable, 0, 'mock_log_name', mock_test_spec_list, [])
  720. assert mock_cycle_crash.called
  721. assert mock_get_results.called
  722. assert isinstance(results[mock_test_spec.__name__], multi_test_framework.Result.Timeout)
  723. assert isinstance(results[mock_test_spec_2.__name__], multi_test_framework.Result.Unknown)
  724. assert results[mock_test_spec_2.__name__].extra_info, "Extra info missing from Unknown failure"
  725. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._report_result')
  726. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._exec_single_test')
  727. @mock.patch('ly_test_tools.o3de.editor_test_utils.save_failed_asset_joblogs', mock.MagicMock())
  728. def test_RunSingleTest_ValidTest_ReportsResults(self, mock_exec_single_test, mock_report_result):
  729. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  730. mock_request = mock.MagicMock()
  731. mock_workspace = mock.MagicMock()
  732. mock_collected_test_data = mock.MagicMock()
  733. mock_test_spec = mock.MagicMock()
  734. mock_result = mock.MagicMock()
  735. mock_test_name = 'mock_test_result'
  736. mock_exec_single_test.return_value = {mock_test_name: mock_result}
  737. mock_test_suite._run_single_test(
  738. mock_request, mock_workspace, mock_collected_test_data, mock_test_spec)
  739. assert mock_exec_single_test.called
  740. assert mock_collected_test_data.results.update.called
  741. mock_report_result.assert_called_with(mock_test_name, mock_result)
  742. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._test_reporting')
  743. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._exec_multitest')
  744. def test_RunBatchedTests_ValidTests_CallsCorrectly(self, mock_exec_multitest, mock_reporting):
  745. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  746. mock_test_suite.atom_tools_executable_name = "dummy_executable"
  747. mock_request = mock.MagicMock()
  748. mock_workspace = mock.MagicMock()
  749. mock_collected_test_data = mock.MagicMock()
  750. mock_test_spec_list = mock.MagicMock()
  751. mock_extra_cmdline_args = [""]
  752. mock_test_suite._run_batched_tests(
  753. mock_request, mock_workspace, mock_collected_test_data, mock_test_spec_list, mock_extra_cmdline_args)
  754. assert mock_exec_multitest.called
  755. assert mock_reporting.called
  756. assert type(mock_test_suite.executable) in [WinAtomToolsLauncher, LinuxAtomToolsLauncher]
  757. assert mock_test_suite.executable.workspace == mock_workspace
  758. @mock.patch('threading.Thread')
  759. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_number_parallel_executables')
  760. @mock.patch('ly_test_tools.o3de.editor_test_utils.save_failed_asset_joblogs', mock.MagicMock())
  761. def test_RunParallelTests_TwoTestsAndExecutables_TwoThreads(self, mock_get_number_executables, mock_thread):
  762. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  763. mock_request = mock.MagicMock()
  764. mock_workspace = mock.MagicMock()
  765. mock_collected_test_data = mock.MagicMock()
  766. mock_extra_cmdline_args = [""]
  767. mock_get_number_executables.return_value = 2
  768. mock_test_spec_list = [mock.MagicMock(), mock.MagicMock()]
  769. mock_test_suite._run_parallel_tests(
  770. mock_request, mock_workspace, mock_collected_test_data, mock_test_spec_list, mock_extra_cmdline_args)
  771. assert mock_collected_test_data.results.update.call_count == len(mock_test_spec_list)
  772. assert mock_thread.call_count == len(mock_test_spec_list)
  773. @mock.patch('threading.Thread')
  774. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_number_parallel_executables')
  775. @mock.patch('ly_test_tools.o3de.editor_test_utils.save_failed_asset_joblogs', mock.MagicMock())
  776. def test_RunParallelTests_TenTestsAndTwoExecutables_TenThreads(self, mock_get_number_executables, mock_thread):
  777. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  778. mock_request = mock.MagicMock()
  779. mock_workspace = mock.MagicMock()
  780. mock_collected_test_data = mock.MagicMock()
  781. mock_extra_cmdline_args = [""]
  782. mock_get_number_executables.return_value = 2
  783. mock_test_spec_list = []
  784. for i in range(10):
  785. mock_test_spec_list.append(mock.MagicMock())
  786. mock_test_suite._run_parallel_tests(
  787. mock_request, mock_workspace, mock_collected_test_data, mock_test_spec_list, mock_extra_cmdline_args)
  788. assert mock_collected_test_data.results.update.call_count == len(mock_test_spec_list)
  789. assert mock_thread.call_count == len(mock_test_spec_list)
  790. @mock.patch('threading.Thread')
  791. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_number_parallel_executables')
  792. @mock.patch('ly_test_tools.o3de.editor_test_utils.save_failed_asset_joblogs', mock.MagicMock())
  793. def test_RunParallelTests_TenTestsAndThreeEditors_TenThreads(self, mock_get_number_executables, mock_thread):
  794. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  795. mock_request = mock.MagicMock()
  796. mock_workspace = mock.MagicMock()
  797. mock_collected_test_data = mock.MagicMock()
  798. mock_extra_cmdline_args = [""]
  799. mock_get_number_executables.return_value = 3
  800. mock_test_spec_list = []
  801. for i in range(10):
  802. mock_test_spec_list.append(mock.MagicMock())
  803. mock_test_suite._run_parallel_tests(
  804. mock_request, mock_workspace, mock_collected_test_data, mock_test_spec_list, mock_extra_cmdline_args)
  805. assert mock_collected_test_data.results.update.call_count == len(mock_test_spec_list)
  806. assert mock_thread.call_count == len(mock_test_spec_list)
  807. @mock.patch('threading.Thread')
  808. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_number_parallel_executables')
  809. @mock.patch('ly_test_tools.o3de.editor_test_utils.save_failed_asset_joblogs', mock.MagicMock())
  810. def test_RunParallelBatchedTests_TwoTestsAndEditors_TwoThreads(self, mock_get_number_executables, mock_thread):
  811. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  812. mock_request = mock.MagicMock()
  813. mock_workspace = mock.MagicMock()
  814. mock_collected_test_data = mock.MagicMock()
  815. mock_extra_cmdline_args = [""]
  816. mock_get_number_executables.return_value = 2
  817. mock_test_spec_list = [mock.MagicMock(), mock.MagicMock()]
  818. mock_test_suite._run_parallel_batched_tests(
  819. mock_request, mock_workspace, mock_collected_test_data, mock_test_spec_list, mock_extra_cmdline_args)
  820. assert mock_collected_test_data.results.update.call_count == len(mock_test_spec_list)
  821. assert mock_thread.call_count == len(mock_test_spec_list)
  822. @mock.patch('threading.Thread')
  823. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_number_parallel_executables')
  824. @mock.patch('ly_test_tools.o3de.editor_test_utils.save_failed_asset_joblogs', mock.MagicMock())
  825. def test_RunParallelBatchedTests_TenTestsAndTwoEditors_2Threads(self, mock_get_number_executables, mock_thread):
  826. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  827. mock_request = mock.MagicMock()
  828. mock_workspace = mock.MagicMock()
  829. mock_collected_test_data = mock.MagicMock()
  830. mock_extra_cmdline_args = [""]
  831. mock_get_number_executables.return_value = 2
  832. mock_test_spec_list = []
  833. for i in range(10):
  834. mock_test_spec_list.append(mock.MagicMock())
  835. mock_test_suite._run_parallel_batched_tests(
  836. mock_request, mock_workspace, mock_collected_test_data, mock_test_spec_list, mock_extra_cmdline_args)
  837. assert mock_collected_test_data.results.update.call_count == 2
  838. assert mock_thread.call_count == 2
  839. @mock.patch('threading.Thread')
  840. @mock.patch('ly_test_tools.o3de.multi_test_framework.MultiTestSuite._get_number_parallel_executables')
  841. @mock.patch('ly_test_tools.o3de.editor_test_utils.save_failed_asset_joblogs', mock.MagicMock())
  842. def test_RunParallelBatchedTests_TenTestsAndThreeEditors_ThreeThreads(
  843. self, mock_get_number_executables, mock_thread):
  844. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  845. mock_request = mock.MagicMock()
  846. mock_workspace = mock.MagicMock()
  847. mock_collected_test_data = mock.MagicMock()
  848. mock_extra_cmdline_args = [""]
  849. mock_get_number_executables.return_value = 3
  850. mock_test_spec_list = []
  851. for i in range(10):
  852. mock_test_spec_list.append(mock.MagicMock())
  853. mock_test_suite._run_parallel_batched_tests(
  854. mock_request, mock_workspace, mock_collected_test_data, mock_test_spec_list, mock_extra_cmdline_args)
  855. assert mock_collected_test_data.results.update.call_count == 3
  856. assert mock_thread.call_count == 3
  857. def test_GetNumberParallelEditors_ConfigExists_ReturnsConfig(self):
  858. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  859. mock_request = mock.MagicMock()
  860. mock_request.config.getoption.return_value = 1
  861. number_of_executables = mock_test_suite._get_number_parallel_executables(mock_request)
  862. assert number_of_executables == 1
  863. def test_GetNumberParallelEditors_ConfigNotExists_ReturnsDefault(self):
  864. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  865. mock_request = mock.MagicMock()
  866. mock_request.config.getoption.return_value = None
  867. number_of_executables = mock_test_suite._get_number_parallel_executables(mock_request)
  868. assert number_of_executables == mock_test_suite.get_number_parallel_executables()
  869. @mock.patch('ly_test_tools.o3de.editor_test_utils.kill_all_ly_processes')
  870. @mock.patch('ly_test_tools.o3de.editor_test_utils.prepare_asset_processor')
  871. @mock.patch('ly_test_tools.launchers.launcher_helper.create_editor')
  872. @mock.patch('ly_test_tools.launchers.launcher_helper.create_atom_tools_launcher')
  873. def test_SetupTest_AtomExe_SetsExecutable(self, mock_create_atom, mock_create_editor, mock_prepare_ap,
  874. mock_kill_processes):
  875. mock_workspace = mock.MagicMock()
  876. mock_exe = 'mock_atom_exe'
  877. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  878. mock_test_suite.atom_tools_executable_name = mock_exe
  879. mock_test_suite.executable = mock.MagicMock()
  880. mock_test_suite._setup_test(mock_workspace, mock.MagicMock())
  881. mock_create_atom.assert_called_once_with(mock_workspace, mock_exe)
  882. assert not mock_create_editor.called
  883. assert mock_prepare_ap.called
  884. assert mock_kill_processes.called
  885. assert mock_test_suite.executable.configure_settings.called
  886. @mock.patch('ly_test_tools.o3de.editor_test_utils.kill_all_ly_processes')
  887. @mock.patch('ly_test_tools.o3de.editor_test_utils.prepare_asset_processor')
  888. @mock.patch('ly_test_tools.launchers.launcher_helper.create_editor')
  889. @mock.patch('ly_test_tools.launchers.launcher_helper.create_atom_tools_launcher')
  890. def test_SetupTest_EditorExe_SetsExecutable(self, mock_create_atom, mock_create_editor, mock_prepare_ap,
  891. mock_kill_processes):
  892. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  893. mock_test_suite.atom_tools_executable_name = None
  894. mock_test_suite.executable = mock.MagicMock()
  895. mock_test_suite._setup_test(mock.MagicMock(), mock.MagicMock())
  896. assert not mock_create_atom.called
  897. assert mock_create_editor.called
  898. assert mock_prepare_ap.called
  899. assert mock_kill_processes.called
  900. assert mock_test_suite.executable.configure_settings.called
  901. @mock.patch('ly_test_tools.o3de.editor_test_utils.save_failed_asset_joblogs')
  902. def test_TestReporting_AllPassResults_NoSaveLogs(self, mock_save_logs):
  903. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  904. mock_collected_test_data = mock.MagicMock()
  905. mock_pass = multi_test_framework.Result.Pass(mock.MagicMock(), mock.MagicMock(), mock.MagicMock())
  906. mock_results = [mock_pass]
  907. mock_test_suite._test_reporting(mock_collected_test_data, mock_results, mock.MagicMock(), mock.MagicMock())
  908. assert not mock_save_logs.called
  909. assert mock_collected_test_data.results.update.called
  910. @mock.patch('ly_test_tools.o3de.editor_test_utils.save_failed_asset_joblogs')
  911. def test_TestReporting_UnknownResults_SaveLogs(self, mock_save_logs):
  912. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  913. mock_collected_test_data = mock.MagicMock()
  914. mock_results = [None]
  915. mock_test_suite._test_reporting(mock_collected_test_data, mock_results, mock.MagicMock(), mock.MagicMock())
  916. assert mock_save_logs.called
  917. assert mock_collected_test_data.results.update.called
  918. @mock.patch('ly_test_tools.o3de.editor_test_utils.save_failed_asset_joblogs')
  919. def test_TestReporting_BothResults_SaveLogs(self, mock_save_logs):
  920. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  921. mock_collected_test_data = mock.MagicMock()
  922. mock_pass = multi_test_framework.Result.Pass(mock.MagicMock(), mock.MagicMock(), mock.MagicMock())
  923. mock_results = [mock_pass, None]
  924. mock_test_suite._test_reporting(mock_collected_test_data, mock_results, mock.MagicMock(), mock.MagicMock())
  925. assert mock_save_logs.called
  926. assert mock_collected_test_data.results.update.called
  927. @mock.patch('ly_test_tools.o3de.editor_test_utils.save_failed_asset_joblogs')
  928. def test_TestReporting_ManyResults_SaveLogs(self, mock_save_logs):
  929. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  930. mock_collected_test_data = mock.MagicMock()
  931. mock_pass = multi_test_framework.Result.Pass(mock.MagicMock(), mock.MagicMock(), mock.MagicMock())
  932. mock_fail = multi_test_framework.Result.Fail(mock.MagicMock(), mock.MagicMock(), mock.MagicMock())
  933. mock_results = [mock_pass, mock_fail, None]
  934. mock_test_suite._test_reporting(mock_collected_test_data, mock_results, mock.MagicMock(), mock.MagicMock())
  935. assert mock_save_logs.called
  936. assert mock_collected_test_data.results.update.called
  937. def test_SetupCmdlineArgs_EditorExe_EnablesPrefab(self):
  938. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  939. mock_executable = WinEditor(mock.MagicMock(), [])
  940. mock_test_spec_list = mock.MagicMock()
  941. under_test = mock_test_suite._setup_cmdline_args(None, mock_executable, mock_test_spec_list, mock.MagicMock())
  942. assert "--regset=/Amazon/Preferences/EnablePrefabSystem=true" in under_test
  943. assert "-rhi=null" in under_test
  944. assert "--attach-debugger" not in under_test
  945. assert "--wait-for-debugger" not in under_test
  946. def test_SetupCmdlineArgs_AtomExe_NotEnablesPrefab(self):
  947. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  948. mock_executable = WinAtomToolsLauncher(mock.MagicMock(), [])
  949. mock_test_spec_list = mock.MagicMock()
  950. under_test = mock_test_suite._setup_cmdline_args(None, mock_executable, mock_test_spec_list, mock.MagicMock())
  951. assert "--regset=/Amazon/Preferences/EnablePrefabSystem=true" not in under_test
  952. assert "-rhi=null" in under_test
  953. assert "--attach-debugger" not in under_test
  954. assert "--wait-for-debugger" not in under_test
  955. def test_SetupCmdlineArgs_Debugger_EnablesDebugger(self):
  956. mock_test_suite = ly_test_tools.o3de.multi_test_framework.MultiTestSuite()
  957. mock_executable = WinAtomToolsLauncher(mock.MagicMock(), [])
  958. mock_test_spec = mock.MagicMock()
  959. mock_test_spec.attach_debugger = True
  960. mock_test_spec.wait_for_debugger = True
  961. mock_test_spec_list = [mock_test_spec]
  962. under_test = mock_test_suite._setup_cmdline_args(None, mock_executable, mock_test_spec_list, mock.MagicMock())
  963. assert "--regset=/Amazon/Preferences/EnablePrefabSystem=true" not in under_test
  964. assert "-rhi=null" in under_test
  965. assert "--attach-debugger" in under_test
  966. assert "--wait-for-debugger" in under_test
  967. @mock.patch('_pytest.python.Class.collect')
  968. class TestMultiTestCollector(unittest.TestCase):
  969. def setUp(self):
  970. mock_name = mock.MagicMock()
  971. mock_collector = mock.MagicMock()
  972. self.mock_test_class = ly_test_tools.o3de.multi_test_framework.MultiTestSuite.MultiTestCollector.from_parent(
  973. name=mock_name, parent=mock_collector)
  974. self.mock_test_class.obj = mock.MagicMock()
  975. single_1 = mock.MagicMock()
  976. single_1.__name__ = 'single_1_name'
  977. single_2 = mock.MagicMock()
  978. single_2.__name__ = 'single_2_name'
  979. self.mock_test_class.obj.get_single_tests.return_value = [single_1, single_2]
  980. batch_1 = mock.MagicMock()
  981. batch_1.__name__ = 'batch_1_name'
  982. batch_2 = mock.MagicMock()
  983. batch_2.__name__ = 'batch_2_name'
  984. parallel_1 = mock.MagicMock()
  985. parallel_1.__name__ = 'parallel_1_name'
  986. parallel_2 = mock.MagicMock()
  987. parallel_2.__name__ = 'parallel_2_name'
  988. both_1 = mock.MagicMock()
  989. both_1.__name__ = 'both_1_name'
  990. both_2 = mock.MagicMock()
  991. both_2.__name__ = 'both_2_name'
  992. self.mock_test_class.obj.filter_shared_tests.side_effect = [ [batch_1, batch_2],
  993. [parallel_1, parallel_2],
  994. [both_1, both_2] ]
  995. def test_Collect_NoParallelNoBatched_RunsAsSingleTests(self, mock_collect):
  996. self.mock_test_class.config.getoption.return_value = True
  997. self.mock_test_class.collect()
  998. assert self.mock_test_class.obj.single_1_name.__name__ == 'single_run'
  999. assert self.mock_test_class.obj.single_2_name.__name__ == 'single_run'
  1000. assert self.mock_test_class.obj.batch_1_name.__name__ == 'single_run'
  1001. assert self.mock_test_class.obj.batch_2_name.__name__ == 'single_run'
  1002. assert self.mock_test_class.obj.parallel_1_name.__name__ == 'single_run'
  1003. assert self.mock_test_class.obj.parallel_2_name.__name__ == 'single_run'
  1004. assert self.mock_test_class.obj.both_1_name.__name__ == 'single_run'
  1005. assert self.mock_test_class.obj.both_2_name.__name__ == 'single_run'
  1006. def test_Collect_AllValidTests_RunsAsInteded(self, mock_collect):
  1007. self.mock_test_class.config.getoption.return_value = False
  1008. self.mock_test_class.collect()
  1009. assert self.mock_test_class.obj.single_1_name.__name__ == 'single_run'
  1010. assert self.mock_test_class.obj.single_2_name.__name__ == 'single_run'
  1011. assert self.mock_test_class.obj.batch_1_name.__name__ == 'result'
  1012. assert self.mock_test_class.obj.batch_2_name.__name__ == 'result'
  1013. assert self.mock_test_class.obj.parallel_1_name.__name__ == 'result'
  1014. assert self.mock_test_class.obj.parallel_2_name.__name__ == 'result'
  1015. assert self.mock_test_class.obj.both_1_name.__name__ == 'result'
  1016. assert self.mock_test_class.obj.both_2_name.__name__ == 'result'
  1017. def test_Collect_AllValidTests_CallsCollect(self, mock_collect):
  1018. self.mock_test_class.collect()
  1019. assert mock_collect.called
  1020. def test_Collect_NormalCollection_ReturnsFilteredRuns(self, mock_collect):
  1021. mock_run = mock.MagicMock()
  1022. mock_run.obj.marks = {"run_type": 'run_shared'}
  1023. mock_run_2 = mock.MagicMock()
  1024. mock_run_2.obj.marks = {"run_type": 'result'}
  1025. mock_collect.return_value = [mock_run_2]
  1026. collection = self.mock_test_class.collect()
  1027. assert collection == [mock_run_2]
  1028. def test_Collect_NormalRun_ReturnsRunners(self, mock_collect):
  1029. self.mock_test_class.collect()
  1030. runners = self.mock_test_class.obj._runners
  1031. assert runners[0].name == 'run_batched_tests'
  1032. assert runners[1].name == 'run_parallel_tests'
  1033. assert runners[2].name == 'run_parallel_batched_tests'
  1034. def test_Collect_NormalCollection_StoresRunners(self, mock_collect):
  1035. mock_runner = mock.MagicMock()
  1036. mock_run = mock.MagicMock()
  1037. mock_run.obj.marks = {"run_type": 'run_shared'}
  1038. mock_run.function.marks = {"runner": mock_runner}
  1039. mock_runner_2 = mock.MagicMock()
  1040. mock_runner_2.result_pytestfuncs = []
  1041. mock_run_2 = mock.MagicMock()
  1042. mock_run_2.obj.marks = {"run_type": 'result'}
  1043. mock_run_2.function.marks = {"runner": mock_runner_2}
  1044. mock_collect.return_value = [mock_run_2]
  1045. self.mock_test_class.collect()
  1046. assert mock_run_2 in mock_runner_2.result_pytestfuncs
  1047. @mock.patch('ly_test_tools.o3de.multi_test_framework.isinstance', mock.MagicMock())
  1048. @mock.patch('ly_test_tools.o3de.multi_test_framework.issubclass', mock.MagicMock())
  1049. def test_MakeSingleRun_SingleRun_SetupTeardown(self, mock_collect):
  1050. mock_inner_test_spec = mock.MagicMock()
  1051. mock_self = mock.MagicMock()
  1052. mock_single_run_func = multi_test_framework.MultiTestSuite.MultiTestCollector._make_single_run(
  1053. mock_inner_test_spec)
  1054. mock_single_run_func(mock_self, mock.MagicMock(), mock.MagicMock(), mock.MagicMock(), mock.MagicMock())
  1055. mock_inner_test_spec.setup.assert_called_once()
  1056. mock_inner_test_spec.teardown.assert_called_once()
  1057. mock_self._run_single_test.assert_called_once()
  1058. @mock.patch('ly_test_tools.o3de.multi_test_framework.isinstance', mock.MagicMock(return_value=False))
  1059. @mock.patch('ly_test_tools.o3de.multi_test_framework.issubclass', mock.MagicMock(return_value=False))
  1060. def test_MakeSingleRun_NoSingleRun_NoSetupTeardown(self, mock_collect):
  1061. mock_inner_test_spec = mock.MagicMock()
  1062. mock_self = mock.MagicMock()
  1063. mock_single_run_func = multi_test_framework.MultiTestSuite.MultiTestCollector._make_single_run(
  1064. mock_inner_test_spec)
  1065. mock_single_run_func(mock_self, mock.MagicMock(), mock.MagicMock(), mock.MagicMock(), mock.MagicMock())
  1066. assert not mock_inner_test_spec.setup.called
  1067. assert not mock_inner_test_spec.teardown.called
  1068. mock_self._run_single_test.assert_called_once()
  1069. def test_CreateRunner_HappyPath_SetsRunnersProperly(self, mock_collect):
  1070. mock_runner_name = 'mock_runner_name'
  1071. mock_function = mock.MagicMock()
  1072. mock_shared_test_spec_1 = mock.MagicMock()
  1073. mock_shared_test_spec_1.__name__ = 'mock_shared_test_spec_1'
  1074. mock_shared_test_spec_2 = mock.MagicMock()
  1075. mock_shared_test_spec_2.__name__ = 'mock_shared_test_spec_2'
  1076. mock_tests = [mock_shared_test_spec_1, mock_shared_test_spec_2]
  1077. mock_obj = mock.MagicMock()
  1078. multi_test_framework.MultiTestSuite.MultiTestCollector._create_runner(mock_runner_name, mock_function,
  1079. mock_tests, mock_obj)
  1080. assert hasattr(mock_obj, mock_runner_name)
  1081. assert hasattr(mock_obj, mock_shared_test_spec_1.__name__)
  1082. assert hasattr(mock_obj, mock_shared_test_spec_2.__name__)
  1083. def test_CreateRunner_MakeSharedRun_CallsAttributeFunc(self, mock_collect):
  1084. mock_runner_name = 'mock_runner_name'
  1085. mock_obj = mock.MagicMock()
  1086. mock_function = mock.MagicMock()
  1087. mock_function.__name__ = 'mock_func_name'
  1088. mock_tests = []
  1089. mock_request = mock.MagicMock()
  1090. mock_workspace = mock.MagicMock()
  1091. mock_collected_test_data = mock.MagicMock()
  1092. multi_test_framework.MultiTestSuite.MultiTestCollector._create_runner(mock_runner_name, mock_function,
  1093. mock_tests, mock_obj)
  1094. getattr(mock_obj, mock_runner_name)(mock_obj, mock_request, mock_workspace, mock_collected_test_data,
  1095. mock.MagicMock())
  1096. mock_obj.mock_func_name.assert_called_once_with(mock_request, mock_workspace, mock_collected_test_data,
  1097. mock_tests)
  1098. def test_CreateRunner_MakeResultsRun_CallsAttributeFunc(self, mock_collect):
  1099. mock_runner_name = 'mock_runner_name'
  1100. mock_obj = mock.MagicMock()
  1101. mock_function = mock.MagicMock()
  1102. mock_shared_test_spec_1 = mock.MagicMock()
  1103. mock_shared_test_spec_1.__name__ = 'mock_shared_test_spec_name_1'
  1104. mock_shared_test_spec_2 = mock.MagicMock()
  1105. mock_shared_test_spec_2.__name__ = 'mock_shared_test_spec_name_2'
  1106. mock_tests = [mock_shared_test_spec_1, mock_shared_test_spec_2]
  1107. mock_collected_test_data = mock.MagicMock()
  1108. mock_result_1 = mock.MagicMock()
  1109. mock_result_2 = mock.MagicMock()
  1110. mock_collected_test_data.results = {mock_shared_test_spec_1.__name__: mock_result_1,
  1111. mock_shared_test_spec_2.__name__: mock_result_2}
  1112. multi_test_framework.MultiTestSuite.MultiTestCollector._create_runner(mock_runner_name, mock_function,
  1113. mock_tests, mock_obj)
  1114. getattr(mock_obj, mock_shared_test_spec_1.__name__)(mock_obj, mock.MagicMock(), mock.MagicMock(),
  1115. mock_collected_test_data, mock.MagicMock())
  1116. mock_obj._report_result.assert_called_with(mock_shared_test_spec_1.__name__, mock_result_1)
  1117. getattr(mock_obj, mock_shared_test_spec_2.__name__)(mock_obj, mock.MagicMock(), mock.MagicMock(),
  1118. mock_collected_test_data, mock.MagicMock())
  1119. mock_obj._report_result.assert_called_with(mock_shared_test_spec_2.__name__, mock_result_2)