I had run into the exact same issue as Nate using:
locustio==0.13.5
bzt==1.14.2
I believe the issue is that Locust 0.13.5's
response.failure() method is doing the following (
source):
events.request_failure.fire(
request_type=self.locust_request_meta["method"],
name=self.locust_request_meta["name"],
response_time=self.locust_request_meta["response_time"],
response_length=self.locust_request_meta["content_size"],
exception=exc,
)
which fires all event handlers like this (
source):
def fire(self, reverse=False, **kwargs):
if reverse:
self._handlers.reverse()
for handler in self._handlers:
handler(**kwargs)
However, the handler implemented in Taurus 1.14.2 does not accept kwargs (
source):
def __on_request_failure(self, request_type, name, response_time, exception):
self.num_requests -= 1
self.writer.writerow(self.__getrec(request_type, name, response_time, 0, exception))
self.fhd.flush()
self.__check_limits()
Knowing this, we can write our own implementation of failure() that checks the arguments of each event handler, and calling the Taurus handler differently. The following is my implementation:
def failure(response, exc):
"""
Report the response as a failure.
exc can be either a python exception, or a string in which case it will
be wrapped inside a CatchResponseError.
This method should be used rather than response.failure() as it accounts
for the incompatible __on_request_failure event handler implemented in
the Taurus Locust wrapper by checking the signature of each handler, and
calling the function appropriately
Example::
with self.client.get("/", catch_response=True) as response:
if response.content == b"":
failure(response, "No data")
"""
if isinstance(exc, six.string_types):
exc = CatchResponseError(exc)
request_type = response.locust_request_meta["method"]
name = response.locust_request_meta["name"]
response_time = response.locust_request_meta["response_time"]
response_length = response.locust_request_meta["content_size"]
print('request_failure event handlers: {}'.format(
events.request_failure._handlers))
for handler in events.request_failure._handlers:
argspec = inspect.getfullargspec(handler)
if argspec.varkw is None and argspec.args==['self', 'request_type', 'name', 'response_time', 'exception']:
# Special case for incompatible Taurus handler
handler(request_type, name, response_time, exc)
else:
handler(
request_type=request_type,
name=name,
response_time=response_time,
exception=exc,
response_length=response_length,
)
response._is_reported = True
This method can then be called instead of response.failre(result).
Obviously an issue with this fix is that it will break when either Locust or Taurus is updated, but this does resolve the issue for me on the versions above.