Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/dimensioning/esp32_c3/base.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/files_api_001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/files_api_002.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/files_api_003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/high_mem_cap_001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/high_mem_cap_002.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/high_mem_cap_003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/low_mem_cap_001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/low_mem_cap_002.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/low_mem_cap_003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1,907 changes: 1,907 additions & 0 deletions docs/dimensioning/esp32_c3/measurements.json

Large diffs are not rendered by default.

Binary file added docs/dimensioning/esp32_c3/multipart_001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/multipart_002.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/multipart_003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/tls_001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_c3/tls_002.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_s3/base.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_s3/files_api_001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_s3/files_api_002.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_s3/files_api_003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_s3/high_mem_cap_001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_s3/high_mem_cap_002.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_s3/high_mem_cap_003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_s3/low_mem_cap_001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_s3/low_mem_cap_002.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dimensioning/esp32_s3/low_mem_cap_003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2,034 changes: 2,034 additions & 0 deletions docs/dimensioning/esp32_s3/measurements.json

Large diffs are not rendered by default.

Binary file added docs/dimensioning/esp32_s3/multipart_001.png
Binary file added docs/dimensioning/esp32_s3/multipart_002.png
Binary file added docs/dimensioning/esp32_s3/multipart_003.png
Binary file added docs/dimensioning/esp32_s3/tls_001.png
Binary file added docs/dimensioning/esp32_s3/tls_002.png
Binary file added docs/dimensioning/esp32_s3/tls_003.png
61 changes: 33 additions & 28 deletions docs/dimensioning/http_dimensioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,24 @@ with no active network traffic.

| id | http_mem_cap | http_multipart | socket_max_con | tls | footprint_bytes |
| --- | --- | --- | --- | --- | --- |
| base | 0.05 | False | 1 | False | 39200 |
| low_mem_cap_001 | 0.0127 | False | 1 | False | 39200 |
| low_mem_cap_002 | 0.0253 | False | 2 | False | 40416 |
| low_mem_cap_003 | 0.0505 | False | 4 | False | 42848 |
| high_mem_cap_001 | 0.0568 | False | 1 | False | 46368 |
| high_mem_cap_002 | 0.114 | False | 2 | False | 54752 |
| high_mem_cap_003 | 0.228 | False | 4 | False | 71520 |
| multipart_001 | 0.0127 | True | 1 | False | 43616 |
| multipart_002 | 0.0253 | True | 2 | False | 44832 |
| multipart_003 | 0.0505 | True | 4 | False | 47264 |
| tls_001 | 0.0127 | False | 1 | True | 41872 |
| tls_002 | 0.0253 | False | 2 | True | 43088 |
| tls_003 | 0.0505 | False | 4 | True | 45520 |
| base | 0.05 | False | 1 | False | 40320 |
| low_mem_cap_001 | 0.0127 | False | 1 | False | 40320 |
| low_mem_cap_002 | 0.0253 | False | 2 | False | 41536 |
| low_mem_cap_003 | 0.0505 | False | 4 | False | 43968 |
| high_mem_cap_001 | 0.0568 | False | 1 | False | 47488 |
| high_mem_cap_002 | 0.114 | False | 2 | False | 55872 |
| high_mem_cap_003 | 0.228 | False | 4 | False | 72640 |
| multipart_001 | 0.0127 | True | 1 | False | 45040 |
| multipart_002 | 0.0253 | True | 2 | False | 46256 |
| multipart_003 | 0.0505 | True | 4 | False | 48688 |
| files_api_001 | 0.0127 | False | 1 | False | 47872 |
| files_api_002 | 0.0253 | False | 2 | False | 49088 |
| files_api_003 | 0.0505 | False | 4 | False | 51520 |
| tls_001 | 0.0127 | False | 1 | True | 43040 |
| tls_002 | 0.0253 | False | 2 | True | 44256 |

## Heap usage under network traffic
![image info](./img/esp32_c3/base.png)
![image info](./esp32_c3/base.png)


# ESP32-S3 (8MB PSRAM)
Expand All @@ -53,19 +55,22 @@ with no active network traffic.
## Idle heap usage
| id | http_mem_cap | http_multipart | socket_max_con | tls | footprint_bytes |
| --- | --- | --- | --- | --- | --- |
| base | 0.05 | False | 1 | False | 45856 |
| low_mem_cap_001 | 0.000247 | False | 1 | False | 38688 |
| low_mem_cap_002 | 0.000493 | False | 2 | False | 39904 |
| low_mem_cap_003 | 0.000985 | False | 4 | False | 42336 |
| high_mem_cap_001 | 0.00111 | False | 1 | False | 45856 |
| high_mem_cap_002 | 0.00222 | False | 2 | False | 54240 |
| high_mem_cap_003 | 0.00443 | False | 4 | False | 71008 |
| multipart_001 | 0.000247 | True | 1 | False | 40896 |
| multipart_002 | 0.000493 | True | 2 | False | 42112 |
| multipart_003 | 0.000985 | True | 4 | False | 44544 |
| tls_001 | 0.000247 | False | 1 | True | 41072 |
| tls_002 | 0.000493 | False | 2 | True | 42288 |
| tls_003 | 0.000985 | False | 4 | True | 44720 |
| base | 0.05 | False | 1 | False | 47456 |
| low_mem_cap_001 | 0.000247 | False | 1 | False | 40288 |
| low_mem_cap_002 | 0.000493 | False | 2 | False | 41504 |
| low_mem_cap_003 | 0.000985 | False | 4 | False | 43936 |
| high_mem_cap_001 | 0.00111 | False | 1 | False | 47456 |
| high_mem_cap_002 | 0.00222 | False | 2 | False | 55840 |
| high_mem_cap_003 | 0.00443 | False | 4 | False | 72608 |
| multipart_001 | 0.000247 | True | 1 | False | 44848 |
| multipart_002 | 0.000493 | True | 2 | False | 46064 |
| multipart_003 | 0.000985 | True | 4 | False | 48496 |
| files_api_001 | 0.000247 | False | 1 | False | 47840 |
| files_api_002 | 0.000493 | False | 2 | False | 49056 |
| files_api_003 | 0.000985 | False | 4 | False | 51488 |
| tls_001 | 0.000247 | False | 1 | True | 42624 |
| tls_002 | 0.000493 | False | 2 | True | 43840 |
| tls_003 | 0.000985 | False | 4 | True | 46272 |

## Heap usage under network traffic
![image info](./img/esp32_s3/base.png)
![image info](./esp32_s3/base.png)
Binary file removed docs/dimensioning/img/esp32_c3/base.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_c3/high_mem_cap_001.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_c3/high_mem_cap_002.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_c3/high_mem_cap_003.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_c3/low_mem_cap_001.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_c3/low_mem_cap_002.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_c3/low_mem_cap_003.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_c3/multipart_001.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_c3/multipart_002.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_c3/multipart_003.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_c3/tls_001.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_c3/tls_002.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/base.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/high_mem_cap_001.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/high_mem_cap_002.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/high_mem_cap_003.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/low_mem_cap_001.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/low_mem_cap_002.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/low_mem_cap_003.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/multipart_001.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/multipart_002.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/multipart_003.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/tls_001.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/tls_002.png
Diff not rendered.
Binary file removed docs/dimensioning/img/esp32_s3/tls_003.png
Diff not rendered.
5 changes: 5 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
mpremote==1.27.0
locust==2.27.0
gevent==24.2.1
greenlet==3.0.3
requests==2.32.3
urllib3==2.2.2
pylint
black
requests
Expand Down
36 changes: 36 additions & 0 deletions tests/system/http_dimensioning/boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from pyrobusta.protocol.http import HttpEngine
from pyrobusta.connectivity import wifi

from pyrobusta.utils.config import get_config, CONF_HTTP_MULTIPART

TS_DURATION = 100
MEM_TIME_SERIES = [0] * TS_DURATION

Expand All @@ -22,11 +24,24 @@ def time_series(*_):
return "application/json", MEM_TIME_SERIES


@HttpEngine.route("/test/stream", "POST")
def chunked_callback(http_ctx, chunk_or_part):
if (
http_ctx.headers.get("content-type", "").startswith("multipart/form-data")
and http_ctx.mp_is_last
):
return "text/plain", "OK"
elif not chunk_or_part: # Received terminating chunk/part
return "text/plain", "OK"
pass # process chunk/part data as needed


async def mem_usage():
i = 0
collect()
while True:
i = (i + 1) % TS_DURATION
collect()
MEM_TIME_SERIES[i] = mem_alloc()
await asyncio.sleep(1)

Expand All @@ -35,6 +50,27 @@ async def main():
server = http_server.HttpServer()
connected = wifi.initialize()
if connected and not machine.reset_cause() == machine.SOFT_RESET:
if get_config(CONF_HTTP_MULTIPART):

def multipart_response(num_responses, part_size):
i = 0

def response_generator():
nonlocal i
i += 1
if i > num_responses:
return None
return "text/plain", b"X" * part_size

return response_generator

def multipart_callback(http_ctx, _):
part_count = int(http_ctx.headers.get("x-part-count", 1))
part_size = int(http_ctx.headers.get("x-part-size", 1024))
return "multipart/form-data", multipart_response(part_count, part_size)

HttpEngine.register("/test/multipart", multipart_callback, "GET")

asyncio.create_task(server.start_socket_server())
asyncio.create_task(mem_usage())
while True:
Expand Down
164 changes: 164 additions & 0 deletions tests/system/http_dimensioning/http_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
from locust import HttpUser, task, constant

TLS_VERIFY = False


class DefaultUser(HttpUser):
"""
Use the /index.html and /examples.html
endpoints to test static file serving.
"""

wait_time = constant(0)

def on_start(self):
self.client.verify = TLS_VERIFY

@task(2)
def get_index(self):
response = self.client.get(
"/index.html",
name="/index.html",
)
print(
self.client.base_url + "/index.html",
response.status_code,
response.elapsed.total_seconds(),
)

@task(2)
def get_docs(self):
response = self.client.get(
"/examples.html",
name="/examples.html",
)
print(
self.client.base_url + "/examples.html",
response.status_code,
response.elapsed.total_seconds(),
)

@task(1)
def post_chunked(self):
"""
Use the /test/stream endpoint to test chunked request handling,
sending a chunked request with multiple chunks of specified size.
"""
part_count = 10
part_size = 256
chunked_data = b""
for i in range(part_count):
chunked_data += b"%X\r\n" % part_size
chunked_data += b"X" * part_size + b"\r\n"
chunked_data += b"0\r\n\r\n"

response = self.client.post(
"/test/stream",
data=chunked_data,
headers={
"Content-Type": "application/octet-stream",
"Transfer-Encoding": "chunked",
},
name="/test/stream",
)
print(
self.client.base_url
+ "/test/stream (chunked; parts=%d, size=%d)" % (part_count, part_size),
response.status_code,
response.elapsed.total_seconds(),
)


class MultipartUser(HttpUser):
wait_time = constant(0)

def on_start(self):
self.client.verify = TLS_VERIFY

@task(2)
def get_multipart(self):
"""
Use the /test/multipart endpoint with the x-part-count and x-part-size
headers to test multipart response handling.
"""
part_count = 10
part_size = 256
response = self.client.get(
"/test/multipart",
headers={"x-part-count": str(part_count), "x-part-size": str(part_size)},
name="/test/multipart",
)
print(
self.client.base_url
+ "/test/multipart (parts=%d, size=%d)" % (part_count, part_size),
response.status_code,
response.elapsed.total_seconds(),
)

@task(1)
def post_multipart(self):
"""
Use the /test/stream endpoint to test multipart request handling,
sending multipart requests with multiple parts of specified size.
"""
part_count = 10
part_size = 256
multipart_data = b""
for i in range(part_count):
multipart_data += b"--boundary\r\n"
multipart_data += (
b'Content-Disposition: form-data; name="part"; filename="part%d.txt"\r\n'
% i
)
multipart_data += b"Content-Type: text/plain\r\n\r\n"
multipart_data += b"X" * part_size + b"\r\n"
multipart_data += b"--boundary--\r\n"

response = self.client.post(
"/test/stream",
data=multipart_data,
headers={"Content-Type": "multipart/form-data; boundary=boundary"},
name="/test/stream",
)
print(
self.client.base_url
+ "/test/stream (multipart; parts=%d, size=%d)" % (part_count, part_size),
response.status_code,
response.elapsed.total_seconds(),
)


class FilesApiUser(HttpUser):
"""
Use the /files endpoint to test static
file serving with directory listing.
"""

wait_time = constant(0)

def on_start(self):
self.client.verify = TLS_VERIFY

@task(2)
def get_index(self):
response = self.client.get(
"/files/www/index.html",
name="/files/www/index.html",
)
print(
self.client.base_url + "/files/www/index.html",
response.status_code,
response.elapsed.total_seconds(),
)

@task(2)
def get_dir(self):
response = self.client.get(
"/files/www/",
name="/files/www/",
)
print(
self.client.base_url + "/files/www/",
response.status_code,
response.elapsed.total_seconds(),
)
Loading
Loading