Skip to content

Commit

Permalink
Fixing previous fix that didn't fix the Content-Length bug
Browse files Browse the repository at this point in the history
Added new unit tests to make sure that the behavior is correct
  • Loading branch information
kelvl committed Aug 22, 2012
1 parent 24d55ea commit d40f909
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 12 deletions.
27 changes: 19 additions & 8 deletions src/shadow/proxy/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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),
Expand All @@ -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]
Expand Down
114 changes: 110 additions & 4 deletions tests/unit/test_proxy_flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit d40f909

Please sign in to comment.