Add max_outlier_analysis_script/tests/test_core.py
This commit is contained in:
parent
8f351f9310
commit
30950eb6c2
1 changed files with 77 additions and 0 deletions
77
max_outlier_analysis_script/tests/test_core.py
Normal file
77
max_outlier_analysis_script/tests/test_core.py
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import pytest
|
||||
import pandas as pd
|
||||
import math
|
||||
from pathlib import Path
|
||||
|
||||
from src.max_outlier_analysis_script import core
|
||||
|
||||
SAMPLE_CSV_PATH = Path(__file__).parent / 'data' / 'test_outlier_sample.csv'
|
||||
|
||||
@pytest.fixture
|
||||
def sample_data():
|
||||
"""Lädt CSV-Testdaten in ein passendes Python-Objekt (Liste von Dicts)."""
|
||||
if not SAMPLE_CSV_PATH.exists():
|
||||
# Fallback: künstliche Testdaten, falls Datei fehlt
|
||||
return [
|
||||
{
|
||||
'corr_id': 'c1', 'stratum': 'near-expiry-unpinned', 'job_parallelism': 5,
|
||||
'expires_at_dist_hours': 0.2, 'retry_total_overhead_ms': 12.5, 'latency_max': 350.0
|
||||
},
|
||||
{
|
||||
'corr_id': 'c2', 'stratum': 'normal', 'job_parallelism': 4,
|
||||
'expires_at_dist_hours': 3.1, 'retry_total_overhead_ms': 6.2, 'latency_max': 180.0
|
||||
},
|
||||
{
|
||||
'corr_id': 'c3', 'stratum': 'near-expiry-unpinned', 'job_parallelism': 6,
|
||||
'expires_at_dist_hours': 0.1, 'retry_total_overhead_ms': 15.8, 'latency_max': 420.0
|
||||
},
|
||||
]
|
||||
df = pd.read_csv(SAMPLE_CSV_PATH)
|
||||
return df.to_dict(orient='records')
|
||||
|
||||
|
||||
def test_analyze_returns_expected_keys(sample_data):
|
||||
"""Verifiziert, dass alle erwarteten Kennzahlen im Ergebnis enthalten sind."""
|
||||
result = core.analyze_max_outliers(sample_data)
|
||||
|
||||
assert isinstance(result, dict)
|
||||
expected_keys = {'max_above_p99_count', 'near_expiry_cluster_percentage', 'retry_overhead_variance'}
|
||||
assert expected_keys.issubset(result.keys())
|
||||
|
||||
|
||||
def test_result_value_types(sample_data):
|
||||
"""Stellt sicher, dass die Rückgabewerte vom korrekten Typ sind."""
|
||||
result = core.analyze_max_outliers(sample_data)
|
||||
|
||||
assert isinstance(result['max_above_p99_count'], int)
|
||||
assert isinstance(result['near_expiry_cluster_percentage'], float)
|
||||
assert isinstance(result['retry_overhead_variance'], float)
|
||||
|
||||
|
||||
def test_statistical_consistency(sample_data):
|
||||
"""Überprüft einfache statistische Plausibilität der berechneten Werte."""
|
||||
result = core.analyze_max_outliers(sample_data)
|
||||
|
||||
# Max über p99 kann nicht negativ sein
|
||||
assert result['max_above_p99_count'] >= 0
|
||||
# Prozentsatz muss im Bereich 0-100 liegen
|
||||
assert 0.0 <= result['near_expiry_cluster_percentage'] <= 100.0
|
||||
# Varianz >= 0
|
||||
assert result['retry_overhead_variance'] >= 0.0
|
||||
|
||||
|
||||
def test_error_handling_on_empty_input():
|
||||
"""Leere Eingaben sollten einen kontrollierten Fehler oder leeren Output liefern."""
|
||||
with pytest.raises((ValueError, AssertionError, ZeroDivisionError, KeyError)):
|
||||
_ = core.analyze_max_outliers([])
|
||||
|
||||
|
||||
def test_invariance_same_input():
|
||||
"""Gleiche Eingaben müssen deterministische Ergebnisse liefern (idempotent)."""
|
||||
d = [
|
||||
{'corr_id': 'x1', 'stratum': 's1', 'job_parallelism': 2, 'expires_at_dist_hours': 1.0, 'retry_total_overhead_ms': 5.0, 'latency_max': 120.0},
|
||||
{'corr_id': 'x2', 'stratum': 's1', 'job_parallelism': 3, 'expires_at_dist_hours': 2.0, 'retry_total_overhead_ms': 8.0, 'latency_max': 150.0},
|
||||
]
|
||||
res1 = core.analyze_max_outliers(d)
|
||||
res2 = core.analyze_max_outliers(d)
|
||||
assert res1 == res2
|
||||
Loading…
Reference in a new issue