- Deprecated/broken migration files archived - New auth_schema migration (015) - Trading service events migration (016) - Migration renumbering utility - Migration test suite
373 lines
12 KiB
PL/PgSQL
373 lines
12 KiB
PL/PgSQL
-- ================================================================================================
|
|
-- Configuration Schema Test Suite (Migration 007)
|
|
-- PostgreSQL 16.10 + TimescaleDB 2.22.1
|
|
-- Tests hot-reload config, versioning, and parameter validation
|
|
-- ================================================================================================
|
|
|
|
BEGIN;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 1: Configuration Tables Existence
|
|
-- Verify all config tables are created
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_required_tables TEXT[] := ARRAY[
|
|
'config_parameters',
|
|
'config_history',
|
|
'config_categories',
|
|
'config_validation_rules'
|
|
];
|
|
v_table TEXT;
|
|
v_missing_tables TEXT[] := ARRAY[]::TEXT[];
|
|
v_found_count INTEGER := 0;
|
|
BEGIN
|
|
FOREACH v_table IN ARRAY v_required_tables
|
|
LOOP
|
|
IF EXISTS (
|
|
SELECT 1 FROM information_schema.tables
|
|
WHERE table_schema = 'public'
|
|
AND table_name = v_table
|
|
) THEN
|
|
v_found_count := v_found_count + 1;
|
|
ELSE
|
|
v_missing_tables := array_append(v_missing_tables, v_table);
|
|
END IF;
|
|
END LOOP;
|
|
|
|
IF array_length(v_missing_tables, 1) IS NULL THEN
|
|
RAISE NOTICE 'TEST 1 PASS: All % config tables exist', array_length(v_required_tables, 1);
|
|
ELSE
|
|
RAISE WARNING 'TEST 1 WARNING: Missing tables (% of %): %',
|
|
array_length(v_missing_tables, 1),
|
|
array_length(v_required_tables, 1),
|
|
array_to_string(v_missing_tables, ', ');
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 2: Configuration Parameter Storage
|
|
-- Test storing and retrieving configuration parameters
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_param_id UUID := uuid_generate_v4();
|
|
v_param_value JSONB;
|
|
BEGIN
|
|
-- Insert configuration parameter
|
|
INSERT INTO config_parameters (
|
|
id, key, value, category, description, is_encrypted
|
|
) VALUES (
|
|
v_param_id,
|
|
'test.risk.var_limit',
|
|
'{"limit": 100000, "confidence": 0.99}'::jsonb,
|
|
'risk_management',
|
|
'VaR limit configuration',
|
|
false
|
|
);
|
|
|
|
-- Retrieve and validate
|
|
SELECT value INTO v_param_value
|
|
FROM config_parameters
|
|
WHERE id = v_param_id;
|
|
|
|
IF v_param_value->>'limit' = '100000' THEN
|
|
RAISE NOTICE 'TEST 2 PASS: Configuration parameter stored and retrieved correctly';
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 2 FAIL: Configuration value mismatch';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 3: Configuration Versioning
|
|
-- Test configuration change history tracking
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_param_id UUID;
|
|
v_old_value JSONB := '{"limit": 100000}'::jsonb;
|
|
v_new_value JSONB := '{"limit": 150000}'::jsonb;
|
|
v_version_count INTEGER;
|
|
BEGIN
|
|
-- Get test parameter
|
|
SELECT id INTO v_param_id
|
|
FROM config_parameters
|
|
WHERE key = 'test.risk.var_limit';
|
|
|
|
-- Store original value in history
|
|
INSERT INTO config_history (
|
|
parameter_id, old_value, new_value, changed_by, change_reason
|
|
) VALUES (
|
|
v_param_id, v_old_value, v_new_value, 'admin_user', 'Risk limit adjustment'
|
|
);
|
|
|
|
-- Update current value
|
|
UPDATE config_parameters
|
|
SET value = v_new_value, version = version + 1
|
|
WHERE id = v_param_id;
|
|
|
|
-- Verify history
|
|
SELECT COUNT(*) INTO v_version_count
|
|
FROM config_history
|
|
WHERE parameter_id = v_param_id;
|
|
|
|
IF v_version_count > 0 THEN
|
|
RAISE NOTICE 'TEST 3 PASS: Configuration versioning operational (% versions)', v_version_count;
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 3 FAIL: Configuration history not recorded';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 4: Hot-Reload Notification
|
|
-- Test configuration change notification system
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_param_id UUID;
|
|
v_notification_count INTEGER;
|
|
BEGIN
|
|
SELECT id INTO v_param_id
|
|
FROM config_parameters
|
|
WHERE key = 'test.risk.var_limit';
|
|
|
|
-- Simulate hot-reload notification
|
|
NOTIFY config_update, '{"parameter_id": "' || v_param_id || '", "action": "update"}';
|
|
|
|
RAISE NOTICE 'TEST 4 PASS: Hot-reload notification sent successfully';
|
|
RAISE NOTICE 'TEST 4 INFO: Applications listening on config_update channel will reload';
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 5: Configuration Categories
|
|
-- Test configuration categorization
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_categories TEXT[] := ARRAY[
|
|
'risk_management',
|
|
'trading',
|
|
'market_data',
|
|
'authentication',
|
|
'performance'
|
|
];
|
|
v_category TEXT;
|
|
v_param_count INTEGER;
|
|
BEGIN
|
|
-- Create category entries if table exists
|
|
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'config_categories') THEN
|
|
FOREACH v_category IN ARRAY v_categories
|
|
LOOP
|
|
INSERT INTO config_categories (name, description)
|
|
VALUES (
|
|
v_category,
|
|
'Configuration category: ' || v_category
|
|
)
|
|
ON CONFLICT (name) DO NOTHING;
|
|
END LOOP;
|
|
|
|
-- Count parameters by category
|
|
SELECT COUNT(*) INTO v_param_count
|
|
FROM config_parameters
|
|
WHERE category = 'risk_management';
|
|
|
|
RAISE NOTICE 'TEST 5 PASS: Configuration categories operational (% risk_management params)', v_param_count;
|
|
ELSE
|
|
RAISE NOTICE 'TEST 5 INFO: config_categories table not found, skipping';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 6: Configuration Validation Rules
|
|
-- Test parameter validation constraints
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_param_id UUID;
|
|
v_test_value JSONB := '{"limit": 50000}'::jsonb;
|
|
v_min_limit INTEGER := 10000;
|
|
v_max_limit INTEGER := 200000;
|
|
BEGIN
|
|
SELECT id INTO v_param_id
|
|
FROM config_parameters
|
|
WHERE key = 'test.risk.var_limit';
|
|
|
|
-- Create validation rule if table exists
|
|
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'config_validation_rules') THEN
|
|
INSERT INTO config_validation_rules (
|
|
parameter_id, rule_type, rule_config
|
|
) VALUES (
|
|
v_param_id,
|
|
'range',
|
|
format('{"min": %s, "max": %s}', v_min_limit, v_max_limit)::jsonb
|
|
);
|
|
|
|
-- Validate test value
|
|
IF (v_test_value->>'limit')::INTEGER BETWEEN v_min_limit AND v_max_limit THEN
|
|
RAISE NOTICE 'TEST 6 PASS: Configuration validation rules enforced';
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 6 FAIL: Value validation failed';
|
|
END IF;
|
|
ELSE
|
|
RAISE NOTICE 'TEST 6 INFO: config_validation_rules table not found, skipping';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 7: Encrypted Configuration Values
|
|
-- Test encrypted parameter storage
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_secret_id UUID := uuid_generate_v4();
|
|
v_encrypted_value TEXT;
|
|
v_plain_value TEXT := 'api_key_12345';
|
|
BEGIN
|
|
-- Encrypt value using pgcrypto
|
|
v_encrypted_value := encode(encrypt(v_plain_value::bytea, 'encryption_key'::bytea, 'aes'), 'hex');
|
|
|
|
-- Store encrypted parameter
|
|
INSERT INTO config_parameters (
|
|
id, key, value, category, is_encrypted
|
|
) VALUES (
|
|
v_secret_id,
|
|
'test.api.secret_key',
|
|
to_jsonb(v_encrypted_value),
|
|
'authentication',
|
|
true
|
|
);
|
|
|
|
-- Verify encryption flag
|
|
IF EXISTS (
|
|
SELECT 1 FROM config_parameters
|
|
WHERE id = v_secret_id AND is_encrypted = true
|
|
) THEN
|
|
RAISE NOTICE 'TEST 7 PASS: Encrypted configuration storage validated';
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 7 FAIL: Encryption flag not set';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 8: Configuration Rollback
|
|
-- Test rolling back to previous configuration version
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_param_id UUID;
|
|
v_history_id UUID;
|
|
v_old_value JSONB;
|
|
v_rollback_value JSONB;
|
|
BEGIN
|
|
SELECT id INTO v_param_id
|
|
FROM config_parameters
|
|
WHERE key = 'test.risk.var_limit';
|
|
|
|
-- Get previous version from history
|
|
SELECT id, old_value INTO v_history_id, v_old_value
|
|
FROM config_history
|
|
WHERE parameter_id = v_param_id
|
|
ORDER BY changed_at DESC
|
|
LIMIT 1;
|
|
|
|
-- Rollback to previous version
|
|
UPDATE config_parameters
|
|
SET value = v_old_value,
|
|
version = version + 1
|
|
WHERE id = v_param_id
|
|
RETURNING value INTO v_rollback_value;
|
|
|
|
-- Record rollback in history
|
|
INSERT INTO config_history (
|
|
parameter_id, old_value, new_value, changed_by, change_reason
|
|
) VALUES (
|
|
v_param_id,
|
|
v_rollback_value,
|
|
v_old_value,
|
|
'admin_user',
|
|
'Rollback to previous version'
|
|
);
|
|
|
|
RAISE NOTICE 'TEST 8 PASS: Configuration rollback successful';
|
|
RAISE NOTICE 'TEST 8 INFO: Rolled back to: %', v_old_value;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 9: Configuration Query Performance
|
|
-- Test indexed query performance
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_start_time TIMESTAMP;
|
|
v_end_time TIMESTAMP;
|
|
v_duration INTERVAL;
|
|
BEGIN
|
|
v_start_time := clock_timestamp();
|
|
|
|
-- Query by key (should use index)
|
|
PERFORM * FROM config_parameters WHERE key = 'test.risk.var_limit';
|
|
|
|
v_end_time := clock_timestamp();
|
|
v_duration := v_end_time - v_start_time;
|
|
|
|
IF v_duration < INTERVAL '10 milliseconds' THEN
|
|
RAISE NOTICE 'TEST 9 PASS: Configuration query performance acceptable (%)', v_duration;
|
|
ELSE
|
|
RAISE WARNING 'TEST 9 WARNING: Query took % (> 10ms)', v_duration;
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 10: Multi-Environment Configuration
|
|
-- Test environment-specific configuration support
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
v_environments TEXT[] := ARRAY['development', 'staging', 'production'];
|
|
v_env TEXT;
|
|
v_env_param_id UUID;
|
|
BEGIN
|
|
FOREACH v_env IN ARRAY v_environments
|
|
LOOP
|
|
v_env_param_id := uuid_generate_v4();
|
|
|
|
INSERT INTO config_parameters (
|
|
id,
|
|
key,
|
|
value,
|
|
category,
|
|
environment
|
|
) VALUES (
|
|
v_env_param_id,
|
|
'test.database.pool_size',
|
|
to_jsonb(CASE v_env
|
|
WHEN 'development' THEN 5
|
|
WHEN 'staging' THEN 10
|
|
WHEN 'production' THEN 50
|
|
END),
|
|
'database',
|
|
v_env
|
|
);
|
|
END LOOP;
|
|
|
|
-- Verify environment-specific configs
|
|
IF EXISTS (
|
|
SELECT 1 FROM config_parameters
|
|
WHERE key = 'test.database.pool_size'
|
|
GROUP BY key
|
|
HAVING COUNT(DISTINCT environment) = 3
|
|
) THEN
|
|
RAISE NOTICE 'TEST 10 PASS: Multi-environment configuration validated';
|
|
ELSE
|
|
RAISE NOTICE 'TEST 10 INFO: Environment column may not exist in config_parameters';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ================================================================================================
|
|
-- Cleanup: Rollback all test data
|
|
-- ================================================================================================
|
|
ROLLBACK;
|
|
|
|
-- Test Summary
|
|
SELECT 'Configuration Schema Test Suite Completed - Review NOTICE/WARNING messages above' AS test_summary;
|