def main(): parser = argparse.ArgumentParser(description='Run a hpfeeds broker') parser.add_argument('--bind', default=None, action='store') parser.add_argument('--exporter', default='', action='store') parser.add_argument('--name', default='hpfeeds', action='store') parser.add_argument('--debug', default=False, action='store_true') parser.add_argument('--auth', default=None, action='append') parser.add_argument('--tlscert', default=None, action='store') parser.add_argument('--tlskey', default=None, action='store') parser.add_argument('-e', '--endpoint', default=None, action='append') args = parser.parse_args() if (args.tlscert and not args.tlskey) or (args.tlskey and not args.tlscert): parser.error('Must specify --tlskey AND --tlscert') return logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO, ) auth = multi.Authenticator() auths = args.auth if args.auth else ['sqlite'] for a in auths: try: auth.add(get_authenticator(a)) except ServerException as e: print(str(e)) sys.exit(1) broker = Server( auth=auth, exporter=args.exporter, name=args.name, ) if args.bind or not args.endpoint: bind = args.bind or '0.0.0.0:20000' broker.add_endpoint_legacy(bind, tlscert=args.tlscert, tlskey=args.tlskey) if args.endpoint: for endpoint in args.endpoint: broker.add_endpoint_str(endpoint) return aiorun.run(broker.serve_forever())
class TestBrokerIntegration(unittest.TestCase): log = logging.getLogger('hpfeeds.test_broker_connection') def setUp(self): authenticator = Authenticator({ 'test': { 'secret': 'secret', 'subchans': ['test-chan'], 'pubchans': ['test-chan'], 'owner': 'some-owner', } }) self.server = Server(authenticator) self.server.add_endpoint_str( "tls:interface=127.0.0.1:port=0:cert=hpfeeds/tests/testcert.crt:key=hpfeeds/tests/testcert.key" ) def test_subscribe_and_publish(self): prometheus.reset() async def inner(): self.log.debug('Starting server') server_future = asyncio.ensure_future(self.server.serve_forever()) await self.server.when_started self.port = self.server.endpoints[0]['port'] import ssl ssl_context = ssl.create_default_context( ssl.Purpose.SERVER_AUTH, cafile='hpfeeds/tests/testcert.crt') ssl_context.check_hostname = False self.log.debug('Creating client service') client = ClientSession('127.0.0.1', self.port, 'test', 'secret', ssl=ssl_context) client.subscribe('test-chan') # Wait till client connected await client.when_connected assert prometheus.REGISTRY.get_sample_value( 'hpfeeds_broker_client_connections') == 1 assert prometheus.REGISTRY.get_sample_value( 'hpfeeds_broker_connection_made') == 1 self.log.debug('Publishing test message') client.publish('test-chan', b'test message') self.log.debug('Waiting for read()') assert ('test', 'test-chan', b'test message') == await client.read() # We would test this after call to subscribe, but need to wait until sure server has processed command assert prometheus.REGISTRY.get_sample_value( 'hpfeeds_broker_subscriptions', { 'ident': 'test', 'chan': 'test-chan' }) == 1 # This will only have incremented when server has processed auth message # Test can only reliably assert this is the case after reading a message assert prometheus.REGISTRY.get_sample_value( 'hpfeeds_broker_connection_ready', {'ident': 'test'}) == 1 self.log.debug('Stopping client') await client.close() assert prometheus.REGISTRY.get_sample_value( 'hpfeeds_broker_connection_send_buffer_fill', {'ident': 'test'}) == 12 assert prometheus.REGISTRY.get_sample_value( 'hpfeeds_broker_connection_send_buffer_drain', {'ident': 'test'}) == 32 self.log.debug('Stopping server') server_future.cancel() await server_future asyncio.get_event_loop().run_until_complete(inner()) assert len(self.server.connections) == 0, 'Connection left dangling' assert prometheus.REGISTRY.get_sample_value( 'hpfeeds_broker_client_connections') == 0 assert prometheus.REGISTRY.get_sample_value( 'hpfeeds_broker_connection_lost', {'ident': 'test'}) == 1 # Closing should auto unsubscribe assert prometheus.REGISTRY.get_sample_value( 'hpfeeds_broker_subscriptions', { 'ident': 'test', 'chan': 'test-chan' }) == 0