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 __init__(self, pvdb, interfaces=None): if interfaces is None: interfaces = ca.get_server_address_list() self.interfaces = interfaces self.udp_socks = {} # map each interface to a UDP socket for searches self.beacon_socks = {} # map each interface to a UDP socket for beacons self.pvdb = pvdb self.log = logging.getLogger(f'caproto.ctx.{id(self)}') self.circuits = set() self.broadcaster = ca.Broadcaster(our_role=ca.SERVER) self.subscriptions = defaultdict(deque) # Map Subscription to {'before': last_update, 'after': last_update} # to silence duplicates for Subscriptions that use edge-triggered sync # Channel Filter. self.last_sync_edge_update = defaultdict(lambda: defaultdict(dict)) self.last_dead_band = {} self.beacon_count = 0 self.environ = get_environment_variables() # ca_server_port: the default tcp/udp port from the environment self.ca_server_port = self.environ['EPICS_CA_SERVER_PORT'] # the specific tcp port in use by this server self.port = None self.log.debug('EPICS_CA_SERVER_PORT set to %d. This is the UDP port ' 'to be used for searches, and the first TCP server port' ' to be tried.', self.ca_server_port) ignore_addresses = self.environ['EPICS_CAS_IGNORE_ADDR_LIST'] self.ignore_addresses = ignore_addresses.split(' ')
def __init__(self, pvdb, interfaces=None): if interfaces is None: interfaces = ca.get_server_address_list( protocol=ca.Protocol.PVAccess) self.interfaces = interfaces self.udp_socks = {} # map each interface to a UDP socket for searches self.beacon_socks = { } # map each interface to a UDP socket for beacons self.pvdb = pvdb self.log = logging.getLogger('caproto.pva.ctx') self.addresses = [] self.circuits = set() self.authentication_methods = {'anonymous', 'ca'} self.environ = get_environment_variables() # pva_server_port: the default tcp/udp port from the environment self.pva_server_port = self.environ['EPICS_PVAS_SERVER_PORT'] self.pva_broadcast_port = self.environ['EPICS_PVAS_BROADCAST_PORT'] self.broadcaster = pva.Broadcaster( our_role=ca.SERVER, broadcast_port=self.pva_broadcast_port, server_port=None, # TBD ) # the specific tcp port in use by this server self.port = None self.log.debug( 'EPICS_PVA_SERVER_PORT set to %d. This is the UDP port to be used' 'for searches.') self.subscription_queue = None self.subscriptions = defaultdict(deque)
def test_server_addresses(monkeypatch, protocol, env_addr, expected): env = ca.get_environment_variables() key = ca.Protocol(protocol).server_env_key env[f'EPICS_{key}_INTF_ADDR_LIST'] = env_addr patch_env(monkeypatch, env) assert set(ca.get_server_address_list(protocol=protocol)) == set(expected)
def __init__(self, pvdb, interfaces=None): if interfaces is None: interfaces = ca.get_server_address_list() self.interfaces = interfaces self.udp_socks = {} # map each interface to a UDP socket for searches self.beacon_socks = { } # map each interface to a UDP socket for beacons self.pvdb = pvdb self.log = logging.getLogger(f'caproto.ctx.{id(self)}') self.circuits = set() self.broadcaster = ca.Broadcaster(our_role=ca.SERVER) self.subscriptions = defaultdict(deque) # Map Subscription to {'before': last_update, 'after': last_update} # to silence duplicates for Subscriptions that use edge-triggered sync # Channel Filter. self.last_sync_edge_update = defaultdict(lambda: defaultdict(dict)) self.last_dead_band = {} self.beacon_count = 0 self.environ = get_environment_variables() ignore_addresses = self.environ['EPICS_CAS_IGNORE_ADDR_LIST'] self.ignore_addresses = ignore_addresses.split(' ')
def template_arg_parser(*, desc, default_prefix, argv=None, macros=None, supported_async_libs=None): """ Construct a template arg parser for starting up an IOC Parameters ---------- description : string Human-friendly description of what that IOC does. default_prefix : string args : list, optional Defaults to sys.argv macros : dict, optional Maps macro names to default value (string) or None (indicating that this macro parameter is required). supported_async_libs : list, optional "White list" of supported server implementations. The first one will be the default. If None specified, the parser will accept all of the (hard-coded) choices. Returns ------- parser : argparse.ArgumentParser split_args : callable[argparse.Namespace, Tuple[dict, dict]] A helper function to extract and split the 'standard' CL arguments. This function sets the logging level and returns the kwargs for constructing the IOC and for the launching the server. """ if argv is None: argv = sys.argv if macros is None: macros = {} parser = argparse.ArgumentParser( description=desc, formatter_class=argparse.RawDescriptionHelpFormatter, epilog=f'caproto version {ca.__version__}') parser.add_argument('--prefix', type=str, default=default_prefix) group = parser.add_mutually_exclusive_group() group.add_argument('-q', '--quiet', action='store_true', help=("Suppress INFO log messages. " "(Still show WARNING or higher.)")) group.add_argument('-v', '--verbose', action='count', help="Show more log messages. (Use -vvv for even more.)") parser.add_argument('--list-pvs', action='store_true', help="At startup, log the list of PV names served.") choices = tuple(supported_async_libs or ('asyncio', 'curio', 'trio')) parser.add_argument('--async-lib', default=choices[0], choices=choices, help=("Which asynchronous library to use. " "Default is asyncio.")) default_intf = ca.get_server_address_list(protocol=ca.Protocol.PVAccess) if default_intf == ['0.0.0.0']: default_msg = '0.0.0.0' else: default_msg = (f"{' '.join(default_intf)} as specified by environment " f"variable EPICS_PVAS_INTF_ADDR_LIST") parser.add_argument('--interfaces', default=default_intf, nargs='+', help=(f"Interfaces to listen on. Default is " f"{default_msg}. Multiple entries can be " f"given; separate entries by spaces.")) for name, default_value in macros.items(): if default_value is None: parser.add_argument(f'--{name}', type=str, required=True, help="Macro substitution required by this IOC") else: parser.add_argument(f'--{name}', type=str, default=default_value, help="Macro substitution, optional") def split_args(args): """ Helper function to pull the standard information out of the parsed args. Returns ------- ioc_options : dict kwargs to be handed into the IOC init. run_options : dict kwargs to be handed to run """ if args.verbose: if args.verbose > 1: ca.set_handler(level='DEBUG') else: ca._log._set_handler_with_logger(logger_name='caproto.pva.ctx', level='DEBUG') ca._log._set_handler_with_logger(logger_name='caproto.pva.circ', level='INFO') elif args.quiet: ca.set_handler(level='WARNING') else: ca._log._set_handler_with_logger(logger_name='caproto.pva.ctx', level='INFO') return ( # IOC options dict(prefix=args.prefix, macros={key: getattr(args, key) for key in macros}, ), # Run options dict( module_name=f'caproto.pva.{args.async_lib}.server', log_pv_names=args.list_pvs, interfaces=args.interfaces, ), ) return parser, split_args