furtka/tests
Daniel Maksymilian Syrnicki f3cd9e963c
All checks were successful
Build ISO / build-iso (push) Successful in 17m24s
CI / lint (push) Successful in 26s
CI / test (push) Successful in 43s
CI / validate-json (push) Successful in 24s
CI / markdown-links (push) Successful in 16s
Release / release (push) Successful in 11m34s
feat(install): async background install with progress polling
POST /api/apps/install now returns 202 Accepted after the synchronous
pre-validation (resolve source, copy files, write .env, check for
placeholder secrets, validate path-type settings). The docker-facing
phases (compose pull → ensure volumes → compose up) are dispatched as
a background systemd-run unit (furtka-install-<app>) that writes stage
transitions to /var/lib/furtka/install-state.json. The UI polls
GET /api/apps/install/status every 1.5s and re-labels the modal
submit button — "Image wird heruntergeladen…" →
"Speicherbereiche werden erstellt…" → "Container wird gestartet…" —
instead of sitting dead on "Installing…" for 30+ seconds on large
images like Jellyfin.

Mirrors the exact shape of /api/catalog/sync/apply and
/api/furtka/update/apply: same fcntl lock, same atomic state-file
writes, same terminal-state poll loop ("done" | "error"). New CLI
subcommand `furtka app install-bg <name>` is what systemd-run invokes;
it's hidden from --help because regular CLI users still want the
synchronous `furtka app install <name>`.

Reinstall button on the app list polls too — after dispatch, its text
reflects the background stage until terminal, matching the modal
flow.

Tests:
- tests/test_install_runner.py (new, 9 cases): state roundtrip, lock
  contention, happy-path phase ordering, error writes on pull/up
  failure, lock release on both terminal outcomes.
- tests/test_api.py: new no_systemd_run fixture stubs subprocess.run;
  existing install tests adapted to 202 response; new tests for 409
  lock contention and the status endpoint.
- tests/test_cli.py: install-bg dispatches correctly and returns 1
  on failure with journald-friendly stderr.

256 tests pass, ruff check + format clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:50:49 +02:00
..
test_api.py feat(install): async background install with progress polling 2026-04-21 15:50:49 +02:00
test_app.py feat(furtka): serve from /opt/furtka/current, retire /srv/furtka/www/ 2026-04-16 13:15:59 +02:00
test_auth.py feat(auth): login-guard the Furtka UI with a cookie session 2026-04-21 13:01:17 +02:00
test_catalog.py feat(catalog): on-box apps catalog synced independently of core version 2026-04-20 14:16:02 +02:00
test_cli.py feat(install): async background install with progress polling 2026-04-21 15:50:49 +02:00
test_drives.py feat(webinstaller): plain-English drive picker on step 2 2026-04-16 12:01:57 +02:00
test_https.py feat(https): local HTTPS via Caddy tls internal + opt-in redirect toggle 2026-04-17 12:19:06 +02:00
test_install_runner.py feat(install): async background install with progress polling 2026-04-21 15:50:49 +02:00
test_installer.py style(tests): reflow OPTIONAL_PATH_MANIFEST to match ruff format 2026-04-21 11:56:52 +02:00
test_manifest.py feat(manifest): add 'path' setting type with server-side validation 2026-04-21 11:39:15 +02:00
test_reconciler.py fix(furtka): audit follow-ups — placeholder secrets, isolate reconcile, .env perms 2026-04-15 10:17:00 +02:00
test_scanner.py feat(furtka): resource-manager skeleton — manifest, scanner, CLI 2026-04-15 09:59:41 +02:00
test_sources.py feat(catalog): on-box apps catalog synced independently of core version 2026-04-20 14:16:02 +02:00
test_updater.py feat(catalog): on-box apps catalog synced independently of core version 2026-04-20 14:16:02 +02:00
test_webinstaller_assets.py feat(auth): login-guard the Furtka UI with a cookie session 2026-04-21 13:01:17 +02:00