Permalink
Browse files

Fixing previous fix that didn't fix the Content-Length bug

Added new unit tests to make sure that the behavior is correct
  • Loading branch information...
1 parent 24d55ea commit d40f909a2c78351ace1fc62abaf9c27c3675c1ef @kelvl kelvl committed Aug 22, 2012
Showing with 129 additions and 12 deletions.
  1. +19 −8 src/shadow/proxy/web.py
  2. +110 −4 tests/unit/test_proxy_flask.py
View
@@ -95,13 +95,22 @@ def format_response(self, response, elapsed_time=None):
}
return resp
- def format_request(self, request):
+ def format_request(self, url, method, headers, params, data, request):
req = {
- 'url': request.path,
- 'method': request.method,
- 'headers': dict([(unicode(k), unicode(v)) for k, v in request.headers.items()]),
- 'get': dict([(unicode(k), unicode(v)) for k, v in request.args.items()]),
- 'post': dict([(unicode(k), unicode(v)) for k, v in request.form.items()])
+ 'original': {
+ 'url': request.path,
+ 'method': request.method,
+ 'headers': dict([(unicode(k), unicode(v)) for k, v in request.headers.items()]),
+ 'get': dict([(unicode(k), unicode(v)) for k, v in request.args.items()]),
+ 'post': dict([(unicode(k), unicode(v)) for k, v in request.form.items()])
+ },
+ 'modified': {
+ 'url': url,
+ 'method': method,
+ 'headers': headers,
+ 'get': params,
+ 'post': data
+ }
}
return req
@@ -128,9 +137,11 @@ def timer(self, timed_func, *args, **kwargs):
def catch_all(self, path):
method = request.method
- headers = dict([(k, v) for k, v in request.headers.items() if v not in ('Content-Length', '')])
+ headers = dict([(k, v) for k, v in request.headers.items() if k not in ('Content-Length')])
params = dict(request.args)
data = dict(request.form)
+ url = request.path
+
true_greenlets = [self.service.spawn(self.timer, timed_func=requests.request,
method=method,
url='{server}{path}'.format(server=service, path=path),
@@ -153,7 +164,7 @@ def catch_all(self, path):
greenlets = true_greenlets + shadow_greenlets
- self.service.spawn(self.process_greenlets, self.format_request(request), greenlets)
+ self.service.spawn(self.process_greenlets, self.format_request(url, method, headers, params, data, request), greenlets)
try:
first_response = true_greenlets[0].get(block=True)[0]
@@ -185,7 +185,7 @@ def test_format_request():
req, expected = _mock_request()
- eq_(app.format_request(req), expected)
+ eq_(app.format_request(req.path, req.method, req.headers, req.args, req.form, req), {'original': expected, 'modified': expected})
def test_timer_normal():
@@ -268,17 +268,114 @@ def test_process_greenlets():
greenlets = [gevent.spawn(ident, x) for x in [(resp, elapsed_time), (resp2, elapsed_time2)]]
- app.process_greenlets(app.format_request(req), greenlets)
+ app.process_greenlets(app.format_request(req.path, req.method, req.headers, req.args, req.form, req), greenlets)
mock_result_logger.log_result.assert_called_with({
- 'request': expected_req,
+ 'request': {
+ 'original': expected_req,
+ 'modified': expected_req
+ },
'results': [
expected_resp,
expected_resp2
]
})
+def test_no_content_length():
+ from shadow.proxy.web import ProxyFlask
+ from shadow.proxy.web import AbstractResultsLogger
+ import shadow.proxy.web
+ import gevent
+
+ shadow.proxy.web.config = {
+ 'safe_mode': True
+ }
+
+ svc = gevent
+
+ requests = shadow.proxy.web.requests
+ requests.request = mock.Mock()
+
+ resp, expected_resp, elapsed_time = _mock_response()
+
+ req, expected_req = _mock_request()
+
+ req.headers = {'header': 'header_value', 'Content-Length': '231'}
+
+ shadow.proxy.web.request = req
+
+ requests.request.return_value = resp
+
+ mock_result_logger = mock.Mock(spec=AbstractResultsLogger)
+
+ additional_headers = [('add_header', 'header_value'), ('header', 'altered_header_value')]
+ additional_get = [('add_get', 'get_value')]
+ additional_post = [('add_post', 'post_value')]
+
+ additional_true_headers = [('add_true_header', 'true_header_value'), ('true_header', 'altered_true_header_value')]
+ additional_true_get = [('add_true_get', 'get_true_value')]
+ additional_true_post = [('add_true_post', 'post_true_value')]
+
+ app = ProxyFlask(
+ svc,
+ ['true_server'],
+ ['shadow_server'],
+ shadow_servers_timeout=1337.0,
+ true_servers_timeout=1339.0,
+ true_servers_additional_headers=additional_true_headers,
+ true_servers_additional_get_params=additional_true_get,
+ true_servers_additional_post_params=additional_true_post,
+ shadow_servers_additional_headers=additional_headers,
+ shadow_servers_additional_get_params=additional_get,
+ shadow_servers_additional_post_params=additional_post,
+ result_loggers=[mock_result_logger]
+ )
+
+ path = "/"
+
+ # mock timer to return the randomly generated time
+ app.timer = lambda timed_func, *args, **kwargs: (timed_func(*args, **kwargs), elapsed_time)
+
+ app.catch_all(path)
+
+ requests.request.assert_has_calls([call(
+ url="true_server/",
+ headers=dict(expected_req['headers'].items() + additional_true_headers),
+ data=dict(expected_req['post'].items() + additional_true_post),
+ params=dict(expected_req['get'].items() + additional_true_get),
+ timeout=1339.0,
+ method=expected_req['method'],
+ config=shadow.proxy.web.config
+ ), call(
+ url="shadow_server/",
+ headers=dict(expected_req['headers'].items() + additional_headers),
+ data=dict(expected_req['post'].items() + additional_post),
+ params=dict(expected_req['get'].items() + additional_get),
+ timeout=1337.0,
+ method=expected_req['method'],
+ config=shadow.proxy.web.config
+ )], any_order=True)
+
+ mock_result_logger.log_result.assert_called_with({
+ 'request': {
+ 'modified': expected_req,
+ 'original': {
+ 'url': req.path,
+ 'method': req.method,
+ 'headers': dict([(unicode(k), unicode(v)) for k, v in req.headers.items()]),
+ 'get': dict([(unicode(k), unicode(v)) for k, v in req.args.items()]),
+ 'post': dict([(unicode(k), unicode(v)) for k, v in req.form.items()])
+ }
+ },
+ 'results': [
+ expected_resp,
+ expected_resp
+ ]
+ })
+
+
+
def test_catch_all_default():
from shadow.proxy.web import ProxyFlask
from shadow.proxy.web import AbstractResultsLogger
@@ -353,7 +450,16 @@ def test_catch_all_default():
)], any_order=True)
mock_result_logger.log_result.assert_called_with({
- 'request': expected_req,
+ 'request': {
+ 'modified': expected_req,
+ 'original': {
+ 'url': req.path,
+ 'method': req.method,
+ 'headers': dict([(unicode(k), unicode(v)) for k, v in req.headers.items()]),
+ 'get': dict([(unicode(k), unicode(v)) for k, v in req.args.items()]),
+ 'post': dict([(unicode(k), unicode(v)) for k, v in req.form.items()])
+ }
+ },
'results': [
expected_resp,
expected_resp

0 comments on commit d40f909

Please sign in to comment.