Files
pvemanager/backend/tests/README.md
markmorado 89d70654fc fix(reinstall): use OSTemplate.vmid (not template_vmid) and convert memory bytes->MB
- AttributeError: OSTemplate has no 'template_vmid' field; the actual column is 'vmid'.
- Use OSTemplate.get_vmid_for_node() to support cross-node replicated templates,
  falling back to source_node/vmid otherwise.
- VMInstance.memory is stored in bytes, but Proxmox config expects MB.
2026-04-29 23:48:48 +02:00

2.8 KiB

Backend Tests

Smoke / unit tests for the FastAPI backend, focused on the security-critical modules: app.crypto, app.auth, app.rbac.

Layout

backend/
├── pytest.ini              # pytest config (testpaths=tests, markers, addopts)
├── requirements-dev.txt    # test deps (-r requirements.txt + pytest …)
└── tests/
    ├── conftest.py         # env setup + reusable fixtures
    ├── test_crypto.py      # Fernet field-encryption helpers
    ├── test_auth.py        # password hashing, JWT, IP parsing, perm helpers
    └── test_rbac.py        # PermissionEngine + registry

How conftest.py keeps tests hermetic

The application reads configuration at import time:

  • app.config.Settings is a pydantic-settings model that auto-loads .env from the current working directory.
  • app.db constructs the SQLAlchemy engine on import.

tests/conftest.py therefore, before any app.* import:

  1. Sets DATABASE_URL, SECRET_KEY, ADMIN_PASSWORD, LOG_LEVEL to safe test values via os.environ.setdefault.
  2. Generates a fresh FERNET_KEY so encrypt/decrypt round-trips succeed.
  3. Adds backend/ to sys.path.
  4. chdirs to a temp directory so the developer's local .env (which contains keys not declared on Settings) is not picked up. Without this step pydantic raises extra_forbidden.

No real Postgres connection is opened — SQLAlchemy connects lazily, and these tests never issue a query.

Running locally

There is no system-wide Python on this host, so use the same Python image as CI:

docker run --rm -v "$PWD/backend:/app" -w /app python:3.12-slim bash -c '
  pip install -r requirements-dev.txt &&
  python -m pytest -p no:warnings
'

Run a single test:

python -m pytest tests/test_auth.py::TestJWT -v

CI

GitHub Actions runs the suite on every push / PR to main that touches backend/** — see .github/workflows/backend-tests.yml. Coverage is reported to the job log and uploaded as an artifact.

Adding more tests

  • Pure / domain logic (no DB): use the fake_user_factory / fake_role_factory fixtures in conftest.py. They produce SimpleNamespace objects that satisfy duck-typed access in auth.py and rbac/engine.py.
  • Touches the DB: build out a SQLite-backed fixture (override app.db.engine with sqlite:///:memory: and Base.metadata.create_all). Not required for the current smoke layer.
  • API endpoints: spin up TestClient(app) once get_db and any external Proxmox / SSH dependencies are dependency-overridden.

Markers

Defined in pytest.ini:

  • @pytest.mark.smoke — quickest sanity checks.
  • @pytest.mark.unit — pure unit tests.
  • @pytest.mark.integration — multi-module integration.

Run only smoke tests:

python -m pytest -m smoke