121 lines
4.2 KiB
Python
121 lines
4.2 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from yuxi.channels.adapters.nextcloudtalk.metrics import NextcloudTalkMetrics, _percentile
|
||
|
|
|
||
|
|
|
||
|
|
class TestPercentile:
|
||
|
|
def test_empty_returns_zero(self):
|
||
|
|
assert _percentile([], 50) == 0.0
|
||
|
|
|
||
|
|
def test_single_element(self):
|
||
|
|
assert _percentile([5.0], 50) == 5.0
|
||
|
|
assert _percentile([5.0], 95) == 5.0
|
||
|
|
|
||
|
|
def test_median_even_count(self):
|
||
|
|
data = [1.0, 2.0, 3.0, 4.0]
|
||
|
|
assert _percentile(data, 50) == 2.5
|
||
|
|
|
||
|
|
def test_median_odd_count(self):
|
||
|
|
data = [1.0, 2.0, 3.0, 4.0, 5.0]
|
||
|
|
assert _percentile(data, 50) == 3.0
|
||
|
|
|
||
|
|
def test_p95(self):
|
||
|
|
data = [float(i) for i in range(100)]
|
||
|
|
result = _percentile(data, 95)
|
||
|
|
assert 93 <= result <= 95
|
||
|
|
|
||
|
|
def test_p99(self):
|
||
|
|
data = [float(i) for i in range(100)]
|
||
|
|
result = _percentile(data, 99)
|
||
|
|
assert 97 <= result <= 99
|
||
|
|
|
||
|
|
def test_unsorted_input(self):
|
||
|
|
data = [5.0, 1.0, 4.0, 2.0, 3.0]
|
||
|
|
assert _percentile(data, 50) == 3.0
|
||
|
|
|
||
|
|
|
||
|
|
class TestNextcloudTalkMetrics:
|
||
|
|
def test_initial_snapshot(self):
|
||
|
|
metrics = NextcloudTalkMetrics()
|
||
|
|
snap = metrics.snapshot()
|
||
|
|
assert "uptime_seconds" in snap
|
||
|
|
assert snap["send"]["count"] == 0
|
||
|
|
assert snap["send"]["error_count"] == 0
|
||
|
|
assert snap["receive"]["count"] == 0
|
||
|
|
assert snap["receive"]["error_count"] == 0
|
||
|
|
assert snap["circuit_breaker"]["trip_count"] == 0
|
||
|
|
assert snap["send"]["avg_latency_ms"] is None
|
||
|
|
assert snap["receive"]["avg_latency_ms"] is None
|
||
|
|
|
||
|
|
def test_record_send_success_updates_counts(self):
|
||
|
|
metrics = NextcloudTalkMetrics()
|
||
|
|
metrics.record_send_success(0.1)
|
||
|
|
metrics.record_send_success(0.2)
|
||
|
|
snap = metrics.snapshot()
|
||
|
|
assert snap["send"]["count"] == 2
|
||
|
|
assert snap["send"]["error_count"] == 0
|
||
|
|
|
||
|
|
def test_record_send_error(self):
|
||
|
|
metrics = NextcloudTalkMetrics()
|
||
|
|
metrics.record_send_error()
|
||
|
|
metrics.record_send_error()
|
||
|
|
snap = metrics.snapshot()
|
||
|
|
assert snap["send"]["count"] == 0
|
||
|
|
assert snap["send"]["error_count"] == 2
|
||
|
|
|
||
|
|
def test_record_receive_success(self):
|
||
|
|
metrics = NextcloudTalkMetrics()
|
||
|
|
metrics.record_receive_success(0.05)
|
||
|
|
metrics.record_receive_success(0.15)
|
||
|
|
snap = metrics.snapshot()
|
||
|
|
assert snap["receive"]["count"] == 2
|
||
|
|
assert snap["receive"]["error_count"] == 0
|
||
|
|
|
||
|
|
def test_record_receive_error(self):
|
||
|
|
metrics = NextcloudTalkMetrics()
|
||
|
|
metrics.record_receive_error()
|
||
|
|
snap = metrics.snapshot()
|
||
|
|
assert snap["receive"]["count"] == 0
|
||
|
|
assert snap["receive"]["error_count"] == 1
|
||
|
|
|
||
|
|
def test_record_circuit_breaker_trip(self):
|
||
|
|
metrics = NextcloudTalkMetrics()
|
||
|
|
metrics.record_circuit_breaker_trip()
|
||
|
|
metrics.record_circuit_breaker_trip()
|
||
|
|
snap = metrics.snapshot()
|
||
|
|
assert snap["circuit_breaker"]["trip_count"] == 2
|
||
|
|
|
||
|
|
def test_average_latency_calculation(self):
|
||
|
|
metrics = NextcloudTalkMetrics()
|
||
|
|
metrics.record_send_success(0.1)
|
||
|
|
metrics.record_send_success(0.3)
|
||
|
|
metrics.record_send_success(0.2)
|
||
|
|
snap = metrics.snapshot()
|
||
|
|
avg = snap["send"]["avg_latency_ms"]
|
||
|
|
assert avg is not None
|
||
|
|
assert 199 <= avg <= 201
|
||
|
|
|
||
|
|
def test_percentile_values(self):
|
||
|
|
metrics = NextcloudTalkMetrics()
|
||
|
|
for i in range(100):
|
||
|
|
metrics.record_send_success(float(i) / 1000.0)
|
||
|
|
snap = metrics.snapshot()
|
||
|
|
assert snap["send"]["p50_latency_ms"] is not None
|
||
|
|
assert snap["send"]["p95_latency_ms"] is not None
|
||
|
|
assert snap["send"]["p99_latency_ms"] is not None
|
||
|
|
assert snap["send"]["p95_latency_ms"] > snap["send"]["p50_latency_ms"]
|
||
|
|
|
||
|
|
def test_latency_deque_bounded(self):
|
||
|
|
metrics = NextcloudTalkMetrics(max_latency_samples=10)
|
||
|
|
for i in range(20):
|
||
|
|
metrics.record_send_success(float(i) / 1000.0)
|
||
|
|
snap = metrics.snapshot()
|
||
|
|
assert snap["send"]["count"] == 20
|
||
|
|
assert snap["send"]["avg_latency_ms"] is not None
|
||
|
|
|
||
|
|
def test_uptime_seconds_positive(self):
|
||
|
|
metrics = NextcloudTalkMetrics()
|
||
|
|
import time
|
||
|
|
time.sleep(0.1)
|
||
|
|
snap = metrics.snapshot()
|
||
|
|
assert snap["uptime_seconds"] >= 0
|