Skip to content

Commit 80e5bfa

Browse files
authored
Merge pull request #20 from input-output-hk/edd/add-loadtests
Load tests
2 parents 24e8536 + 07836c6 commit 80e5bfa

File tree

10 files changed

+151
-0
lines changed

10 files changed

+151
-0
lines changed

test/load/.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
RUN_TIME=1m
2+
USERS=10
3+
SPAWN_RATE=1

test/load/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__pycache__

test/load/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export SWARM_SIZE?=1
2+
3+
run:
4+
docker-compose up --scale worker=$(SWARM_SIZE)

test/load/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Load tests
2+
3+
The document describes how to run load tests against https://metadata.cardano-testnet.iohkdev.io/.
4+
It is recommended to perform a load run before every release to gather results and make sure there is no performance deterioration or any unexpected behavior.
5+
6+
Performance tests are completed with locust.io, written in Python, and performed from a test engineers home computer. The users are ramped up at a rate of 10 per second until they hit the target Total Users. This is maintained for several minutes and results are then aggregated from across the entire run.
7+
8+
## To run the test
9+
10+
1. Start locust docker
11+
```
12+
$ cd test/load
13+
$ make
14+
```
15+
16+
2. Visit http://0.0.0.0:8089/ and run test from there.
17+
18+
## Pre-relese test
19+
20+
Total Users = 1000
21+
Ramp up rate = 10
22+
23+
Execution time = 10 minutes from the point where all users ramp up.
24+
25+
Store results in https://github.com/input-output-hk/offchain-metadata-tools/wiki/Load-Tests-Results

test/load/__init__.py

Whitespace-only changes.

test/load/docker-compose.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
version: '3'
2+
3+
services:
4+
master:
5+
image: locustio/locust
6+
ports:
7+
- "8089:8089"
8+
volumes:
9+
- ./:/mnt/locust
10+
command: -f /mnt/locust/locustfile.py --master --csv=/mnt/locust/results
11+
12+
worker:
13+
image: locustio/locust
14+
volumes:
15+
- ./:/mnt/locust
16+
command: -f /mnt/locust/locustfile.py --worker --master-host master

test/load/generator/__init__.py

Whitespace-only changes.

test/load/generator/properties.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from random import choice
2+
from string import ascii_uppercase
3+
4+
properties = ["subject", "url", "name", "ticker", "policy", "logo", "description"]
5+
6+
def get_random_property():
7+
return choice(properties)
8+
9+
def get_invalid_property():
10+
return (''.join(choice(ascii_uppercase) for i in range(8)))
11+
12+
if __name__ == '__main__':
13+
pass

test/load/generator/subjects.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from random import choice
2+
from string import ascii_uppercase
3+
4+
subjects = ["2e6d83507419c027eac6eb9430b780c0793e2c1762b7bff56fbba6f5736f6d65636f696e",
5+
"34250edd1e9836f5378702fbf9416b709bc140e04f668cc3552085184154414441636f696e",
6+
"34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518",
7+
"3e8777fa3ed835dd8036d2182918845c72a91b22c098439fd77dcbc350",
8+
"446ffdf62c2474c0f84387b3ed0796b7d2daab0b282742dfad02da3f544553544e45544e465430303076303030",
9+
"69b30e43bc5401bb34d0b12bd06cd9b537f33065aa49df7e8652739d4c51",
10+
"6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7",
11+
"789ef8ae89617f34c07f7f6a12e4d65146f958c0bc15a97b4ff169f16861707079636f696e",
12+
"789ef8ae89617f34c07f7f6a12e4d65146f958c0bc15a97b4ff169f17375706572636f696e",
13+
"789ef8ae89617f34c07f7f6a12e4d65146f958c0bc15a97b4ff169f174727565636f696e",
14+
"789ef8ae89617f34c07f7f6a12e4d65146f958c0bc15a97b4ff169f1",
15+
"9b87fdecd7a27e3b570fe821d790034a782d5248f4d22efc165c4d20796f7572636f696e",
16+
"baa836fef09cb35e180fce4b55ded152907af1e2c840ed5218776f2f",
17+
"c43a140cfe4476635776dbc5adea18604997348fc00607925165d4d4636f6c696e636f696e",
18+
"c43a140cfe4476635776dbc5adea18604997348fc00607925165d4d46a616d6573636f696e",
19+
"fc88532b68d36f5d951f44155166091a234a064250a6ae844128f8a4686f736b636f696e73"
20+
]
21+
22+
def get_random_subject():
23+
return choice(subjects)
24+
25+
def get_invalid_subject():
26+
return (''.join(choice(ascii_uppercase) for i in range(56)))
27+
28+
if __name__ == '__main__':
29+
pass

test/load/locustfile.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from locust import HttpUser, TaskSet, constant, task
2+
3+
from generator.subjects import get_random_subject, get_invalid_subject
4+
from generator.properties import get_random_property, get_invalid_property
5+
6+
class QueryUser(HttpUser):
7+
host = "https://metadata.cardano-testnet.iohkdev.io"
8+
9+
# between each task a user will wait 1 second
10+
wait_time = constant(1)
11+
12+
# task(n) assigns the probability of that task being performed by the user.
13+
# in this code, task(1) is equal to 10% and task(2) is equal to 20%
14+
15+
@task(2)
16+
def get_metadata_subject(self):
17+
subject = get_random_subject()
18+
self.client.get(f"/metadata/{subject}")
19+
20+
@task(2)
21+
def get_metadata_subject_properties(self):
22+
subject = get_random_subject()
23+
24+
self.client.get(f"/metadata/{subject}/properties")
25+
26+
# @task(2)
27+
# def get_metadata_subject_properties_property(self):
28+
# subject = get_random_subject()
29+
# property = get_random_property()
30+
31+
# self.client.get(f"/metadata/{subject}/properties/{property}")
32+
33+
# @task(1)
34+
# def get_metadata_query(self):
35+
# self.client.get(f"/metadata/query")
36+
37+
@task(1)
38+
def get_metadata_subject_invalid(self):
39+
subject = get_invalid_subject()
40+
41+
with self.client.get(f"/metadata/{subject}", catch_response=True) as response:
42+
if response.status_code == 404:
43+
response.success()
44+
45+
@task(1)
46+
def get_metadata_subject_properties_invalid(self):
47+
subject = get_invalid_subject()
48+
49+
with self.client.get(f"/metadata/{subject}/properties", catch_response=True) as response:
50+
if response.status_code == 404:
51+
response.success()
52+
53+
@task(1)
54+
def get_metadata_subject_properties_property_invalid(self):
55+
subject = get_invalid_subject()
56+
property = get_invalid_property()
57+
58+
with self.client.get(f"/metadata/{subject}/properties/{property}", catch_response=True) as response:
59+
if response.status_code == 404:
60+
response.success()

0 commit comments

Comments
 (0)