def __init__(self, query_result=[]): self._query_result = query_result self._receive_queue = aio.Queue() self._register_queue = aio.Queue() self._async_group = aio.Group() self._async_group.spawn(aio.call_on_cancel, self._receive_queue.close) self._async_group.spawn(aio.call_on_cancel, self._register_queue.close)
def __init__(self, conn: tcp.Connection, always_enabled: bool, response_timeout: float, supervisory_timeout: float, test_timeout: float, send_window_size: int, receive_window_size: int): self._conn = conn self._always_enabled = always_enabled self._is_enabled = always_enabled self._response_timeout = response_timeout self._supervisory_timeout = supervisory_timeout self._test_timeout = test_timeout self._send_window_size = send_window_size self._receive_window_size = receive_window_size self._read_queue = aio.Queue() self._write_queue = aio.Queue() self._test_event = asyncio.Event() self._ssn = 0 self._rsn = 0 self._ack = 0 self._w = 0 self._write_supervisory_handle = None self._waiting_ack_handles = {} self._waiting_ack_cv = asyncio.Condition() self.async_group.spawn(self._read_loop) self.async_group.spawn(self._write_loop) self.async_group.spawn(self._test_loop) self.async_group.spawn(aio.call_on_cancel, self._on_close)
async def test_backend_to_frontend(backend, web_server, client, create_msg): client_change_queue = aio.Queue() client.register_change_cb(lambda: client_change_queue.put_nowait(None)) entry_queue = aio.Queue() backend.register_change_cb(entry_queue.put_nowait) await client_change_queue.get() assert_client_vs_server_state(client) entries = [] for _ in range(10): msg = create_msg() await backend.register(ts_now(), msg) reg_entries = await entry_queue.get() entry = reg_entries[0] entries.insert(0, entry) await client_change_queue.get() assert entry in client.server_state['entries'] assert util.first(client.server_state['entries'], lambda i: i.msg == msg) assert entries == client.server_state['entries'] assert client.server_state['first_id'] == 1 assert client.server_state['last_id'] == len(entries) assert_client_vs_server_state(client)
async def test_example_docs(): from hat import aio from hat import juggler from hat import util port = util.get_unused_tcp_port() host = '127.0.0.1' server_conns = aio.Queue() server = await juggler.listen(host, port, server_conns.put_nowait, autoflush_delay=0) client_conn = await juggler.connect(f'ws://{host}:{port}/ws', autoflush_delay=0) server_conn = await server_conns.get() server_remote_data = aio.Queue() server_conn.register_change_cb( lambda: server_remote_data.put_nowait(server_conn.remote_data)) client_conn.set_local_data(123) data = await server_remote_data.get() assert data == 123 await server.async_close() await client_conn.wait_closed() await server_conn.wait_closed()
async def test_autoflush_zero(server_port): async with create_conn_pair(server_port, 0) as conn_pair: conn1, conn2 = conn_pair assert conn1.local_data is None assert conn1.remote_data is None assert conn2.local_data is None assert conn2.remote_data is None conn1_changes = aio.Queue() conn2_changes = aio.Queue() conn1.register_change_cb( lambda: conn1_changes.put_nowait(conn1.remote_data)) conn2.register_change_cb( lambda: conn2_changes.put_nowait(conn2.remote_data)) conn1.set_local_data(123) conn1.set_local_data('abc') conn1.set_local_data('xyz') conn2.remote_data is None change1 = await conn2_changes.get() change2 = await conn2_changes.get() change3 = await conn2_changes.get() assert change1 == 123 assert change2 == 'abc' assert change3 == 'xyz' assert conn2.remote_data == 'xyz' assert conn2_changes.empty()
def __init__(self, user, roles): self._user = user self._roles = roles self._local_data = None self._local_data_queue = aio.Queue() self._receive_queue = aio.Queue() self._remote_data = None self._change_cbs = util.CallbackRegistry() self._async_group = aio.Group()
def __init__(self): self._async_group = aio.Group() self._mid_queue = aio.Queue() self._global_components_queue = aio.Queue() self._local_components_queue = aio.Queue() self._mid = 0 self._local_components = [] self._global_components = [] self._change_cbs = util.CallbackRegistry()
async def test_adapter_remote_data(ui_path, ui_addr, ws_addr, patch_autoflush_delay): conf = { 'address': ui_addr, 'initial_view': None, 'users': [{ 'name': 'user', 'password': get_password_conf('pass', 'salt'), 'roles': [], 'view': None }] } adapter = Adapter() adapters = {'adapter': adapter} views = ViewManager({}) server = await hat.gui.server.create_server(conf, ui_path, adapters, views) client = await juggler.connect(ws_addr, autoflush_delay=0) await client.send({ 'type': 'login', 'name': 'user', 'password': hash_password('pass') }) session = await adapter.session_queue.get() assert session.client.remote_data is None assert client.remote_data.get('adapter') is None frontend_data_queue = aio.Queue() session.client.register_change_cb( lambda: frontend_data_queue.put_nowait(session.client.remote_data)) backend_data_queue = aio.Queue() client.register_change_cb( lambda: backend_data_queue.put_nowait(client.remote_data)) with pytest.raises(asyncio.TimeoutError): await asyncio.wait_for(frontend_data_queue.get(), 0.001) with pytest.raises(asyncio.TimeoutError): await asyncio.wait_for(backend_data_queue.get(), 0.001) client.set_local_data({'adapter': 123}) data = await frontend_data_queue.get() assert data == 123 session.client.set_local_data('abc') data = await backend_data_queue.get() assert data == {'adapter': 'abc'} await client.async_close() await server.async_close() await views.async_close()
async def test_adapter_state(run_gui, gui_conf, tmp_path, event_process, event_client): gui_conf = add_adapters_users_roles(gui_conf, tmp_path, no_users_roles=1) gui_process = run_gui(gui_conf) user_conf = gui_conf['users'][0] client = await create_client(gui_conf, user_conf) client_change_queue = aio.Queue() client.register_change_cb(lambda: client_change_queue.put_nowait(None)) await client.receive() await client.login() await client.receive() # event server to client await register_event(event_client, ('a1', 'data'), {'abc': 1}) await aio.first(client_change_queue, lambda _: client.server_state) assert client.server_state == {'adapter1': [{'abc': 1}]} # client to event server client.set_local_data({'adapter1': ['a', 'b', 'c']}) event = await get_first_event(event_client, lambda e: e.event_type == ('a1', 'action')) assert event.payload.data == ['a', 'b', 'c'] # data with wrong adapter name client.set_local_data({'adapter2': ['a', 'b', 'c']}) event = await get_first_event(event_client, lambda e: e.event_type == ('a1', 'action')) assert event.payload.data is None await client.async_close() gui_process.close_and_wait_or_kill()
async def test_frontend_to_backend(backend, web_server, client, create_msg): client_change_queue = aio.Queue() client.register_change_cb(lambda: client_change_queue.put_nowait(None)) client.set_filter(common.Filter(msg='message no 1')) await client_change_queue.get() assert_client_vs_server_state(client) for _ in range(10): await backend.register(ts_now(), create_msg()) await client_change_queue.get() assert len(client.server_state['entries']) == 2 assert all('message no 1' in e.msg.msg for e in client.server_state['entries']) client.set_filter(common.Filter()) await client_change_queue.get() assert len(client.server_state['entries']) == 10 assert client_change_queue.empty() client.set_filter(common.Filter(msg='bla bla')) await client_change_queue.get() assert len(client.server_state['entries']) == 0 assert client_change_queue.empty() client.set_filter(common.Filter(severity=common.Severity.ERROR)) await client_change_queue.get() assert len(client.server_state['entries']) == 2 assert all(e.msg.severity == common.Severity.ERROR for e in client.server_state['entries'])
async def test_reconnect(slave_addr, connection_conf): slave_queue = aio.Queue() server = await modbus.create_tcp_server(modbus.ModbusType.TCP, slave_addr, slave_cb=slave_queue.put_nowait) conf = {'connection': connection_conf, 'remote_devices': []} event_client = EventClient() device = await aio.call(master.create, conf, event_client, event_type_prefix) slave = await slave_queue.get() assert slave.is_open assert slave_queue.empty() await slave.async_close() assert device.is_open slave = await slave_queue.get() assert slave.is_open assert slave_queue.empty() await device.async_close() await slave.wait_closing() await server.async_close() await event_client.async_close()
async def test_read(create_master_slave, modbus_type, comm_type, device_id, data_type, start_address, quantity, result): read_queue = aio.Queue() async def on_read(slave, device_id, data_type, start_address, quantity): f = asyncio.Future() entry = device_id, data_type, start_address, quantity, f read_queue.put_nowait(entry) return await f async with create_master_slave(modbus_type, comm_type, read_cb=on_read) as (master, slave): read_future = asyncio.ensure_future(master.read( device_id, data_type, start_address, quantity)) entry = await read_queue.get() assert entry[0] == device_id assert entry[1] == data_type assert entry[2] == start_address assert entry[3] == quantity entry[4].set_result(result) read_result = await read_future assert read_result == result
def _create_connection( transport, interrogate_cb, counter_interrogate_cb, command_cb, ): info = ConnectionInfo( local_addr=Address(*transport.conn.info.local_addr), remote_addr=Address(*transport.conn.info.remote_addr)) conn = Connection() conn._transport = transport conn._interrogate_cb = interrogate_cb conn._counter_interrogate_cb = counter_interrogate_cb conn._command_cb = command_cb conn._info = info conn._interrogate_queue = None conn._interrogate_lock = asyncio.Lock() conn._counter_interrogate_queue = None conn._counter_interrogate_lock = asyncio.Lock() conn._data_queue = aio.Queue() conn._command_futures = {} conn.async_group.spawn(conn._read_loop) return conn
def _create_connection(syntax_names, cosp_conn, cp_ppdu, cpa_ppdu, local_psel, remote_psel): cp_user_data = cp_ppdu['normal-mode-parameters']['user-data'] cpa_user_data = cpa_ppdu['normal-mode-parameters']['user-data'] conn_req_user_data = (syntax_names.get_name( cp_user_data[1][0]['presentation-context-identifier']), cp_user_data[1][0]['presentation-data-values'][1]) conn_res_user_data = (syntax_names.get_name( cpa_user_data[1][0]['presentation-context-identifier']), cpa_user_data[1][0]['presentation-data-values'][1]) conn = Connection() conn._cosp_conn = cosp_conn conn._syntax_names = syntax_names conn._conn_req_user_data = conn_req_user_data conn._conn_res_user_data = conn_res_user_data conn._info = ConnectionInfo(local_psel=local_psel, remote_psel=remote_psel, **cosp_conn.info._asdict()) conn._close_ppdu = _arp_ppdu() conn._read_queue = aio.Queue() conn._async_group = aio.Group() conn._async_group.spawn(conn._read_loop) return conn
async def test_single_state(): queue = aio.Queue() states = [ stc.State('s1', transitions=[ stc.Transition('e1', 's1', ['transit']), stc.Transition('e2', 's1', ['transit'], [], True) ], entries=['enter'], exits=['exit']) ] actions = { 'enter': lambda _, e: queue.put_nowait(('enter', e)), 'exit': lambda _, e: queue.put_nowait(('exit', e)), 'transit': lambda _, e: queue.put_nowait(('transit', e)) } machine = stc.Statechart(states, actions) assert machine.state is None f = asyncio.ensure_future(machine.run()) a, e = await queue.get() assert a == 'enter' assert e is None assert machine.state == 's1' await asyncio.sleep(0.001) assert queue.empty() event = stc.Event('e1', None) machine.register(event) a, e = await queue.get() assert (a, e) == ('exit', event) a, e = await queue.get() assert (a, e) == ('transit', event) a, e = await queue.get() assert (a, e) == ('enter', event) assert machine.state == 's1' await asyncio.sleep(0.001) assert queue.empty() event = stc.Event('e2', 123) machine.register(event) a, e = await queue.get() assert (a, e) == ('transit', event) assert machine.state == 's1' await asyncio.sleep(0.001) assert queue.empty() event = stc.Event('e3', None) machine.register(event) assert machine.state == 's1' await asyncio.sleep(0.001) assert queue.empty() f.cancel() with pytest.raises(asyncio.CancelledError): await f
async def test_query(comm_address, comm_conf): event_types = [(), ('a', ), ('b', ), ('a', 'a'), ('a', 'b'), ('a', 'b', 'c'), ('', '', '')] events = [ hat.event.common.Event(event_id=hat.event.common.EventId(server=0, instance=i), event_type=event_type, timestamp=common.now(), source_timestamp=None, payload=None) for i, event_type in enumerate(event_types) ] query_data = common.QueryData() query_queue = aio.Queue() def query_cb(data): query_queue.put_nowait(data) return events engine = ModuleEngine(query_cb=query_cb) comm = await hat.event.server.communication.create(comm_conf, engine) client = await hat.event.client.connect(comm_address) result = await client.query(query_data) assert result == events temp_query_data = await query_queue.get() assert temp_query_data == query_data await client.async_close() await comm.async_close() await engine.async_close()
async def _client_loop(self): changes = aio.Queue() def on_change(): remote_data = (self._conn.remote_data if isinstance( self._conn.remote_data, dict) else {}) changes.put_nowait(remote_data.get(self._name)) try: with self._conn.register_change_cb(on_change): on_change() while True: remote_data = await changes.get() if json.equals(remote_data, self._remote_data): continue self._remote_data = remote_data self._change_cbs.notify() except Exception as e: mlog.error("client loop error: %s", e, exc_info=e) finally: self.close() self._receive_queue.close()
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 test_queue_put(): queue = aio.Queue(1) await queue.put(1) put_future = asyncio.ensure_future(queue.put(1)) asyncio.get_event_loop().call_soon(queue.close) with pytest.raises(aio.QueueClosedError): await put_future
def test_queue_get_nowait_until_empty(): queue = aio.Queue() queue.put_nowait(1) queue.put_nowait(2) queue.put_nowait(3) result = queue.get_nowait_until_empty() assert result == 3
async def test_event_to_adapters(run_gui, gui_conf, tmp_path, event_process, event_client): no_adapters = 10 gui_conf = add_adapters_users_roles(gui_conf, tmp_path, no_users_roles=1, adapters_per_role=no_adapters) adapters = [i['name'] for i in gui_conf['adapters']] gui_process = run_gui(gui_conf) user_conf = gui_conf['users'][0] client = await create_client(gui_conf, user_conf) client_change_queue = aio.Queue() client.register_change_cb(lambda: client_change_queue.put_nowait(None)) await client.receive() await client.login() await client.receive() await register_event(event_client, ('a1', 'data'), {'abc': 1}) for adapter in adapters: assert await client.receive() == {'type': 'adapter', 'name': adapter, 'data': {'abc': 1}} await aio.first(client_change_queue, lambda _: len(client.server_state) == no_adapters) assert client.server_state == {a: [{'abc': 1}] for a in adapters} await client.async_close() gui_process.close_and_wait_or_kill()
async def test_write(create_master_slave, modbus_type, comm_type, device_id, data_type, start_address, values, result): write_queue = aio.Queue() async def on_write(slave, device_id, data_type, start_address, values): f = asyncio.Future() entry = device_id, data_type, start_address, values, f write_queue.put_nowait(entry) return await f async with create_master_slave(modbus_type, comm_type, write_cb=on_write) as (master, slave): write_future = asyncio.ensure_future(master.write( device_id, data_type, start_address, values)) entry = await write_queue.get() assert entry[0] == device_id assert entry[1] == data_type assert entry[2] == start_address assert entry[3] == values entry[4].set_result(result) read_result = await write_future assert read_result == result
async def test_bind_connections(addr, bind_connections, conn_count): conn_queue = aio.Queue() srv = await tcp.listen(conn_queue.put_nowait, addr, bind_connections=bind_connections) conns = [] for _ in range(conn_count): conn1 = await tcp.connect(addr) conn2 = await conn_queue.get() conns.append((conn1, conn2)) for conn1, conn2 in conns: assert conn1.is_open assert conn2.is_open await srv.async_close() for conn1, conn2 in conns: if bind_connections: with pytest.raises(ConnectionError): await conn1.read() assert not conn1.is_open assert not conn2.is_open else: assert conn1.is_open assert conn2.is_open await conn1.async_close() await conn2.async_close()
async def create_master_slave(modbus_type, comm_type, read_cb=None, write_cb=None, write_mask_cb=None): if comm_type == CommType.TCP: slave_queue = aio.Queue() srv = await modbus.create_tcp_server( modbus_type, tcp_addr, slave_queue.put_nowait, read_cb, write_cb, write_mask_cb) master = await modbus.create_tcp_master( modbus_type, tcp_addr) slave = await slave_queue.get() try: yield master, slave finally: await master.async_close() await srv.async_close() elif comm_type == CommType.SERIAL: master = await modbus.create_serial_master( modbus_type, nullmodem[0]) slave = await modbus.create_serial_slave( modbus_type, nullmodem[1], read_cb, write_cb, write_mask_cb) try: yield master, slave finally: await master.async_close() await slave.async_close() else: raise ValueError()
async def create(local_addr: typing.Optional[Address] = None, remote_addr: typing.Optional[Address] = None, queue_size: int = 0, **kwargs) -> 'Endpoint': """Create new UDP endpoint Args: local_addr: local address remote_addr: remote address queue_size: receive queue max size kwargs: additional arguments passed to :meth:`asyncio.AbstractEventLoop.create_datagram_endpoint` """ endpoint = Endpoint() endpoint._local_addr = local_addr endpoint._remote_addr = remote_addr endpoint._async_group = aio.Group() endpoint._queue = aio.Queue(queue_size) class Protocol(asyncio.DatagramProtocol): def connection_lost(self, exc): endpoint._async_group.close() def datagram_received(self, data, addr): endpoint._queue.put_nowait((data, Address(addr[0], addr[1]))) loop = asyncio.get_running_loop() endpoint._transport, endpoint._protocol = \ await loop.create_datagram_endpoint(Protocol, local_addr, remote_addr, **kwargs) endpoint._async_group.spawn(aio.call_on_cancel, endpoint._transport.close) endpoint._async_group.spawn(aio.call_on_cancel, endpoint._queue.close) return endpoint
async def test_readexactly(addr): conn_queue = aio.Queue() srv = await tcp.listen(conn_queue.put_nowait, addr) conn1 = await tcp.connect(addr) conn2 = await conn_queue.get() data = b'123' result = await conn1.readexactly(0) assert result == b'' conn1.write(data) result = await conn2.readexactly(len(data)) assert result == data conn2.write(data) result = await conn1.readexactly(len(data) - 1) assert result == data[:-1] result = await conn1.readexactly(1) assert result == data[-1:] conn2.write(data) await conn2.async_close() with pytest.raises(ConnectionError): await conn1.readexactly(len(data) + 1) with pytest.raises(ConnectionError): await conn1.readexactly(1) await conn1.async_close() await srv.async_close()
async def create_server(address): server = Server() server._conn_queue = aio.Queue() server._srv = await chatter.listen( common.sbs_repo, address, lambda conn: server._conn_queue.put_nowait(Connection(conn))) return server
async def test_send_command(addr, command, success): conn_queue = aio.Queue() async def on_command(conn, commands): nonlocal command if (isinstance(command.value, iec104.NormalizedValue) or isinstance(command.value, iec104.FloatingValue)): assert math.isclose(command.value.value, commands[0].value.value, rel_tol=1e-3) command = command._replace(value=command.value._replace( value=commands[0].value.value)) assert commands == [command] return success srv = await iec104.listen(conn_queue.put_nowait, addr, command_cb=on_command) conn = await iec104.connect(addr) srv_conn = await conn_queue.get() result = await conn.send_command(command) assert result == success await srv.async_close() await conn.async_close() await srv_conn.async_close()
async def create_backend(path: Path, low_size: int, high_size: int, enable_archive: bool, disable_journal: bool ) -> 'Backend': """Create backend""" db = await database.create_database(path, disable_journal) try: first_id = await db.get_first_id() last_id = await db.get_last_id() except BaseException: await aio.uncancellable(db.async_close()) raise backend = Backend() backend._path = path backend._low_size = low_size backend._high_size = high_size backend._enable_archive = enable_archive backend._disable_journal = disable_journal backend._db = db backend._first_id = first_id backend._last_id = last_id backend._async_group = aio.Group() backend._change_cbs = util.CallbackRegistry() backend._msg_queue = aio.Queue(register_queue_size) backend._executor = aio.create_executor() backend._async_group.spawn(aio.call_on_cancel, db.async_close) backend._async_group.spawn(backend._loop) mlog.debug('created backend with database %s', path) return backend
def __init__(self, event_client: common.DeviceEventClient, event_type_prefix: common.EventTypePrefix): self._event_client = event_client self._event_type_prefix = event_type_prefix self._async_group = event_client.async_group.create_subgroup() self._read_queue = aio.Queue() self.async_group.spawn(self._read_loop)