Warning, /swf-monitor/docs/TEST_SYSTEM.md is written in an unsupported language. File is not indexed.
0001 # SWF Monitor Test System
0002
0003 ## Overview
0004
0005 The SWF Monitor test system provides comprehensive coverage of Django web interface, REST APIs, database models, and system integrations. The test suite includes 88+ tests organized into focused modules for maintainability and AI-friendly navigation.
0006
0007 ## Test Categories
0008
0009 ### 🌐 **Web Interface Tests**
0010 - **UI Views**: Django template rendering, form handling, navigation
0011 - **Authentication**: Login/logout flows, permission enforcement
0012 - **User Experience**: Dashboard functionality, data visualization
0013
0014 ### 🔌 **API Tests**
0015 - **REST Endpoints**: CRUD operations for all models
0016 - **Authentication**: Token-based and session authentication
0017 - **Data Validation**: Input sanitization, error handling
0018 - **Integration**: End-to-end API workflows
0019
0020 ### 🔒 **Security Tests**
0021 - **Django HTTPS Authentication**: Token and session-based security
0022 - **Permission Enforcement**: Role-based access control
0023 - **SSL/TLS Configuration**: Certificate validation, secure connections
0024
0025 ### 🔧 **Integration Tests**
0026 - **Django Dual Server**: HTTP (8002) and HTTPS (8443) endpoints
0027 - **ActiveMQ SSL**: Message broker connectivity and certificate handling
0028 - **Database**: Model relationships, migrations, data integrity
0029 - **REST Logging**: End-to-end logging workflow validation
0030 - **SSE Streaming**: Server-Sent Events message broadcasting and filtering
0031
0032 ## Directory Structure
0033
0034 ```
0035 src/monitor_app/tests/
0036 ├── __init__.py # Package marker
0037 ├── conftest.py # Shared fixtures and configuration
0038 ├── test_system_agent_api.py # System agent CRUD operations (7 tests)
0039 ├── test_applog_api.py # Application log API testing (3 tests)
0040 ├── test_applog_ui.py # Application log UI views (3 tests)
0041 ├── test_monitor_app_ui.py # Monitor app UI functionality (8 tests)
0042 ├── test_log_summary_api.py # Log summary API endpoint (1 test)
0043 ├── test_run_api.py # Run management CRUD operations (7 tests)
0044 ├── test_stf_file_api.py # STF file management API (9 tests)
0045 ├── test_subscriber_api.py # Subscriber management API (9 tests)
0046 ├── test_message_queue_dispatch_api.py # Message queue dispatch testing (8 tests)
0047 ├── test_rest_logging_integration.py # End-to-end REST logging tests (7 tests)
0048 ├── test_activemq_ssl_connection.py # ActiveMQ SSL connectivity (4 tests)
0049 ├── test_django_https_authentication.py # Django HTTPS auth unit tests (7 tests)
0050 ├── test_django_dual_server_integration.py # Live server integration tests (5 tests)
0051 ├── test_mcp_rest.py # MCP REST API endpoints (6 tests)
0052 ├── test_sse_stream.py # SSE message streaming tests (5 tests)
0053 └── test_rest_logging.py # REST logging utilities (1 test)
0054 ```
0055
0056 ## Running Tests
0057
0058 ```bash
0059 ./run_tests.py
0060 ```
0061
0062 This script automatically:
0063 - Activates the virtual environment (uses swf-testbed's .venv if available)
0064 - Runs pytest with proper Django configuration
0065 - Provides detailed test output and coverage
0066
0067 ## Test Types and Patterns
0068
0069 ### Authentication Patterns
0070
0071 **🚨 CRITICAL FOR AI DEVELOPERS: Two distinct authentication patterns exist**
0072
0073 #### Pattern A: APITestCase + force_authenticate() (Unit Tests)
0074 **Use for**: Testing individual API endpoints within Django's test framework
0075 **Authentication**: Uses Django's `force_authenticate()` - bypasses actual token validation
0076 **Network**: No real HTTP requests - uses Django's test client
0077
0078 ```python
0079 class SystemAgentAPITests(APITestCase):
0080 def setUp(self):
0081 self.user = User.objects.create_user(username='testuser', password=os.getenv('SWF_TESTUSER_PASSWORD'))
0082 self.client.force_authenticate(user=self.user) # Bypasses token auth
0083
0084 def test_create_agent(self):
0085 response = self.client.post('/api/systemagents/', data, format='json')
0086 self.assertEqual(response.status_code, 201)
0087 ```
0088
0089 #### Pattern B: TestCase + Real Tokens + HTTP Requests (Integration Tests)
0090 **Use for**: Testing against running Django servers (dual server, live integration)
0091 **Authentication**: Creates real Django User and Token objects, uses actual HTTP authentication
0092 **Network**: Makes real HTTP requests to running servers
0093
0094 ```python
0095 class AgentMonitorIntegrationTest(TestCase):
0096 def setUp(self):
0097 # Create REAL Django user and token in test database
0098 self.user = User.objects.create_user(
0099 username='testuser',
0100 password=os.getenv('SWF_TESTUSER_PASSWORD') # Never hardcode passwords!
0101 )
0102 self.token = Token.objects.create(user=self.user)
0103
0104 # Configure real HTTP session
0105 self.session = requests.Session()
0106 self.session.headers.update({'Authorization': f'Token {self.token.key}'})
0107
0108 def test_live_server_request(self):
0109 response = self.session.get('https://localhost:8443/api/systemagents/')
0110 self.assertEqual(response.status_code, 200)
0111 ```
0112
0113 **⚠️ SECURITY REQUIREMENT: Never hardcode passwords**
0114 - Always use `os.getenv('SWF_TESTUSER_PASSWORD')` for test passwords
0115 - Test will skip if environment variable not set
0116 - This prevents password leakage in version control
0117
0118 ### Unit Tests
0119 **Purpose**: Test individual components in isolation
0120 **Pattern**: APITestCase with force_authenticate() (Pattern A)
0121 **Example**: `test_system_agent_api.py`
0122
0123 ### Integration Tests
0124 **Purpose**: Test interactions between components and external systems
0125 **Pattern**: Live server requests with real HTTP calls
0126 **Example**: `test_django_dual_server_integration.py`
0127
0128 ```python
0129 class DjangoDualServerIntegrationTest(TestCase):
0130 def test_django_https_server_authenticated_request(self):
0131 headers = {'Authorization': f'Token {self.api_token}'}
0132 response = requests.get(
0133 f"{self.django_https_url}/api/systemagents/",
0134 headers=headers,
0135 verify=False,
0136 timeout=5
0137 )
0138 self.assertEqual(response.status_code, 200)
0139 ```
0140
0141 ### API Tests
0142 **Purpose**: Validate REST API endpoints and data handling
0143 **Pattern**: APITestCase with JSON payloads
0144 **Example**: `test_system_agent_api.py`
0145
0146 ```python
0147 class SystemAgentAPITests(APITestCase):
0148 def test_create_system_agent(self):
0149 data = {'instance_name': 'test-agent', 'agent_type': 'test'}
0150 response = self.client.post('/api/systemagents/', data, format='json')
0151 self.assertEqual(response.status_code, status.HTTP_201_CREATED)
0152 ```
0153
0154 ## Test Configuration
0155
0156 ### pytest.ini
0157 ```ini
0158 [pytest]
0159 DJANGO_SETTINGS_MODULE = swf_monitor_project.settings
0160 python_files = tests.py test_*.py *_tests.py
0161 pythonpath = src
0162 markers =
0163 django_db: mark a test as requiring the Django database
0164 ```
0165
0166 ### conftest.py
0167 Shared fixtures and configuration for all tests:
0168 - Database setup and teardown
0169 - Common test data creation
0170 - Authentication helpers
0171 - Mock configurations
0172
0173 ## Test Data Management
0174
0175 ### Fixtures
0176 - **Real data**: Uses Django's fixture system for static reference data
0177 - **Generated data**: Creates test-specific data in setUp() methods
0178 - **Isolated**: Each test gets a clean database state
0179
0180 ### Test Database
0181 - **Automatic creation**: Django creates `test_swfdb` database
0182 - **Migration application**: All migrations run before tests
0183 - **Cleanup**: Database destroyed after test completion
0184
0185 ## Best Practices
0186
0187 ### File Organization
0188 1. **One test class per file**: Maintains focus and clarity
0189 2. **Descriptive naming**: `test_<component>_<type>.py` pattern
0190 3. **Logical grouping**: Related functionality in same file
0191 4. **Manageable size**: Each file under 200 lines for AI-friendly navigation
0192
0193 ### Test Writing
0194 1. **Clear test names**: Describe what is being tested
0195 2. **AAA pattern**: Arrange, Act, Assert structure
0196 3. **Isolated tests**: Each test is independent
0197 4. **Meaningful assertions**: Check behavior, not implementation
0198
0199 ### Naming Conventions
0200 ```python
0201 # Good: Describes what is being tested
0202 def test_django_https_authenticated_request_with_token(self):
0203 """Test that authenticated Django HTTPS requests with token work correctly."""
0204
0205 # Bad: Vague test name
0206 def test_auth(self):
0207 """Test authentication."""
0208 ```
0209
0210 ## Continuous Integration
0211
0212 The test suite is designed for CI/CD environments:
0213 - **No external dependencies**: Tests run in isolation
0214 - **Predictable**: Consistent results across environments
0215 - **Fast execution**: Optimized for rapid feedback
0216 - **Clear reporting**: Detailed test output and failure messages
0217
0218 ## Troubleshooting
0219
0220 ### Common Issues
0221
0222 **Test Discovery Problems**
0223 ```bash
0224 # Ensure proper Python path
0225 export PYTHONPATH=/direct/eic+u/wenauseic/github/swf-monitor/src
0226 ```
0227
0228 **Database Connection Errors**
0229 ```bash
0230 # Check PostgreSQL is running
0231 systemctl status postgresql
0232 # Verify test database permissions
0233 psql -U admin -d test_swfdb
0234 ```
0235
0236 **Import Errors**
0237 ```bash
0238 # Verify virtual environment
0239 source /eic/u/wenauseic/github/swf-testbed/.venv/bin/activate
0240 # Check Django settings
0241 python -c "import django; django.setup(); print('Django OK')"
0242 ```
0243
0244 ## Adding New Tests
0245
0246 ### 1. Choose Test Type
0247 - **Unit test**: Test single component in isolation
0248 - **API test**: Test REST endpoint functionality
0249 - **Integration test**: Test component interactions
0250 - **UI test**: Test web interface behavior
0251
0252 ### 2. Create Test File
0253 ```python
0254 # src/monitor_app/tests/test_new_feature_api.py
0255 from django.test import TestCase
0256 from rest_framework.test import APITestCase
0257 from monitor_app.models import YourModel
0258
0259 class NewFeatureAPITests(APITestCase):
0260 def setUp(self):
0261 """Set up test data."""
0262 pass
0263
0264 def test_new_feature_functionality(self):
0265 """Test the new feature works correctly."""
0266 # Arrange
0267 # Act
0268 # Assert
0269 pass
0270 ```
0271
0272 ### 3. Follow Naming Convention
0273 - File: `test_<component>_<type>.py`
0274 - Class: `<Component><Type>Tests`
0275 - Methods: `test_<specific_behavior>`
0276
0277 ### 4. Run and Validate
0278 ```bash
0279 # Run just your new test
0280 ./run_tests.py src/monitor_app/tests/test_new_feature_api.py
0281
0282 # Run full suite to ensure no regressions
0283 ./run_tests.py
0284 ```
0285
0286 ## SSE (Server-Sent Events) Testing
0287
0288 ### Overview
0289 The SSE streaming tests (`test_sse_stream.py`) validate real-time message broadcasting functionality used by the monitor to push workflow events to connected clients.
0290
0291 ### Test Architecture
0292 The SSE tests use **Django's test infrastructure** rather than external HTTP connections, providing:
0293 - **Fast execution** (< 5 seconds vs 70+ second timeouts)
0294 - **Reliable results** (no network timing issues)
0295 - **Proper isolation** (no interference between tests)
0296
0297 ### Test Classes
0298
0299 #### TestSSEBroadcaster
0300 Tests the core message broadcasting logic:
0301 - **Message Broadcasting**: Validates messages reach connected clients
0302 - **Message Filtering**: Ensures filtering by message type and agent works
0303 - **Client Management**: Tests client connection/disconnection lifecycle
0304 - **Channel Layer Integration**: Validates Redis-backed cross-process messaging
0305
0306 #### TestSSEEndpoint
0307 Tests HTTP endpoint behavior:
0308 - **Authentication**: Verifies token-based auth is required
0309 - **Response Format**: Validates SSE content-type headers
0310 - **Status Endpoint**: Tests broadcaster status reporting
0311
0312 ### Key Features Tested
0313
0314 1. **Message Filtering**
0315 ```python
0316 filters = {'msg_types': ['data_ready'], 'agents': ['data-agent']}
0317 # Only matching messages reach the client
0318 ```
0319
0320 2. **Client Queue Management**
0321 ```python
0322 client_queue = broadcaster.add_client(client_id, request, filters)
0323 # Messages queued for delivery to specific clients
0324 ```
0325
0326 3. **Channel Layer Fanout**
0327 ```python
0328 async_to_sync(channel_layer.group_send)('workflow_events', {...})
0329 # Redis-based message distribution across processes
0330 ```
0331
0332 ### Test Execution
0333 ```bash
0334 # Run SSE tests specifically
0335 ./run_tests.py src/monitor_app/tests/test_sse_stream.py
0336
0337 # Run with verbose output to see detailed SSE operations
0338 python -m pytest monitor_app/tests/test_sse_stream.py -v
0339 ```
0340
0341 ### Architecture Lessons Learned
0342 - **Avoid external connections in tests** - use Django's test client instead
0343 - **Test core logic directly** - don't rely on network timing
0344 - **Mock timing-dependent components** - background threads, async operations
0345 - **Use TransactionTestCase** for tests that need real database transactions
0346
0347 ---
0348
0349 This comprehensive test system ensures the SWF Monitor maintains high quality, security, and reliability while providing clear guidance for developers and AI assistants working with the codebase.
0350
0351 ## History
0352
0353 The current organized test structure was created through a comprehensive refactoring effort. For details about this transformation, see [Test Refactoring Report](TEST_REFACTORING_REPORT.md).