def test_before_api_call_raise_exception(): from folklore.service import ServiceHandler, ApiMap, Context from folklore.hook import define_hook try: raise TypeError('type error') except Exception: info = sys.exc_info() app = ServiceHandler('TestService') @app.handle_system_exception def system_exception(tp, value, tb): return info[0], info[1], tb @define_hook(event='before_api_call') def raise_a_exception(ctx): raise AttributeError('exc') app.use(raise_a_exception) @app.api def raise_test(): return 'should not be called' api_map = ApiMap(app, Context({'client_addr': 'localhost', 'meta': {}})) with pytest.raises(TypeError) as exc: api_map.raise_test() assert str(exc.value) == 'type error'
def test_api_map(): from folklore.service import ApiMap, Context, ServiceHandler,\ SOFT_TIMEOUT, HARD_TIMEOUT, TApplicationException from folklore.hook import define_hook handler = ServiceHandler('TestService') @define_hook(event='before_api_call') def _test_ctx(ctx): for key in ('args', 'kwargs', 'api_name', 'start_at', 'conf', 'meta', 'logger', 'exc'): assert key in ctx assert ctx.conf['soft_timeout'] == SOFT_TIMEOUT assert ctx.conf['hard_timeout'] == HARD_TIMEOUT assert ctx.meta == {} handler.use(_test_ctx) @handler.api def ping(): return 'pong' api_map = ApiMap(handler, Context(client_addr='127.0.0.1', meta={})) ctx = api_map._ApiMap__ctx assert api_map.ping().value == 'pong' assert list(ctx.keys()) == ['env'] with pytest.raises(TApplicationException) as e: api_map.missing() assert str(e.value) == "API 'missing' undefined"
def test_use_hook(): from folklore.service import ServiceHandler from folklore.hook import define_hook app = ServiceHandler('TestService') @define_hook(event='test_hook') def test_hook(): return 'hello world' app.use(test_hook) assert app.hook_registry.on_test_hook() == ['hello world']
def test_extend(): from folklore.service import ServiceHandler, ServiceModule app = ServiceHandler('TestService') mod = ServiceModule() @mod.api def ping(): return 'pong' app.extend(mod) assert app.api_map['ping'].func is ping
def test_thrift_exception(): from folklore.service import ServiceHandler, ApiMap, Context from thriftpy.thrift import TException class ThriftException(TException): def __init__(self, msg): self.msg = msg def __repr__(self): return self.msg app = ServiceHandler('TestService') @app.handle_thrift_exception def thrift_exception(tp, value, tb): exc = TypeError(str(value)) return TypeError, exc, tb @app.api def thrift_raise(): raise ThriftException('thrift raise') api_map = ApiMap(app, Context({'client_addr': 'localhost', 'meta': {}})) with pytest.raises(TypeError) as exc: api_map.thrift_raise() assert str(exc.value) == 'thrift raise'
def test_service(): from folklore.service import FolkloreService, ServiceHandler handler = ServiceHandler('TestService', hard_timeout=20, soft_timeout=3) @handler.api def ping(): return 'pong' service = FolkloreService() service.set_handler(handler) m = service.api_map._ApiMap__map assert 'ping' in m assert m['ping'].func is ping assert m['ping'].conf == {'hard_timeout': 20, 'soft_timeout': 3} assert getattr(handler.thrift_module, 'TestService') is service.service_def
def test_exception_decorator(): from folklore.service import ServiceHandler try: raise TypeError('type error') except Exception: exc_info = sys.exc_info() app = ServiceHandler('TestService') for t, e, tb in [ app.system_exc_handler(*exc_info), app.api_exc_handler(*exc_info), ]: assert tb == exc_info[2] assert t is TApplicationException assert isinstance(e, TApplicationException) assert e.type == 6 assert e.message == 'type error' t, e, tb = app.thrift_exc_handler(*exc_info) assert tb == exc_info[2] assert t is TypeError assert isinstance(e, TypeError) try: raise AttributeError except Exception: info = sys.exc_info() @app.handle_system_exception def system_exception(tp, value, tb): return info @app.handle_api_exception def api_exception(tp, value, tb): return info @app.handle_thrift_exception def thrift_exception(tp, value, tb): return info assert app.system_exc_handler(*exc_info) == info assert app.api_exc_handler(*exc_info) == info assert app.thrift_exc_handler(*exc_info) == info
def test_service_handler(): from folklore.service import ServiceHandler handler = ServiceHandler('TestService', soft_timeout=10, hard_timeout=30) @handler.api def ping(): return 'pong' @handler.api(soft_timeout=15) def ping2(): return 'pong2' assert handler.api_map['ping'].func is ping assert handler.api_map['ping'].conf['soft_timeout'] == 10 assert handler.api_map['ping2'].func is ping2 assert handler.api_map['ping2'].conf['soft_timeout'] == 15 assert handler.service_name == 'TestService'
def test_timeout(): from folklore.service import ServiceHandler, ApiMap, Context import gevent app = ServiceHandler('TestService', soft_timeout=0, hard_timeout=1) class UnknownException(Exception): def __init__(self, exc): self.exc = exc @app.handle_system_exception def system_exception(tp, value, tb): exc = UnknownException(value) return UnknownException, exc, tb @app.api def timeout(): gevent.sleep(2) api_map = ApiMap(app, Context({'client_addr': 'localhost', 'meta': {}})) with pytest.raises(UnknownException) as exc: api_map.timeout() assert str(exc.value.exc) == 'Timeout after 1 seconds'
def test_api_exception(): from folklore.service import ServiceHandler, ApiMap, Context app = ServiceHandler('TestService') class ApiException(Exception): def __init__(self, exc): self.exc = exc @app.handle_api_exception def api_exception(tp, value, tb): exc = ApiException(value) return ApiException, exc, tb @app.api def api_unknown_raise(): raise TypeError('type error') api_map = ApiMap(app, Context({'client_addr': 'localhost', 'meta': {}})) with pytest.raises(ApiException) as exc: api_map.api_unknown_raise() assert isinstance(exc.value, ApiException) assert isinstance(exc.value.exc, TypeError) assert str(exc.value.exc) == 'type error'