Skip to content

test: assert write failures propagate, and run MinIO in CI - #22

Closed
saby1101 wants to merge 1 commit into
fix/provider-correctnessfrom
test/write-path-assertions
Closed

saby1101 wants to merge 1 commit into
fix/provider-correctnessfrom
test/write-path-assertions

Conversation

@saby1101

Copy link
Copy Markdown
Member

Batch 2 of the review findings. Stacked on #20; retarget to main once that merges. Tests and CI only — no source changes.

Write failures were never asserted

Every write test asserted that a mock was called with the right arguments, then resolved. Nothing fed a rejected write. So swallowing an error — dropping the await, or attaching .catch(() => undefined) — left the suite green on all five providers while writes silently failed.

Six such mutations survived the previous suite. Two re-run against this one:

S3 save + .catch(() => undefined)       -> 1 test failed  (was: survived)
Azure Buffer.from(data,"utf8")->"ascii" -> 1 test failed  (was: survived)

no-floating-promises catches a dropped await, but not a swallowed rejection, so lint was never the backstop here.

Adds one rejection test per write method across s3, gcs, azure and local.

Three more holes

  • Azure getContainerClient was never asserted. Every operation could target the wrong container and the suite would stay green. The mock is hoisted so its argument can be checked against AZURE_STORAGE_CONTAINER.
  • Unicode was untested. Every payload fixture was ASCII ("content", "hello"), so an encoding regression mangling non-ASCII bytes passed. Covered for azure, gcs, and as a real MinIO round trip including a unicode key.
  • The integration spec never read a missing key — the real GetObject 404 path, the same error-shape class as the NoSuchKey/NotFound mismatch fixed in S3 provider: dead NoSuchKey checks, inconsistent timestamp fallback, validation ordering #9, which mocks by construction cannot catch. Added for both getAsBuffer and getAsStream.

Integration spec: 6 → 9 tests.

MinIO now runs in CI

Skipping by default locally is right; never running in CI is not — that combination rots, and this repo already has one bug that only real I/O would have caught.

Started as a step, not a service container: services: cannot pass a command and the minio image needs server /data. My first attempt used bitnami/minio as a service, which would have failed — that image no longer exists on Docker Hub. Verified the step-based version end to end locally: ready in ~4s, all 9 integration tests pass.

Verification

lint     clean
build    clean
tests    149 passed, 100% statements/branches/functions/lines
minio    9 passed against a real container

Source restored bit-identical after the mutation runs (git diff empty).

Every write test asserted only that a mock was called with the right arguments and
then resolved. Nothing fed a rejected write, so swallowing an error — dropping the
await, or attaching .catch(() => undefined) — left the suite green on all five
providers while writes silently failed. Six such mutations survived the previous
suite; two were re-run against this one and both now fail.

Adds a rejection test per write method across s3, gcs, azure and local, plus:

- Azure getContainerClient was never asserted, so every operation could target the
  wrong container unnoticed.
- Unicode payloads were untested — all fixtures were ASCII, so changing Azure's utf8
  encoding to ascii passed. Covered for azure, gcs and the MinIO round trip.
- The integration spec had no missing-key read. That is the real GetObject 404 path,
  the same error-shape class as the NoSuchKey/NotFound mismatch in #9, which mocks
  cannot catch.

CI now runs the integration suite against MinIO. It is started as a step rather than
a service container: services cannot pass a command and the minio image needs
"server /data". Skipping by default locally is right; never running in CI is not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant