diff --git a/Makefile b/Makefile index 49ad55c..6d28f1f 100644 --- a/Makefile +++ b/Makefile @@ -20,4 +20,7 @@ down: docker-compose down down-test: - docker-compose -f ./docker-compose.yml -f ./docker-compose.test.yml down \ No newline at end of file + docker-compose -f ./docker-compose.yml -f ./docker-compose.test.yml down + +loadtest: + docker-compose -f ./load-test/docker-compose.yml up --scale worker=4 \ No newline at end of file diff --git a/load-test/Dockerfile b/load-test/Dockerfile new file mode 100644 index 0000000..876c5da --- /dev/null +++ b/load-test/Dockerfile @@ -0,0 +1,6 @@ +FROM locustio/locust + +COPY requirements.txt /tmp/requirements.txt + +RUN pip3 install --upgrade -r /tmp/requirements.txt + diff --git a/load-test/docker-compose.yml b/load-test/docker-compose.yml new file mode 100644 index 0000000..b7fcc33 --- /dev/null +++ b/load-test/docker-compose.yml @@ -0,0 +1,29 @@ +version: '3' + +services: + master: + build: + context: . + dockerfile: Dockerfile + environment: + SIGNALING_SERVER_URL: ws://signaling-server:4000 + ports: + - '8089:8089' + volumes: + - ./:/mnt/locust + command: -f /mnt/locust/locustfile.py --master -H http://master:8089 + + worker: + build: + context: . + dockerfile: Dockerfile + environment: + SIGNALING_SERVER_URL: ws://signaling-server:4000 + volumes: + - ./:/mnt/locust + command: -f /mnt/locust/locustfile.py --worker --master-host master + +networks: + default: + external: + name: signaling-server diff --git a/load-test/locustfile.py b/load-test/locustfile.py new file mode 100644 index 0000000..95cc4b5 --- /dev/null +++ b/load-test/locustfile.py @@ -0,0 +1,53 @@ +from locust import HttpUser, TaskSet, task, between, events +from websocket import create_connection +import time +import json +import gevent +from uuid import uuid4 +import os + +class UserBehavior(TaskSet): + def on_start(self): + self.ws = create_connection(os.environ.get('SIGNALING_SERVER_URL')) + + def _receive(): + while True: + res = self.ws.recv() + data = json.loads(res) + end_at = time.time() + + if 'valid' in data.keys(): + response_time = int((end_at - data['valid']['startAt']) * 1000) + events.request_success.fire( + request_type='WebSocket', + name='test/ws/receive', + response_time=response_time, + response_length=len(res), + ) + + + gevent.spawn(_receive) + + def on_quit(self): + self.ws.close() + + @task(1) + def say_hello(self): + start_at = time.time() + + body = { + "encryptedPayload": "8090be8fad3f11789665bd74d6b03fe42f99d35fc8d045ac319400e25137ec9f2c834e612333519fd32a6300d058f613059dceca4c0464b25ad9cf467ca23c15d0dca5aad5e650aec08c394880139e6d61cd751ae743e1d4161bcf6b0a583d43569bb35d09464f36fff3b1af229741c3435818dd56e24559b0ec425df9d252124b99a02e7468ed74cf85ae090d27dd5edb4b50add1c575bfb309e3990e367b787bfd388abcaf3dc3751b5c6922b0a3190b1f1dabde788f911d532a6560f6d074cab9a3", + "connectionId": str(uuid4()), + "method": "iceCandidate", + "source": "iOS", + "requestId": "AD10B2D9-7EFD-4096-A931-455A416D87B9", + "startAt": start_at + } + + self.ws.send(json.dumps(body)) + + + +class WebsiteUser(HttpUser): + tasks = [UserBehavior] + wait_time = between(1, 1) \ No newline at end of file diff --git a/load-test/requirements.txt b/load-test/requirements.txt new file mode 100644 index 0000000..52c0d5c --- /dev/null +++ b/load-test/requirements.txt @@ -0,0 +1,6 @@ +gevent==21.12.0 +gevent-websocket==0.10.1 +greenlet==1.1.2 +websocket-client==1.3.3 +zope.event==4.5.0 +zope.interface==5.4.0