def test_env_util_smoke(protocol): ca.get_environment_variables() try: ca.get_netifaces_addresses() except RuntimeError: # Netifaces may be unavailable ... ca.get_address_list(protocol=protocol) ca.get_beacon_address_list(protocol=protocol) ca._utils.get_manually_specified_beacon_addresses(protocol=protocol) ca._utils.get_manually_specified_client_addresses(protocol=protocol) ca.get_server_address_list(protocol=protocol)
def test_broadcast_auto_address_list(): pytest.importorskip('netifaces') env = os.environ.copy() try: os.environ['EPICS_CA_ADDR_LIST'] = '' os.environ['EPICS_CA_AUTO_ADDR_LIST'] = 'YES' expected = [bcast for addr, bcast in ca.get_netifaces_addresses()] assert ca.get_address_list() == expected finally: os.environ = env
def search(*pvs): '''Search for a PV over the network by broadcasting over UDP Returns: (host, port) ''' udp_sock = bcast_socket() udp_sock.bind(('', 0)) port = udp_sock.getsockname()[1] seq_id = random.randint(1, 2 ** 31) search_ids = {pv: random.randint(1, 2 ** 31) for pv in pvs} search_req = pva.SearchRequestLE( sequence_id=seq_id, flags=(pva.SearchFlags.reply_required | pva.SearchFlags.broadcast), response_address='127.0.0.1', # TODO host ip response_port=port, protocols=['tcp'], channels=[{'id': search_ids[pv], 'channel_name': pv} for pv in pvs] ) # NOTE: cache needed here to give interface for channels cache = pva.CacheContext() payload = search_req.serialize(cache=cache) header = pva.MessageHeaderLE( flags=(pva.MessageFlags.APP_MESSAGE | pva.MessageFlags.FROM_CLIENT | pva.MessageFlags.LITTLE_ENDIAN), command=search_req.ID, payload_size=len(payload) ) for addr, bcast_addr in get_netifaces_addresses(): search_req.response_address = addr bytes_to_send = bytes(header) + search_req.serialize(cache=cache) dest = (addr, pva.PVA_BROADCAST_PORT) print('Sending SearchRequest to', bcast_addr, 'requesting response at {}:{}'.format(addr, port)) udp_sock.sendto(bytes_to_send, dest) response_data, addr = udp_sock.recvfrom(1024) response_data = bytearray(response_data) print('Received from', addr, ':', response_data) response_header, buf, offset = pva.MessageHeaderLE.deserialize( response_data, cache=pva.NullCache) assert response_header.valid msg_class = response_header.get_message( pva.MessageFlags.FROM_SERVER, use_fixed_byte_order=pva.LITTLE_ENDIAN) print('Response header:', response_header) print('Response msg class:', msg_class) msg, buf, off = msg_class.deserialize(buf, cache=pva.NullCache) offset += off print('Response message:', msg) assert offset == len(response_data) if msg.found: id_to_pv = {id_: pv for pv, id_ in search_ids.items()} found_pv = id_to_pv[msg.search_instance_ids[0]] print('Found {} on {}:{}!' ''.format(found_pv, msg.server_address, msg.server_port)) return (msg.server_address, msg.server_port) else: # TODO as a simple client, this only grabs the first response from # the quickest server, which is clearly not the right way to do it raise ValueError('PVs {} not found in brief search' ''.format(pvs))