You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_debugger_server.py 12 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. # Copyright 2020 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ============================================================================
  15. """
  16. Function:
  17. Test debugger server.
  18. Usage:
  19. pytest tests/ut/debugger/test_debugger_server.py
  20. """
  21. import signal
  22. from threading import Thread
  23. from unittest import mock
  24. from unittest.mock import MagicMock
  25. import grpc
  26. import pytest
  27. from mindinsight.debugger.common.exceptions.exceptions import DebuggerParamValueError, \
  28. DebuggerCompareTensorError, DebuggerCreateWatchPointError, DebuggerDeleteWatchPointError
  29. from mindinsight.debugger.common.utils import Streams
  30. from mindinsight.debugger.debugger_cache import DebuggerCache
  31. from mindinsight.debugger.debugger_server import DebuggerServer
  32. from mindinsight.debugger.debugger_server import grpc_server_base
  33. from mindinsight.debugger.proto.debug_grpc_pb2 import RunCMD
  34. from mindinsight.debugger.stream_handler import GraphHandler, WatchpointHandler, MetadataHandler, \
  35. TensorHandler
  36. from tests.ut.debugger.configurations import compare_debugger_result_with_file, mock_tensor_history
  37. class TestDebuggerServer:
  38. """Test debugger server."""
  39. @classmethod
  40. def setup_class(cls):
  41. """Initialize for test class."""
  42. cls._server = None
  43. def setup_method(self):
  44. """Prepare debugger server object."""
  45. self._server = DebuggerServer()
  46. @mock.patch.object(signal, 'signal')
  47. @mock.patch.object(Thread, 'join')
  48. @mock.patch.object(Thread, 'start')
  49. @mock.patch.object(grpc_server_base, 'add_EventListenerServicer_to_server')
  50. @mock.patch.object(grpc, 'server')
  51. def test_stop_server(self, *args):
  52. """Test stop debugger server."""
  53. mock_grpc_server_manager = MagicMock()
  54. args[0].return_value = mock_grpc_server_manager
  55. self._server.start()
  56. self._server._stop_handler(MagicMock(), MagicMock())
  57. assert self._server.back_server is not None
  58. assert self._server.grpc_server_manager == mock_grpc_server_manager
  59. @mock.patch.object(DebuggerCache, 'get_data')
  60. def test_poll_data(self, *args):
  61. """Test poll data request."""
  62. mock_data = {'pos': 'mock_data'}
  63. args[0].return_value = mock_data
  64. res = self._server.poll_data('0')
  65. assert res == mock_data
  66. def test_poll_data_with_exept(self):
  67. """Test poll data with wrong input."""
  68. with pytest.raises(DebuggerParamValueError, match='Pos should be string.'):
  69. self._server.poll_data(1)
  70. @mock.patch.object(GraphHandler, 'search_nodes')
  71. def test_search(self, *args):
  72. """Test search node."""
  73. mock_graph = {'nodes': ['mock_nodes']}
  74. args[0].return_value = mock_graph
  75. res = self._server.search({'name': 'mock_name'})
  76. assert res == mock_graph
  77. def test_tensor_comparision_with_wrong_status(self):
  78. """Test tensor comparison with wrong status."""
  79. with pytest.raises(
  80. DebuggerCompareTensorError,
  81. match='Failed to compare tensors as the MindSpore is not in waiting state.'):
  82. self._server.tensor_comparisons(name='mock_node_name:0', shape='[:, :]')
  83. @mock.patch.object(MetadataHandler, 'state', 'waiting')
  84. @mock.patch.object(GraphHandler, 'get_node_type')
  85. @mock.patch.object(GraphHandler, 'get_graph_id_by_name')
  86. @mock.patch.object(GraphHandler, 'get_full_name', return_value='mock_node_name')
  87. def test_tensor_comparision_with_wrong_type(self, *args):
  88. """Test tensor comparison with wrong type."""
  89. args[1].return_value = 'name_scope'
  90. with pytest.raises(DebuggerParamValueError, match='The node type must be parameter'):
  91. self._server.tensor_comparisons(name='mock_node_name:0', shape='[:, :]')
  92. @mock.patch.object(MetadataHandler, 'state', 'waiting')
  93. @mock.patch.object(GraphHandler, 'get_graph_id_by_name')
  94. @mock.patch.object(GraphHandler, 'get_node_type', return_value='Parameter')
  95. @mock.patch.object(GraphHandler, 'get_full_name', return_value='mock_node_name')
  96. @mock.patch.object(TensorHandler, 'get_tensors_diff')
  97. def test_tensor_comparision(self, *args):
  98. """Test tensor comparison"""
  99. mock_diff_res = {'tensor_value': {}}
  100. args[0].return_value = mock_diff_res
  101. res = self._server.tensor_comparisons('mock_node_name:0', '[:, :]')
  102. assert res == mock_diff_res
  103. def test_retrieve_with_pending(self):
  104. """Test retrieve request in pending status."""
  105. res = self._server.retrieve(mode='all')
  106. assert res.get('metadata', {}).get('state') == 'pending'
  107. @mock.patch.object(MetadataHandler, 'state', 'waiting')
  108. def test_retrieve_all(self):
  109. """Test retrieve request."""
  110. res = self._server.retrieve(mode='all')
  111. compare_debugger_result_with_file(res, 'debugger_server/retrieve_all.json')
  112. def test_retrieve_with_invalid_mode(self):
  113. """Test retrieve with invalid mode."""
  114. with pytest.raises(DebuggerParamValueError, match='Invalid mode.'):
  115. self._server.retrieve(mode='invalid_mode')
  116. @mock.patch.object(GraphHandler, 'get')
  117. @mock.patch.object(GraphHandler, 'get_node_type', return_value='name_scope')
  118. @mock.patch.object(GraphHandler, 'get_full_name', return_value='mock_node_name')
  119. def test_retrieve_node(self, *args):
  120. """Test retrieve node information."""
  121. mock_graph = {'graph': {}}
  122. args[2].return_value = mock_graph
  123. res = self._server._retrieve_node({'name': 'mock_node_name'})
  124. assert res == mock_graph
  125. def test_retrieve_tensor_history_with_pending(self):
  126. """Test retrieve request in pending status."""
  127. res = self._server.retrieve_tensor_history('mock_node_name')
  128. assert res.get('metadata', {}).get('state') == 'pending'
  129. @mock.patch.object(MetadataHandler, 'state', 'waiting')
  130. @mock.patch.object(GraphHandler, 'get_tensor_history')
  131. @mock.patch.object(GraphHandler, 'get_node_type', return_value='Parameter')
  132. def test_retrieve_tensor_history(self, *args):
  133. """Test retrieve tensor history."""
  134. args[1].return_value = mock_tensor_history()
  135. res = self._server.retrieve_tensor_history('mock_node_name')
  136. compare_debugger_result_with_file(res, 'debugger_server/retrieve_tensor_history.json')
  137. @mock.patch.object(GraphHandler, 'get_node_type')
  138. def test_validate_leaf_name(self, *args):
  139. """Test validate leaf name."""
  140. args[0].return_value = 'name_scope'
  141. with pytest.raises(DebuggerParamValueError, match='Invalid leaf node name.'):
  142. self._server._validate_leaf_name(node_name='mock_node_name', graph_name='mock_graph_name')
  143. @mock.patch.object(TensorHandler, 'get')
  144. @mock.patch.object(DebuggerServer, '_get_tensor_name_and_type_by_ui_name')
  145. def test_retrieve_tensor_value(self, *args):
  146. """Test retrieve tensor value."""
  147. mock_tensor_value = {'tensor_value': {'name': 'mock_name:0'}}
  148. args[0].return_value = ('Parameter', 'mock_node_name')
  149. args[1].return_value = mock_tensor_value
  150. res = self._server.retrieve_tensor_value('mock_name:0', 'data', '[:, :]')
  151. assert res == mock_tensor_value
  152. @mock.patch.object(WatchpointHandler, 'get')
  153. def test_retrieve_watchpoints(self, *args):
  154. """Test retrieve watchpoints."""
  155. mock_watchpoint = {'watch_points': {}}
  156. args[0].return_value = mock_watchpoint
  157. res = self._server._retrieve_watchpoint({})
  158. assert res == mock_watchpoint
  159. @mock.patch.object(DebuggerServer, '_retrieve_node')
  160. def test_retrieve_watchpoint(self, *args):
  161. """Test retrieve single watchpoint."""
  162. mock_watchpoint = {'nodes': {}}
  163. args[0].return_value = mock_watchpoint
  164. res = self._server._retrieve_watchpoint({'watch_point_id': 1})
  165. assert res == mock_watchpoint
  166. @mock.patch.object(DebuggerServer, '_validate_leaf_name')
  167. @mock.patch.object(DebuggerServer, '_get_tensor_history')
  168. @mock.patch.object(DebuggerServer, '_get_nodes_info', return_value={'graph': {}})
  169. def test_retrieve_watchpoint_hit(self, *args):
  170. """Test retrieve single watchpoint."""
  171. args[1].return_value = {'tensor_history': {}}
  172. res = self._server._retrieve_watchpoint_hit({'name': 'hit_node_name', 'single_node': True})
  173. assert res == {'tensor_history': {}, 'graph': {}}
  174. def test_create_watchpoint_with_wrong_state(self):
  175. """Test create watchpoint with wrong state."""
  176. with pytest.raises(DebuggerCreateWatchPointError, match='Failed to create watchpoint'):
  177. self._server.create_watchpoint(watch_condition={'condition': 'INF'})
  178. @mock.patch.object(MetadataHandler, 'state', 'waiting')
  179. @mock.patch.object(GraphHandler, 'get_node_basic_info', return_value=[MagicMock()])
  180. @mock.patch.object(GraphHandler, 'get_node_type', return_value='aggregation_scope')
  181. @mock.patch.object(WatchpointHandler, 'create_watchpoint')
  182. def test_create_watchpoint(self, *args):
  183. """Test create watchpoint."""
  184. args[0].return_value = 1
  185. res = self._server.create_watchpoint({'condition': 'INF'}, ['watch_node_name'])
  186. assert res == {'id': 1, 'metadata': {'enable_recheck': False, 'state': 'waiting'}}
  187. @mock.patch.object(MetadataHandler, 'state', 'waiting')
  188. @mock.patch.object(GraphHandler, 'validate_graph_name', return_value='kernel_graph_0')
  189. @mock.patch.object(GraphHandler, 'get_searched_node_list')
  190. @mock.patch.object(WatchpointHandler, 'validate_watchpoint_id')
  191. @mock.patch.object(WatchpointHandler, 'update_watchpoint')
  192. def test_update_watchpoint(self, *args):
  193. """Test update watchpoint."""
  194. args[2].return_value = [MagicMock(name='search_name/op_name')]
  195. res = self._server.update_watchpoint(
  196. watch_point_id=1, watch_nodes=['search_name'],
  197. mode=1, search_pattern={'name': 'search_name'}, graph_name='kernel_graph_0')
  198. assert res == {'metadata': {'enable_recheck': False, 'state': 'waiting'}}
  199. def test_delete_watchpoint_with_wrong_state(self):
  200. """Test delete watchpoint with wrong state."""
  201. with pytest.raises(DebuggerDeleteWatchPointError, match='Failed to delete watchpoint'):
  202. self._server.delete_watchpoint(watch_point_id=1)
  203. @mock.patch.object(MetadataHandler, 'enable_recheck', True)
  204. @mock.patch.object(WatchpointHandler, 'is_recheckable', return_value=True)
  205. @mock.patch.object(WatchpointHandler, 'delete_watchpoint')
  206. def test_delete_watchpoint(self, *args):
  207. """Test delete watchpoint with wrong state."""
  208. self._server.cache_store.get_stream_handler(Streams.METADATA).state = 'waiting'
  209. args[0].return_value = None
  210. res = self._server.delete_watchpoint(1)
  211. assert res == {'metadata': {'enable_recheck': True, 'state': 'waiting'}}
  212. @pytest.mark.parametrize('mode, cur_state, state', [
  213. ('continue', 'waiting', 'running'),
  214. ('pause', 'running', 'waiting'),
  215. ('terminate', 'waiting', 'pending')])
  216. def test_control(self, mode, cur_state, state):
  217. """Test control request."""
  218. with mock.patch.object(MetadataHandler, 'state', cur_state):
  219. res = self._server.control({'mode': mode})
  220. assert res == {'metadata': {'enable_recheck': False, 'state': state}}
  221. def test_construct_run_event(self):
  222. """Test construct run event."""
  223. res = self._server._construct_run_event({'level': 'node'})
  224. assert res.run_cmd == RunCMD(run_level='node', node_name='')