3.0 KiB
3.0 KiB
QA: S3 image storage
All tests live in test/ (package test). No cloud account, no real SMTP, no real SQLite file. Test names carry "S3Storage".
Settled decisions: boot backfill gets a log line only, wired in the composition root, with no cap and no use case change. No ETag is emitted; the staticimages handler is unchanged and conditional requests are validated by Last-Modified only.
Automated
- Config validation: table test over STORAGE_DRIVER and S3_* lookup functions (the MissingEnvVarError pattern, a
StorageRequiredEnvVars(driver)helper likeDatabaseRequiredEnvVars). Covers the validation table, UPLOAD_DIR ignored, unknown driver error. - Registry: storage.Open with "local" returns local storage, "s3" returns the S3 storage after HEAD bucket, anything else returns the "unsupported storage driver" error.
- Fake S3: an httptest.Server on 127.0.0.1 only (never bind :port) implementing HEAD bucket, PUT, GET with Range, HEAD and DELETE object, with injectable statuses and recorded keys, headers and bodies.
- Adapter tests against the fake: the Put, Open (found, 404, 500) and Delete scenarios, HEAD bucket 404/403/500, prefix handling, ModTime and Size from metadata, Content as io.ReadSeeker (seek then read issues a ranged GET), secret absent from error text.
- Handler tests: staticimages.NewHandler over OpenMediaUseCase over the S3 storage on the fake server, mounted on a fresh chi.NewRouter() at /static/uploadedImages/*. Cover GET, HEAD, 304 via If-Modified-Since, 206, 416, SVG CSP, 404, 500, traversal.
- Handler regression: a storage fake returning a non-seekable Blob. GET and HEAD behave exactly as today.
- Backfill log: the boot log line for the number of images read, captured with a log writer, containing no credential.
- Local regression: all existing image tests pass unchanged.
- Gates:
task testandtask lint:gopass.task mutateis not part of this slice, but the new storage package becomes a target if the mutation scope is widened. The 404 to ErrBlobNotFound and idempotent-Delete branches need killing tests.
Optional integration (task test:s3)
Start a SeaweedFS container with Docker, create a bucket, set RENEWCMS_TEST_S3_ENDPOINT and run the adapter tests against it. Skip with a message when Docker is unavailable. Not part of task test.
Manual
- Run docker-compose.s3.yml, upload an image in the SPA, confirm the object is in the bucket and /static/uploadedImages/ serves it, including after the container is recreated.
- Real AWS S3, R2, B2 or Scaleway smoke test, and an instance-role credential check.
- Start with a wrong bucket and confirm a clear, secret-free startup error.
- Sync an old UPLOAD_DIR with
aws s3 syncormc mirrorand confirm old images load. - Confirm docs describe: variables (configuration.md, .env.example, docker.env.example, Docker docs), UPLOAD_DIR ignored with s3, manual migration, update backups covering the DB only and not the bucket, and the updated architecture.md "Storage and database seams" section.