- Deprecated/broken migration files archived - New auth_schema migration (015) - Trading service events migration (016) - Migration renumbering utility - Migration test suite
411 lines
16 KiB
PL/PgSQL
411 lines
16 KiB
PL/PgSQL
-- ================================================================================================
|
|
-- Compliance Views Test Suite (Migration 004)
|
|
-- PostgreSQL 16.10 + TimescaleDB 2.22.1
|
|
-- Tests SOX, MiFID II, and regulatory compliance views
|
|
-- ================================================================================================
|
|
|
|
BEGIN;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 1: Compliance Views Existence
|
|
-- Verify all required compliance views are created
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_required_views TEXT[] := ARRAY[
|
|
'audit_trail_complete',
|
|
'sox_user_access_report',
|
|
'sox_configuration_changes',
|
|
'mifid_transaction_reporting',
|
|
'mifid_best_execution_analysis',
|
|
'compliance_dashboard',
|
|
'risk_breach_summary',
|
|
'regulatory_audit_log'
|
|
];
|
|
v_view TEXT;
|
|
v_missing_views TEXT[] := ARRAY[]::TEXT[];
|
|
v_found_count INTEGER := 0;
|
|
BEGIN
|
|
FOREACH v_view IN ARRAY v_required_views
|
|
LOOP
|
|
IF EXISTS (
|
|
SELECT 1 FROM information_schema.views
|
|
WHERE table_schema = 'public'
|
|
AND table_name = v_view
|
|
) THEN
|
|
v_found_count := v_found_count + 1;
|
|
ELSE
|
|
v_missing_views := array_append(v_missing_views, v_view);
|
|
END IF;
|
|
END LOOP;
|
|
|
|
IF array_length(v_missing_views, 1) IS NULL THEN
|
|
RAISE NOTICE 'TEST 1 PASS: All % compliance views exist', array_length(v_required_views, 1);
|
|
ELSE
|
|
RAISE WARNING 'TEST 1 WARNING: Missing views (% of %): %',
|
|
array_length(v_missing_views, 1),
|
|
array_length(v_required_views, 1),
|
|
array_to_string(v_missing_views, ', ');
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 2: Audit Trail Completeness
|
|
-- Verify audit_trail_complete view provides comprehensive audit data
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_column_count INTEGER;
|
|
v_required_columns TEXT[] := ARRAY[
|
|
'event_id',
|
|
'correlation_id',
|
|
'event_timestamp',
|
|
'event_type',
|
|
'user_id',
|
|
'component',
|
|
'event_data',
|
|
'severity'
|
|
];
|
|
v_col TEXT;
|
|
v_missing_columns TEXT[] := ARRAY[]::TEXT[];
|
|
BEGIN
|
|
-- Check if view exists
|
|
IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'audit_trail_complete') THEN
|
|
RAISE NOTICE 'TEST 2 INFO: Skipping - audit_trail_complete view not found';
|
|
RETURN;
|
|
END IF;
|
|
|
|
-- Check required columns
|
|
FOREACH v_col IN ARRAY v_required_columns
|
|
LOOP
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_name = 'audit_trail_complete'
|
|
AND column_name = v_col
|
|
) THEN
|
|
v_missing_columns := array_append(v_missing_columns, v_col);
|
|
END IF;
|
|
END LOOP;
|
|
|
|
IF array_length(v_missing_columns, 1) IS NULL THEN
|
|
RAISE NOTICE 'TEST 2 PASS: audit_trail_complete has all required columns';
|
|
ELSE
|
|
RAISE WARNING 'TEST 2 WARNING: Missing columns in audit_trail_complete: %',
|
|
array_to_string(v_missing_columns, ', ');
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 3: SOX User Access Report
|
|
-- Verify SOX compliance view tracks user access properly
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_test_user_id UUID := uuid_generate_v4();
|
|
v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
|
|
v_access_count INTEGER;
|
|
BEGIN
|
|
-- Check if view exists
|
|
IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'sox_user_access_report') THEN
|
|
RAISE NOTICE 'TEST 3 INFO: Skipping - sox_user_access_report view not found';
|
|
RETURN;
|
|
END IF;
|
|
|
|
-- Insert test audit events
|
|
INSERT INTO audit_events (
|
|
correlation_id, event_timestamp, event_type, severity, component,
|
|
user_id, event_data, event_hash, node_id, process_id
|
|
) VALUES
|
|
(uuid_generate_v4(), v_current_ns, 'authentication_success', 'info', 'authentication',
|
|
v_test_user_id::text, '{"action": "login", "ip": "192.168.1.100"}'::jsonb,
|
|
encode(sha256('sox1'::bytea), 'hex'), 'node-01', 12345),
|
|
(uuid_generate_v4(), v_current_ns + 1000000, 'permission_granted', 'notice', 'authorization',
|
|
v_test_user_id::text, '{"permission": "read:trades"}'::jsonb,
|
|
encode(sha256('sox2'::bytea), 'hex'), 'node-01', 12345);
|
|
|
|
-- Query view
|
|
EXECUTE format('SELECT COUNT(*) FROM sox_user_access_report WHERE user_id = %L', v_test_user_id::text)
|
|
INTO v_access_count;
|
|
|
|
IF v_access_count >= 0 THEN
|
|
RAISE NOTICE 'TEST 3 PASS: SOX user access report queryable (found % matching records)', v_access_count;
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 3 FAIL: SOX user access report query failed';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 4: SOX Configuration Changes
|
|
-- Verify configuration change tracking for SOX compliance
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
|
|
v_config_count INTEGER;
|
|
BEGIN
|
|
-- Check if view exists
|
|
IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'sox_configuration_changes') THEN
|
|
RAISE NOTICE 'TEST 4 INFO: Skipping - sox_configuration_changes view not found';
|
|
RETURN;
|
|
END IF;
|
|
|
|
-- Insert test configuration change events
|
|
INSERT INTO audit_events (
|
|
correlation_id, event_timestamp, event_type, severity, component,
|
|
user_id, event_data, event_hash, node_id, process_id
|
|
) VALUES
|
|
(uuid_generate_v4(), v_current_ns, 'configuration_updated', 'notice', 'configuration',
|
|
'admin_user', '{"key": "risk_limit", "old": "100000", "new": "150000"}'::jsonb,
|
|
encode(sha256('config1'::bytea), 'hex'), 'node-01', 12345);
|
|
|
|
-- Query view
|
|
EXECUTE 'SELECT COUNT(*) FROM sox_configuration_changes WHERE event_timestamp >= $1'
|
|
INTO v_config_count
|
|
USING v_current_ns;
|
|
|
|
IF v_config_count >= 0 THEN
|
|
RAISE NOTICE 'TEST 4 PASS: SOX configuration changes tracking operational (found % records)', v_config_count;
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 4 FAIL: SOX configuration changes query failed';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 5: MiFID Transaction Reporting
|
|
-- Verify MiFID II transaction reporting compliance
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_order_id UUID := uuid_generate_v4();
|
|
v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
|
|
v_transaction_count INTEGER;
|
|
BEGIN
|
|
-- Check if view exists
|
|
IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'mifid_transaction_reporting') THEN
|
|
RAISE NOTICE 'TEST 5 INFO: Skipping - mifid_transaction_reporting view not found';
|
|
RETURN;
|
|
END IF;
|
|
|
|
-- Insert test order
|
|
INSERT INTO orders (
|
|
id, symbol, side, order_type, time_in_force,
|
|
quantity, limit_price, account_id, venue
|
|
) VALUES (
|
|
v_order_id, 'AAPL', 'buy', 'limit', 'day',
|
|
100, 15000, 'ACC001', 'NASDAQ'
|
|
);
|
|
|
|
-- Insert execution
|
|
INSERT INTO executions (
|
|
order_id, symbol, side, quantity, price,
|
|
venue, execution_timestamp, execution_type
|
|
) VALUES (
|
|
v_order_id, 'AAPL', 'buy', 100, 15050,
|
|
'NASDAQ', v_current_ns, 'fill'
|
|
);
|
|
|
|
-- Query view
|
|
EXECUTE format('SELECT COUNT(*) FROM mifid_transaction_reporting WHERE order_id = %L', v_order_id)
|
|
INTO v_transaction_count;
|
|
|
|
IF v_transaction_count >= 0 THEN
|
|
RAISE NOTICE 'TEST 5 PASS: MiFID transaction reporting functional (found % records)', v_transaction_count;
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 5 FAIL: MiFID transaction reporting query failed';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 6: Best Execution Analysis
|
|
-- Verify MiFID II best execution analysis
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_execution_count INTEGER;
|
|
v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
|
|
BEGIN
|
|
-- Check if view exists
|
|
IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'mifid_best_execution_analysis') THEN
|
|
RAISE NOTICE 'TEST 6 INFO: Skipping - mifid_best_execution_analysis view not found';
|
|
RETURN;
|
|
END IF;
|
|
|
|
-- Insert test executions at different venues
|
|
INSERT INTO executions (
|
|
order_id, symbol, side, quantity, price,
|
|
venue, execution_timestamp, execution_type
|
|
) VALUES
|
|
(uuid_generate_v4(), 'MSFT', 'buy', 50, 40000, 'NYSE', v_current_ns, 'fill'),
|
|
(uuid_generate_v4(), 'MSFT', 'buy', 50, 40010, 'NASDAQ', v_current_ns + 100000, 'fill'),
|
|
(uuid_generate_v4(), 'MSFT', 'buy', 50, 40005, 'ARCA', v_current_ns + 200000, 'fill');
|
|
|
|
-- Query view
|
|
EXECUTE 'SELECT COUNT(*) FROM mifid_best_execution_analysis WHERE symbol = $1'
|
|
INTO v_execution_count
|
|
USING 'MSFT';
|
|
|
|
IF v_execution_count >= 0 THEN
|
|
RAISE NOTICE 'TEST 6 PASS: Best execution analysis operational (found % records)', v_execution_count;
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 6 FAIL: Best execution analysis query failed';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 7: Compliance Dashboard View
|
|
-- Verify compliance dashboard aggregates all compliance data
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_dashboard_count INTEGER;
|
|
BEGIN
|
|
-- Check if view exists
|
|
IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'compliance_dashboard') THEN
|
|
RAISE NOTICE 'TEST 7 INFO: Skipping - compliance_dashboard view not found';
|
|
RETURN;
|
|
END IF;
|
|
|
|
-- Query view
|
|
EXECUTE 'SELECT COUNT(*) FROM compliance_dashboard'
|
|
INTO v_dashboard_count;
|
|
|
|
IF v_dashboard_count >= 0 THEN
|
|
RAISE NOTICE 'TEST 7 PASS: Compliance dashboard view queryable (% records)', v_dashboard_count;
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 7 FAIL: Compliance dashboard query failed';
|
|
END IF;
|
|
|
|
-- Check if view has required aggregations
|
|
IF EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_name = 'compliance_dashboard'
|
|
AND column_name IN ('total_transactions', 'risk_breaches', 'audit_events')
|
|
) THEN
|
|
RAISE NOTICE 'TEST 7 INFO: Dashboard includes aggregated compliance metrics';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 8: Risk Breach Summary
|
|
-- Verify risk breach aggregation for compliance reporting
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_breach_count INTEGER;
|
|
v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
|
|
BEGIN
|
|
-- Check if view exists
|
|
IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'risk_breach_summary') THEN
|
|
RAISE NOTICE 'TEST 8 INFO: Skipping - risk_breach_summary view not found';
|
|
RETURN;
|
|
END IF;
|
|
|
|
-- Insert test risk events
|
|
INSERT INTO risk_events (
|
|
correlation_id, event_timestamp, detected_timestamp,
|
|
event_type, severity, symbol, account_id,
|
|
event_data, event_hash, node_id, process_id
|
|
) VALUES
|
|
(uuid_generate_v4(), v_current_ns, v_current_ns, 'var_breach', 'high',
|
|
'AAPL', 'ACC001', '{"breach_amount": 25000}'::jsonb,
|
|
encode(sha256('breach1'::bytea), 'hex'), 'node-01', 12345),
|
|
(uuid_generate_v4(), v_current_ns + 1000000, v_current_ns + 1000000, 'position_limit_breach', 'critical',
|
|
'TSLA', 'ACC001', '{"breach_amount": 50000}'::jsonb,
|
|
encode(sha256('breach2'::bytea), 'hex'), 'node-01', 12345);
|
|
|
|
-- Query view
|
|
EXECUTE 'SELECT COUNT(*) FROM risk_breach_summary WHERE severity IN ($1, $2)'
|
|
INTO v_breach_count
|
|
USING 'high', 'critical';
|
|
|
|
IF v_breach_count >= 0 THEN
|
|
RAISE NOTICE 'TEST 8 PASS: Risk breach summary operational (found % breaches)', v_breach_count;
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 8 FAIL: Risk breach summary query failed';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 9: Regulatory Audit Log
|
|
-- Verify comprehensive regulatory audit logging
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_audit_count INTEGER;
|
|
v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
|
|
BEGIN
|
|
-- Check if view exists
|
|
IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'regulatory_audit_log') THEN
|
|
RAISE NOTICE 'TEST 9 INFO: Skipping - regulatory_audit_log view not found';
|
|
RETURN;
|
|
END IF;
|
|
|
|
-- Insert various audit events
|
|
INSERT INTO audit_events (
|
|
correlation_id, event_timestamp, event_type, severity, component,
|
|
user_id, event_data, event_hash, node_id, process_id
|
|
) VALUES
|
|
(uuid_generate_v4(), v_current_ns, 'compliance_validation_completed', 'info', 'compliance_engine',
|
|
'system', '{"validation": "pre_trade_check", "result": "pass"}'::jsonb,
|
|
encode(sha256('reg1'::bytea), 'hex'), 'node-01', 12345),
|
|
(uuid_generate_v4(), v_current_ns + 1000000, 'regulatory_report_generated', 'notice', 'reporting',
|
|
'system', '{"report_type": "daily_position"}'::jsonb,
|
|
encode(sha256('reg2'::bytea), 'hex'), 'node-01', 12345);
|
|
|
|
-- Query view
|
|
EXECUTE 'SELECT COUNT(*) FROM regulatory_audit_log WHERE event_timestamp >= $1'
|
|
INTO v_audit_count
|
|
USING v_current_ns;
|
|
|
|
IF v_audit_count >= 0 THEN
|
|
RAISE NOTICE 'TEST 9 PASS: Regulatory audit log operational (found % events)', v_audit_count;
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 9 FAIL: Regulatory audit log query failed';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 10: Compliance View Performance
|
|
-- Verify compliance views have acceptable query performance
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_start_time TIMESTAMP;
|
|
v_end_time TIMESTAMP;
|
|
v_duration INTERVAL;
|
|
v_view_name TEXT;
|
|
v_views TEXT[] := ARRAY['audit_trail_complete', 'sox_user_access_report', 'mifid_transaction_reporting'];
|
|
BEGIN
|
|
FOREACH v_view_name IN ARRAY v_views
|
|
LOOP
|
|
-- Check if view exists
|
|
IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = v_view_name) THEN
|
|
CONTINUE;
|
|
END IF;
|
|
|
|
v_start_time := clock_timestamp();
|
|
|
|
-- Query view with LIMIT to test index usage
|
|
EXECUTE format('SELECT * FROM %I LIMIT 100', v_view_name);
|
|
|
|
v_end_time := clock_timestamp();
|
|
v_duration := v_end_time - v_start_time;
|
|
|
|
IF v_duration < INTERVAL '1 second' THEN
|
|
RAISE NOTICE 'TEST 10 INFO: View % query time: %', v_view_name, v_duration;
|
|
ELSE
|
|
RAISE WARNING 'TEST 10 WARNING: View % slow query (% > 1s)', v_view_name, v_duration;
|
|
END IF;
|
|
END LOOP;
|
|
|
|
RAISE NOTICE 'TEST 10 PASS: Compliance view performance tests completed';
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- Cleanup: Rollback all test data
|
|
-- ================================================================================================
|
|
ROLLBACK;
|
|
|
|
-- Test Summary
|
|
SELECT 'Compliance Views Test Suite Completed - Review NOTICE/WARNING messages above' AS test_summary;
|