Skip to content

Commit

Permalink
feat(load_tests): add stops redesign test for dev
Browse files Browse the repository at this point in the history
  • Loading branch information
thecristen committed Oct 2, 2023
1 parent 3dfdc4e commit fa92a78
Show file tree
Hide file tree
Showing 7 changed files with 667 additions and 0 deletions.
1 change: 1 addition & 0 deletions apps/site/load_tests/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python 3.11.2
124 changes: 124 additions & 0 deletions apps/site/load_tests/socket_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import json
import logging
import re
import time
import gevent
import websocket
from locust import User


class SocketIOUser(User):
"""
A locust that includes a socket io websocket connection.
You could easily use this a template for plain WebSockets,
socket.io just happens to be my use case. You can use multiple
inheritance to combine this with an HttpUser
(class MyUser(HttpUser, SocketIOUser)
"""

abstract = True
message_regex = re.compile(r"(\d*)(.*)")
description_regex = re.compile(r"<([0-9]+)>$")

def connect(self, host: str, header=[], **kwargs):
# websocket.enableTrace(True)
self.ws = websocket.create_connection(host, header=header, **kwargs)
self.sleep_ref = 1
gevent.spawn(self.receive_loop)

def on_message(self, message): # override this method in your subclass for custom handling
m = self.message_regex.match(message)
response_time = 0 # unknown
if m is None:
# uh oh...
raise Exception(
f"got no matches for {self.message_regex} in {message}")
code = m.group(1)
json_string = m.group(2)
if code == "0":
name = "0 open"
elif code == "3":
name = "3 heartbeat"
elif code == "40":
name = "40 message ok"
elif code == "42":
# this is rather specific to our use case. Some messages contain an originating timestamp,
# and we use that to calculate the delay & report it as locust response time
# see it as inspiration rather than something you just pick up and use
current_timestamp = time.time()
obj = json.loads(json_string)
# logging.debug(json_string)
ts_type, payload = obj
name = f"{code} {ts_type} apiUri: {payload['apiUri']}"

if payload["value"] != "":
value = payload["value"]

if "draw" in value:
description = value["draw"]["description"]
description_match = self.description_regex.search(
description)
if description_match:
sent_timestamp = int(description_match.group(1))
response_time = current_timestamp - sent_timestamp
else:
# differentiate samples that have no timestamps from ones that do
name += "_"
elif "source_ts" in value:
sent_timestamp = value["source_ts"]
response_time = (current_timestamp - sent_timestamp) * 1000
else:
name += "_missingTimestamp"
else:
print(f"Received unexpected message: {message}")
return

self.environment.events.request.fire(
request_type="WSR",
name=name,
response_time=response_time,
response_length=len(message),
exception=None,
context=self.context(),
)

def receive_loop(self):
while True:
message = self.ws.recv()
# logging.debug(f"WSR: {message}")
self.on_message(message)

def send(self, body, name=None, context={}):
if not name:
if body == "2":
name = "2 heartbeat"
else:
# hoping this is a subscribe type message, try to detect name
m = re.search(r'(\d*)\["([a-z]*)"', body)
assert m is not None
code = m.group(1)
action = m.group(2)
url_part = re.search(r'"url": *"([^"]*)"', body)
assert url_part is not None
url = re.sub(r"/[0-9_]*/", "/:id/", url_part.group(1))
name = f"{code} {action} url: {url}"

self.environment.events.request.fire(
request_type="WSS",
name=name,
response_time=None,
response_length=len(body),
exception=None,
context={**self.context(), **context},
)
# logging.debug(f"WSS: {body}")
self.ws.send(body)

def sleep_with_heartbeat(self, seconds):
while seconds >= 0:
gevent.sleep(min(15, seconds))
seconds -= 15
self.sleep_ref += 1
# [null,"2","phoenix","heartbeat",{}]
self.send(
f'{{"topic":"phoenix","event":"heartbeat","payload":{{}},"ref":{self.sleep_ref}}}', name="Heartbeat")
94 changes: 94 additions & 0 deletions apps/site/load_tests/stops-bus.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
place-nubn
61
17091
place-crtst
place-wtcst
place-conrd
27092
17093
17094
17095
1
247
30249
place-estav
place-boxdt
place-belsq
121009
111803
111640
6555
49001
55
128
7
11802
1799
11803
1807
2777
111830
111146
109805
109821
109898
16535
6555
177
6551
903
9031
178
1994
65541
7834
7845
86971
88333
903
7645
86944
2099
72805
5700
4513
4524
7223
117
7415
7486
47527
94320
6773
6600
4674
6613
4728
4520
4524
4563
4736
4709
4747
4807
5700
4522
22751
49807
16881
4511
65
4510
45003
6902
3065
3067
38813
13142
3149
3181
3199
3160
3327
3806
3824
164 changes: 164 additions & 0 deletions apps/site/load_tests/stops-commuter-rail.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
place-DB-2222
place-DB-2205
place-DB-2249
place-DB-2230
place-DB-2265
place-DB-0095
place-sstat
place-DB-2240
place-DB-2258
place-FR-0361
place-FR-0064
place-FR-0115
place-FR-0201
place-FR-0494
place-FR-0132
place-FR-0167
place-FR-0301
place-FR-0451
place-north
place-portr
place-FR-0394
place-FR-0253
place-FR-3338
place-FR-0098
place-FR-0074
place-FR-0219
place-WML-0102
place-bbsta
place-WML-0035
place-WML-0214
place-WML-0364
place-WML-0025
place-WML-0177
place-WML-0081
place-sstat
place-WML-0274
place-WML-0125
place-WML-0135
place-WML-0147
place-WML-0199
place-WML-0091
place-WML-0340
place-WML-0442
place-bbsta
place-FB-0118
place-FB-0109
place-forhl
place-FB-0303
place-FS-0049
place-FB-0275
place-NEC-2203
place-FB-0125
place-FB-0230
place-FB-0148
place-FB-0143
place-DB-0095
place-rugg
place-sstat
place-FB-0191
place-FB-0166
place-brntn
place-GRB-0199
place-GRB-0146
place-GRB-0276
place-jfk
place-GRB-0183
place-GRB-0233
place-qnctr
place-sstat
place-GRB-0162
place-GRB-0118
place-NHRML-0127
place-WR-0228
place-WR-0205
place-WR-0325
place-WR-0085
place-WR-0329
place-WR-0264
place-mlmnl
place-WR-0075
place-WR-0067
place-north
place-WR-0163
place-ogmnl
place-WR-0120
place-WR-0099
place-WR-0062
place-PB-0194
place-brntn
place-PB-0281
place-PB-0245
place-jfk
place-KB-0351
place-qnctr
place-sstat
place-PB-0158
place-PB-0212
place-NHRML-0127
place-NHRML-0254
place-NHRML-0218
place-north
place-NHRML-0073
place-NHRML-0055
place-NHRML-0152
place-brntn
place-MM-0277
place-MM-0200
place-MM-0219
place-MM-0150
place-jfk
place-MM-0356
place-MM-0186
place-qnctr
place-sstat
place-bbsta
place-NB-0072
place-forhl
place-NB-0109
place-NB-0076
place-NB-0127
place-NB-0137
place-NB-0120
place-NB-0064
place-rugg
place-sstat
place-NB-0080
place-ER-0183
place-GB-0229
place-chels
place-GB-0316
place-ER-0227
place-ER-0276
place-ER-0115
place-GB-0254
place-GB-0198
place-ER-0362
place-ER-0208
place-north
place-ER-0099
place-GB-0353
place-ER-0312
place-ER-0168
place-ER-0128
place-GB-0296
place-NEC-1969
place-bbsta
place-SB-0156
place-NEC-2139
place-forhl
place-NEC-2203
place-NEC-2040
place-NEC-1891
place-NEC-1851
place-NEC-2173
place-rugg
place-NEC-2108
place-sstat
place-SB-0189
place-NEC-1768
place-NEC-1659
place-bbsta
place-FB-0118
place-FS-0049
place-sstat
Loading

0 comments on commit fa92a78

Please sign in to comment.