def test_middleware_preserves_file_wrapper(wsgi_env, start_response, context, tmpdir): path = tmpdir.join('filecontent') path.write('CONTENT') def app(environ, _start_response): _start_response('200 OK', [('Content-Type', 'text/plain')]) return environ['wsgi.file_wrapper'](open(str(path))) mw = wsgi.TaliskerMiddleware(app, {}, {}) wsgi_env['wsgi.file_wrapper'] = wsgiref.util.FileWrapper with freeze_time() as frozen: respiter = mw(wsgi_env, start_response) context.assert_not_log(msg='GET /') frozen.tick(1.0) respiter.close() assert isinstance(respiter, wsgiref.util.FileWrapper) context.assert_log( msg='GET /', extra=dict([ ('method', 'GET'), ('path', '/'), ('status', 200), ('duration_ms', 1000.0), ('ip', '127.0.0.1'), ('proto', 'HTTP/1.0'), ('length', len('CONTENT')), ('filepath', str(path)), ]), )
def test_middleware_basic(wsgi_env, start_response, context): def app(environ, _start_response): _start_response('200 OK', [('Content-Type', 'text/plain')]) return [b'OK'] extra_env = {'ENV': 'VALUE'} extra_headers = {'Some-Header': 'value'} wsgi_env['HTTP_X_REQUEST_ID'] = 'ID' mw = wsgi.TaliskerMiddleware(app, extra_env, extra_headers) output = b''.join(mw(wsgi_env, start_response)) assert output == b'OK' assert wsgi_env['ENV'] == 'VALUE' assert wsgi_env['REQUEST_ID'] == 'ID' assert start_response.status == '200 OK' assert start_response.headers == [ ('Content-Type', 'text/plain'), ('Some-Header', 'value'), ('X-Request-Id', 'ID'), ] context.assert_log( name='talisker.wsgi', msg='GET /', extra={'request_id': 'ID'}, )
def test_middleware_debug_invalid_ip(wsgi_env, start_response, context): def app(environ, _start_response): _start_response('200 OK', [('Content-Type', 'text/plain')]) return [b'OK'] wsgi_env['HTTP_X_DEBUG'] = '1' wsgi_env['REMOTE_ADDR'] = '1.2.3.4' mw = wsgi.TaliskerMiddleware(app, {}, {}) output = b''.join(mw(wsgi_env, start_response)) assert output == b'OK' assert start_response.status == '200 OK' if talisker.sentry.enabled: assert len(context.sentry) == 0 context.assert_log( level='warning', msg='X-Debug header set but not trusted IP address', extra={ 'access_route': '1.2.3.4', 'x_debug': '1', }, )
def test_middleware_debug(wsgi_env, start_response, context): def app(environ, _start_response): _start_response('200 OK', [('Content-Type', 'text/plain')]) return [b'OK'] wsgi_env['HTTP_X_DEBUG'] = '1' mw = wsgi.TaliskerMiddleware(app, {}, {}) output = b''.join(mw(wsgi_env, start_response)) assert output == b'OK' assert start_response.status == '200 OK' if talisker.sentry.enabled: msg = context.sentry[0] assert msg['message'] == 'Debug: /' assert msg['level'] == 'debug'
def test_middleware_debug_middleware_no_content(wsgi_env, start_response, context): from werkzeug.debug import DebuggedApplication # DebuggedApplication turns any WSGI app into a super lazy version def app(environ, start_response): start_response('304 Not Modified', []) # no content return [] mw = wsgi.TaliskerMiddleware(DebuggedApplication(app), {}, {}) output = b''.join(mw(wsgi_env, start_response)) assert start_response.status == '304 Not Modified' assert output == b''
def test_middleware_sets_header_deadline(wsgi_env, start_response, config): config['TALISKER_REQUEST_TIMEOUT'] = 2000 contexts = [] def app(environ, _start_response): contexts.append(Context.current()) _start_response('200 OK', [('Content-Type', 'text/plain')]) return [b'OK'] ts = datetime.utcnow() + timedelta(seconds=10) wsgi_env['HTTP_X_REQUEST_DEADLINE'] = ts.isoformat() + 'Z' mw = wsgi.TaliskerMiddleware(app, {}, {}) list(mw(wsgi_env, start_response)) assert contexts[0].deadline == datetime_to_timestamp(ts)
def test_middleware_sets_deadlines(wsgi_env, start_response, config): config['TALISKER_SOFT_REQUEST_TIMEOUT'] = 1000 config['TALISKER_REQUEST_TIMEOUT'] = 2000 contexts = [] def app(environ, _start_response): contexts.append(Context.current()) _start_response('200 OK', [('Content-Type', 'text/plain')]) return [b'OK'] mw = wsgi.TaliskerMiddleware(app, {}, {}) list(mw(wsgi_env, start_response)) assert contexts[0].soft_timeout == 1000 assert contexts[0].deadline == contexts[0].start_time + 2.0
def test_middleware_error_after_start_response( exc_type, wsgi_env, start_response, sentry_id, context): def app(wsgi_env, _start_response): _start_response('200 OK', [('Content-Type', 'application/json')]) raise exc_type('error') extra_env = {'ENV': 'VALUE'} extra_headers = {'Some-Header': 'value'} wsgi_env['HTTP_X_REQUEST_ID'] = 'ID' wsgi_env['HTTP_ACCEPT'] = 'application/json' mw = wsgi.TaliskerMiddleware(app, extra_env, extra_headers) output = b''.join(mw(wsgi_env, start_response)) error = json.loads(output.decode('utf8')) assert error['title'] == 'Server Error: ' + exc_type.__name__ assert wsgi_env['ENV'] == 'VALUE' assert wsgi_env['REQUEST_ID'] == 'ID' assert start_response.status == '500 Internal Server Error' assert start_response.headers[:4] == [ ('Content-Type', 'application/json'), ('Some-Header', 'value'), ('X-Request-Id', 'ID'), ('X-Sentry-Id', 'SENTRY_ID') ] extra = { 'status': 500, 'exc_type': exc_type.__name__, } if exc_type is wsgi.RequestTimeout: extra['timeout'] = True context.assert_log( name='talisker.wsgi', msg='GET /', extra=extra, ) if talisker.sentry.enabled: msg = context.sentry[0] assert msg['event_id'] == 'SENTRY_ID' assert msg['message'] == '{}: {}'.format( exc_type.__name__, 'error' )
def test_middleware_debug_middleware(wsgi_env, start_response, context): from werkzeug.debug import DebuggedApplication # DebuggedApplication turns any WSGI app into a super lazy version def app(environ, start_response): start_response('302 Found', [('Location', '/other')]) yield b'' mw = wsgi.TaliskerMiddleware(DebuggedApplication(app), {}, {}) wsgi_env['HTTP_X_REQUEST_ID'] = 'ID' output = b''.join(mw(wsgi_env, start_response)) assert start_response.status == '302 Found' assert output == b'' assert start_response.headers == [ ('Location', '/other'), ('X-Request-Id', 'ID'), ]
def test_middleware_debug_middleware_error(wsgi_env, start_response, context): from werkzeug.debug import DebuggedApplication def app(environ, _): raise Exception('error') mw = wsgi.TaliskerMiddleware(DebuggedApplication(app), {}, {}) wsgi_env['HTTP_X_REQUEST_ID'] = 'ID' list(mw(wsgi_env, start_response)) assert start_response.status == '500 INTERNAL SERVER ERROR' assert start_response.headers == [ ('Content-Type', 'text/html; charset=utf-8'), ('X-XSS-Protection', '0'), ('X-Request-Id', 'ID'), ] context.assert_log(name='talisker.wsgi', msg='GET /')