0

I'm writing Locust scripts and want to extend a base class. There are two values (dto_class and api_suffix) that are different from one sub-class to another. Everything else is shared

locust_base.py (base class):

### locust_base.py ###
from locust import HttpUser, between, task
## other imports ##

class BaseUser(HttpUser):
   """
   do some stuff        
   """
   def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.dto_class = kwargs.pop('dto_class')
        self.api_suffix: str = kwargs.pop('api_suffix')
        """
        set other stuff
        """

The sub-classes (e.g. locust_specific_dto.py) look like:

"""
locust_specific_dto.py
"""
from locust_base import BaseUser

class SpecificDtoUser(BaseUser):
   def __init__(self, *args, **kwargs):
         super(SpecificDtoUser, self).__init__(dto_class=SpecificDto, api_suffix="specificEndpoint", *args, **kwargs)

However, when running locust -f locust_specific_dto.py, this error gets output:

KeyError: 'dto_class'
2024-05-09T18:09:14Z <Greenlet at 0x21e4d99d580: <lambda>> failed with KeyError

[2024-05-09 14:09:14,811] WSAMZN-SPLR8QE1/CRITICAL/locust.runners: Unhandled exception in greenlet: <Greenlet at 0x21e4d99d580: <lambda>>
Traceback (most recent call last):
  File "src\\gevent\\greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run
  File "{REDACTED}\AppData\Roaming\Python\Python311\site-packages\locust\runners.py", line 553, in <lambda>
    lambda: self._start(user_count, spawn_rate, wait=wait, user_classes=user_classes)
    ^^^^^^^^^^^^^^^^^
  File "{REDACTED}\AppData\Roaming\Python\Python311\site-packages\locust\runners.py", line 524, in _start
    self.spawn_users(user_classes_spawn_count, wait)
    ^^^^^^^^^^^^^^^^^
  File "{REDACTED}\AppData\Roaming\Python\Python311\site-packages\locust\runners.py", line 238, in spawn_users
    new_users += spawn(user_class, spawn_count)
    ^^^^^^^^^^^^^^^^^
  File "{REDACTED}\AppData\Roaming\Python\Python311\site-packages\locust\runners.py", line 227, in spawn
    new_user = self.user_classes_by_name[user_class](self.environment)
    ^^^^^^^^^^^^^^^^^
  File "{REDACTED}\Documents\dev\{REDACTED}\locust_base.py", line 23, in __init__
    self.dto_class = kwargs.pop('dto_class')
    ^^^^^^^^^^^^^^^^^
KeyError: 'dto_class'

1 Answer 1

0

Locust is trying to instantiate your BaseUser directly (not just your subclass). Set abstract=True on that class to skip it.

See https://docs.locust.io/en/stable/api.html?highlight=Abstract#locust.User.abstract

Sign up to request clarification or add additional context in comments.

3 Comments

reran with abstract=True at the first line of BaseUser, same error stackoverflow.com/a/64383314/24959674
Try using named parameters instead of kwargs and see if you get a better callstack. Are you on latest version of locust?
that worked (super().__init__(SubClass, "subClass", *args, **kwargs) in the SubClass) , thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.