Real-infrastructure test harness
This is an opt-in acceptance test for DaoFlow's real remote execution path. It is separate from the normal browser test suite and is intentionally not run for pull requests.
Run it only against an operator-provisioned, disposable SSH-and-Docker target:
DAOFLOW_REAL_INFRA=1 bun run test:e2e:real-infra
The command refuses to continue unless its complete configuration is present. It performs a strict SSH host-key check and verifies a pre-existing marker file and nonce before it resets the dedicated control-plane database or changes the remote target.
Required configuration
Supply the following through your secret manager or shell environment. Do not put the values in a checked-in file, command history, test artifact, or log.
| Purpose | Environment variables |
|---|---|
| Remote SSH target | DAOFLOW_REAL_INFRA_SSH_HOST, DAOFLOW_REAL_INFRA_SSH_PORT, DAOFLOW_REAL_INFRA_SSH_USER, DAOFLOW_REAL_INFRA_SSH_PRIVATE_KEY |
| Exact SSH trust pin | DAOFLOW_REAL_INFRA_SSH_HOST_KEY |
| Remote ownership guard | DAOFLOW_REAL_INFRA_REMOTE_MARKER_PATH, DAOFLOW_REAL_INFRA_REMOTE_MARKER_NONCE |
| S3-compatible backup destination | DAOFLOW_REAL_INFRA_S3_ENDPOINT, DAOFLOW_REAL_INFRA_S3_BUCKET, DAOFLOW_REAL_INFRA_S3_ACCESS_KEY, DAOFLOW_REAL_INFRA_S3_SECRET_ACCESS_KEY, DAOFLOW_REAL_INFRA_S3_REGION |
| Dedicated control plane | PLAYWRIGHT_REAL_INFRA_DATABASE_URL, REDIS_URL, BETTER_AUTH_SECRET, ENCRYPTION_KEY, TEMPORAL_ADDRESS |
DAOFLOW_REAL_INFRA_RUN_TOKEN is generated by the runner when it is not already set. DAOFLOW_REAL_INFRA_ARTIFACT_DIR optionally chooses the directory for the redacted output; it defaults to a per-run directory under test-results/real-infra/.
The PostgreSQL URL must use a loopback host and the exact disposable database name daoflow_real_infra_${DAOFLOW_REAL_INFRA_RUN_TOKEN}. The preflight rejects every other database before the reset command can run.
The remote marker is created by the target's operator, not by the test. It must be an absolute path and contain exactly the configured nonce. A marker mismatch stops the run and prevents both product mutations and cleanup.
What the test proves
Each run uses one unique token in the server, project, environment, service, Compose project, volume, backup policy, remote workspace, and S3 prefix. It then:
- Registers the server, scans the SSH identity, approves the exact pinned key, and checks readiness.
- Uploads a valid Compose file through DaoFlow and verifies a real remote container and HTTP response over pinned SSH.
- Writes a sentinel, backs it up, deploys a deliberately missing image, and waits for a failed deployment.
- Checks that the failure diagnosis cites exact persisted event and deployment-log IDs.
- Rolls back to the known-good release, deletes the sentinel, restores the backup, and verifies the sentinel returned.
- Confirms the control plane recorded audits for every product mutation in the lifecycle.
The harness is serial, uses one browser worker, retries nothing, and disables screenshots, videos, and traces so credentials are not captured. Its Playwright and command time limits are below ten minutes.
Cleanup and evidence
Cleanup runs in a finally block. It rechecks the remote marker and removes only containers, networks, volumes, workspaces, and S3 objects carrying the current run token. It never performs a global Docker or bucket prune. It then asserts that no owned remote resource or S3 object remains.
The dedicated control-plane database is intentionally left for the workflow or operator to tear down as one unit. Remote evidence is preserved in redacted artifacts instead of leaving test resources running:
result.json— lifecycle result and evidence IDscleanup.json— marker and zero-owned-resource cleanup resultcommand-outcomes.jsonl— redacted command outcomes
Short-lived local SSH keys, host pins, and multiplexing state are kept under the compact run-token directory /tmp/dfri/ and removed automatically when the harness command exits. The compact path keeps OpenSSH control sockets below platform path limits.
The scheduled GitHub Actions workflow runs only from its protected real-infrastructure environment. Manual runs are additionally restricted to main. It starts disposable PostgreSQL, Redis, Temporal, and MinIO support services, loads the target only from secrets, and uploads these artifacts even when the harness fails.