Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop Locust When Specified Number Of User Tasks Complete

Tags:

locust

In my scenario, I'm running Locust without the web UI. The command I'm using is

locust -f my_locust_file --no_web -c 20 -r 4     # as a hack I add -t 10s

This corresponds to a 4 users being hatched every second up to a total of 20 users.

My objective is to have each of the 20 locust users execute a task and I'd like the locust run to complete and exit when the last user's (20th user) task completes. The collected statistics should only include the response times associated with each task.

In this scenario, 5 tasks (user scenarios) have been identified which can be randomly associated with a user:

class UserScenarios(TaskSet):
    tasks = [Sequence_One, ServerSequence, Components_Sequence, Embedded_Sequence, Connectivity_Sequence]

class MyLocust(HttpLocust):
    def __init__(self):
        super().__init__()
        MyLocust.counter += 1
        print(f"Counter = {MyLocust.counter}")

    counter = 0
    task_set = UserScenarios
    wait_time = between(1, 1)
    host = 'https://*****.com'

Each task (user scenario) corresponds to a different sequence of 3 or 4 pages that should be loaded in order. An example sanitized and simplified sequence consisting of 2 pages is:

class Sequence_One(TaskSequence):

    @seq_task(1)
    def get_task1(self):
        response = self.client.get(url='https://****',
                                   name='https://****',
                                   timeout=30,
                                   allow_redirects=False,
                                   headers={...})   

    @seq_task(2)
    def get_task2(self):
        response = self.client.get(url='https://****',
                                   name='https://****',
                                   timeout=30,
                                   allow_redirects=False,
                                   headers={...})  

Is there a way to stop the test after the 20th (nth) user task completes? If every task visits 4 pages for example, I want the test to terminate after the 20*4 = 80 page request is made. In fact only 80 total page requests should be made as part of this test.

My experience with this test is that page requests continue to be made after the last user task completes until I either manually stop the test or use a time limit which is a bit longer than the tasks actually need to complete.

like image 628
CK215 Avatar asked Jan 26 '23 09:01

CK215


1 Answers

This is actually possible! While it's not documented, at least anywhere that I could find, stopping a Locust can be achieved by calling raise StopLocust()

In the provided scenario, each of your tasks is a TaskSequence class. In order to quit a Locust after a single task has been performed, you will need to add another step (function) to the overall class which makes a call to StopLocust(). I've provided an example below -

class Scenario(TaskSequence):

    @seq_task(1)
    def task_1(self):
        self.client.get("/going_somewhere")

    @seq_task(2)
    def task_2(self):
        self.client.get("/going_somewhere_else")

    @seq_task(3)
    def done(self):
        raise StopLocust()

By default, a Locust is set to never end and will continuously pick a task from the available task sets provided to it. Supplying raise StopLocust() will tell the current user (Locust) to stop and no longer pick tasks once it reaches the end of that current task.

like image 109
Andrew Avatar answered Mar 25 '23 08:03

Andrew