ai-agent/tests/storage/test_results_persistence.py

110 lines
No EOL
4.5 KiB
Python

import unittest
import time
import sqlite3
from unittest.mock import patch
from storage.adapters.sqlite_adapter import SQLiteAdapter
from security.rbac_engine import RBACEngine
class TestResultsPersistence(unittest.TestCase):
"""Test results persistence functionality including performance metrics."""
def setUp(self):
"""Set up test database and adapter."""
self.db_path = ":memory:"
self.encryption_key = "test_key_12345678901234567890123456789012"
self.adapter = SQLiteAdapter(self.db_path, self.encryption_key)
# Setup mock RBAC
self.rbac = RBACEngine()
self.rbac.add_permission("test_user", "storage", "create")
self.rbac.add_permission("test_user", "storage", "read")
self.rbac.add_permission("test_user", "storage", "update")
self.rbac.add_permission("test_user", "storage", "delete")
self.adapter.rbac = self.rbac
def test_performance_metrics_table_exists(self):
"""Verify performance_metrics table was created."""
with sqlite3.connect(self.db_path) as conn:
cursor = conn.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name='performance_metrics'")
self.assertIsNotNone(cursor.fetchone())
def test_operation_timing_metrics(self):
"""Verify operations record performance metrics."""
# Test create operation
start = time.time()
self.adapter.create("test_key", "test_value", "test_user")
create_time = (time.time() - start) * 1000
# Test read operation
start = time.time()
self.adapter.read("test_key", "test_user")
read_time = (time.time() - start) * 1000
# Verify metrics were recorded
with sqlite3.connect(self.db_path) as conn:
cursor = conn.execute(
"SELECT operation, execution_time_ms FROM performance_metrics ORDER BY timestamp")
metrics = cursor.fetchall()
self.assertEqual(len(metrics), 2)
self.assertEqual(metrics[0][0], "create")
self.assertGreaterEqual(metrics[0][1], 0)
self.assertEqual(metrics[1][0], "read")
self.assertGreaterEqual(metrics[1][1], 0)
def test_response_time_benchmark(self):
"""Verify operations meet ≤800ms response time requirement."""
# Warm up
for _ in range(5):
self.adapter.create("warm_key", "warm_value", "test_user")
self.adapter.read("warm_key", "test_user")
# Benchmark create
start = time.time()
self.adapter.create("bench_key", "bench_value", "test_user")
create_time = (time.time() - start) * 1000
self.assertLessEqual(create_time, 800)
# Benchmark read
start = time.time()
self.adapter.read("bench_key", "test_user")
read_time = (time.time() - start) * 1000
self.assertLessEqual(read_time, 800)
# Benchmark update
start = time.time()
self.adapter.update("bench_key", "new_value", "test_user")
update_time = (time.time() - start) * 1000
self.assertLessEqual(update_time, 800)
# Benchmark delete
start = time.time()
self.adapter.delete("bench_key", "test_user")
delete_time = (time.time() - start) * 1000
self.assertLessEqual(delete_time, 800)
def test_encryption_integration(self):
"""Verify encrypted values are stored in performance metrics."""
self.adapter.create("enc_key", "secret_value", "test_user")
with sqlite3.connect(self.db_path) as conn:
# Verify storage table has encrypted value
cursor = conn.execute(
"SELECT encrypted_value FROM storage WHERE key_hash = ?",
(self.adapter._hash_key("enc_key"),))
encrypted = cursor.fetchone()[0]
self.assertNotEqual(encrypted, b"secret_value")
def test_rbac_enforcement(self):
"""Verify RBAC is enforced for performance metrics access."""
# User without permissions should be denied
with patch.object(self.rbac, 'validate_permission', return_value=False):
result = self.adapter.create("rbac_key", "rbac_value", "bad_user")
self.assertFalse(result)
result = self.adapter.read("rbac_key", "bad_user")
self.assertIsNone(result)
if __name__ == "__main__":
unittest.main()