Skip to main content
Glama
test_audit_log.py6.59 kB
#!/usr/bin/env python3 """ Test script for audit log functionality. Run after MCP server restart to verify audit log implementation. """ import json from pathlib import Path # Paths PROJECT_ROOT = Path(__file__).parent.parent.parent AUDIT_LOG_PATH = PROJECT_ROOT / "data" / "logs" / "audit_log.parquet" def test_audit_log_exists(): """Test 1: Verify audit log file exists""" print("Test 1: Checking if audit log exists...") if AUDIT_LOG_PATH.exists(): print(f"✅ Audit log exists at {AUDIT_LOG_PATH}") return True else: print(f"❌ Audit log not found at {AUDIT_LOG_PATH}") print(" This is expected if no write operations have occurred since server restart.") return False def test_audit_log_content(): """Test 2: Read and analyze audit log content""" if not AUDIT_LOG_PATH.exists(): print("\nTest 2: Skipped (no audit log exists yet)") return False print("\nTest 2: Analyzing audit log content...") try: import pandas as pd df = pd.read_parquet(AUDIT_LOG_PATH) print(f"✅ Successfully read audit log") print(f" Total entries: {len(df)}") print(f" Columns: {list(df.columns)}") if len(df) > 0: print(f"\n Operation breakdown:") print(df["operation"].value_counts().to_string()) print(f"\n Data types modified:") print(df["data_type"].value_counts().to_string()) print(f"\n Most recent operation:") latest = df.iloc[-1] print(f" - Audit ID: {latest['audit_id']}") print(f" - Timestamp: {latest['timestamp']}") print(f" - Operation: {latest['operation']}") print(f" - Data type: {latest['data_type']}") print(f" - Record ID: {latest['record_id']}") return True except Exception as e: print(f"❌ Error reading audit log: {e}") return False def test_schema_validation(): """Test 3: Verify audit log matches schema""" if not AUDIT_LOG_PATH.exists(): print("\nTest 3: Skipped (no audit log exists yet)") return False print("\nTest 3: Validating audit log schema...") try: import pandas as pd # Load audit log df = pd.read_parquet(AUDIT_LOG_PATH) # Expected columns from schema expected_columns = { "audit_id", "timestamp", "operation", "data_type", "record_id", "affected_fields", "old_values", "new_values", "user", "snapshot_reference", "notes" } actual_columns = set(df.columns) missing = expected_columns - actual_columns extra = actual_columns - expected_columns if not missing and not extra: print("✅ Schema validation passed") return True else: if missing: print(f"❌ Missing columns: {missing}") if extra: print(f"⚠️ Extra columns: {extra}") return False except Exception as e: print(f"❌ Error validating schema: {e}") return False def print_usage_instructions(): """Print instructions for manual testing via MCP""" print("\n" + "="*70) print("MANUAL TESTING INSTRUCTIONS") print("="*70) print(""" To test the audit log functionality via MCP tools: 1. Add a test record: mcp_parquet_add_record( data_type="beliefs", record={ "belief_id": "test-audit-123", "name": "Test Record", "categories": "Testing", "confidence_level": "High", "date": "2025-12-17", "notes": "Testing audit log", "import_date": "2025-12-17", "import_source_file": "audit_test" } ) Expected: Returns audit_id, no snapshot unless configured 2. Read audit log: mcp_parquet_read_audit_log(limit=10) Expected: Shows the add operation with new_values 3. Update the record: mcp_parquet_update_records( data_type="beliefs", filters={"belief_id": "test-audit-123"}, updates={"notes": "Updated via audit test"} ) Expected: Returns audit_ids, captures old and new values 4. Read audit log again: mcp_parquet_read_audit_log( data_type="beliefs", record_id="test-audit-123" ) Expected: Shows both add and update operations 5. Rollback the update: mcp_parquet_rollback_operation(audit_id="<audit_id_from_update>") Expected: Restores original notes value, creates rollback audit entry 6. Delete the record: mcp_parquet_delete_records( data_type="beliefs", filters={"belief_id": "test-audit-123"} ) Expected: Creates audit entry with complete record data 7. Rollback the delete: mcp_parquet_rollback_operation(audit_id="<audit_id_from_delete>") Expected: Restores the deleted record 8. Final cleanup - delete again: mcp_parquet_delete_records( data_type="beliefs", filters={"belief_id": "test-audit-123"} ) """) def main(): print("="*70) print("AUDIT LOG IMPLEMENTATION TEST") print("="*70) print("\nThis script validates the audit log implementation.") print("Run AFTER restarting the MCP server.\n") results = [] # Run tests results.append(("Audit log exists", test_audit_log_exists())) results.append(("Audit log content", test_audit_log_content())) results.append(("Schema validation", test_schema_validation())) # Summary print("\n" + "="*70) print("TEST SUMMARY") print("="*70) passed = sum(1 for _, result in results if result) total = len(results) for test_name, result in results: status = "✅ PASS" if result else "❌ FAIL" print(f"{status}: {test_name}") print(f"\nPassed: {passed}/{total}") if passed == 0: print("\n⚠️ No tests passed. This is expected if:") print(" 1. MCP server hasn't been restarted yet") print(" 2. No write operations have occurred since restart") print("\n Next step: Restart MCP server and perform a write operation") elif passed < total: print("\n⚠️ Some tests failed. Review errors above.") else: print("\n✅ All tests passed! Audit log implementation is working.") # Print manual testing instructions print_usage_instructions() if __name__ == "__main__": main()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/markmhendrickson/mcp-server-parquet'

If you have feedback or need assistance with the MCP directory API, please join our Discord server