async def test_client_register(server_address): register_events = [ common.RegisterEvent(event_type=('a', 'b', 'c'), source_timestamp=common.now(), payload=common.EventPayload( common.EventPayloadType.JSON, i)) for i in range(10) ] server = await create_server(server_address) client = await hat.event.client.connect(server_address) conn = await server.get_connection() client.register([]) msg = await conn.receive() assert msg.first is True assert msg.last is True assert msg.data == chatter.Data('HatEvent', 'MsgRegisterReq', []) client.register(register_events) msg = await conn.receive() assert msg.first is True assert msg.last is True assert msg.data == chatter.Data( 'HatEvent', 'MsgRegisterReq', [common.register_event_to_sbs(i) for i in register_events]) await conn.async_close() await client.async_close() await server.async_close() with pytest.raises(ConnectionError): client.register(register_events)
async def test_client_register_with_response(server_address): register_events = [ common.RegisterEvent(event_type=('a', 'b', 'c'), source_timestamp=common.now(), payload=common.EventPayload( common.EventPayloadType.JSON, i)) for i in range(10) ] events = [ common.Event(event_id=common.EventId(1, 2), event_type=register_event.event_type, timestamp=common.now(), source_timestamp=register_event.source_timestamp, payload=register_event.payload) for register_event in register_events ] events = [event if i % 2 else None for i, event in enumerate(events)] server = await create_server(server_address) client = await hat.event.client.connect(server_address) conn = await server.get_connection() register_future = asyncio.ensure_future(client.register_with_response([])) msg = await conn.receive() assert msg.first is True assert msg.last is False assert msg.data == chatter.Data('HatEvent', 'MsgRegisterReq', []) assert not register_future.done() conn.send_register_res(msg.conv, []) received = await register_future assert received == [] register_future = asyncio.ensure_future( client.register_with_response(register_events)) msg = await conn.receive() assert msg.first is True assert msg.last is False assert msg.data == chatter.Data( 'HatEvent', 'MsgRegisterReq', [common.register_event_to_sbs(i) for i in register_events]) assert not register_future.done() conn.send_register_res(msg.conv, events) received = await register_future assert received == events await conn.async_close() await client.async_close() await server.async_close() with pytest.raises(ConnectionError): await client.register_with_response(register_events)
def send_register_res(self, conv, events): data = chatter.Data(module='HatEvent', type='MsgRegisterRes', data=[(('event', common.event_to_sbs(event)) if event else ('failure', None)) for event in events]) self._conn.send(data, conv=conv)
async def test_send_receive(sbs_repo, unused_tcp_port): address = f'tcp+sbs://127.0.0.1:{unused_tcp_port}' conn2_future = asyncio.Future() srv = await chatter.listen(sbs_repo, address, lambda conn: conn2_future.set_result(conn)) conn1 = await chatter.connect(sbs_repo, address) conn2 = await conn2_future data = chatter.Data(module='Test', type='Data', data=123) conv = conn1.send(data) assert conv.owner is True msg = await conn2.receive() assert msg.data == data assert msg.conv.owner is False assert msg.conv.first_id == conv.first_id assert msg.first is True assert msg.last is True assert msg.token is True await conn1.async_close() await conn2.async_close() await srv.async_close() with pytest.raises(ConnectionError): conn1.send(data) with pytest.raises(ConnectionError): await conn2.receive()
async def test_client_subscriptions(server_address): server = await create_server(server_address) client = await hat.event.client.connect(server_address) conn = await server.get_connection() with pytest.raises(asyncio.TimeoutError): await asyncio.wait_for(conn.receive(), 0.01) await client.async_close() await conn.wait_closed() subscriptions = [('a', ), ('b', '*')] client = await hat.event.client.connect(server_address, subscriptions) conn = await server.get_connection() msg = await conn.receive() assert msg.first is True assert msg.last is True assert msg.data == chatter.Data('HatEvent', 'MsgSubscribe', [list(i) for i in subscriptions]) await conn.async_close() await client.async_close() await server.async_close()
def _send_msg_slave(self): msg = common.MsgSlave(components=self._components) with contextlib.suppress(ConnectionError): self._conn.send( chatter.Data(module='HatMonitor', type='MsgSlave', data=common.msg_slave_to_sbs(msg)))
async def test_example_docs(): from hat import aio from hat import chatter from hat import sbs from hat import util sbs_repo = sbs.Repository( chatter.sbs_repo, r""" module Example Msg = Integer """) port = util.get_unused_tcp_port() address = f'tcp+sbs://127.0.0.1:{port}' server_conns = aio.Queue() server = await chatter.listen(sbs_repo, address, server_conns.put_nowait) client_conn = await chatter.connect(sbs_repo, address) server_conn = await server_conns.get() data = chatter.Data('Example', 'Msg', 123) client_conn.send(data) msg = await server_conn.receive() assert msg.data == data await server.async_close() await client_conn.wait_closed() await server_conn.wait_closed()
async def _process_msg_query(self, msg): query_data = common.query_from_sbs(msg.data.data) events = await self._engine.query(query_data) data = chatter.Data(module='HatEvent', type='MsgQueryRes', data=[common.event_to_sbs(e) for e in events]) self._conn.send(data, conv=msg.conv)
async def register_with_response(self, events): """Register events Each `RegisterEvent` from `events` is paired with results `Event` if new event was successfuly created or `None` is new event could not be created. Args: events (List[common.RegisterEvent]): register events Returns: List[Optional[common.Event]] Raises: chatter.ConnectionClosedError: closed chatter connection Exception """ conv = self._conn.send(chatter.Data( module='HatEvent', type='MsgRegisterReq', data=[common.register_event_to_sbs(i) for i in events]), last=False) response_future = asyncio.Future() self._conv_futures[conv] = response_future return await response_future
def _send_msg_master(self): msg = common.MsgMaster(mid=self._mid, components=self._components) with contextlib.suppress(ConnectionError): self._conn.send( chatter.Data(module='HatMonitor', type='MsgMaster', data=common.msg_master_to_sbs(msg)))
def _send_msg_set_rank(self, cid, mid, rank): self._conn.send( chatter.Data(module='HatMonitor', type='MsgSetRank', data={ 'cid': cid, 'mid': mid, 'rank': rank }))
def _send_msg_client(self): self._conn.send( chatter.Data(module='HatMonitor', type='MsgClient', data=common.create_msg_client_sbs( name=self._name, group=self._group, address=self._address, ready=self._ready)))
async def test_client_query(server_address): events = [ common.Event(event_id=common.EventId(1, 2), event_type=('a', 'b', 'c'), timestamp=common.now(), source_timestamp=None, payload=common.EventPayload(common.EventPayloadType.JSON, i)) for i in range(10) ] server = await create_server(server_address) client = await hat.event.client.connect(server_address) conn = await server.get_connection() query_data = common.QueryData() query_future = asyncio.ensure_future(client.query(query_data)) msg = await conn.receive() assert msg.first is True assert msg.last is False assert msg.data == chatter.Data('HatEvent', 'MsgQueryReq', common.query_to_sbs(query_data)) assert not query_future.done() conn.send_query_res(msg.conv, []) received = await query_future assert received == [] query_data = common.QueryData(event_types=[['*']]) query_future = asyncio.ensure_future(client.query(query_data)) msg = await conn.receive() assert msg.first is True assert msg.last is False assert msg.data == chatter.Data('HatEvent', 'MsgQueryReq', common.query_to_sbs(query_data)) assert not query_future.done() conn.send_query_res(msg.conv, events) received = await query_future assert received == events await conn.async_close() await client.async_close() await server.async_close() with pytest.raises(ConnectionError): await client.query(common.QueryData())
def _send_msg_slave(self): self._conn.send( chatter.Data(module='HatMonitor', type='MsgSlave', data={ 'components': [ common.component_info_to_sbs(i) for i in self._local_components ] }))
async def _register_request_response(self, process_events, conn, msg): events = await self._engine.register(process_events) if msg.last: return conn.send(chatter.Data(module='HatEvent', type='MsgRegisterRes', data=[('event', common.event_to_sbs(event)) if event else ('failure', None) for event in events]), conv=msg.conv)
def _send_msg_master(self, conn): conn.send( chatter.Data(module='HatMonitor', type='MsgMaster', data={ 'mid': self._connections[conn], 'components': [ common.component_info_to_sbs(i) for i in self._global_components ] }))
async def query(self, data: common.QueryData) -> typing.List[common.Event]: """Query events from server Raises: ConnectionError """ msg_data = chatter.Data(module='HatEvent', type='MsgQueryReq', data=common.query_to_sbs(data)) conv = self._conn.send(msg_data, last=False) return await self._wait_conv_res(conv)
def register(self, events: typing.List[common.RegisterEvent]): """Register events Raises: ConnectionError """ msg_data = chatter.Data( module='HatEvent', type='MsgRegisterReq', data=[common.register_event_to_sbs(i) for i in events]) self._conn.send(msg_data)
def _on_events(self, events): conn_notify = {} for event in events: for conn in self._subs_registry.find(event.event_type): conn_notify[conn] = (conn_notify.get(conn, []) + [event]) for conn, notify_events in conn_notify.items(): with contextlib.suppress(chatter.ConnectionClosedError): conn.send( chatter.Data( module='HatEvent', type='MsgNotify', data=[common.event_to_sbs(e) for e in notify_events]))
def _on_events(self, events): if not self._subscription: return events = [ e for e in events if self._subscription.matches(e.event_type) ] if not events: return data = chatter.Data('HatEvent', 'MsgNotify', [common.event_to_sbs(e) for e in events]) with contextlib.suppress(ConnectionError): self._conn.send(data)
def _send_msg_server(self, conn): conn.send( chatter.Data(module='HatMonitor', type='MsgServer', data={ 'cid': self._connections[conn], 'mid': self.mid, 'components': [ common.component_info_to_sbs(info) for info in self.components ] }))
async def _process_msg_register(self, msg): register_events = [ common.register_event_from_sbs(i) for i in msg.data.data ] events = await self._engine.register(self._source, register_events) if msg.last: return data = chatter.Data(module='HatEvent', type='MsgRegisterRes', data=[ (('event', common.event_to_sbs(e)) if e is not None else ('failure', None)) for e in events ]) self._conn.send(data, conv=msg.conv)
async def test_send_receive_native_data(sbs_repo, unused_tcp_port): address = f'tcp+sbs://127.0.0.1:{unused_tcp_port}' conn2_future = asyncio.Future() srv = await chatter.listen(sbs_repo, address, lambda conn: conn2_future.set_result(conn)) conn1 = await chatter.connect(sbs_repo, address) conn2 = await conn2_future data = chatter.Data(module=None, type='Integer', data=123) conn1.send(data) msg = await conn2.receive() assert data == msg.data await conn1.async_close() await conn2.async_close() await srv.async_close()
def register(self, events): """Register events Args: events (List[common.RegisterEvent]): register events Raises: chatter.ConnectionClosedError: closed chatter connection Exception """ self._conn.send( chatter.Data( module='HatEvent', type='MsgRegisterReq', data=[common.register_event_to_sbs(i) for i in events]))
async def test_connection_close_when_queue_blocking(sbs_repo, unused_tcp_port): address = f'tcp+sbs://127.0.0.1:{unused_tcp_port}' conn2_future = asyncio.Future() srv = await chatter.listen(sbs_repo, address, lambda conn: conn2_future.set_result(conn)) conn1 = await chatter.connect(sbs_repo, address, queue_maxsize=1) conn2 = await conn2_future data = chatter.Data(module='Test', type='Data', data=123) conn2.send(data) conn2.send(data) await asyncio.sleep(0.01) await conn1.async_close() await asyncio.wait_for(conn2.closed, 0.1) await srv.async_close()
async def test_query(addr, server): conf = {'address': addr} logger = common.Logger() device = hat.manager.devices.event.Device(conf, logger) latest_queue = create_change_queue(device.data, 'latest') client = await device.create() conn = await server.connection_queue.get() latest = await latest_queue.get() assert latest == [] msg = await conn.receive() assert msg.first is True assert msg.last is True assert msg.data.module == 'HatEvent' assert msg.data.type == 'MsgSubscribe' assert msg.data.data == [['*']] msg = await conn.receive() assert msg.first is True assert msg.last is False assert msg.data.module == 'HatEvent' assert msg.data.type == 'MsgQueryReq' events = [ create_event(('a', 'b', 'c'), 123), create_event(('c', 'b', 'a'), 321) ] data = [hat.event.common.event_to_sbs(event) for event in events] conn.send(chatter.Data('HatEvent', 'MsgQueryRes', data), conv=msg.conv) latest = await latest_queue.get() assert len(events) == len(latest) events = sorted(events, key=lambda i: i.event_type) latest = sorted(latest, key=lambda i: i['event_type']) for event, i in zip(events, latest): assert event.event_id.server == i['event_id']['server'] assert event.event_id.instance == i['event_id']['instance'] assert list(event.event_type) == i['event_type'] assert event.payload.data == i['payload'] await client.async_close()
async def register_with_response( self, events: typing.List[common.RegisterEvent] ) -> typing.List[typing.Optional[common.Event]]: # NOQA """Register events Each `common.RegisterEvent` from `events` is paired with results `common.Event` if new event was successfuly created or ``None`` is new event could not be created. Raises: ConnectionError """ msg_data = chatter.Data( module='HatEvent', type='MsgRegisterReq', data=[common.register_event_to_sbs(i) for i in events]) conv = self._conn.send(msg_data, last=False) return await self._wait_conv_res(conv)
async def test_register(addr, server, text, register_events, with_source_timestamp): conf = {'address': addr} logger = common.Logger() device = hat.manager.devices.event.Device(conf, logger) client = await device.create() conn = await server.connection_queue.get() msg = await conn.receive() assert msg.first is True assert msg.last is True assert msg.data.module == 'HatEvent' assert msg.data.type == 'MsgSubscribe' assert msg.data.data == [['*']] msg = await conn.receive() assert msg.first is True assert msg.last is False assert msg.data.module == 'HatEvent' assert msg.data.type == 'MsgQueryReq' conn.send(chatter.Data('HatEvent', 'MsgQueryRes', []), conv=msg.conv) await device.execute('register', text, with_source_timestamp) msg = await conn.receive() assert msg.first is True assert msg.last is True assert msg.data.module == 'HatEvent' assert msg.data.type == 'MsgRegisterReq' events = [ hat.event.common.register_event_from_sbs(i) for i in msg.data.data ] assert all( ((i.source_timestamp is not None) if with_source_timestamp else ( i.source_timestamp is None)) for i in events) events = [i._replace(source_timestamp=None) for i in events] assert events == register_events await client.async_close()
async def query(self, data): """Query events from server Args: data (common.QueryData): query data Returns: List[common.Event] Raises: chatter.ConnectionClosedError: closed chatter connection Exception """ conv = self._conn.send(chatter.Data(module='HatEvent', type='MsgQueryReq', data=common.query_to_sbs(data)), last=False) response_future = asyncio.Future() self._conv_futures[conv] = response_future return await response_future
async def test_send_receive(sbs_repo, unused_tcp_port): address = f'tcp+sbs://127.0.0.1:{unused_tcp_port}' conn2_future = asyncio.Future() srv = await chatter.listen(sbs_repo, address, lambda conn: conn2_future.set_result(conn)) conn1 = await chatter.connect(sbs_repo, address) conn2 = await conn2_future data = chatter.Data(module='Test', type='Data', data=123) conn1.send(data) msg = await conn2.receive() assert data == msg.data await conn1.async_close() await conn2.async_close() await srv.async_close() with pytest.raises(chatter.ConnectionClosedError): conn1.send(data) with pytest.raises(chatter.ConnectionClosedError): await conn2.receive()