async def test_sentry_extras_provider_subscriber(self, wampclient: WAMPClient, context: Context, monkeypatch): class DummyReporter(ExceptionReporter): def report_exception(self, ctx: Context, exception: BaseException, message: str, extra: Dict[str, Any]) -> None: errors.append((exception, message, extra)) def handler(ctx): ctx.loop.call_soon(event.set) raise Exception('foo') event = asyncio.Event() errors = [] context.add_resource(DummyReporter(), types=[ExceptionReporter]) context.add_resource(WAMPExtrasProvider(), types=[ExtrasProvider]) await wampclient.subscribe(handler, 'dummytopic') monkeypatch.setattr('asphalt.wamp.extras_providers.SENTRY_CLASS_NAME', qualified_name(DummyReporter)) await wampclient.publish('dummytopic', options=dict(acknowledge=True, exclude_me=False)) await event.wait() assert len(errors) == 1 exc, message, extra = errors[0] assert type(exc) is Exception assert str(exc) == 'foo' assert message == "Error running subscription handler for topic 'dummytopic'" assert extra == {'extra': {'topic': 'dummytopic'}, 'user_context': {'auth_role': 'authorized_users', 'id': 'device1', 'session_id': wampclient.session_id} }
async def start(self, ctx: Context): if isinstance(self.commit_executor, str): self.commit_executor = await ctx.request_resource(Executor, self.commit_executor) elif self.commit_executor is None: self.commit_executor = ThreadPoolExecutor(self.commit_executor_workers) ctx.add_teardown_callback(self.commit_executor.shutdown) for resource_name, context_attr, bind, factory, ready_callback in self.session_factories: if ready_callback: retval = ready_callback(bind, factory) if isawaitable(retval): await retval engine = bind if isinstance(bind, Engine) else bind.engine ctx.add_resource(engine, resource_name) ctx.add_resource(factory, resource_name) ctx.add_resource_factory(partial(self.create_session, factory=factory), [Session], resource_name, context_attr) logger.info('Configured SQLAlchemy session maker (%s / ctx.%s; dialect=%s)', resource_name, context_attr, bind.dialect.name) await yield_() for resource_name, context_attr, bind, factory, ready_callback in self.session_factories: if isinstance(bind, Engine): bind.dispose() logger.info('SQLAlchemy session maker (%s / ctx.%s) shut down', resource_name, context_attr)
async def test_report_applicationerror(self, wampclient: WAMPClient, context: Context, custom_exception): class DummyReporter(ExceptionReporter): def report_exception(self, ctx: Context, exception: BaseException, message: str, extra: Dict[str, Any]) -> None: errors.append((exception, message, extra)) class CustomError(Exception): pass def handler(ctx): if custom_exception: raise CustomError else: raise ApplicationError('dummy.error') errors = [] context.add_resource(DummyReporter(), types=[ExceptionReporter]) wampclient.map_exception(CustomError, 'dummy.error') await wampclient.register(handler, 'dummyprocedure') with pytest.raises(CustomError): await wampclient.call('dummyprocedure') assert not errors
async def test_sentry_extras_provider_procedure(self, wampclient: WAMPClient, context: Context, monkeypatch): class DummyReporter(ExceptionReporter): def report_exception(self, ctx: Context, exception: BaseException, message: str, extra: Dict[str, Any]) -> None: errors.append((exception, message, extra)) def handler(ctx): raise Exception('foo') errors = [] context.add_resource(DummyReporter(), types=[ExceptionReporter]) context.add_resource(WAMPExtrasProvider(), types=[ExtrasProvider]) await wampclient.register(handler, 'dummyprocedure') monkeypatch.setattr('asphalt.wamp.extras_providers.SENTRY_CLASS_NAME', qualified_name(DummyReporter)) with pytest.raises(ApplicationError): await wampclient.call('dummyprocedure') assert len(errors) == 1 exc, message, extra = errors[0] assert type(exc) is Exception assert str(exc) == 'foo' assert message == "Error running handler for procedure 'dummyprocedure'" assert extra == {'extra': {'procedure': 'dummyprocedure'}, 'user_context': {'auth_role': 'authorized_users', 'id': 'device1', 'session_id': wampclient.session_id} }
def test_get_resources(self, context): context.add_resource(9, 'foo') context.add_resource_factory(lambda ctx: len(ctx.context_chain), int, 'bar') context.require_resource(int, 'bar') subctx = Context(context) subctx.add_resource(4, 'foo') assert subctx.get_resources(int) == {1, 4}
async def start(self, ctx: Context): for resource_name, context_attr, serializer in self.serializers: types = [Serializer, type(serializer)] if isinstance(serializer, CustomizableSerializer): types.append(CustomizableSerializer) ctx.add_resource(serializer, resource_name, context_attr, types=types) logger.info('Configured serializer (%s / ctx.%s; type=%s)', resource_name, context_attr, serializer.mimetype)
async def start(self, ctx: Context): for resource_name, context_attr, client in self.clients: ctx.add_resource(client, resource_name, context_attr) logger.info('Configured Memcached client (%s / ctx.%s)', resource_name, context_attr) await yield_() for resource_name, context_attr, client in self.clients: client.close() logger.info('Memcached client (%s) shut down', resource_name)
async def start(self, ctx: Context): for resource_name, store in self.stores: await store.start(ctx) ctx.add_resource(store, resource_name) logger.info('Configured feed state store (%s; class=%s)', resource_name, qualified_name(store)) for resource_name, context_attr, config in self.feeds: feed = await create_feed(ctx, **config) ctx.add_resource(feed, resource_name, context_attr, types=[type(feed), FeedReader]) logger.info('Configured feed (%s / ctx.%s; url=%s)', resource_name, context_attr, feed.url)
async def start(self, ctx: Context): for resource_name, context_attr, server in self.servers: await server.start(ctx) ctx.add_resource(server, resource_name, context_attr, BaseWebServer) logger.info('Started %s (%s / ctx.%s)', server.__class__.__name__, resource_name, context_attr) await yield_() for resource_name, context_attr, server in self.servers: await server.shutdown() logger.info('Shut down %s (%s)', server.__class__.__name__, resource_name)
async def start(self, ctx: Context): for resource_name, context_attr, client in self.clients: await client.start(ctx) ctx.add_resource(client, resource_name, context_attr) logger.info( 'Configured InfluxDB client (%s / ctx.%s; base_urls=%r)', resource_name, context_attr, client.base_urls) await yield_() for resource_name, context_attr, client in self.clients: logger.info('InfluxDB client (%s) shut down', resource_name)
async def start(self, ctx: Context): for resource_name, context_attr, mailer in self.mailers: await mailer.start(ctx) ctx.add_resource(mailer, resource_name, context_attr, [Mailer, type(mailer)]) logger.info('Configured mailer (%s / ctx.%s; class=%s)', resource_name, context_attr, mailer.__class__.__name__) await yield_() for resource_name, context_attr, mailer in self.mailers: logger.info('Mailer (%s) stopped', resource_name)
async def start(self, ctx: Context): # Autobahn uses txaio to bridge the API gap between asyncio and Twisted so we need to set # it up for asyncio here txaio.use_asyncio() txaio.config.loop = ctx.loop ctx.add_resource(WAMPExtrasProvider(), 'wamp', types=[ExtrasProvider]) for resource_name, context_attr, client in self.clients: await client.start(ctx) ctx.add_resource(client, resource_name, context_attr) logger.info('Configured WAMP client (%s / ctx.%s; host=%s; port=%d; realm=%s)', resource_name, context_attr, client.host, client.port, client.realm) await yield_() for resource_name, context_attr, client in self.clients: await client.stop() logger.info('Shut down WAMP client (%s)', resource_name)
async def start(self, ctx: Context) -> AsyncGenerator[None, Exception | None]: if self.ready_callback: retval = self.ready_callback(self.bind, self.sessionmaker) if isawaitable(retval): await retval ctx.add_resource(self.engine, self.resource_name) ctx.add_resource(self.sessionmaker, self.resource_name) if isinstance(self.engine, AsyncEngine): ctx.add_resource_factory( self.create_async_session, [AsyncSession], self.resource_name, ) else: self.commit_executor = ThreadPoolExecutor( self.commit_executor_workers) ctx.add_teardown_callback(self.commit_executor.shutdown) ctx.add_resource_factory( self.create_session, [Session], self.resource_name, ) logger.info( "Configured SQLAlchemy resources (%s; dialect=%s, driver=%s)", self.resource_name, self.bind.dialect.name, self.bind.dialect.driver, ) yield if isinstance(self.bind, Engine): self.bind.dispose() elif isinstance(self.bind, AsyncEngine): await self.bind.dispose() logger.info("SQLAlchemy resources (%s) shut down", self.resource_name)