def run_watcher(args): """Runs the watcher. :param argparse.Namespace args: the parsed arguments passed to the CLI. """ import socket import asyncio import signal from theia.comm import Client from watchdog.observers import Observer from theia.watcher import SourcesDaemon hostname = socket.gethostname() loop = asyncio.get_event_loop() client = Client(loop=loop, host=args.collector_server, port=args.collector_port, path='/event', secure=args.secure) client.connect() daemon = SourcesDaemon(observer=Observer(), client=client, tags=[hostname]) for file_path in args.files: daemon.add_source(fpath=file_path, tags=args.tags) loop.add_signal_handler(signal.SIGHUP, loop.stop) loop.add_signal_handler(signal.SIGINT, loop.stop) loop.add_signal_handler(signal.SIGTERM, loop.stop) loop.run_forever() loop.close()
def _connect_and_send(self, path, criteria, callback): client = Client(loop=self.loop, host=self.host, port=self.port, path=path, recv=callback) client.connect() self.connections.add(client) def on_client_closed(websocket, code, reason): """Remove the underlying client from the connections set once its connection is closed. """ # client was closed if client in self.connections: self.connections.remove(client) client.on_close(on_client_closed) msg = json.dumps(criteria) client.send(msg) return ResultHandler(client)
def test_assert_result_handler_closed_handlers_called(m_is_open, m_on_close, m_close): m_is_open.return_value = True handlers = [] def fake_client_close(): for hnd in handlers: hnd(None, 1006, 'server stop') m_close.side_effect = fake_client_close def fake_client_on_close(handler): handlers.append(handler) closed_handler = mock.MagicMock() client = Client(loop=None, host=None, port=None) rh = ResultHandler(client=client) rh.when_closed(closed_handler) rh.cancel() assert closed_handler.called_once_with(client, 1006, 'server stop')
def test_result_handler_cancel(m_is_open, m_close): m_is_open.return_value = True rh = ResultHandler(client=Client(loop=None, host=None, port=None)) rh.cancel() assert m_is_open.call_count == 1 assert m_close.call_count == 1
def test_result_handler_when_closed(): rh = ResultHandler(client=Client(loop=None, host=None, port=None)) def closed_handler(*args, **kwargs): pass rh.when_closed(closed_handler) assert rh._close_handlers assert closed_handler in rh._close_handlers
def simulate_events(args): """Connects and generates random events. The events are generated according to the given arguments. :param argparse.Namespace args: the parsed arguments passed to the program. """ loop = asyncio.get_event_loop() client = Client(host=args.host, port=args.port, path='/event', loop=loop) client.connect() ser = EventSerializer() tags = [args.tags] if isinstance(args.tags, str) else args.tags class _SenderThread(Thread): """Sender Thread. Runs continuously. """ def __init__(self): super(_SenderThread, self).__init__() self.is_running = False def run(self): """Generate and send events continuously. """ self.is_running = True while self.is_running: _send_event(args, tags, client, ser) time.sleep(args.delay) sender_thread = _SenderThread() sender_thread.is_running = True sender_thread.start() loop.run_forever()
def test_client_close_handlers(): mock_close_handler = mock.MagicMock() mock_websocket = mock.MagicMock() client = Client(host='localhost', port=11223, loop=None) client.websocket = mock_websocket client.on_close(mock_close_handler) client._closed(code=1006, reason='unit test') assert mock_close_handler.called_once_with(mock_websocket, 1006, 'unit test')
def test_query_live(m_connect_and_send, m_on_close): query = Query(host='localhost', port=11223) def callback(*args): pass rh = ResultHandler(client=Client(loop=None, host=None, port=None)) def fake_connect_and_send(*args, **kwargs): return rh m_connect_and_send.side_effect = fake_connect_and_send criteria = {'id': 'event-1'} result = query.find(criteria, callback) assert result is not None assert result == rh assert m_connect_and_send.called_once_with('/live', criteria, callback)
def test_client_send_event(m_send, m_recv, m_connect): from time import sleep evloop = asyncio.new_event_loop() async def fake_connect(url, loop): assert url == 'ws://localhost:1122/path' assert loop == evloop return WebSocket() async def fake_recv(): await asyncio.sleep(100) return None send_msgs = [] async def fake_send(msg): print('[fake send]') send_msgs.append(msg) evloop.stop() m_connect.side_effect = fake_connect m_recv.side_effect = fake_recv m_send.side_effect = fake_send client = Client(loop=evloop, host='localhost', port=1122, path='/path') client.connect() assert client.loop == evloop assert client.host == 'localhost' assert client.port == 1122 assert client.secure == False assert client.path == '/path' assert client.serializer is not None assert client.websocket is not None assert client._is_open == True client.send_event( Event(id='0001', timestamp=10, source='s-1', content='c-1', tags=['t'])) evloop.run_forever() assert len(send_msgs) == 1 assert 'id:0001' in send_msgs[0].decode('utf-8') for t in asyncio.Task.all_tasks(evloop): t.cancel() print('Task:', t, 'cancelled.') evloop.close()
def test_client_connect_and_close(m_close, m_recv, m_connect): from time import sleep evloop = asyncio.new_event_loop() async def fake_connect(url, loop): assert url == 'ws://localhost:1122/path' assert loop == evloop return WebSocket() async def fake_recv(): await asyncio.sleep(100) return None def fake_close(code, reason): assert code == 1000 assert reason == 'test-close' m_connect.side_effect = fake_connect m_recv.side_effect = fake_recv m_close.side_effect = fake_close client = Client(loop=evloop, host='localhost', port=1122, path='/path') client.connect() assert client.loop == evloop assert client.host == 'localhost' assert client.port == 1122 assert client.secure == False assert client.path == '/path' assert client.serializer is not None assert client.websocket is not None assert client._is_open == True client.close(reason='test-close') assert client._is_open == False assert m_close.call_count == 1 evloop.stop() for t in asyncio.Task.all_tasks(evloop): t.cancel() print('Task:', t, 'cancelled.') evloop.close()
def test_sources_daemon_modified_file(m_send_event, m_schedule, m_start): with tempfile.TemporaryDirectory() as tmpdir: state = {} def fake_schedule(dir_handler, pdir, recursive): assert isinstance(dir_handler, DirectoryEventHandler) assert pdir == tmpdir assert recursive is False state[pdir] = dir_handler m_schedule.side_effect = fake_schedule def fake_send(event): assert event.content is not None assert event.content == state['content'].decode('utf-8') assert event.tags == state['tags'] m_send_event.side_effect = fake_send client = Client(loop=None, host=None, port=None) # just create a reference, don't connect sd = SourcesDaemon(observer=Observer(), client=client, tags=['a', 'b']) assert m_start.call_count == 1 with open(os.path.join(tmpdir, 'test_source'), 'w+b') as test_source: sd.add_source(fpath=os.path.join(tmpdir, 'test_source'), tags=['c']) assert m_schedule.call_count == 1 assert len(sd.sources) == 1 assert len(sd.sources.get(tmpdir, {})) == 1 assert sd.sources[tmpdir].get('test_source') is not None assert sd.sources[tmpdir].get('test_source').tags == [ 'a', 'b', 'c' ] content = 'test content'.encode('utf-8') state['content'] = content state['tags'] = ['a', 'b', 'c'] test_source.write(content) test_source.flush() # notify the daemon by calling the handler directly fh = state[tmpdir] fh.on_modified(_FakeEvent(src=os.path.join(tmpdir, 'test_source'))) assert m_send_event.call_count == 1 content = 'another change'.encode('utf-8') state['content'] = content test_source.write(content) test_source.flush() fh.on_modified(_FakeEvent(src=os.path.join(tmpdir, 'test_source'))) assert m_send_event.call_count == 2
from threading import Thread from uuid import uuid4 from theia.comm import Client from theia.model import Event loop = asyncio.get_event_loop() loop.set_debug(True) print('1') def recv(msg): print('RECEIVED: ', msg) cl = Client(loop, host='localhost', port=8765, path='/event', recv=recv) cl.connect() def do_send(): while True: msg = input('>') id = str(uuid4()) cl.send_event(Event(id=id, source='repl-test', content=msg)) print(' >>%s:%s' % (id, msg)) Thread(target=do_send).start() loop.run_forever()