"""MCP передаёт команды одной сессии и не удаляет чужие точки.""" from pathlib import Path import sys import unittest ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(ROOT / 'toolchain')) from sdbg.mcp_adapter import McpSession from sdbg.session import SessionError class McpAdapterTests(unittest.TestCase): def setUp(self): self.calls = [] def rpc(path, method, arguments, timeout=10, **identity): self.calls.append((path, method, arguments, timeout, identity)) if method == 'status': return {'session_id': 'test-session', 'build_id': 'test-build', 'generation': 7} return {'method': method, 'arguments': arguments} self.client = McpSession('/tmp/sprinter-test.sock', rpc=rpc) def test_personal_breakpoints_are_tagged_and_cleared_by_owner(self): self.client.break_line('/src/main.c', 12) self.client.break_function('main') self.client.clear_breakpoint(7) self.client.clear_owned_breakpoints() self.assertTrue(self.client.owner.startswith('mcp:')) for _, method, arguments, _, identity in self.calls: if method == 'status': continue self.assertEqual(arguments['owner'], self.client.owner) self.assertEqual(identity['session_id'], 'test-session') self.assertEqual(identity['build_id'], 'test-build') self.assertEqual([item[1] for item in self.calls if item[1] != 'status'], ['break_line', 'break_function', 'clear_breakpoint', 'clear_owned_breakpoints']) def test_memory_and_events_validate_before_rpc(self): self.client.read_memory('0xc000', 16) self.assertEqual(self.calls[-1][2], {'address': 0xc000, 'length': 16}) self.client.events(after=4, timeout=12) self.assertEqual(self.calls[-1][1:4], ('events', {'after': 4, 'timeout': 12, 'owner': self.client.owner}, 14)) before = len(self.calls) with self.assertRaisesRegex(SessionError, 'Адрес памяти'): self.client.read_memory('not-an-address') with self.assertRaisesRegex(SessionError, 'timeout'): self.client.events(timeout=31) with self.assertRaisesRegex(SessionError, 'kind'): self.client.step_source('back') self.assertEqual(len(self.calls), before) def test_press_key_releases_shift_after_snapshot_error(self): calls = [] def rpc(path, method, arguments, timeout=10, **identity): calls.append((method, arguments)) if method == 'status': return {'session_id': 'test-session', 'build_id': 'test-build', 'generation': 7, 'running': True} if method == 'snapshot': raise SessionError('Потеряна связь с MAME') return {} client = McpSession('/tmp/sprinter-test.sock', rpc=rpc) with self.assertRaisesRegex(SessionError, 'Потеряна связь'): client.press_key('X') keys = [args for method, args in calls if method == 'input_key'] self.assertEqual([item['down'] for item in keys], [True, True, False, False]) self.assertEqual(keys[0]['tag'], keys[-1]['tag']) self.assertEqual(keys[1]['tag'], keys[-2]['tag']) self.assertTrue(all(item['owner'] == client.owner for item in keys)) if __name__ == '__main__': unittest.main()