Sachin Patil
Sachin Patil

Reputation: 39

Not able to simulate 2 users after every 5 seconds at spawn_rate of 2 users/seconds in locust python

https://docs.locust.io/en/stable/writing-a-locustfile.html

Tried several approaches without any success.

Approach I:

Tried below approach, it spawns 2 users every 5 seconds but spawn_rate is 0.4 user every second and not 2 users/s at start of the step.

Expected:

Actual:

code:

import logging
import math
from urllib.parse import urljoin

from locust import SequentialTaskSet, task, HttpUser, LoadTestShape
from locust.exception import StopUser

class LoadTest(SequentialTaskSet):

@task
def get_oauth_token(self):
    logging.info("Oauth Token request")

@task
def get_output(self):
    logging.info("task 2")

@task
def stop(self):
    logging.info("Stopping user")
    raise StopUser()


class ApiUser(HttpUser):
    tasks = [LoadTest]
    host = 'hosturl'

class StepLoadShape(LoadTestShape):
    """
    A step load shape
    Keyword arguments:
        step_time -- Time between steps
        step_load -- User increase amount at each step
        spawn_rate -- Users to stop/start per second at every step
        time_limit -- Time limit in seconds
    """
    spawn_rate = 0.4 # Means 2 users every 5 seconds
    time_limit = 600 # 10 mins
    step_time = 600  # 10 mins
    step_load = 10   # Total load 10

def tick(self):
    run_time = self.get_run_time()

    if run_time > self.time_limit:
        return None

    current_step = math.floor(run_time / self.step_time) + 1
    return (current_step * self.step_load, self.spawn_rate)

Approach II:

Tried stage shape from documentation, but locust stops spawning after spawning first two users.

Expected:

Actual:

code:

stages = [
    {"duration": 25, "users": 2, "spawn_rate": 2},
    {"duration": 20, "users": 2, "spawn_rate": 2},
    {"duration": 15, "users": 2, "spawn_rate": 2},
    {"duration": 10, "users": 2, "spawn_rate": 2},
    {"duration": 5, "users": 2, "spawn_rate": 2},
]

def tick(self):
    run_time = self.get_run_time()

    for stage in self.stages:
        if run_time < stage["duration"]:
            tick_data = (stage["users"], stage["spawn_rate"])
            return tick_data

    return None

Any solution?

Update :

Case I : Below stages list didn't work, it spawns 2 users at 2 users/s rate, then nothing happens throughout locust lifecycle.

stages = [
    {"duration": 25, "users": 2, "spawn_rate": 2},
    {"duration": 20, "users": 4, "spawn_rate": 2},
    {"duration": 15, "users": 6, "spawn_rate": 2},
    {"duration": 10, "users": 8, "spawn_rate": 2},
    {"duration": 5, "users": 10, "spawn_rate": 2},
]

Case II: Below stages list didn't work, it spawned users with increment rate 2 users/s. i.e. 2 users/s for first 5 seconds, 4 users/s for next 5 seconds, 6 users/s for next etc. So total 30 users were spawned.

stages = [
        {"duration": 5, "users": 2, "spawn_rate": 2},
        {"duration": 10, "users": 4, "spawn_rate": 2},
        {"duration": 15, "users": 6, "spawn_rate": 2},
        {"duration": 20, "users": 8, "spawn_rate": 2},
        {"duration": 60, "users": 10, "spawn_rate": 2},
    ]

Case III:

stages = [
    {"duration": 5, "users": 2, "spawn_rate": 2},
    {"duration": 10, "users": 2, "spawn_rate": 2.001},
    {"duration": 15, "users": 2, "spawn_rate": 2},
    {"duration": 20, "users": 2, "spawn_rate": 2.001},
    {"duration": 60, "users": 2, "spawn_rate": 2},
]

Above approach spawns 2 users/second. But In case there are already 2 users spawned at moment tick function is triggered from shape class, locust runner.start method only spawns remaining users which is 0. This is like putting constant load of 2 users. Which is not expected. Not exactly what I expected.

Can't understand if there is a way to spawn 2 users after every 5 seconds at spawn_rate of 2 users/seconds

Upvotes: 1

Views: 1121

Answers (2)

Sachin Patil
Sachin Patil

Reputation: 39

This is also not the solution:

One way could be as shown below. And I need to change user spawning logic in runner.py and shape.py inside locust library.

Reason: Locust does not spawn 2 full users if 2 users are already running in the shape_worker function internally.

stages = [
    {"duration": 5, "users": 2, "spawn_rate": 2},
    {"duration": 10, "users": 2, "spawn_rate": 2.001},
    {"duration": 15, "users": 2, "spawn_rate": 2},
    {"duration": 20, "users": 2, "spawn_rate": 2.001},
    {"duration": 60, "users": 2, "spawn_rate": 2},
]

I changed spawn rate to show fractional different value than last stage. This seems to work with marginal error. Still I'd say this would be a huge difference at large scale.

If you observe in the below log there is difference of 5 seconds between spawning of users. And 2 users are spawned at start of every stage at rate of 2 users/second (approx)

Output log:

[2021-03-04 09:19:10,257] DESKTOP-AH172M9/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces)
[2021-03-04 09:19:10,270] DESKTOP-AH172M9/INFO/locust.main: Starting Locust 1.4.3
[2021-03-04 09:19:16,072] DESKTOP-AH172M9/INFO/locust.runners: Shape test starting. User count and spawn rate are ignored for this type of load test
[2021-03-04 09:19:16,077] DESKTOP-AH172M9/INFO/locust.runners: Shape worker starting
[2021-03-04 09:19:16,078] DESKTOP-AH172M9/INFO/locust.runners: Shape test updating to 2 users at 2.00 spawn rate
[2021-03-04 09:19:16,081] DESKTOP-AH172M9/INFO/locust.runners: Spawning 2 users at the rate 2 users/s (0 users already running)...
[2021-03-04 09:19:16,084] DESKTOP-AH172M9/INFO/root: In on_start method
[2021-03-04 09:19:16,095] DESKTOP-AH172M9/INFO/root: getting auth token
[2021-03-04 09:19:16,097] DESKTOP-AH172M9/INFO/root: in task 2
[2021-03-04 09:19:16,099] DESKTOP-AH172M9/INFO/root: Stopping user
[2021-03-04 09:19:16,598] DESKTOP-AH172M9/INFO/locust.runners: All users spawned: ApiUser: 2 (1 total running)
[2021-03-04 09:19:16,599] DESKTOP-AH172M9/INFO/root: In on_start method
[2021-03-04 09:19:16,600] DESKTOP-AH172M9/INFO/root: getting auth token
[2021-03-04 09:19:16,600] DESKTOP-AH172M9/INFO/root: in task 2
[2021-03-04 09:19:16,602] DESKTOP-AH172M9/INFO/root: Stopping user
[2021-03-04 09:19:21,128] DESKTOP-AH172M9/INFO/locust.runners: Shape test updating to 2 users at 2.00 spawn rate
[2021-03-04 09:19:21,130] DESKTOP-AH172M9/INFO/locust.runners: Spawning 2 users at the rate 2.001 users/s (0 users already running)...
[2021-03-04 09:19:21,133] DESKTOP-AH172M9/INFO/root: In on_start method
[2021-03-04 09:19:21,135] DESKTOP-AH172M9/INFO/root: getting auth token
[2021-03-04 09:19:21,136] DESKTOP-AH172M9/INFO/root: in task 2
[2021-03-04 09:19:21,137] DESKTOP-AH172M9/INFO/root: Stopping user
[2021-03-04 09:19:21,646] DESKTOP-AH172M9/INFO/locust.runners: All users spawned: ApiUser: 2 (1 total running)
[2021-03-04 09:19:21,648] DESKTOP-AH172M9/INFO/root: In on_start method
[2021-03-04 09:19:21,649] DESKTOP-AH172M9/INFO/root: getting auth token
[2021-03-04 09:19:21,649] DESKTOP-AH172M9/INFO/root: in task 2
[2021-03-04 09:19:21,650] DESKTOP-AH172M9/INFO/root: Stopping user
[2021-03-04 09:19:26,186] DESKTOP-AH172M9/INFO/locust.runners: Shape test updating to 2 users at 2.00 spawn rate
[2021-03-04 09:19:26,189] DESKTOP-AH172M9/INFO/locust.runners: Spawning 2 users at the rate 2 users/s (0 users already running)...
[2021-03-04 09:19:26,193] DESKTOP-AH172M9/INFO/root: In on_start method
[2021-03-04 09:19:26,194] DESKTOP-AH172M9/INFO/root: getting auth token
[2021-03-04 09:19:26,196] DESKTOP-AH172M9/INFO/root: in task 2
[2021-03-04 09:19:26,197] DESKTOP-AH172M9/INFO/root: Stopping user
[2021-03-04 09:19:26,697] DESKTOP-AH172M9/INFO/locust.runners: All users spawned: ApiUser: 2 (1 total running)
[2021-03-04 09:19:26,698] DESKTOP-AH172M9/INFO/root: In on_start method
[2021-03-04 09:19:26,698] DESKTOP-AH172M9/INFO/root: getting auth token
[2021-03-04 09:19:26,698] DESKTOP-AH172M9/INFO/root: in task 2
[2021-03-04 09:19:26,698] DESKTOP-AH172M9/INFO/root: Stopping user
[2021-03-04 09:19:31,249] DESKTOP-AH172M9/INFO/locust.runners: Shape test updating to 2 users at 2.00 spawn rate
[2021-03-04 09:19:31,249] DESKTOP-AH172M9/INFO/locust.runners: Spawning 2 users at the rate 2.001 users/s (0 users already running)...
[2021-03-04 09:19:31,249] DESKTOP-AH172M9/INFO/root: In on_start method
[2021-03-04 09:19:31,249] DESKTOP-AH172M9/INFO/root: getting auth token
[2021-03-04 09:19:31,253] DESKTOP-AH172M9/INFO/root: in task 2
[2021-03-04 09:19:31,254] DESKTOP-AH172M9/INFO/root: Stopping user
[2021-03-04 09:19:31,768] DESKTOP-AH172M9/INFO/locust.runners: All users spawned: ApiUser: 2 (1 total running)
[2021-03-04 09:19:31,768] DESKTOP-AH172M9/INFO/root: In on_start method
[2021-03-04 09:19:31,768] DESKTOP-AH172M9/INFO/root: getting auth token
[2021-03-04 09:19:31,768] DESKTOP-AH172M9/INFO/root: in task 2
[2021-03-04 09:19:31,772] DESKTOP-AH172M9/INFO/root: Stopping user
[2021-03-04 09:19:36,311] DESKTOP-AH172M9/INFO/locust.runners: Shape test updating to 2 users at 2.00 spawn rate
[2021-03-04 09:19:36,313] DESKTOP-AH172M9/INFO/locust.runners: Spawning 2 users at the rate 2 users/s (0 users already running)...
[2021-03-04 09:19:36,316] DESKTOP-AH172M9/INFO/root: In on_start method
[2021-03-04 09:19:36,317] DESKTOP-AH172M9/INFO/root: getting auth token
[2021-03-04 09:19:36,317] DESKTOP-AH172M9/INFO/root: in task 2
[2021-03-04 09:19:36,319] DESKTOP-AH172M9/INFO/root: Stopping user
[2021-03-04 09:19:36,827] DESKTOP-AH172M9/INFO/locust.runners: All users spawned: ApiUser: 2 (1 total running)
[2021-03-04 09:19:36,828] DESKTOP-AH172M9/INFO/root: In on_start method
[2021-03-04 09:19:36,828] DESKTOP-AH172M9/INFO/root: getting auth token
[2021-03-04 09:19:36,828] DESKTOP-AH172M9/INFO/root: in task 2
[2021-03-04 09:19:36,828] DESKTOP-AH172M9/INFO/root: Stopping user
[2021-03-04 09:20:16,615] DESKTOP-AH172M9/INFO/locust.runners: Shape test stopping
[2021-03-04 09:20:45,087] DESKTOP-AH172M9/INFO/locust.main: Running teardowns...
[2021-03-04 09:20:45,088] DESKTOP-AH172M9/INFO/locust.main: Shutting down (exit code 0), bye.
[2021-03-04 09:20:45,088] DESKTOP-AH172M9/INFO/locust.main: Cleaning up runner...

Upvotes: 0

aekis.dev
aekis.dev

Reputation: 2764

You are getting 2 users because you are explicitly returning 2 users in your stages data for the load test shape. The tick function should return a tuple in the form of (num_users, spawn_rate).

Let's say that you wanna obtain 10 total users spawning 2 users every 2 seconds. You could just execute locust with the args --users 10 --spawn-rate 1. It's simple but not exactly what you wanna get, but let me explain. That will spawn 1 user every second until the total users gets 10.

To use the load shape form you need to return the tuple (num_users, spawn_rate) using the same logic. Modifiying the number of users and the spawn rate you will get the desired behavior. A first aproach will be:

stages = [
    {"duration": 25, "users": 2, "spawn_rate": 2},
    {"duration": 20, "users": 4, "spawn_rate": 2},
    {"duration": 15, "users": 6, "spawn_rate": 2},
    {"duration": 10, "users": 8, "spawn_rate": 2},
    {"duration": 5, "users": 10, "spawn_rate": 2},
]

As you could noticed I'm varying the number of users incrementing the total number in each stage while keeping the same spawn_rate

Upvotes: 0

Related Questions