ai-agent/symphony-ai-agent/testing/Goal-2-Task-3/rbac_performance_test.py

88 lines
No EOL
3.3 KiB
Python

import datetime
import time
import statistics
import concurrent.futures
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
import resource
import psutil
import prometheus_client
from prometheus_client import Gauge, Histogram
# Prometheus metrics
REQUEST_LATENCY = Histogram('rbac_latency_seconds', 'RBAC operation latency')
REQUEST_RATE = Gauge('rbac_requests_per_second', 'RBAC request rate')
MEMORY_USAGE = Gauge('rbac_memory_bytes', 'RBAC memory usage')
class RBACPerformanceTest:
def __init__(self):
self.cert_cache = []
self._setup_metrics()
def _setup_metrics(self):
prometheus_client.start_http_server(8000)
def generate_test_cert(self, role):
"""Generate test certificate per SYM-SEC-004"""
key = ec.generate_private_key(ec.SECP384R1())
subject = issuer = x509.Name([
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Test Org"),
x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, role),
x509.NameAttribute(NameOID.COMMON_NAME, "test.example.com"),
])
cert = x509.CertificateBuilder().subject_name(
subject
).issuer_name(
issuer
).public_key(
key.public_key()
).serial_number(
x509.random_serial_number()
).not_valid_before(
datetime.datetime.utcnow()
).not_valid_after(
datetime.datetime.utcnow() + datetime.timedelta(days=1)
).add_extension(
x509.BasicConstraints(ca=False, path_length=None), critical=True,
).sign(key, hashes.SHA256())
return cert.public_bytes(serialization.Encoding.PEM)
def test_role_resolution(self, cert_pem):
"""Test role resolution performance"""
start = time.time()
# Simulate RBAC role resolution
cert = x509.load_pem_x509_certificate(cert_pem)
ou = cert.subject.get_attributes_for_oid(NameOID.ORGANIZATIONAL_UNIT_NAME)[0].value
latency = time.time() - start
REQUEST_LATENCY.observe(latency)
return latency
def run_concurrent_tests(self, num_threads=10000):
"""Run concurrent session test"""
with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor:
futures = [executor.submit(self.test_role_resolution, self.cert_cache[i % 100])
for i in range(num_threads)]
results = [f.result() for f in futures]
MEMORY_USAGE.set(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)
return {
'p50': statistics.median(results),
'p90': statistics.quantiles(results, n=10)[8],
'p99': statistics.quantiles(results, n=100)[98],
'success_rate': len([r for r in results if r < 0.05]) / len(results)
}
if __name__ == "__main__":
test = RBACPerformanceTest()
# Pre-generate 100 test certs
test.cert_cache = [test.generate_test_cert(f"role_{i}") for i in range(100)]
# Run tests
print("Running role resolution benchmark...")
resolution_stats = test.run_concurrent_tests()
print(f"Resolution stats: {resolution_stats}")