122 lines
4.0 KiB
Python
122 lines
4.0 KiB
Python
"""Tests for WebSocket load testing infrastructure (issue #1505)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
PROJECT_ROOT = Path(__file__).parent.parent
|
|
|
|
_spec = importlib.util.spec_from_file_location(
|
|
"ws_load_test_test",
|
|
PROJECT_ROOT / "bin" / "ws_load_test.py",
|
|
)
|
|
_mod = importlib.util.module_from_spec(_spec)
|
|
sys.modules["ws_load_test_test"] = _mod
|
|
_spec.loader.exec_module(_mod)
|
|
|
|
main = _mod.main
|
|
measure_memory = _mod.measure_memory
|
|
run_load_test = _mod.run_load_test
|
|
write_report = _mod.write_report
|
|
|
|
|
|
class TestMemoryStats:
|
|
@patch("ws_load_test_test.tracemalloc.get_traced_memory", return_value=(1024, 4096))
|
|
@patch("ws_load_test_test.resource.getrusage")
|
|
def test_measure_memory_reports_tracemalloc_and_rss_bytes(self, mock_getrusage, _mock_tracemalloc):
|
|
mock_getrusage.return_value = type("Usage", (), {"ru_maxrss": 512})()
|
|
with patch.object(_mod.sys, "platform", "linux"):
|
|
stats = measure_memory()
|
|
|
|
assert stats["tracemalloc_current_bytes"] == 1024
|
|
assert stats["tracemalloc_peak_bytes"] == 4096
|
|
assert stats["rss_bytes"] == 512 * 1024
|
|
|
|
|
|
class TestRunLoadTest:
|
|
def test_run_load_test_reports_concurrency_and_messages(self):
|
|
events = []
|
|
|
|
class FakeConnection:
|
|
def __init__(self, url):
|
|
self.url = url
|
|
|
|
async def __aenter__(self):
|
|
events.append(("enter", self.url))
|
|
return self
|
|
|
|
async def __aexit__(self, exc_type, exc, tb):
|
|
events.append(("exit", self.url))
|
|
|
|
async def send(self, payload):
|
|
events.append(("send", payload))
|
|
|
|
async def exercise():
|
|
return await run_load_test(
|
|
url="ws://nexus.local:8765",
|
|
concurrency=3,
|
|
rounds=2,
|
|
hold_seconds=0,
|
|
payload={"type": "probe"},
|
|
connector=lambda url: FakeConnection(url),
|
|
)
|
|
|
|
report = _mod.asyncio.run(exercise())
|
|
|
|
assert report["url"] == "ws://nexus.local:8765"
|
|
assert report["concurrency"] == 3
|
|
assert report["rounds"] == 2
|
|
assert report["attempted_connections"] == 6
|
|
assert report["successful_connections"] == 6
|
|
assert report["failed_connections"] == 0
|
|
assert report["messages_sent"] == 6
|
|
assert report["success_rate"] == 1.0
|
|
assert "memory_before" in report
|
|
assert "memory_after" in report
|
|
assert len([e for e in events if e[0] == "send"]) == 6
|
|
|
|
|
|
class TestReportOutput:
|
|
def test_write_report_serializes_json(self, tmp_path):
|
|
out = tmp_path / "ws-load-report.json"
|
|
payload = {"successful_connections": 4, "failed_connections": 0}
|
|
write_report(out, payload)
|
|
assert json.loads(out.read_text()) == payload
|
|
|
|
def test_main_writes_output_file(self, tmp_path):
|
|
out = tmp_path / "report.json"
|
|
fake_report = {
|
|
"url": "ws://127.0.0.1:8765",
|
|
"concurrency": 4,
|
|
"rounds": 2,
|
|
"attempted_connections": 8,
|
|
"successful_connections": 8,
|
|
"failed_connections": 0,
|
|
"messages_sent": 0,
|
|
"success_rate": 1.0,
|
|
"memory_before": {"rss_bytes": 1, "tracemalloc_current_bytes": 2, "tracemalloc_peak_bytes": 3},
|
|
"memory_after": {"rss_bytes": 4, "tracemalloc_current_bytes": 5, "tracemalloc_peak_bytes": 6},
|
|
}
|
|
|
|
async def fake_run_load_test(**_kwargs):
|
|
return fake_report
|
|
|
|
with patch.object(_mod, "run_load_test", fake_run_load_test):
|
|
rc = main([
|
|
"--url",
|
|
"ws://127.0.0.1:8765",
|
|
"--concurrency",
|
|
"4",
|
|
"--rounds",
|
|
"2",
|
|
"--output",
|
|
str(out),
|
|
])
|
|
|
|
assert rc == 0
|
|
assert json.loads(out.read_text()) == fake_report
|