test_asset_processor.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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. Unit tests for ly_test_tools.o3de.asset_processor
  6. """
  7. import datetime
  8. import unittest.mock as mock
  9. import os
  10. import pytest
  11. import ly_test_tools._internal.managers.workspace
  12. import ly_test_tools._internal.managers.abstract_resource_locator
  13. import ly_test_tools.o3de.asset_processor
  14. pytestmark = pytest.mark.SUITE_smoke
  15. mock_initial_path = "mock_initial_path"
  16. mock_engine_root = "mock_engine_root"
  17. mock_dev_path = "mock_dev_path"
  18. mock_build_directory = 'mock_build_directory'
  19. mock_project = 'mock_project'
  20. mock_project_path = os.path.join('some', 'dir', mock_project)
  21. @mock.patch('ly_test_tools._internal.managers.abstract_resource_locator.os.path.abspath',
  22. mock.MagicMock(return_value=mock_initial_path))
  23. @mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_engine_root',
  24. mock.MagicMock(return_value=(mock_engine_root, mock_dev_path)))
  25. @mock.patch('ly_test_tools.o3de.asset_processor.logger.warning', mock.MagicMock())
  26. class TestAssetProcessor(object):
  27. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  28. def test_Init_DefaultParams_MembersSetCorrectly(self, mock_workspace):
  29. under_test = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  30. assert under_test._workspace == mock_workspace
  31. assert under_test._port is not None
  32. assert under_test._ap_proc is None
  33. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  34. @mock.patch('subprocess.Popen')
  35. @mock.patch('ly_test_tools.o3de.asset_processor.AssetProcessor.connect_socket')
  36. @mock.patch('ly_test_tools.o3de.asset_processor.ASSET_PROCESSOR_PLATFORM_MAP', {'foo': 'bar'})
  37. @mock.patch('time.sleep', mock.MagicMock())
  38. @mock.patch('tempfile.TemporaryDirectory', mock.MagicMock())
  39. def test_Start_NoneRunning_ProcStarted(self, mock_connect, mock_popen, mock_workspace):
  40. mock_ap_path = 'mock_ap_path'
  41. mock_workspace.asset_processor_platform = 'foo'
  42. mock_workspace.paths.asset_processor.return_value = mock_ap_path
  43. mock_workspace.project = mock_project
  44. mock_workspace.paths.project.return_value = mock_project_path
  45. under_test = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  46. under_test.enable_asset_processor_platform = mock.MagicMock()
  47. under_test.wait_for_idle = mock.MagicMock()
  48. mock_proc_object = mock.MagicMock()
  49. mock_proc_object.poll.return_value = None
  50. mock_popen.return_value = mock_proc_object
  51. under_test.start(connect_to_ap=True)
  52. assert under_test._ap_proc is not None
  53. mock_popen.assert_called_once()
  54. assert '--zeroAnalysisMode' in mock_popen.call_args[0][0]
  55. mock_connect.assert_called()
  56. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  57. @mock.patch('subprocess.Popen')
  58. @mock.patch('os.path.basename', mock.MagicMock(return_value=""))
  59. @mock.patch('os.path.dirname', mock.MagicMock(return_value=""))
  60. @mock.patch('ly_test_tools.environment.process_utils.kill_processes_with_name_not_started_from',
  61. mock.MagicMock(return_value=None))
  62. @mock.patch('ly_test_tools.environment.process_utils.process_exists', mock.MagicMock(return_value=True))
  63. @mock.patch('socket.socket.connect')
  64. def test_Start_ProcAlreadyRunning_ProcNotChanged(self, mock_connect, mock_popen, mock_workspace):
  65. under_test = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  66. under_test.process_exists = mock.MagicMock(return_value=True)
  67. under_test.asset_processor_platform = mock.MagicMock(return_value=ly_test_tools.HOST_OS_PLATFORM)
  68. mock_proc = mock.MagicMock()
  69. under_test._ap_proc = mock_proc
  70. under_test.start(connect_to_ap=True)
  71. assert under_test._ap_proc == mock_proc
  72. mock_popen.assert_not_called()
  73. mock_connect.assert_not_called()
  74. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  75. @mock.patch('ly_test_tools.o3de.asset_processor.waiter.wait_for')
  76. def test_Stop_ProcAlreadyRunning_ProcStopped(self, mock_waiter, mock_workspace):
  77. under_test = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  78. under_test.get_process_list = mock.MagicMock(return_value=[mock.MagicMock()])
  79. under_test._control_connection = mock.MagicMock()
  80. under_test.get_pid = mock.MagicMock(return_value=0)
  81. under_test.send_quit = mock.MagicMock(return_value=True)
  82. mock_proc = mock.MagicMock()
  83. under_test._ap_proc = mock_proc
  84. under_test.stop()
  85. under_test.send_quit.assert_called_once()
  86. mock_waiter.assert_called_once()
  87. assert under_test._ap_proc is None
  88. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  89. @mock.patch('ly_test_tools.o3de.asset_processor.waiter.wait_for')
  90. @pytest.mark.test_case_id('NOT_RUNNING')
  91. @pytest.mark.test_case_id('NO_CONTROL')
  92. @pytest.mark.test_case_id('NO_QUIT')
  93. @pytest.mark.test_case_id('IO_ERROR')
  94. @pytest.mark.test_case_id('TIMEOUT')
  95. @pytest.mark.test_case_id('NO_STOP')
  96. @pytest.mark.parametrize(
  97. "test_id,_ap_proc,_control_connection,send_quit,timesout,no_stop",
  98. [
  99. ('NOT_RUNNING', None, None, False, 0, False),
  100. ('NO_CONTROL', mock.MagicMock(), None, False, 0, False),
  101. ('NO_QUIT', mock.MagicMock(), mock.MagicMock(), mock.MagicMock(return_value=False), 0, False),
  102. ('IO_ERROR',
  103. mock.MagicMock(), mock.MagicMock(), mock.MagicMock(return_value=False, side_effect=IOError), 0, False),
  104. ('TIMEOUT', mock.MagicMock(), mock.MagicMock(), mock.MagicMock(return_value=True), 0, False),
  105. ('NO_STOP', mock.MagicMock(), mock.MagicMock(), mock.MagicMock(return_value=True), 0, True),
  106. ],
  107. )
  108. def test_Stop_ReturnsStopReason(self, mock_waiter, mock_workspace, test_id, _ap_proc, _control_connection,
  109. send_quit, timesout, no_stop):
  110. AssetProcessorError = ly_test_tools.o3de.asset_processor.AssetProcessorError
  111. StopProcess = ly_test_tools.o3de.asset_processor.StopReason
  112. ly_test_tools.environment.waiter.wait_for = mock.MagicMock(side_effect=AssetProcessorError)
  113. under_test = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  114. if _ap_proc:
  115. under_test.get_process_list = mock.MagicMock(return_value=[mock.MagicMock()])
  116. else:
  117. under_test.get_process_list = None
  118. under_test._ap_proc = _ap_proc
  119. under_test._control_connection = _control_connection
  120. under_test.send_quit = send_quit
  121. if no_stop:
  122. under_test.process_exists = mock.MagicMock()
  123. under_test.stop(timeout=timesout) == StopProcess.__getattr__(test_id)
  124. else:
  125. assert under_test.stop(timeout=timesout) == StopProcess.__getattr__(test_id)
  126. assert under_test._ap_proc is None
  127. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  128. @mock.patch('subprocess.run')
  129. @mock.patch('tempfile.TemporaryDirectory', mock.MagicMock())
  130. def test_BatchProcess_NoFastscanBatchCompletes_Success(self, mock_run, mock_workspace):
  131. mock_workspace.project = None
  132. mock_workspace.paths.project.return_value = mock_project_path
  133. under_test = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  134. apb_path = mock_workspace.paths.asset_processor_batch()
  135. mock_run.return_value.returncode = 0
  136. result, _ = under_test.batch_process(1, False)
  137. assert result
  138. mock_run.assert_called_once_with([apb_path,
  139. f'--regset="/Amazon/AzCore/Bootstrap/project_path={mock_project_path}"',
  140. '--logDir', f'{under_test.log_root()}'],
  141. close_fds=True,
  142. capture_output=False,
  143. timeout=1)
  144. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  145. @mock.patch('subprocess.run')
  146. @mock.patch('tempfile.TemporaryDirectory', mock.MagicMock())
  147. def test_BatchProcess_FastscanBatchCompletes_Success(self, mock_run, mock_workspace):
  148. mock_workspace.project = mock_project
  149. mock_workspace.paths.project.return_value = mock_project_path
  150. under_test = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  151. apb_path = mock_workspace.paths.asset_processor_batch()
  152. mock_run.return_value.returncode = 0
  153. result = under_test.batch_process(1, True)
  154. assert result
  155. mock_run.assert_called_once_with([apb_path, '--zeroAnalysisMode',
  156. f'--regset="/Amazon/AzCore/Bootstrap/project_path={mock_project_path}"',
  157. '--logDir', f'{under_test.log_root()}'],
  158. close_fds=True,
  159. capture_output=False,
  160. timeout=1)
  161. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  162. @mock.patch('subprocess.run')
  163. @mock.patch('tempfile.TemporaryDirectory', mock.MagicMock())
  164. def test_BatchProcess_ReturnCodeFail_Failure(self, mock_run, mock_workspace):
  165. mock_workspace.project = None
  166. mock_workspace.paths.project.return_value = mock_project_path
  167. under_test = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  168. mock_run.return_value.returncode = 1
  169. result, _ = under_test.batch_process(None, False)
  170. assert not result
  171. mock_run.assert_called_once()
  172. assert f'--regset="/Amazon/AzCore/Bootstrap/project_path={mock_project_path}"' in mock_run.call_args[0][0]
  173. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  174. def test_EnableAssetProcessorPlatform_AssetProcessorObject_Updated(self, mock_workspace):
  175. under_test = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  176. under_test.enable_asset_processor_platform('foo')
  177. assert "foo" in under_test._enabled_platform_overrides
  178. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  179. def test_BackupAPSettings_Called_CallsBackupAPSettings(self, mock_workspace):
  180. mock_temp_path = 'foo_path'
  181. mock_asset_processor = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  182. mock_workspace.settings.get_temp_path.return_value = mock_temp_path
  183. mock_asset_processor.backup_ap_settings()
  184. mock_workspace.settings.backup_asset_processor_settings.assert_called_with(mock_temp_path)
  185. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  186. def test_RestoreAPSettings_Called_CallsRestoreAPSettings(self, mock_workspace):
  187. mock_temp_path = 'foo_path'
  188. mock_asset_processor = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  189. mock_workspace.settings.get_temp_path.return_value = mock_temp_path
  190. mock_asset_processor.restore_ap_settings()
  191. mock_workspace.settings.restore_asset_processor_settings.assert_called_with(mock_temp_path)
  192. @mock.patch('ly_test_tools.o3de.asset_processor.AssetProcessor.restore_ap_settings')
  193. @mock.patch('ly_test_tools.o3de.asset_processor.AssetProcessor.stop')
  194. @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager')
  195. def test_Teardown_Called_CallsRestoreAPSettingsAndStop(self, mock_workspace, mock_stop, mock_restore_ap):
  196. mock_asset_processor = ly_test_tools.o3de.asset_processor.AssetProcessor(mock_workspace)
  197. mock_asset_processor.teardown()
  198. mock_stop.assert_called()
  199. mock_restore_ap.assert_called()