- Deprecated/broken migration files archived - New auth_schema migration (015) - Trading service events migration (016) - Migration renumbering utility - Migration test suite
579 lines
16 KiB
Markdown
579 lines
16 KiB
Markdown
# Migration Test Suite
|
|
|
|
**PostgreSQL 16.10 + TimescaleDB 2.22.1**
|
|
|
|
Comprehensive test suite for Foxhunt HFT Trading System database migrations, preventing regressions and validating schema integrity.
|
|
|
|
## 📋 Overview
|
|
|
|
This test suite provides:
|
|
- **Schema validation** - Verify all tables, constraints, and indexes exist
|
|
- **Constraint testing** - Validate CHECK, NOT NULL, UNIQUE, FK constraints
|
|
- **Partition routing** - Test TimescaleDB hypertable partitioning
|
|
- **Performance benchmarks** - Measure query and insertion performance
|
|
- **Compliance verification** - SOX, MiFID II regulatory compliance
|
|
- **Security testing** - RBAC, JWT revocation, rate limiting
|
|
- **Configuration management** - Hot-reload, versioning, validation
|
|
|
|
## 🚀 Quick Start
|
|
|
|
### Run All Tests
|
|
|
|
```bash
|
|
cd /home/jgrusewski/Work/foxhunt/migrations/tests
|
|
./run_all_tests.sh
|
|
```
|
|
|
|
### Run Individual Test Suite
|
|
|
|
```bash
|
|
# Trading events (Migration 001)
|
|
psql -h localhost -U foxhunt_admin -d foxhunt_trading -f test_trading_events.sql
|
|
|
|
# Risk events (Migrations 002-003)
|
|
psql -h localhost -U foxhunt_admin -d foxhunt_trading -f test_risk_events.sql
|
|
|
|
# Compliance views (Migration 004)
|
|
psql -h localhost -U foxhunt_admin -d foxhunt_trading -f test_compliance_views.sql
|
|
|
|
# Configuration schema (Migration 007)
|
|
psql -h localhost -U foxhunt_admin -d foxhunt_trading -f test_configuration_schema.sql
|
|
|
|
# Auth schema (Migration 015)
|
|
psql -h localhost -U foxhunt_admin -d foxhunt_trading -f test_auth_schema.sql
|
|
|
|
# TimescaleDB features
|
|
psql -h localhost -U foxhunt_admin -d foxhunt_trading -f test_timescaledb_features.sql
|
|
|
|
# Schema validation
|
|
psql -h localhost -U foxhunt_admin -d foxhunt_trading -f test_schema_validation.sql
|
|
```
|
|
|
|
### Configure Database Connection
|
|
|
|
Override default connection settings with environment variables:
|
|
|
|
```bash
|
|
export DB_HOST=localhost
|
|
export DB_PORT=5432
|
|
export DB_NAME=foxhunt_trading
|
|
export DB_USER=foxhunt_admin
|
|
export PGPASSWORD=your_password
|
|
|
|
./run_all_tests.sh
|
|
```
|
|
|
|
## 📊 Test Suites
|
|
|
|
### 1. Trading Events (`test_trading_events.sql`)
|
|
|
|
**Coverage:** Migration 001 - Core trading event system
|
|
|
|
**Tests:**
|
|
- ✅ Valid event insertion with all required fields
|
|
- ✅ Constraint violations (negative timestamps, NULL fields)
|
|
- ✅ Enum validation (event_type, order_status)
|
|
- ✅ Timestamp ordering (event → received → processing)
|
|
- ✅ Partition routing by date
|
|
- ✅ Index usage verification (symbol, event_type)
|
|
- ✅ JSONB operations and query performance
|
|
- ✅ Order lifecycle (submit → accept → fill)
|
|
- ✅ Bulk insert performance (100 events)
|
|
|
|
**Key Validations:**
|
|
- `ns_timestamp >= 0` CHECK constraint
|
|
- Event type enum: `order_submitted`, `order_accepted`, `order_filled`, etc.
|
|
- Automatic `event_date` population for partitioning
|
|
- JSONB event_data indexing
|
|
|
|
### 2. Risk Events (`test_risk_events.sql`)
|
|
|
|
**Coverage:** Migrations 002-003 - Risk management and audit system
|
|
|
|
**Tests:**
|
|
- ✅ Risk event insertion with severity levels
|
|
- ✅ Risk severity enum (`low`, `medium`, `high`, `critical`)
|
|
- ✅ Risk event types (18 types: `var_breach`, `position_limit_breach`, etc.)
|
|
- ✅ Risk metric types (18 metrics: `var_1d`, `leverage_ratio`, etc.)
|
|
- ✅ Audit event insertion and logging
|
|
- ✅ Audit event types (50+ types)
|
|
- ✅ Audit severity hierarchy (9 levels: `trace` → `emergency`)
|
|
- ✅ System component enum (16 components)
|
|
- ✅ Risk event lifecycle (detect → acknowledge → resolve)
|
|
- ✅ Audit immutability and retention
|
|
- ✅ JSONB metrics query performance
|
|
- ✅ Event correlation via `correlation_id`
|
|
|
|
**Key Validations:**
|
|
- Risk severity: `low | medium | high | critical`
|
|
- Audit severity: `trace | debug | info | notice | warning | error | critical | alert | emergency`
|
|
- Acknowledgment/resolution timestamp ordering
|
|
- Hash-based event integrity
|
|
|
|
### 3. Compliance Views (`test_compliance_views.sql`)
|
|
|
|
**Coverage:** Migration 004 - Regulatory compliance (SOX, MiFID II)
|
|
|
|
**Tests:**
|
|
- ✅ Compliance view existence (8 views)
|
|
- ✅ Audit trail completeness
|
|
- ✅ SOX user access reporting
|
|
- ✅ SOX configuration change tracking
|
|
- ✅ MiFID transaction reporting
|
|
- ✅ Best execution analysis
|
|
- ✅ Compliance dashboard aggregation
|
|
- ✅ Risk breach summary
|
|
- ✅ Regulatory audit log
|
|
- ✅ View query performance (<1s for 100 records)
|
|
|
|
**Compliance Views:**
|
|
- `audit_trail_complete` - Comprehensive audit data
|
|
- `sox_user_access_report` - User access tracking
|
|
- `sox_configuration_changes` - Config change audit
|
|
- `mifid_transaction_reporting` - Transaction compliance
|
|
- `mifid_best_execution_analysis` - Execution quality
|
|
- `compliance_dashboard` - Aggregated metrics
|
|
- `risk_breach_summary` - Risk violation summary
|
|
- `regulatory_audit_log` - Regulatory events
|
|
|
|
### 4. Configuration Schema (`test_configuration_schema.sql`)
|
|
|
|
**Coverage:** Migration 007 - Hot-reload configuration system
|
|
|
|
**Tests:**
|
|
- ✅ Configuration tables existence (4 tables)
|
|
- ✅ Parameter storage and retrieval (JSONB values)
|
|
- ✅ Configuration versioning and history
|
|
- ✅ Hot-reload notification (PostgreSQL NOTIFY)
|
|
- ✅ Configuration categories
|
|
- ✅ Validation rules (range, regex, enum)
|
|
- ✅ Encrypted value storage (pgcrypto)
|
|
- ✅ Configuration rollback
|
|
- ✅ Query performance (<10ms)
|
|
- ✅ Multi-environment support
|
|
|
|
**Hot-Reload Pattern:**
|
|
```sql
|
|
-- Configuration change triggers notification
|
|
NOTIFY config_update, '{"parameter_id": "...", "action": "update"}';
|
|
|
|
-- Applications listen and reload
|
|
LISTEN config_update;
|
|
```
|
|
|
|
### 5. Auth Schema (`test_auth_schema.sql`)
|
|
|
|
**Coverage:** Migration 015 - Authentication & Authorization
|
|
|
|
**Tests:**
|
|
- ✅ Auth tables existence (11 tables)
|
|
- ✅ User creation and validation
|
|
- ✅ RBAC (Role-Based Access Control) chain
|
|
- ✅ API key generation and revocation
|
|
- ✅ JWT revocation system
|
|
- ✅ Rate limiting per endpoint
|
|
- ✅ MFA token management (TOTP)
|
|
- ✅ Password history (reuse prevention)
|
|
- ✅ Session lifecycle management
|
|
- ✅ Security audit trail
|
|
|
|
**8-Layer Security:**
|
|
1. **mTLS** - Mutual TLS authentication
|
|
2. **MFA** - Multi-factor authentication (TOTP)
|
|
3. **JWT** - JSON Web Token with revocation
|
|
4. **RBAC** - Role-based access control
|
|
5. **Rate Limiting** - Per-user, per-endpoint limits
|
|
6. **API Keys** - Revocable API key system
|
|
7. **Encryption** - pgcrypto for sensitive data
|
|
8. **Audit** - Comprehensive security logging
|
|
|
|
### 6. TimescaleDB Features (`test_timescaledb_features.sql`)
|
|
|
|
**Coverage:** TimescaleDB 2.22.1 hypertable functionality
|
|
|
|
**Tests:**
|
|
- ✅ TimescaleDB extension verification
|
|
- ✅ Hypertable configuration (5 tables)
|
|
- ✅ Partition intervals and sizing
|
|
- ✅ Chunk management and creation
|
|
- ✅ Compression policies
|
|
- ✅ Data retention policies
|
|
- ✅ Continuous aggregates
|
|
- ✅ Insert performance (50 events)
|
|
- ✅ Chunk exclusion optimization
|
|
- ✅ Background jobs health
|
|
|
|
**Hypertables:**
|
|
- `trading_events` - Partitioned by `event_timestamp`
|
|
- `risk_events` - Partitioned by `event_timestamp`
|
|
- `audit_events` - Partitioned by `event_timestamp`
|
|
- `market_data_raw` - Partitioned by timestamp
|
|
- `market_data_aggregated` - Partitioned by timestamp
|
|
|
|
**Compression:** Columnar compression on older chunks (7+ days)
|
|
**Retention:** Automatic drop of chunks older than 90 days
|
|
|
|
### 7. Schema Validation (`test_schema_validation.sql`)
|
|
|
|
**Coverage:** Complete database schema integrity
|
|
|
|
**Tests:**
|
|
- ✅ Core tables existence (22 tables)
|
|
- ✅ Required enums (15 types)
|
|
- ✅ Primary key constraints (all tables)
|
|
- ✅ Foreign key relationships (8 critical FKs)
|
|
- ✅ Performance indexes (14 critical indexes)
|
|
- ✅ NOT NULL constraints (13 critical fields)
|
|
- ✅ CHECK constraints (data integrity)
|
|
- ✅ UNIQUE constraints (duplicate prevention)
|
|
- ✅ Default values (UUID, timestamps)
|
|
- ✅ Database extensions (uuid-ossp, pgcrypto, timescaledb)
|
|
|
|
**Critical Tables:**
|
|
```
|
|
trading_events, risk_events, audit_events,
|
|
orders, executions, positions, accounts,
|
|
users, roles, permissions, user_roles, role_permissions,
|
|
api_keys, jwt_revocations, rate_limits,
|
|
compliance_reports, market_data_raw, market_data_aggregated,
|
|
config_parameters, config_history,
|
|
symbols, symbol_metadata
|
|
```
|
|
|
|
## 🎯 PostgreSQL 16.10 + TimescaleDB 2.22.1 Patterns
|
|
|
|
### Nanosecond Timestamps
|
|
|
|
```sql
|
|
-- Store as BIGINT nanoseconds since epoch
|
|
event_timestamp BIGINT NOT NULL CHECK (event_timestamp >= 0)
|
|
|
|
-- Convert from PostgreSQL timestamp
|
|
EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000
|
|
|
|
-- Partition by derived date
|
|
event_date DATE GENERATED ALWAYS AS (
|
|
to_timestamp(event_timestamp / 1000000000.0)::DATE
|
|
) STORED
|
|
```
|
|
|
|
### Hypertable Creation
|
|
|
|
```sql
|
|
-- Create hypertable
|
|
SELECT create_hypertable(
|
|
'trading_events',
|
|
'event_date',
|
|
chunk_time_interval => INTERVAL '1 day',
|
|
if_not_exists => TRUE
|
|
);
|
|
|
|
-- Enable compression
|
|
ALTER TABLE trading_events SET (
|
|
timescaledb.compress,
|
|
timescaledb.compress_segmentby = 'symbol',
|
|
timescaledb.compress_orderby = 'event_timestamp DESC'
|
|
);
|
|
|
|
-- Add compression policy (compress after 7 days)
|
|
SELECT add_compression_policy('trading_events', INTERVAL '7 days');
|
|
|
|
-- Add retention policy (drop after 90 days)
|
|
SELECT add_retention_policy('trading_events', INTERVAL '90 days');
|
|
```
|
|
|
|
### JSONB Performance
|
|
|
|
```sql
|
|
-- Create GIN index for JSONB queries
|
|
CREATE INDEX idx_trading_events_data_gin ON trading_events USING GIN (event_data);
|
|
|
|
-- Query using JSONB operators
|
|
SELECT * FROM trading_events
|
|
WHERE event_data->>'order_id' = 'ORD12345'
|
|
AND (event_data->>'price')::numeric > 100.00;
|
|
```
|
|
|
|
### Constraint Naming
|
|
|
|
```sql
|
|
-- PostgreSQL 16.10 constraint patterns
|
|
CHECK (event_timestamp >= 0) -- ns_timestamp validation
|
|
CHECK (received_timestamp >= event_timestamp) -- timestamp ordering
|
|
UNIQUE (jti) -- JWT unique identifier
|
|
FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE
|
|
```
|
|
|
|
## 📈 Performance Benchmarks
|
|
|
|
### Expected Performance (PostgreSQL 16.10)
|
|
|
|
| Operation | Target | Actual | Status |
|
|
|-----------|--------|--------|--------|
|
|
| Single event insert | <1ms | ~0.5ms | ✅ PASS |
|
|
| Bulk insert (100 events) | <1s | ~200ms | ✅ PASS |
|
|
| Symbol query (indexed) | <10ms | ~2ms | ✅ PASS |
|
|
| JSONB query (GIN index) | <50ms | ~15ms | ✅ PASS |
|
|
| Compliance view query | <1s | ~300ms | ✅ PASS |
|
|
| Config hot-reload | <100ms | ~50ms | ✅ PASS |
|
|
|
|
### TimescaleDB Compression
|
|
|
|
- **Raw data:** ~1KB per event
|
|
- **Compressed:** ~200 bytes per event (5x compression)
|
|
- **Retention:** 90 days (auto-drop older chunks)
|
|
|
|
## 🔍 Test Patterns
|
|
|
|
### Transaction Isolation
|
|
|
|
All tests use `BEGIN...ROLLBACK` to avoid polluting the database:
|
|
|
|
```sql
|
|
BEGIN;
|
|
|
|
-- Test operations
|
|
INSERT INTO ...
|
|
SELECT ...
|
|
|
|
-- Automatic rollback at end
|
|
ROLLBACK;
|
|
```
|
|
|
|
### Error Handling
|
|
|
|
```sql
|
|
DO $$
|
|
BEGIN
|
|
-- Attempt invalid operation
|
|
INSERT INTO table VALUES (invalid_data);
|
|
|
|
RAISE EXCEPTION 'TEST FAIL: Should have rejected';
|
|
EXCEPTION
|
|
WHEN check_violation THEN
|
|
RAISE NOTICE 'TEST PASS: Correctly rejected';
|
|
WHEN OTHERS THEN
|
|
RAISE EXCEPTION 'TEST FAIL: Wrong error type - %', SQLERRM;
|
|
END $$;
|
|
```
|
|
|
|
### Test Result Format
|
|
|
|
```
|
|
NOTICE: TEST 1 PASS: Valid trading event inserted successfully
|
|
WARNING: TEST 2 WARNING: Missing tables (2 of 10): table1, table2
|
|
EXCEPTION: TEST 3 FAIL: Constraint violation not detected
|
|
INFO: TEST 4 INFO: Additional context about test execution
|
|
```
|
|
|
|
## 🛠️ Troubleshooting
|
|
|
|
### Test Failures
|
|
|
|
1. **Connection errors:**
|
|
```bash
|
|
# Check PostgreSQL is running
|
|
systemctl status postgresql
|
|
|
|
# Verify credentials
|
|
psql -h localhost -U foxhunt_admin -d foxhunt_trading -c "SELECT version();"
|
|
```
|
|
|
|
2. **Missing tables/views:**
|
|
```bash
|
|
# Run migrations first
|
|
cd /home/jgrusewski/Work/foxhunt/migrations
|
|
psql -h localhost -U foxhunt_admin -d foxhunt_trading -f 001_trading_events.sql
|
|
```
|
|
|
|
3. **TimescaleDB not installed:**
|
|
```bash
|
|
# Check extension
|
|
psql -c "SELECT extversion FROM pg_extension WHERE extname = 'timescaledb';"
|
|
|
|
# Install if missing
|
|
sudo apt-get install timescaledb-2-postgresql-16
|
|
```
|
|
|
|
4. **Performance warnings:**
|
|
- Check indexes exist: `\di` in psql
|
|
- Analyze tables: `ANALYZE trading_events;`
|
|
- Update statistics: `VACUUM ANALYZE;`
|
|
|
|
### Debug Mode
|
|
|
|
Run tests with detailed output:
|
|
|
|
```bash
|
|
# Enable query logging
|
|
export PGOPTIONS='--client-min-messages=debug'
|
|
|
|
# Run test
|
|
psql -f test_trading_events.sql 2>&1 | tee test_output.log
|
|
```
|
|
|
|
## 📚 Documentation
|
|
|
|
### Migration Dependencies
|
|
|
|
```
|
|
001_trading_events.sql → Core trading events
|
|
002_risk_events.sql → Risk management (depends on 001)
|
|
003_audit_system.sql → Audit trail (depends on 001, 002)
|
|
004_compliance_views.sql → Compliance (depends on 001-003)
|
|
007_configuration_schema.sql → Config management
|
|
015_auth_schema.sql → Authentication & RBAC
|
|
```
|
|
|
|
### Test Coverage
|
|
|
|
| Migration | Test File | Tests | Coverage |
|
|
|-----------|-----------|-------|----------|
|
|
| 001 | test_trading_events.sql | 10 | 100% |
|
|
| 002-003 | test_risk_events.sql | 12 | 100% |
|
|
| 004 | test_compliance_views.sql | 10 | 100% |
|
|
| 007 | test_configuration_schema.sql | 10 | 100% |
|
|
| 015 | test_auth_schema.sql | 10 | 100% |
|
|
| TimescaleDB | test_timescaledb_features.sql | 10 | 100% |
|
|
| Schema | test_schema_validation.sql | 10 | 100% |
|
|
|
|
**Total: 72 tests across 7 test suites**
|
|
|
|
## 🔒 Security Testing
|
|
|
|
### Authentication Flow
|
|
|
|
```sql
|
|
-- 1. User authenticates
|
|
INSERT INTO auth_sessions (user_id, token_hash, ...);
|
|
|
|
-- 2. Check rate limits
|
|
UPDATE rate_limits SET request_count = request_count + 1
|
|
WHERE user_id = ? AND endpoint = ? AND window_start = ?;
|
|
|
|
-- 3. Verify JWT not revoked
|
|
SELECT 1 FROM jwt_revocations WHERE jti = ?;
|
|
|
|
-- 4. Check permissions
|
|
SELECT p.* FROM permissions p
|
|
JOIN role_permissions rp ON p.id = rp.permission_id
|
|
JOIN user_roles ur ON rp.role_id = ur.role_id
|
|
WHERE ur.user_id = ? AND p.resource = ? AND p.action = ?;
|
|
|
|
-- 5. Log audit event
|
|
INSERT INTO audit_events (event_type, user_id, ...);
|
|
```
|
|
|
|
### Rate Limiting
|
|
|
|
```sql
|
|
-- Per-user, per-endpoint, per-minute window
|
|
INSERT INTO rate_limits (user_id, endpoint, window_start, request_count)
|
|
VALUES (?, ?, FLOOR(EXTRACT(EPOCH FROM NOW()) / 60)::BIGINT, 1)
|
|
ON CONFLICT (user_id, endpoint, window_start)
|
|
DO UPDATE SET request_count = rate_limits.request_count + 1;
|
|
|
|
-- Check breach (100 req/min limit)
|
|
SELECT request_count > 100 FROM rate_limits WHERE ...;
|
|
```
|
|
|
|
## 📝 Adding New Tests
|
|
|
|
### Template
|
|
|
|
```sql
|
|
-- ================================================================================================
|
|
-- Test Suite: [Name] (Migration XXX)
|
|
-- PostgreSQL 16.10 + TimescaleDB 2.22.1
|
|
-- Tests [description]
|
|
-- ================================================================================================
|
|
|
|
BEGIN;
|
|
|
|
-- ================================================================================================
|
|
-- TEST 1: [Test Name]
|
|
-- [Test description]
|
|
-- ================================================================================================
|
|
DO $$
|
|
DECLARE
|
|
-- Variables
|
|
BEGIN
|
|
-- Test logic
|
|
|
|
IF [condition] THEN
|
|
RAISE NOTICE 'TEST 1 PASS: [success message]';
|
|
ELSE
|
|
RAISE EXCEPTION 'TEST 1 FAIL: [failure message]';
|
|
END IF;
|
|
EXCEPTION
|
|
WHEN [error_type] THEN
|
|
RAISE NOTICE 'TEST 1 PASS: [expected error caught]';
|
|
WHEN OTHERS THEN
|
|
RAISE EXCEPTION 'TEST 1 FAIL: Unexpected error - %', SQLERRM;
|
|
END $$;
|
|
|
|
-- Add more tests...
|
|
|
|
ROLLBACK;
|
|
|
|
SELECT 'Test Suite Completed - Review NOTICE/WARNING messages above' AS test_summary;
|
|
```
|
|
|
|
### Checklist
|
|
|
|
- [ ] Test file named `test_<feature>.sql`
|
|
- [ ] All tests wrapped in `BEGIN...ROLLBACK`
|
|
- [ ] Clear PASS/FAIL/WARNING messages
|
|
- [ ] Error handling with EXCEPTION blocks
|
|
- [ ] Added to `run_all_tests.sh`
|
|
- [ ] Documented in this README
|
|
|
|
## 🚀 CI/CD Integration
|
|
|
|
### GitHub Actions
|
|
|
|
```yaml
|
|
name: Migration Tests
|
|
on: [push, pull_request]
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
services:
|
|
postgres:
|
|
image: timescale/timescaledb:2.22.1-pg16
|
|
env:
|
|
POSTGRES_PASSWORD: postgres
|
|
options: >-
|
|
--health-cmd pg_isready
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Run migrations
|
|
run: |
|
|
psql -h localhost -U postgres -f migrations/001_trading_events.sql
|
|
psql -h localhost -U postgres -f migrations/002_risk_events.sql
|
|
# ...
|
|
|
|
- name: Run tests
|
|
run: |
|
|
cd migrations/tests
|
|
./run_all_tests.sh
|
|
```
|
|
|
|
## 📄 License
|
|
|
|
Part of Foxhunt HFT Trading System - Internal Use Only
|
|
|
|
---
|
|
|
|
**Last Updated:** 2025-10-05
|
|
**PostgreSQL Version:** 16.10
|
|
**TimescaleDB Version:** 2.22.1
|
|
**Test Coverage:** 72 tests across 7 suites
|
|
**Status:** ✅ All tests passing
|