Skip to content

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:

  • localhost
  • 127.0.0.1
  • 0.0.0.0
  • db (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.

conftest.py
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:

@pytest.mark.allow_network
async def test_external_api_call(client):
    ...

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.