Skip to content

Commit

Permalink
Changed the way we get the content-length of a request to check the l…
Browse files Browse the repository at this point in the history
…ength of the response's actual content, instead of checking the content-length header. Unless the request is made using prefetch=False, in which case we fall back to the content-length header, in order to *not* trigger fetching of the body content. Fixes #33.
  • Loading branch information
heyman committed Nov 29, 2012
1 parent 7e9c95c commit 81ac588
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 6 deletions.
11 changes: 9 additions & 2 deletions locust/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ def on_pre_request(request):
# record the consumed time
request_meta["response_time"] = int((time.time() - request_meta["start_time"]) * 1000)

# get the length of the content, but if the argument prefetch is set to False, we take
# the size from the content-length header, in order to not trigger fetching of the body
if kwargs.get("prefetch", True):
request_meta["content_size"] = len(response.content or "")
else:
request_meta["content_size"] = int(response.headers.get("content-length") or 0)

if catch_response:
response.locust_request_meta = request_meta
return ResponseContextManager(response)
Expand All @@ -136,7 +143,7 @@ def on_pre_request(request):
request_meta["method"],
request_meta["name"],
request_meta["response_time"],
int(response.headers.get("content-length") or 0)
request_meta["content_size"],
)
return response

Expand Down Expand Up @@ -211,7 +218,7 @@ def success(self):
self.locust_request_meta["method"],
self.locust_request_meta["name"],
self.locust_request_meta["response_time"],
int(self.headers.get("content-length") or 0),
self.locust_request_meta["content_size"],
)
self._is_reported = True

Expand Down
2 changes: 1 addition & 1 deletion locust/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ <h2>Ramping</h2>
<th class="stats_label" href="#" data-sortkey="avg_response_time">Average</th>
<th class="stats_label" href="#" data-sortkey="min_response_time">Min</th>
<th class="stats_label" href="#" data-sortkey="max_response_time">Max</th>
<th class="stats_label" href="#" data-sortkey="avg_content_length">Content-Length</th>
<th class="stats_label" href="#" data-sortkey="avg_content_length">Content Size</th>
<th class="stats_label" href="#" data-sortkey="current_rps"># reqs/sec</th>
</tr>
</thead>
Expand Down
1 change: 0 additions & 1 deletion locust/test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ def test_connection_error(self):
self.assertFalse(r)
self.assertEqual(None, r.content)
self.assertRaises(RequestException, r.raise_for_status)

16 changes: 16 additions & 0 deletions locust/test/test_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,22 @@ class MyLocust(Locust):
locust.client.get("/ultra_fast")
self.assertEqual(RequestStats.get("GET", "/ultra_fast").avg_content_length, len("This is an ultra fast response"))

def test_request_stats_no_content_length(self):
class MyLocust(Locust):
host = "http://127.0.0.1:%i" % self.port
l = MyLocust()
path = "/no_content_length"
r = l.client.get(path)
self.assertEqual(RequestStats.get("GET", path).avg_content_length, len("This response does not have content-length in the header"))

def test_request_stats_no_content_length_no_prefetch(self):
class MyLocust(Locust):
host = "http://127.0.0.1:%i" % self.port
l = MyLocust()
path = "/no_content_length"
r = l.client.get(path, prefetch=False)
self.assertEqual(0, RequestStats.get("GET", path).avg_content_length)

def test_request_stats_named_endpoint(self):
class MyLocust(Locust):
host = "http://127.0.0.1:%i" % self.port
Expand Down
8 changes: 7 additions & 1 deletion locust/test/testcases.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
import unittest
import base64
from copy import copy
from StringIO import StringIO

from locust import events
from locust.stats import RequestStats
from flask import Flask, request, redirect, make_response
from flask import Flask, request, redirect, make_response, send_file

app = Flask(__name__)

Expand Down Expand Up @@ -60,6 +61,11 @@ def basic_auth():
resp.headers["WWW-Authenticate"] = 'Basic realm="Locust"'
return resp

@app.route("/no_content_length")
def no_content_length():
r = send_file(StringIO("This response does not have content-length in the header"))
return r

@app.errorhandler(404)
def not_found(error):
return "Not Found", 404
Expand Down
2 changes: 1 addition & 1 deletion locust/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def request_stats_csv():
'"Average response time"',
'"Min response time"',
'"Max response time"',
'"Average Content-Length"',
'"Average Content Size"',
'"Reqests/s"',
])
]
Expand Down

0 comments on commit 81ac588

Please sign in to comment.