Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resp.failure() shouldnt immediately log a failed request, just mark it a such #1335

Closed
cyberw opened this issue Apr 17, 2020 · 5 comments
Closed
Milestone

Comments

@cyberw
Copy link
Collaborator

cyberw commented Apr 17, 2020

Because resp.failure() immediately logs a failure trows an exception, it is kind of hard to work with.

edit: I was confused, this first thing is entirely possible today

For instance, if you want to tag the request as a failure and then break out of the task entirely, you cant really do that in a straight forward way.

I would like to be able to do this:

    with self.client.post("/", catch_response=True) as resp:
        if resp.status_code != something:
            resp.failure()
            return

or even this (particularly useful when you have wrapped the request method and it does some kind of error checking internally, which you may want to override sometimes):

    with self.client.post("/", catch_response=True) as resp:
        if resp.status_code != something:
            resp.failure()
        if known_error:
            resp.success()

Probably we should also change it from being a method call to being a property.

Because this is potentially a breaking change for some testplans I would like to do it for 1.0

@cyberw cyberw added this to the 1.0 milestone Apr 17, 2020
@heyman
Copy link
Member

heyman commented Apr 17, 2020

Hmm, catch_response=True + resp.failure() doesn't raise an exception? Maybe I'm misunderstanding your post?

The following code works perfectly fine for me (with either HttpLocust or FastHttpLocust):

from locust import HttpLocust, task, constant
from locust.contrib.fasthttp import FastHttpLocust


class TestUser(HttpLocust):
    host = "http://127.0.0.1:8089"
    wait_time = constant(1)
    
    @task
    def test_task(self):
        with self.client.post("/non-existing", catch_response=True) as resp:
            resp.failure("Noooo, fail!")
            print("request failed")
            return
        
        print("end of task (should never run)")

Command line output:

~/projects/locust master ❯ locust -f examples/issue_1335.py -c 1 -r 1 -t 3 --headless
[2020-04-17 16:57:44,237] MacBook-Air.localdomain/INFO/locust.main: Run time limit set to 3 seconds
[2020-04-17 16:57:44,237] MacBook-Air.localdomain/INFO/locust.main: Starting Locust 1.0.0
[2020-04-17 16:57:44,238] MacBook-Air.localdomain/INFO/locust.runners: Hatching and swarming 1 users at the rate 1 users/s (0 users already running)...
[2020-04-17 16:57:44,238] MacBook-Air.localdomain/INFO/locust.runners: All locusts hatched: TestUser: 1 (0 already running)
 Name                                                          # reqs      # fails     Avg     Min     Max  |  Median   req/s failures/s
--------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------
 Aggregated                                                         0     0(0.00%)       0       0       0  |       0    0.00    0.00

request failed
request failed
 Name                                                          # reqs      # fails     Avg     Min     Max  |  Median   req/s failures/s
--------------------------------------------------------------------------------------------------------------------------------------------
 POST /non-existing                                                 2   2(100.00%)       5       4       6  |       5    0.00    0.00
--------------------------------------------------------------------------------------------------------------------------------------------
 Aggregated                                                         2   2(100.00%)       5       4       6  |       5    0.00    0.00

request failed
[2020-04-17 16:57:47,080] MacBook-Air.localdomain/INFO/locust.main: Time limit reached. Stopping Locust.
[2020-04-17 16:57:47,080] MacBook-Air.localdomain/INFO/locust.main: Shutting down (exit code 1), bye.
[2020-04-17 16:57:47,080] MacBook-Air.localdomain/INFO/locust.main: Cleaning up runner...
[2020-04-17 16:57:47,081] MacBook-Air.localdomain/INFO/locust.main: Running teardowns...
 Name                                                          # reqs      # fails     Avg     Min     Max  |  Median   req/s failures/s
--------------------------------------------------------------------------------------------------------------------------------------------
 POST /non-existing                                                 3   3(100.00%)       5       4       6  |       5    1.48    1.48
--------------------------------------------------------------------------------------------------------------------------------------------
 Aggregated                                                         3   3(100.00%)       5       4       6  |       5    1.48    1.48

Percentage of the requests completed within given times
 Type                 Name                                                           # reqs    50%    66%    75%    80%    90%    95%    98%    99%  99.9% 99.99%   100%
------------------------------------------------------------------------------------------------------------------------------------------------------
 POST                 /non-existing                                                       3      5      5      7      7      7      7      7      7      7      7      7
------------------------------------------------------------------------------------------------------------------------------------------------------
 None                 Aggregated                                                          3      5      5      7      7      7      7      7      7      7      7      7

Error report
 # occurrences      Error
--------------------------------------------------------------------------------------------------------------------------------------------
 3                  POST /non-existing: "CatchResponseError('Noooo, fail!')"
--------------------------------------------------------------------------------------------------------------------------------------------

@cyberw
Copy link
Collaborator Author

cyberw commented Apr 17, 2020

Oh, right, I'm totally misremembering. It is possible to do the first thing I posted, just not the second one. For example, doing this:

def t1(self):
        with self.client.get("/", catch_response=True) as resp:
            resp.failure("foo")
            resp.success()

... will log two requests, one failure, and one success.

@cyberw cyberw changed the title resp.failure() shouldnt throw an exception, just mark the request as failed resp.failure() shouldnt immediately log a failed request, just mark it a such Apr 17, 2020
@cyberw
Copy link
Collaborator Author

cyberw commented Apr 17, 2020

... and that is bad because it makes it hard to build a more advanced client/user (for example, one that does custom error checking, but allows the error to be overridden/removed in cases where an error is expected)

@heyman
Copy link
Member

heyman commented Apr 17, 2020

Ah, I see what you mean! Definitely agree. Only the last call to either success() or failure() should count.

I have a failing test for it now. I'll set up a PR.

Probably we should also change it from being a method call to being a property.

I don't think it they should be properties. I think it's useful to be able to pass a message to the failure() method.

@heyman
Copy link
Member

heyman commented Apr 17, 2020

PR submitted!

@cyberw cyberw closed this as completed Apr 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants