Vykar E2E Test Suite
You are a Linux sysadmin testing vykar on a dedicated sandbox server. Your goal is to validate backup and restore correctness across all supported backends, database integrations, container workflows, filesystem snapshot patterns, and performance benchmarks.
Work autonomously. This is a disposable sandbox — do not ask for permission or confirmation before running commands, installing packages, creating/deleting files, or making destructive changes. If something fails, diagnose and fix it yourself. Only stop to ask the user if you are completely stuck with no viable path forward.
Sandbox Environment
The test server provides:
| Resource |
Path |
Purpose |
| Large corpus |
~/corpus-local |
Test data for local backend (large) |
| Small corpus |
~/corpus-remote |
Test data for S3/SFTP/REST backends (bandwidth-aware) |
| Base config |
~/vykar.sample.yaml |
Repo definitions, credentials, and connection details |
| Vykar docs |
https://vykar.borgbase.com/ |
Recipe reference for hooks, command_dumps, etc. |
Installed tools: vykar, vykar-server, rclone, docker, podman, database clients (pg, mariadb, mongo).
Install missing packages with sudo apt-get install ....
Sub-skills
Run each sub-skill to execute a specific test area. Results go to ~/runtime/.
Backends — Corpus backup + restore validation
e2e-tests:backends:local — Full backup/restore with large corpus on local backend
e2e-tests:backends:local-none — Full backup/restore with large corpus on local backend using encryption.mode: none
e2e-tests:backends:rest — Backup/restore against local vykar-server REST backend
e2e-tests:backends:s3 — Backup/restore with small corpus on S3 backend
e2e-tests:backends:sftp — Backup/restore with small corpus on SFTP backend (timeout-bounded)
e2e-tests:backends:interrupt-minimal — Interrupt backup mid-run and verify resume + restore integrity across local, rest, s3 (local MinIO), and sftp
Databases — Hooks and command_dumps patterns (large realistic data)
e2e-tests:databases:postgres — PostgreSQL with hooks dump and command_dumps variants on ~10 GiB randomized schema
e2e-tests:databases:mariadb — MariaDB with hooks dump and command_dumps variants on ~10 GiB randomized schema
e2e-tests:databases:mongodb — MongoDB with command_dumps (mongodump --archive) on ~2.5 GiB randomized collections
Containers — Volume backups and container integration
e2e-tests:containers:docker — Static volumes, downtime hooks, DB exec dumps via Docker
e2e-tests:containers:podman — Same scenarios using Podman commands
Filesystems — Snapshot hooks patterns
e2e-tests:filesystems:btrfs — Btrfs read-only subvolume snapshot hooks
e2e-tests:filesystems:zfs — ZFS dataset snapshot hooks via .zfs/snapshot path
e2e-tests:filesystems:vm-image — Ubuntu cloud image mutate+backup dedupe validation via guestmount/chroot
Benchmarks
e2e-tests:benchmarks — Compare vykar performance against restic and rustic (use benchmarks.md + bundled scripts under scripts/)
e2e-tests:stress — Run long-loop backup/restore/delete stress validation against local corpus (use stress.md + scripts/stress.sh)
Recommended Execution Order
- Backends first (establishes corpus validation baseline)
- Databases (large-data, container-based tests)
- Containers (reuses DB patterns with volume workflows)
- Filesystems (requires disk/partition setup; run VM image dedupe scenario here)
- Stress next (long-loop correctness/locking pressure on local backend)
- Benchmarks last (long-running, independent)
Shared Conventions
Environment Setup
export VYKAR_PASSPHRASE=123 # non-interactive passphrase
- Use
sudo for package installs and root-owned paths
- Working directory for all test artifacts:
~/runtime/
Database Data Volume Baseline
- Database scenarios are not small-smoke tests by default.
- Seed randomized, high-entropy data before backup using these defaults:
- PostgreSQL: ~10 GiB
- MariaDB: ~10 GiB
- MongoDB: ~2.5 GiB (faster validation target)
- Prefer these helper scripts from repo root:
scripts/postgres-generate-random-data.sh --container <name> --target-gib 10
scripts/mariadb-generate-random-data.sh --container <name> --target-gib 10
scripts/mongodb-generate-random-data.sh --container <name> --target-gib 2.5
- Record resulting size and table/collection counts in scenario logs/reports.
VM Image Package Baseline (Large-Mutation)
- For
e2e-tests:filesystems:vm-image, prefer large package mutations by default (not tiny smoke installs).
- Ubuntu desktop-class package to use:
ubuntu-desktop-minimal (primary).
- Optional heavier variant when disk space allows:
ubuntu-desktop.
- Recommended phase split for online VM-image tests:
- Phase 1:
apt-get install -y ubuntu-desktop-minimal
- Phase 2:
apt-get install -y --no-install-recommends thunderbird libreoffice-core htop curl jq git
- If the cloud image runs out of free space, document the deviation and use the largest subset that fits.
Config Strategy
- Copy
~/vykar.sample.yaml to a scenario-specific config (e.g., config.postgres.yaml)
- Add test-specific
sources blocks per scenario; keep repo definitions from sample
- Keep each scenario in a separate config file to avoid source overlap
- Reference repos by label:
-R local, -R rest, -R s3, -R sftp
- Include one dedicated local-backend scenario with
encryption.mode: none; treat it as a required backend validation, not an optional smoke test
- For the
e2e-tests:backends:local-none scenario, set:
encryption.mode: none
- omit
encryption.passphrase / VYKAR_PASSPHRASE
- keep the same backup/list/restore/diff validation standard as encrypted local runs
- For local REST server mode, use a single repository URL root (e.g.
http://127.0.0.1:8585) with:
access_token: "<token>"
allow_insecure_http: true
- do not append
/<repo-name> in single-repo mode
- For
e2e-tests:backends:interrupt-minimal, use a dedicated config file and point S3 to local MinIO:
url: "s3+http://127.0.0.1:9000/vykar-stress/<run-id>"
allow_insecure_http: true
region: "us-east-1"
access_key_id: "minioadmin"
secret_access_key: "minioadmin"
Validation Standard
Every test must verify:
vykar backup exits 0
vykar list shows new snapshot for expected source label
vykar --config <config> snapshot list -R <repo> <snapshot_id> confirms expected files or artifacts
- Restore into temp directory and verify:
- Corpus tests:
diff -qr --no-dereference <source> <restore_dir> reports no differences
- Database tests: restore dump, verify row/document counts and sampled content match seeded large dataset
- After verification, immediately remove restored files:
rm -rf <restore_dir>
- Optional: SHA256 manifest comparison for stronger content verification
Cleanup Standard
- Reset repo before reruns: run
vykar --config <config> delete -R <repo> --yes-delete-this-repo before init
- Treat
not found/missing repo as non-fatal
- REST single-repo servers may reject
delete (for example 400/404); if so, continue with init/backup and record it
- Local: remove temporary directories (dumps, restores, configs)
- Do not keep restore trees after
diff/integrity checks unless actively debugging
- Local REST server data: if using single-repo mode, wipe server data dir between reruns (for this sandbox:
/mnt/repos/bench-vykar/vykar-server-data/*)
- Remote storage:
rclone delete --rmdirs <remote:path> between runs
- Do NOT use
rclone purge (may fail with 403 on restricted buckets)
- Treat
directory not found from rclone as non-fatal
- Containers: stop and remove after each scenario
- Filesystems: unmount/destroy test pools after runs
Run Matrix
For tests that span multiple backends, run in this order:
- local first (fast feedback loop)
- rest second (local server path, still exercises HTTP backend)
- s3 third
- sftp last (known instability, use timeouts)
SFTP Guardrails
SFTP can be intermittent even when rclone works fine against the same server:
- Wrap all vykar commands with
timeout: timeout 120s vykar init ..., timeout 3600s vykar backup ...
- On timeout (exit 124), mark test as BLOCKED, kill stuck process, continue cleanup
- Do NOT rerun the entire test suite if only SFTP failed — isolate SFTP results
- Ensure no stuck
vykar process remains after aborted SFTP steps
Interruption Minimal Test (All Backends)
Run order:
local
rest
s3 (local MinIO only)
sftp
Source mapping:
local -> ~/corpus-local/snapshot-1
rest -> ~/corpus-remote/snapshot-1
s3 (local MinIO) -> ~/corpus-remote/snapshot-1
sftp -> ~/corpus-remote/snapshot-1
Interrupt method (backup only):
- Start backup in background:
vykar --config <config> backup -R <repo> <src> > <backup_log> 2>&1 &
pid=$!
- Sleep briefly (
1-5s, backend-specific), then send SIGTERM:kill -TERM "$pid"
- If still running after 2 seconds, send SIGKILL:
kill -KILL "$pid"
- Wait and record interrupt exit code (
interrupt_rc).
Resume + validation sequence:
- Re-run backup (for
sftp, use timeout-bounded commands per SFTP guardrails).
- Parse latest
snapshot_id from Snapshot created: <id> in resume backup log.
vykar --config <config> list -R <repo> --last 5 and confirm snapshot appears.
vykar --config <config> snapshot list -R <repo> <snapshot_id>.
- Restore into empty directory.
- Validate with
diff -qr --no-dereference <src> <restore_dir>.
- Run
vykar --config <config> check -R <repo>.
Status rules:
PASS: interrupted backup + resume backup + list/snapshot list/restore/diff/check all succeed.
FAIL: non-timeout command failure or diff mismatch.
BLOCKED: timeout (rc=124) on timeout-bounded steps.
Deliverables
Each sub-skill should produce:
- Scenario-specific config file saved under
~/runtime/
- Log file under
~/runtime/logs/
- Pass/fail summary report under
~/runtime/reports/
- For interruption scenarios, include per-backend result fields:
backend,status,reason,interrupt_rc,resume_rc,snapshot_id,log_dir,report_path
Common Gotchas
- Mixing
sudo vykar and regular vykar creates root-owned repo files — use sudo rm -rf for cleanup
- Command dump artifacts appear under
vykar-dumps/ in snapshot listings
- Prefer
vykar --config <config> ... in automation; keep --config explicit in all commands
--label (or -l) is for ad-hoc backup paths only. If sources/command_dumps are already defined in config, run vykar --config <config> backup -R <repo> without -l.
vykar snapshot CLI forms:
vykar --config <config> snapshot list -R <repo> <snapshot_id>
vykar --config <config> snapshot delete -R <repo> <snapshot_id>
- REST local server may run in single-repo mode (
http://127.0.0.1:8585 root URL) and reject path-style repos
- Use
diff -qr --no-dereference to avoid false negatives on broken symlinks in corpora
- MariaDB modern images use
mariadb, mariadb-dump, mariadb-admin (not mysql* names)
- For MariaDB
docker exec dumps, prefer socket protocol with retries; in-container TCP to 127.0.0.1 can be intermittently unreliable on this sandbox
- For high-entropy PostgreSQL seed data, use
scripts/postgres-generate-random-data.sh --container <name> --target-gib <N>
- For high-entropy MariaDB seed data, use
scripts/mariadb-generate-random-data.sh --container <name> --target-gib <N>
- For high-entropy MongoDB seed data, use
scripts/mongodb-generate-random-data.sh --container <name> --target-gib <N>
- Btrfs hook snapshots require backing up a real Btrfs subvolume (not a plain directory)
- ZFS restore diffs should ignore the virtual
.zfs directory
- guestmount/chroot image workflows need bind mounts for
/dev, /proc, /sys, and /run before apt operations
- For Ubuntu VM-image scenarios, use
ubuntu-desktop-minimal as the default large package mutation target
- MongoDB host tools may be missing — use
docker exec or podman exec as fallback
- Pre-pull container images before timed runs to avoid skewing measurements
- Sample config repo paths may need adjustment for the sandbox — verify and update before first run
- In interruption tests,
interrupt_rc=0 usually means the backup finished before the signal landed. Re-run with shorter sle
1---2name: e2e-tests3description: End-to-end validation suite for vykar backup tool on a Linux sandbox server4---56# Vykar E2E Test Suite78You are a Linux sysadmin testing vykar on a dedicated sandbox server. Your goal is to validate backup and restore correctness across all supported backends, database integrations, container workflows, filesystem snapshot patterns, and performance benchmarks.910**Work autonomously.** This is a disposable sandbox — do not ask for permission or confirmation before running commands, installing packages, creating/deleting files, or making destructive changes. If something fails, diagnose and fix it yourself. Only stop to ask the user if you are completely stuck with no viable path forward.1112## Sandbox Environment1314The test server provides:1516| Resource | Path | Purpose |17|----------|------|---------|18| Large corpus | `~/corpus-local` | Test data for local backend (large) |19| Small corpus | `~/corpus-remote` | Test data for S3/SFTP/REST backends (bandwidth-aware) |20| Base config | `~/vykar.sample.yaml` | Repo definitions, credentials, and connection details |21| Vykar docs | https://vykar.borgbase.com/ | Recipe reference for hooks, command_dumps, etc. |2223**Installed tools**: `vykar`, `vykar-server`, `rclone`, `docker`, `podman`, database clients (pg, mariadb, mongo).24Install missing packages with `sudo apt-get install ...`.2526## Sub-skills2728Run each sub-skill to execute a specific test area. Results go to `~/runtime/`.2930### Backends — Corpus backup + restore validation31- **`e2e-tests:backends:local`** — Full backup/restore with large corpus on local backend32- **`e2e-tests:backends:local-none`** — Full backup/restore with large corpus on local backend using `encryption.mode: none`33- **`e2e-tests:backends:rest`** — Backup/restore against local `vykar-server` REST backend34- **`e2e-tests:backends:s3`** — Backup/restore with small corpus on S3 backend35- **`e2e-tests:backends:sftp`** — Backup/restore with small corpus on SFTP backend (timeout-bounded)36- **`e2e-tests:backends:interrupt-minimal`** — Interrupt `backup` mid-run and verify resume + restore integrity across `local`, `rest`, `s3` (local MinIO), and `sftp`3738### Databases — Hooks and command_dumps patterns (large realistic data)39- **`e2e-tests:databases:postgres`** — PostgreSQL with hooks dump and command_dumps variants on ~10 GiB randomized schema40- **`e2e-tests:databases:mariadb`** — MariaDB with hooks dump and command_dumps variants on ~10 GiB randomized schema41- **`e2e-tests:databases:mongodb`** — MongoDB with command_dumps (mongodump --archive) on ~2.5 GiB randomized collections4243### Containers — Volume backups and container integration44- **`e2e-tests:containers:docker`** — Static volumes, downtime hooks, DB exec dumps via Docker45- **`e2e-tests:containers:podman`** — Same scenarios using Podman commands4647### Filesystems — Snapshot hooks patterns48- **`e2e-tests:filesystems:btrfs`** — Btrfs read-only subvolume snapshot hooks49- **`e2e-tests:filesystems:zfs`** — ZFS dataset snapshot hooks via .zfs/snapshot path50- **`e2e-tests:filesystems:vm-image`** — Ubuntu cloud image mutate+backup dedupe validation via guestmount/chroot5152### Benchmarks53- **`e2e-tests:benchmarks`** — Compare vykar performance against restic and rustic (use `benchmarks.md` + bundled scripts under `scripts/`)54- **`e2e-tests:stress`** — Run long-loop backup/restore/delete stress validation against local corpus (use `stress.md` + `scripts/stress.sh`)5556## Recommended Execution Order57581. **Backends** first (establishes corpus validation baseline)592. **Databases** (large-data, container-based tests)603. **Containers** (reuses DB patterns with volume workflows)614. **Filesystems** (requires disk/partition setup; run VM image dedupe scenario here)625. **Stress** next (long-loop correctness/locking pressure on local backend)636. **Benchmarks** last (long-running, independent)6465## Shared Conventions6667### Environment Setup68```bash69export VYKAR_PASSPHRASE=123 # non-interactive passphrase70```71- Use `sudo` for package installs and root-owned paths72- Working directory for all test artifacts: `~/runtime/`7374### Database Data Volume Baseline75- Database scenarios are **not** small-smoke tests by default.76- Seed randomized, high-entropy data before backup using these defaults:77 - PostgreSQL: **~10 GiB**78 - MariaDB: **~10 GiB**79 - MongoDB: **~2.5 GiB** (faster validation target)80- Prefer these helper scripts from repo root:81 - `scripts/postgres-generate-random-data.sh --container <name> --target-gib 10`82 - `scripts/mariadb-generate-random-data.sh --container <name> --target-gib 10`83 - `scripts/mongodb-generate-random-data.sh --container <name> --target-gib 2.5`84- Record resulting size and table/collection counts in scenario logs/reports.8586### VM Image Package Baseline (Large-Mutation)87- For `e2e-tests:filesystems:vm-image`, prefer large package mutations by default (not tiny smoke installs).88- Ubuntu desktop-class package to use: `ubuntu-desktop-minimal` (primary).89- Optional heavier variant when disk space allows: `ubuntu-desktop`.90- Recommended phase split for online VM-image tests:91 - Phase 1: `apt-get install -y ubuntu-desktop-minimal`92 - Phase 2: `apt-get install -y --no-install-recommends thunderbird libreoffice-core htop curl jq git`93- If the cloud image runs out of free space, document the deviation and use the largest subset that fits.9495### Config Strategy961. Copy `~/vykar.sample.yaml` to a scenario-specific config (e.g., `config.postgres.yaml`)972. Add test-specific `sources` blocks per scenario; keep repo definitions from sample983. Keep each scenario in a separate config file to avoid source overlap994. Reference repos by label: `-R local`, `-R rest`, `-R s3`, `-R sftp`1005. Include one dedicated local-backend scenario with `encryption.mode: none`; treat it as a required backend validation, not an optional smoke test1016. For the `e2e-tests:backends:local-none` scenario, set:102 - `encryption.mode: none`103 - omit `encryption.passphrase` / `VYKAR_PASSPHRASE`104 - keep the same backup/list/restore/diff validation standard as encrypted local runs1057. For local REST server mode, use a single repository URL root (e.g. `http://127.0.0.1:8585`) with:106 - `access_token: "<token>"`107 - `allow_insecure_http: true`108 - do not append `/<repo-name>` in single-repo mode1098. For `e2e-tests:backends:interrupt-minimal`, use a dedicated config file and point S3 to local MinIO:110 - `url: "s3+http://127.0.0.1:9000/vykar-stress/<run-id>"`111 - `allow_insecure_http: true`112 - `region: "us-east-1"`113 - `access_key_id: "minioadmin"`114 - `secret_access_key: "minioadmin"`115116### Validation Standard117Every test must verify:1181. `vykar backup` exits 01192. `vykar list` shows new snapshot for expected source label1203. `vykar --config <config> snapshot list -R <repo> <snapshot_id>` confirms expected files or artifacts1214. Restore into temp directory and verify:122 - Corpus tests: `diff -qr --no-dereference <source> <restore_dir>` reports no differences123 - Database tests: restore dump, verify row/document counts and sampled content match seeded large dataset124 - After verification, immediately remove restored files: `rm -rf <restore_dir>`1255. Optional: SHA256 manifest comparison for stronger content verification126127### Cleanup Standard1281. **Reset repo before reruns**: run `vykar --config <config> delete -R <repo> --yes-delete-this-repo` before `init`129 - Treat `not found`/missing repo as non-fatal130 - REST single-repo servers may reject `delete` (for example `400/404`); if so, continue with `init`/`backup` and record it1312. **Local**: remove temporary directories (dumps, restores, configs)132 - Do not keep restore trees after `diff`/integrity checks unless actively debugging1333. **Local REST server data**: if using single-repo mode, wipe server data dir between reruns (for this sandbox: `/mnt/repos/bench-vykar/vykar-server-data/*`)1344. **Remote storage**: `rclone delete --rmdirs <remote:path>` between runs135 - Do NOT use `rclone purge` (may fail with 403 on restricted buckets)136 - Treat `directory not found` from rclone as non-fatal1375. **Containers**: stop and remove after each scenario1386. **Filesystems**: unmount/destroy test pools after runs139140### Run Matrix141For tests that span multiple backends, run in this order:1421. **local** first (fast feedback loop)1432. **rest** second (local server path, still exercises HTTP backend)1443. **s3** third1454. **sftp** last (known instability, use timeouts)146147### SFTP Guardrails148SFTP can be intermittent even when rclone works fine against the same server:149- Wrap all vykar commands with `timeout`: `timeout 120s vykar init ...`, `timeout 3600s vykar backup ...`150- On timeout (exit 124), mark test as **BLOCKED**, kill stuck process, continue cleanup151- Do NOT rerun the entire test suite if only SFTP failed — isolate SFTP results152- Ensure no stuck `vykar` process remains after aborted SFTP steps153154### Interruption Minimal Test (All Backends)155Run order:1561. `local`1572. `rest`1583. `s3` (local MinIO only)1594. `sftp`160161Source mapping:162- `local` -> `~/corpus-local/snapshot-1`163- `rest` -> `~/corpus-remote/snapshot-1`164- `s3` (local MinIO) -> `~/corpus-remote/snapshot-1`165- `sftp` -> `~/corpus-remote/snapshot-1`166167Interrupt method (backup only):1681. Start backup in background:169 ```bash170 vykar --config <config> backup -R <repo> <src> > <backup_log> 2>&1 &171 pid=$!172 ```1732. Sleep briefly (`1-5s`, backend-specific), then send SIGTERM:174 ```bash175 kill -TERM "$pid"176 ```1773. If still running after 2 seconds, send SIGKILL:178 ```bash179 kill -KILL "$pid"180 ```1814. Wait and record interrupt exit code (`interrupt_rc`).182183Resume + validation sequence:1841. Re-run backup (for `sftp`, use timeout-bounded commands per SFTP guardrails).1852. Parse latest `snapshot_id` from `Snapshot created: <id>` in resume backup log.1863. `vykar --config <config> list -R <repo> --last 5` and confirm snapshot appears.1874. `vykar --config <config> snapshot list -R <repo> <snapshot_id>`.1885. Restore into empty directory.1896. Validate with `diff -qr --no-dereference <src> <restore_dir>`.1907. Run `vykar --config <config> check -R <repo>`.191192Status rules:193- `PASS`: interrupted backup + resume backup + list/snapshot list/restore/diff/check all succeed.194- `FAIL`: non-timeout command failure or diff mismatch.195- `BLOCKED`: timeout (`rc=124`) on timeout-bounded steps.196197### Deliverables198Each sub-skill should produce:1991. Scenario-specific config file saved under `~/runtime/`2002. Log file under `~/runtime/logs/`2013. Pass/fail summary report under `~/runtime/reports/`2024. For interruption scenarios, include per-backend result fields:203 - `backend,status,reason,interrupt_rc,resume_rc,snapshot_id,log_dir,report_path`204205## Common Gotchas206207- Mixing `sudo vykar` and regular `vykar` creates root-owned repo files — use `sudo rm -rf` for cleanup208- Command dump artifacts appear under `vykar-dumps/` in snapshot listings209- Prefer `vykar --config <config> ...` in automation; keep `--config` explicit in all commands210- `--label` (or `-l`) is for ad-hoc backup paths only. If sources/`command_dumps` are already defined in config, run `vykar --config <config> backup -R <repo>` without `-l`.211- `vykar snapshot` CLI forms:212 - `vykar --config <config> snapshot list -R <repo> <snapshot_id>`213 - `vykar --config <config> snapshot delete -R <repo> <snapshot_id>`214- REST local server may run in single-repo mode (`http://127.0.0.1:8585` root URL) and reject path-style repos215- Use `diff -qr --no-dereference` to avoid false negatives on broken symlinks in corpora216- MariaDB modern images use `mariadb`, `mariadb-dump`, `mariadb-admin` (not `mysql*` names)217- For MariaDB `docker exec` dumps, prefer socket protocol with retries; in-container TCP to `127.0.0.1` can be intermittently unreliable on this sandbox218- For high-entropy PostgreSQL seed data, use `scripts/postgres-generate-random-data.sh --container <name> --target-gib <N>`219- For high-entropy MariaDB seed data, use `scripts/mariadb-generate-random-data.sh --container <name> --target-gib <N>`220- For high-entropy MongoDB seed data, use `scripts/mongodb-generate-random-data.sh --container <name> --target-gib <N>`221- Btrfs hook snapshots require backing up a real Btrfs subvolume (not a plain directory)222- ZFS restore diffs should ignore the virtual `.zfs` directory223- guestmount/chroot image workflows need bind mounts for `/dev`, `/proc`, `/sys`, and `/run` before apt operations224- For Ubuntu VM-image scenarios, use `ubuntu-desktop-minimal` as the default large package mutation target225- MongoDB host tools may be missing — use `docker exec` or `podman exec` as fallback226- Pre-pull container images before timed runs to avoid skewing measurements227- Sample config repo paths may need adjustment for the sandbox — verify and update before first run228- In interruption tests, `interrupt_rc=0` usually means the backup finished before the signal landed. Re-run with shorter sle