The Wayback Machine - https://web.archive.org/web/20200225010144/https://github.com/locustio/locust/issues/771
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

custom client from locust documentation doesn't work at all #771

Closed
JaniszM opened this issue Apr 4, 2018 · 8 comments
Closed

custom client from locust documentation doesn't work at all #771

JaniszM opened this issue Apr 4, 2018 · 8 comments
Labels

Comments

@JaniszM
Copy link

@JaniszM JaniszM commented Apr 4, 2018

Looks like while implementing custom client like HttpLocust when adding inline TaskSet class to Locust inline class is not loaded by Locust.

Expected behaviour

Any inline class should be executed by Locust.
According to https://docs.locust.io/en/latest/testing-other-systems.html#sample-xml-rpc-locust-client class task_set should be loaded by Locust and all tasks in this class should be executed.

Actual behavior

I have implemented websocket client following this documentation. I have two Locust classes in one file loaded by locust and executed by:

locust -f locustfiles/api_load_tests.py --host=https://my_ip--csv=${report_dir}/report_data --no-web -c ${NUM_CLIENTS} -r ${HATCH_RATE} # ApiVehicleUser ApiMessageUser

Class ApiMessageUser that sets task_set = ApiMessage class attribute is loaded and executed correctly but class ApiVehicleUser which is inline class is not loaded. No error is raised neither.

Environment settings (for bug reports)

  • OS: Ubuntu 16.04.4 LTS
  • Python version: Python 3.5.2
  • Locust version: Locust 0.8

Steps to reproduce (for bug reports)

Bellow is a snippet of the locust file:

class BtsLocust(Locust):
    """
    Provides an Http and websocket clients.
    """

    def __init__(self, *args, **kwargs):
        super(BtsLocust, self).__init__(*args, **kwargs)
        self.ws_client = locust_ws_client.LocustWebSocketClient(self.host)  # this is wrapper like `XmlRpcClient` class


class ApiVehicleUser(BtsLocust):
    # task_set = ApiVehicle
    min_wait = 500
    max_wait = 500


    @task
    class ApiVehicle(TaskSet):

        def on_start(self):
            # some setup

        def on_stop(self):
            # some clean up

    @task
    def here_goes_my_tasks_for_ApiVehicle(self):
        # some setup


class ApiMessage(TaskSet):

    def on_start(self):
        # some setup

    @task
    def here_goes_my_tasks_for_ApiMessage(self):
        # some setup


class ApiMessageUser(HttpLocust):
    task_set = ApiMessage
    min_wait = 500
    max_wait = 500

The thing is that I must have HttpLocust and websocket client at one Locust class to combine tests. If I uncomment # task_set = ApiVehicle then ApiVehicle taks set cannot access to websocket client because for some it is not inherited (and HttpLocust is). So there are few problems over here but the main is mentioned above. So assuming that ApiVehicle will be loaded into Locust all should be fine.

Extra ideas

If anyone have idea how to integrate these two clients using even workarounds I would be glad to do this. I tried to set task_set = ApiVehicle and pass ws_client from outside by __init__ methods but this is messing up too much in Locust super-class and causes too much problems.

I have tried also to add @task decorator to inline class, nothing works.

@JaniszM

This comment has been minimized.

Copy link
Author

@JaniszM JaniszM commented Apr 5, 2018

I have found several bugs related to problem above. Also I have working code.

First of all you guys must investigate these problems and take action is this a bug or outdated wiki.

Problems

Example from https://docs.locust.io/en/latest/testing-other-systems.html#sample-xml-rpc-locust-client does not work.
Working code is (important part are commented):

class ApiVehicle(TaskSet):

    def on_start(self):
        # some setup

    def on_stop(self):
        # some clean up

    @task
    def here_goes_my_tasks_for_ApiVehicle(self):
        # some setup

class ApiVehicleUser(HttpLocust):
    task_set = ApiVehicle  # THIS IS MISSING IN DOC, ALSO INNER CLASS CANNOT BE USED CAUSE IT HAS OTHER SCOPE THAN PARENT ONE
    min_wait = 500
    max_wait = 500

    def __init__(self, *args, **kwargs):
        super(ApiVehicleUser, self).__init__(*args, **kwargs)
        self.task_set.ws_client = WebSocketClient(self.host)    # THIS SHOULD GO HERE, NOT IN SUPER CLASS LIKE ON WIKI

class ApiMessage(TaskSet):

    def on_start(self):
        # some setup

    @task
    def here_goes_my_tasks_for_ApiMessage(self):
        # some setup


class ApiMessageUser(HttpLocust):
    task_set = ApiMessage
    min_wait = 500
    max_wait = 500

Wrapper from documentation example class XmlRpcClient(xmlrpclib.ServerProxy): doesn't work.
This wrapper runs somehow the code but doesn't log events.request_failure.fire and events.request_success.fire. In order to have logged requests I had to define simple wrapper like this one:

def locust_wrapper(func, arg, name, endpoint=None):
    start_time = time.time()

    try:
        rsp = func(arg, endpoint)
    except Exception as e:
        print(e)
        total_time = int((time.time() - start_time) * 1000)
        events.request_failure.fire(request_type="WS", name=name, response_time=total_time, exception=e)
    else:
        total_time = int((time.time() - start_time) * 1000)
        events.request_success.fire(request_type="WS", name=name, response_time=total_time, response_length=0)
        return rsp
@JaniszM JaniszM changed the title Inline class of the Locus class not loaded by Locust custom client from locust documentation doesn't work at all Apr 5, 2018
@cgoldberg

This comment has been minimized.

Copy link
Member

@cgoldberg cgoldberg commented Apr 5, 2018

First of all you guys must investigate these problems and take action

by "you guys", do you mean the small group of unpaid volunteers helping to maintain the project that provided free software for you?

If so, a quicker option would be for you to step up and take action. The documentation is part of the codebase, and I'd be happy to review a Pull Request with your proposed changes.

@JaniszM

This comment has been minimized.

Copy link
Author

@JaniszM JaniszM commented Apr 11, 2018

Yeah, brutally yes, that I meant ;)

So If I will be able to find additional time I will do some update to the docs.

Cheers!

@heyman

This comment has been minimized.

Copy link
Member

@heyman heyman commented Apr 11, 2018

@JaniszM If you name the inlined class task_set - like it is in the documentation - I think it should work.

@JaniszM

This comment has been minimized.

Copy link
Author

@JaniszM JaniszM commented Apr 13, 2018

@heyman Unfortunatelly not. Looks like scope of the inner class in python has nothing to do with super class.

@heyman

This comment has been minimized.

Copy link
Member

@heyman heyman commented Apr 13, 2018

@JaniszM I just tested, and the following code works perfectly fine for me:

from locust import HttpLocust, TaskSet, task

    
class WebsiteUser(HttpLocust):
    host = "http://127.0.0.1:8089"
    min_wait = 2000
    max_wait = 5000
    
    class task_set(TaskSet):
        @task
        def page404(self):
            self.client.get("/does_not_exist")    
        
        @task
        def index(self):
            self.client.get("/")
        
        @task
        def stats(self):
            self.client.get("/stats/requests")        
@JaniszM

This comment has been minimized.

Copy link
Author

@JaniszM JaniszM commented Apr 25, 2018

Thats weird. Maybe this is matter of python version?

@cyberw

This comment has been minimized.

Copy link
Contributor

@cyberw cyberw commented Oct 18, 2019

Not updated for a long time? Closing this as could not reproduce.

@cyberw cyberw closed this Oct 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
4 participants
You can’t perform that action at this time.