furtka/tests
Daniel Maksymilian Syrnicki 7b96a25f5b feat(furtka): reconciler + install/remove — slice 2
Fills in the act-on-it half of the resource manager. Reconciler walks
the scanner output and brings docker into the desired state: ensures
each manifest-declared volume exists (idempotent), then runs
docker compose up -d for the project. install/remove on the CLI work
end-to-end against a real /var/lib/furtka/apps/ tree.

- furtka.dockerops: thin subprocess wrapper. Volume + compose
  primitives that other modules call. `_run` raises DockerError with
  the actual stderr so failures are diagnosable.
- furtka.reconciler: builds an ordered Action list (volumes then
  compose_up per app), executes unless dry-run. Broken manifests
  produce a "skip" action, the rest of the apps still get reconciled.
- furtka.installer: copy-from-source with two non-obvious rules —
  user .env is preserved across upgrade installs, and a missing .env
  is bootstrapped from .env.example so compose has values to
  substitute on first install. Bundled-app lookup falls back to
  /opt/furtka/apps/<name>/ when the source arg isn't a path.
- furtka.cli: app install/remove wired up. remove() ignores compose
  down failures so a botched compose doesn't trap users with an
  un-removable folder.
- 15 new tests using monkeypatch'd dockerops so the suite still runs
  without docker installed. Covers reconcile dry-run, multi-volume
  apps, broken-manifest skip behavior, .env preservation, bundled-name
  resolution, and remove edge cases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 10:02:00 +02:00
..
test_app.py fix: enable Furtka units inside custom_commands, not services list 2026-04-14 20:34:34 +02:00
test_cli.py feat(furtka): reconciler + install/remove — slice 2 2026-04-15 10:02:00 +02:00
test_drives.py ci: green the pipeline — tests match 4.x schema, build-iso hits DinD, lint clean 2026-04-14 18:29:42 +02:00
test_installer.py feat(furtka): reconciler + install/remove — slice 2 2026-04-15 10:02:00 +02:00
test_manifest.py feat(furtka): resource-manager skeleton — manifest, scanner, CLI 2026-04-15 09:59:41 +02:00
test_reconciler.py feat(furtka): reconciler + install/remove — slice 2 2026-04-15 10:02:00 +02:00
test_scanner.py feat(furtka): resource-manager skeleton — manifest, scanner, CLI 2026-04-15 09:59:41 +02:00