Agentic-Reliability-Framework-API / test_input_validation.py
petter2025's picture
Create test_input_validation.py
f97adbe verified
raw
history blame
11.3 kB
"""
Unit tests for input validation functions
"""
import pytest
from app import validate_inputs, validate_component_id
class TestComponentIDValidation:
"""Test component ID validation"""
def test_valid_component_ids(self):
"""Test that valid component IDs pass validation"""
valid_ids = [
"api-service",
"auth-service",
"payment-service-v2",
"db-01",
"cache",
"a", # Single character
"api-gateway-prod-001",
]
for component_id in valid_ids:
is_valid, msg = validate_component_id(component_id)
assert is_valid is True, f"'{component_id}' should be valid but got: {msg}"
assert msg == ""
def test_invalid_uppercase(self):
"""Test that uppercase letters are rejected"""
invalid_ids = ["API-SERVICE", "Auth-Service", "PaymentService"]
for component_id in invalid_ids:
is_valid, msg = validate_component_id(component_id)
assert is_valid is False
assert "lowercase" in msg.lower()
def test_invalid_underscore(self):
"""Test that underscores are rejected"""
is_valid, msg = validate_component_id("api_service")
assert is_valid is False
assert "lowercase" in msg.lower() or "hyphen" in msg.lower()
def test_invalid_special_characters(self):
"""Test that special characters are rejected"""
invalid_ids = [
"api@service",
"api.service",
"api service", # Space
"api/service",
"api&service",
]
for component_id in invalid_ids:
is_valid, msg = validate_component_id(component_id)
assert is_valid is False, f"'{component_id}' should be invalid"
def test_empty_string(self):
"""Test that empty string is rejected"""
is_valid, msg = validate_component_id("")
assert is_valid is False
assert "1-255" in msg or "character" in msg.lower()
def test_too_long(self):
"""Test that component IDs longer than 255 chars are rejected"""
long_id = "a" * 256
is_valid, msg = validate_component_id(long_id)
assert is_valid is False
assert "255" in msg
def test_non_string_type(self):
"""Test that non-string types are rejected"""
is_valid, msg = validate_component_id(123)
assert is_valid is False
assert "string" in msg.lower()
class TestNumericInputValidation:
"""Test numeric input validation"""
def test_valid_inputs(self):
"""Test that valid inputs pass validation"""
is_valid, msg = validate_inputs(
latency=150.0,
error_rate=0.05,
throughput=1000.0,
cpu_util=0.7,
memory_util=0.6
)
assert is_valid is True
assert msg == ""
def test_valid_inputs_with_none_optionals(self):
"""Test that None is valid for optional fields"""
is_valid, msg = validate_inputs(
latency=150.0,
error_rate=0.05,
throughput=1000.0,
cpu_util=None,
memory_util=None
)
assert is_valid is True
assert msg == ""
class TestLatencyValidation:
"""Test latency validation"""
def test_valid_latency(self):
"""Test valid latency values"""
valid_values = [0, 1, 100, 500, 1000, 9999]
for latency in valid_values:
is_valid, msg = validate_inputs(latency, 0.05, 1000, None, None)
assert is_valid is True, f"Latency {latency} should be valid"
def test_negative_latency(self):
"""Test that negative latency is rejected"""
is_valid, msg = validate_inputs(-10, 0.05, 1000, None, None)
assert is_valid is False
assert "latency" in msg.lower()
def test_excessive_latency(self):
"""Test that excessive latency is rejected"""
is_valid, msg = validate_inputs(20000, 0.05, 1000, None, None)
assert is_valid is False
assert "latency" in msg.lower()
def test_non_numeric_latency(self):
"""Test that non-numeric latency is rejected"""
is_valid, msg = validate_inputs("invalid", 0.05, 1000, None, None)
assert is_valid is False
assert "latency" in msg.lower()
class TestErrorRateValidation:
"""Test error rate validation"""
def test_valid_error_rates(self):
"""Test valid error rate values"""
valid_values = [0, 0.01, 0.05, 0.5, 0.99, 1.0]
for error_rate in valid_values:
is_valid, msg = validate_inputs(100, error_rate, 1000, None, None)
assert is_valid is True, f"Error rate {error_rate} should be valid"
def test_negative_error_rate(self):
"""Test that negative error rate is rejected"""
is_valid, msg = validate_inputs(100, -0.1, 1000, None, None)
assert is_valid is False
assert "error rate" in msg.lower()
def test_error_rate_exceeds_one(self):
"""Test that error rate > 1 is rejected"""
is_valid, msg = validate_inputs(100, 1.5, 1000, None, None)
assert is_valid is False
assert "error rate" in msg.lower()
def test_non_numeric_error_rate(self):
"""Test that non-numeric error rate is rejected"""
is_valid, msg = validate_inputs(100, "high", 1000, None, None)
assert is_valid is False
assert "error rate" in msg.lower()
class TestThroughputValidation:
"""Test throughput validation"""
def test_valid_throughput(self):
"""Test valid throughput values"""
valid_values = [0, 1, 100, 1000, 10000]
for throughput in valid_values:
is_valid, msg = validate_inputs(100, 0.05, throughput, None, None)
assert is_valid is True, f"Throughput {throughput} should be valid"
def test_negative_throughput(self):
"""Test that negative throughput is rejected"""
is_valid, msg = validate_inputs(100, 0.05, -500, None, None)
assert is_valid is False
assert "throughput" in msg.lower()
def test_non_numeric_throughput(self):
"""Test that non-numeric throughput is rejected"""
is_valid, msg = validate_inputs(100, 0.05, "many", None, None)
assert is_valid is False
assert "throughput" in msg.lower()
class TestCPUUtilizationValidation:
"""Test CPU utilization validation"""
def test_valid_cpu_util(self):
"""Test valid CPU utilization values"""
valid_values = [0, 0.1, 0.5, 0.85, 1.0]
for cpu_util in valid_values:
is_valid, msg = validate_inputs(100, 0.05, 1000, cpu_util, None)
assert is_valid is True, f"CPU util {cpu_util} should be valid"
def test_negative_cpu_util(self):
"""Test that negative CPU utilization is rejected"""
is_valid, msg = validate_inputs(100, 0.05, 1000, -0.1, None)
assert is_valid is False
assert "cpu" in msg.lower()
def test_cpu_util_exceeds_one(self):
"""Test that CPU utilization > 1 is rejected"""
is_valid, msg = validate_inputs(100, 0.05, 1000, 1.5, None)
assert is_valid is False
assert "cpu" in msg.lower()
def test_non_numeric_cpu_util(self):
"""Test that non-numeric CPU utilization is rejected"""
is_valid, msg = validate_inputs(100, 0.05, 1000, "high", None)
assert is_valid is False
assert "cpu" in msg.lower()
class TestMemoryUtilizationValidation:
"""Test memory utilization validation"""
def test_valid_memory_util(self):
"""Test valid memory utilization values"""
valid_values = [0, 0.1, 0.5, 0.85, 1.0]
for memory_util in valid_values:
is_valid, msg = validate_inputs(100, 0.05, 1000, None, memory_util)
assert is_valid is True, f"Memory util {memory_util} should be valid"
def test_negative_memory_util(self):
"""Test that negative memory utilization is rejected"""
is_valid, msg = validate_inputs(100, 0.05, 1000, None, -0.1)
assert is_valid is False
assert "memory" in msg.lower()
def test_memory_util_exceeds_one(self):
"""Test that memory utilization > 1 is rejected"""
is_valid, msg = validate_inputs(100, 0.05, 1000, None, 1.5)
assert is_valid is False
assert "memory" in msg.lower()
def test_non_numeric_memory_util(self):
"""Test that non-numeric memory utilization is rejected"""
is_valid, msg = validate_inputs(100, 0.05, 1000, None, "full")
assert is_valid is False
assert "memory" in msg.lower()
class TestEdgeCases:
"""Test edge cases and boundary conditions"""
def test_zero_values(self):
"""Test that zero is valid for all metrics"""
is_valid, msg = validate_inputs(0, 0, 0, 0, 0)
assert is_valid is True
def test_maximum_values(self):
"""Test maximum boundary values"""
is_valid, msg = validate_inputs(10000, 1.0, 999999, 1.0, 1.0)
assert is_valid is True
def test_float_precision(self):
"""Test that high-precision floats are handled"""
is_valid, msg = validate_inputs(
latency=123.456789,
error_rate=0.123456,
throughput=1234.56,
cpu_util=0.87654321,
memory_util=0.76543210
)
assert is_valid is True
def test_integer_inputs(self):
"""Test that integer inputs are accepted"""
is_valid, msg = validate_inputs(100, 0, 1000, 1, 1)
assert is_valid is True
def test_string_numbers(self):
"""Test that string numbers are converted"""
is_valid, msg = validate_inputs("100", "0.05", "1000", "0.7", "0.6")
assert is_valid is True
class TestErrorMessages:
"""Test that error messages are helpful"""
def test_error_message_contains_field_name(self):
"""Test that error messages identify the problematic field"""
# Latency error
is_valid, msg = validate_inputs(-10, 0.05, 1000, None, None)
assert "latency" in msg.lower()
# Error rate error
is_valid, msg = validate_inputs(100, 2.0, 1000, None, None)
assert "error rate" in msg.lower()
# Throughput error
is_valid, msg = validate_inputs(100, 0.05, -100, None, None)
assert "throughput" in msg.lower()
def test_error_message_has_emoji(self):
"""Test that error messages include emoji for visibility"""
is_valid, msg = validate_inputs(-10, 0.05, 1000, None, None)
assert "❌" in msg
def test_error_message_provides_guidance(self):
"""Test that error messages provide guidance"""
is_valid, msg = validate_inputs(-10, 0.05, 1000, None, None)
assert "between" in msg.lower() or "range" in msg.lower() or "0-10000" in msg
if __name__ == "__main__":
pytest.main([__file__, "-v", "--tb=short"])