E2E Testing & Pytest
Relevant source files
The following files were used as context for generating this wiki page:
The Warpgate end-to-end (E2E) testing framework is built using Pytest to validate the full integration of the bastion host with various protocols including SSH, HTTP, MySQL, and PostgreSQL. The system automates the deployment of Warpgate instances, mock backend servers, and administrative clients to simulate real-world traffic and configuration scenarios.
This testing suite ensures that core functionalities—such as user authentication (Password and TOTP), target authorization, and protocol-specific proxying—work as expected across the entire stack.
Sources: tests/conftest.py:1-25, tests/test_http_basic.py:11-15
Test Infrastructure & Process Management
The E2E framework uses a centralized ProcessManager to orchestrate the lifecycle of the Warpgate binary and its dependencies. This manager handles starting and stopping subprocesses, managing networking ports, and cleaning up resources after test execution.
The ProcessManager Class
The ProcessManager is responsible for provisioning the environment for each test session. It tracks child processes and ensures they receive appropriate termination signals (SIGINT or SIGTERM) to allow for clean exits and coverage data collection.
Sources: tests/conftest.py:53-84
The diagram above illustrates how the ProcessManager spawns the Warpgate binary and external protocol servers using a mix of local binary execution and Docker containers.
Key Infrastructure Components
| Component | Implementation | Description |
|---|---|---|
| Warpgate Binary | target/debug/warpgate | The main Rust binary compiled for testing, often with LLVM coverage instrumentation. |
| Admin Client | api_sdk | A Python-based SDK generated from OpenAPI schemas used to configure Warpgate via its REST API. |
| Mock Servers | Docker Containers | Pre-configured images (e.g., warpgate-e2e-ssh-server) providing target endpoints for proxying. |
| Port Allocation | alloc_port() | Dynamically assigns available local ports to avoid conflicts during parallel-ish execution. |
Sources: tests/conftest.py:27-32, tests/conftest.py:86-120, tests/pyproject.toml:16
Warpgate Lifecycle & Configuration
Testing a Warpgate instance involves a two-stage initialization process: unattended-setup and run.
Unattended Setup
Before running the server, the test suite executes an "unattended setup" command. This command non-interactively generates the configuration file (warpgate.yaml), initializes the SQLite database, and sets up the initial admin user with a provided password.
Sources: warpgate/src/commands/setup.rs:94-150, tests/conftest.py:202-218
Test Fixtures
Pytest fixtures are used to share Warpgate instances across multiple tests to reduce overhead.
shared_wg: A session-scoped fixture that provides a pre-configured and running Warpgate instance.processes: Manages theProcessManagerinstance for the session.ctx: Provides a temporary directory for data storage and config files.
Sources: tests/conftest.py:269-279, tests/conftest.py:313-318
Authentication & Protocol Testing
Testing focuses on verifying that Warpgate correctly intercepts and validates credentials before allowing access to targets.
HTTP Authentication Flow
The HTTP E2E tests verify the redirection logic and the session-based authentication API.
Sources: tests/test_http_basic.py:44-78
Multi-Factor Authentication (OTP)
Tests for TOTP verify that a user can be restricted by a UserRequireCredentialsPolicy. The test suite uses pyotp to generate valid codes that match the secret key registered in Warpgate via the Admin API.
Sources: tests/test_http_user_auth_otp.py:16-50, tests/pyproject.toml:9
Code Coverage Integration
The E2E suite is designed to collect Rust code coverage metrics during Python test execution.
- Instrumentation: The binary is built with coverage support (e.g.,
target/llvm-cov-target/debug/warpgate). - Environment:
LLVM_PROFILE_FILEenvironment variable is set for every spawned Warpgate process. - Signal Handling: The
ProcessManagersendsSIGINTto the Warpgate process, allowing it to flush profile data to.profrawfiles before exiting. - Reporting: Pytest fixtures handle the lifecycle of cleaning old profiles and generating reports after the session.
Sources: tests/conftest.py:28-32, tests/conftest.py:228-232, tests/conftest.py:291-311
Summary
The Warpgate E2E testing framework provides a robust environment for validating the security and functionality of the bastion host. By leveraging Python's Pytest for orchestration and Docker for environmental isolation, it ensures that changes to the safe Rust core do not break the complex interactions between users, administrative policies, and backend targets across SSH, HTTP, and Database protocols.