Safety¶
Production safety gates that prevent tests from running against non-test databases.
How it works¶
The safe_env fixture (session-scoped, autouse) runs automatically before any engine is created. It performs two checks on every DATABASE_URL and *_DATABASE_URL environment variable:
1. Host whitelist¶
The database host must be one of:
localhost127.0.0.10.0.0.0db(Docker Compose service name)
Any other host causes an immediate pytest.exit(returncode=1).
2. test_ prefix¶
The database name must start with test_. This prevents running against myapp instead of test_myapp.
These checks cannot be disabled
There is no flag to skip safety checks. This is intentional. If you're hitting a remote database in tests, something is wrong with your setup.
Environment variable convention¶
| Variable | Purpose |
|---|---|
DATABASE_URL | Main database |
<BIND>_DATABASE_URL | Named binds (e.g., ANALYTICS_DATABASE_URL) |
REDIS_URL | Redis connection |
bluefox-test scans for all variables matching *DATABASE_URL and validates each one.
Network guard (opt-in)¶
install_network_guard() restricts socket connections to local and private IPs during tests. This catches accidental calls to external APIs.
from bluefox_test.safety import install_network_guard
@pytest.fixture(autouse=True)
def _network_guard(monkeypatch):
install_network_guard(monkeypatch)
Tests that need external access use the allow_network marker:
Warning
The network guard is opt-in. bluefox_test_setup() does not install it automatically. Add the fixture to your conftest if you want it.
API reference¶
assert_safe_url(env_var, url)¶
Validates a single database URL. Raises SystemExit if the host is not in the whitelist or the database name doesn't start with test_.
find_all_database_url_vars()¶
Scans os.environ for all variables ending with DATABASE_URL. Returns a dict of {var_name: url}.
enforce_safety()¶
Calls find_all_database_url_vars() and assert_safe_url() for each. Called automatically by the safe_env fixture.
override_env_with_containers(async_url, redis_url, bind_urls=None)¶
Overwrites DATABASE_URL, REDIS_URL, and any bind-specific URLs with the container URLs. Called by the safe_env fixture after containers start.
install_network_guard(monkeypatch)¶
Monkey-patches socket.socket.connect to reject connections to non-local IPs. Respects the allow_network marker.