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()