-- ================================================================================================ -- 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;