def test_body_schema(self): class Api(object): app = Klein() @app.route('/') @json_body @validate(body_schema({'properties': {'foo': {'type': 'string'}}})) def route(self, req, body): pass srv = yield ToyServer.from_test(self, Api().app) resp = yield treq.get( srv.url, persistent=False, data=json.dumps({'foo': 23})) self.assertEqual(json.loads((yield resp.content())), { 'errors': [{ 'type': 'invalid_body', 'message': "23 is not of type 'string'" }] }) resp = yield treq.get( srv.url, persistent=False, data=json.dumps({'foo': 'bar'})) self.assertEqual(resp.code, http.OK)
def test_retry(self): srv = yield ToyServer.from_test(self) reqs = [] @srv.app.route('/foo') def route(req): reqs.append(req) return 'ok' resp = yield retry({ 'owner_id': '1234', 'timestamp': 5, 'attempts': 0, 'intervals': [10], 'request': { 'url': "%s/foo" % (srv.url,), 'method': 'POST' } }, persistent=False) self.assertEqual(resp.code, 200) self.assertEqual((yield resp.content()), 'ok') [req] = reqs self.assertEqual(req.method, 'POST')
def test_retry(self): msgs = self.patch_log() worker = yield self.mk_worker() yield worker.stop() srv = yield ToyServer.from_test(self) reqs = [] @srv.app.route('/foo') def route(req): reqs.append(req) req = { 'owner_id': '1234', 'timestamp': 5, 'attempts': 0, 'intervals': [10], 'request': { 'url': "%s/foo" % (srv.url,), 'method': 'POST' } } pop_all(msgs) yield worker.retry(req) self.assertEqual(pop_all(msgs), [ ('Retrying request', req), ('Retry successful (200)', req), ]) [req] = reqs self.assertEqual(req.method, 'POST') self.assertEqual((yield zitems(worker.redis, pending_key('test'))), [])
def test_has_header(self): class Api(object): app = Klein() @app.route('/') @validate(has_header('X-Foo')) def route(self, req): pass srv = yield ToyServer.from_test(self, Api().app) resp = yield treq.get(srv.url, persistent=False) self.assertEqual(json.loads((yield resp.content())), { 'errors': [{ 'type': 'header_missing', 'message': "Header 'X-Foo' is missing" }] }) resp = yield treq.get( srv.url, headers={'X-Foo': ['bar']}, persistent=False) self.assertEqual(resp.code, http.OK)
def test_validate_fail(self): class Api(object): app = Klein() @app.route('/') @validate( lambda _: errs1, lambda _: None, lambda _: errs2) def route(self, req): pass errs1 = [{ 'type': '1', 'message': 'a' }] errs2 = [{ 'type': 'b', 'message': 'B' }] srv = yield ToyServer.from_test(self, Api().app) resp = yield treq.get(srv.url, persistent=False) self.assertEqual(resp.code, http.BAD_REQUEST) self.assertEqual(json.loads((yield resp.content())), { 'errors': errs1 + errs2 })
def test_retry_unicode(self): srv = yield ToyServer.from_test(self) reqs = [] @srv.app.route('/') def route(req): reqs.append({ 'method': req.method, 'body': req.content.read(), 'headers': { 'X-Bar': req.requestHeaders.getRawHeaders('X-Bar'), } }) yield retry({ 'owner_id': '1234', 'timestamp': 5, 'attempts': 0, 'intervals': [10, 20, 30], 'request': { 'url': u"%s" % (srv.url,), 'method': u'POST', 'body': u'foo', 'headers': {u'X-Bar': [u'baz', u'quux']} } }, persistent=False) [req] = reqs self.assertEqual(req, { 'method': 'POST', 'body': 'foo', 'headers': {'X-Bar': ['baz', 'quux']} })
def test_retry_inc_attempts(self): srv = yield ToyServer.from_test(self) @srv.app.route('/foo') def route(_): pass req = { 'owner_id': '1234', 'timestamp': 5, 'attempts': 0, 'intervals': [10, 20, 30], 'request': { 'url': "%s/foo" % (srv.url,), 'method': 'GET' } } yield retry(req, persistent=False) self.assertEqual(req['attempts'], 1) yield retry(req, persistent=False) self.assertEqual(req['attempts'], 2) yield retry(req, persistent=False) self.assertEqual(req['attempts'], 3)
def test_retry_headers(self): srv = yield ToyServer.from_test(self) headers = [] @srv.app.route('/foo') def route(req): headers.append({ 'X-Foo': req.requestHeaders.getRawHeaders('X-Foo'), 'X-Bar': req.requestHeaders.getRawHeaders('X-Bar') }) yield retry({ 'owner_id': '1234', 'timestamp': 5, 'attempts': 0, 'intervals': [10], 'request': { 'url': "%s/foo" % (srv.url,), 'method': 'POST', 'headers': { 'X-Foo': ['a', 'b'], 'X-Bar': ['c', 'd'], } } }, persistent=False) self.assertEqual(headers, [{ 'X-Foo': ['a', 'b'], 'X-Bar': ['c', 'd'], }])
def test_response_code(self): srv = yield ToyServer.from_test(self) @srv.app.route('/') def route(req): return response(req, {}, http.BAD_REQUEST) resp = yield treq.get(srv.url, persistent=False) self.assertEqual(resp.code, http.BAD_REQUEST)
def test_response_data(self): srv = yield ToyServer.from_test(self) @srv.app.route('/') def route(req): return response(req, {'foo': 23}) resp = yield treq.get(srv.url, persistent=False) self.assertEqual(json.loads((yield resp.content())), {'foo': 23})
def test_response_content_type(self): srv = yield ToyServer.from_test(self) @srv.app.route('/') def route(req): return response(req, {}) resp = yield treq.get(srv.url, persistent=False) self.assertEqual( resp.headers.getRawHeaders('Content-Type'), ['application/json'])
def test_retry_end(self): msgs = self.patch_log() worker = yield self.mk_worker() srv = yield ToyServer.from_test(self) yield worker.stop() @srv.app.route('/foo') def route(req): req.setResponseCode(500) req1 = { 'owner_id': '1234', 'timestamp': 5, 'attempts': 1, 'intervals': [10, 20], 'request': { 'url': "%s/foo" % (srv.url,), 'method': 'POST' } } req2 = { 'owner_id': '1234', 'timestamp': 10, 'attempts': 2, 'intervals': [10, 30, 40], 'request': { 'url': "%s/foo" % (srv.url,), 'method': 'POST' } } pop_all(msgs) yield worker.retry(req1) self.assertEqual(pop_all(msgs), [ ('Retrying request', req1), ('Retry failed (500)', req1), ('No remaining retry intervals, discarding request', req1), ]) yield worker.retry(req2) self.assertEqual(pop_all(msgs), [ ('Retrying request', req2), ('Retry failed (500)', req2), ('No remaining retry intervals, discarding request', req2), ]) self.assertEqual((yield zitems(worker.redis, pending_key('test'))), [])
def test_retry_timeout_reschedule(self): k = pending_key('test') msgs = self.patch_log() worker = yield self.mk_worker({'timeout': 3}) srv = yield ToyServer.from_test(self) self.patch_reactor_call_later(worker.clock) yield worker.stop() @srv.app.route('/foo') def route(req): return Deferred() req = { 'owner_id': '1234', 'timestamp': 5, 'attempts': 0, 'intervals': [10, 20], 'request': { 'url': "%s/foo" % (srv.url,), 'method': 'POST' } } pop_all(msgs) d = worker.retry(req) worker.clock.advance(2) self.assertEqual((yield zitems(worker.redis, k)), []) worker.clock.advance(4) yield d self.assertEqual(pop_all(msgs), [ ('Retrying request', req), ('Retry timed out', req), ('Rescheduling retry', req), ]) self.assertEqual((yield zitems(worker.redis, k)), [ (5 + 20, { 'owner_id': '1234', 'timestamp': 5, 'attempts': 1, 'intervals': [10, 20], 'request': { 'url': "%s/foo" % (srv.url,), 'method': 'POST' } }), ])
def test_validate_pass(self): class Api(object): app = Klein() @app.route('/') @validate( lambda _: None, lambda _: None) def route(self, req): return 'ok' srv = yield ToyServer.from_test(self, Api().app) resp = yield treq.get(srv.url, persistent=False) self.assertEqual(resp.code, http.OK) self.assertEqual((yield resp.content()), 'ok')
def test_retry_failed(self): srv = yield ToyServer.from_test(self) @srv.app.route('/<int:code>') def route(req, code): req.setResponseCode(code) def send(code): return treq.get("%s/%s" % (srv.url, code), persistent=False) self.assertFalse(retry_failed((yield send(200)))) self.assertFalse(retry_failed((yield send(201)))) self.assertFalse(retry_failed((yield send(400)))) self.assertFalse(retry_failed((yield send(404)))) self.assertTrue(retry_failed((yield send(500)))) self.assertTrue(retry_failed((yield send(504)))) self.assertTrue(retry_failed((yield send(599))))
def test_json_body(self): class Api(object): app = Klein() @app.route('/') @json_body def route(self, req, body): bodies.append(body) bodies = [] srv = yield ToyServer.from_test(self, Api().app) yield treq.get( srv.url, persistent=False, data=json.dumps({'foo': 23})) self.assertEqual(bodies, [{'foo': 23}])
def test_retry_data(self): srv = yield ToyServer.from_test(self) contents = [] @srv.app.route('/foo') def route(req): contents.append(req.content.read()) yield retry({ 'owner_id': '1234', 'timestamp': 5, 'attempts': 0, 'intervals': [10], 'request': { 'url': "%s/foo" % (srv.url,), 'method': 'POST', 'body': 'hi' } }, persistent=False) self.assertEqual(contents, ['hi'])
def test_retry_no_dec_req_count_on_reattempt(self): worker = yield self.mk_worker() srv = yield ToyServer.from_test(self) @srv.app.route('/') def route(req): req.setResponseCode(500) yield set_req_count(worker.redis, 'test', '1234', 3) yield worker.retry({ 'owner_id': '1234', 'timestamp': 5, 'attempts': 0, 'intervals': [10, 20], 'request': { 'url': srv.url, 'method': 'GET' } }) self.assertEqual( (yield get_req_count(worker.redis, 'test', '1234')), 3)