Initial Commit
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Garage-backed integration test for `S3.setPartial`.
|
||||
*
|
||||
* Pins STORAGE-01..03 (set-partial semantics) against a real S3 wire so the
|
||||
* read-modify-write fallback survives AWS-SDK body encoding, content-length,
|
||||
* and range-read round-trips that an in-memory FakeS3Client cannot exercise.
|
||||
*
|
||||
* Skips the suite when the GarageS3Fixture failed to start (no Docker /
|
||||
* env-bridge incomplete). Set `GARAGE_S3_ENDPOINT`,
|
||||
* `GARAGE_S3_ADMIN_ENDPOINT`, `GARAGE_S3_ACCESS_KEY_ID`,
|
||||
* `GARAGE_S3_SECRET_ACCESS_KEY` to bypass container startup and use an
|
||||
* existing Garage instance.
|
||||
*/
|
||||
import {
|
||||
afterEach,
|
||||
beforeEach,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
inject as vitestInject,
|
||||
} from "@suaveplan/testing/runner";
|
||||
import { S3 } from "../../src/s3/s3.js";
|
||||
import { inject } from "./setup.js";
|
||||
|
||||
const failed =
|
||||
(vitestInject as (k: string) => string[] | null | undefined)(
|
||||
"__integration_failed__"
|
||||
) ?? [];
|
||||
const garageUnavailable = failed.includes("garage-s3");
|
||||
|
||||
describe.skipIf(garageUnavailable)("S3.setPartial — Garage backed", () => {
|
||||
let storage: S3;
|
||||
let key: string;
|
||||
|
||||
beforeEach(() => {
|
||||
const cfg = inject("garage-s3");
|
||||
storage = new S3({
|
||||
bucket: cfg.bucket,
|
||||
region: cfg.region,
|
||||
endpoint: cfg.endpoint,
|
||||
accessKeyId: cfg.accessKeyId,
|
||||
secretAccessKey: cfg.secretAccessKey,
|
||||
});
|
||||
key = `set-partial/${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await storage.delete(key).catch(() => undefined);
|
||||
});
|
||||
|
||||
it("creates a sparse zero-filled object when key does not exist", {
|
||||
timeout: 60_000,
|
||||
}, async () => {
|
||||
await storage.setPartial(key, 4, new Uint8Array([0xaa, 0xbb]));
|
||||
const got = await storage.get(key);
|
||||
expect(got).toEqual(
|
||||
new Uint8Array([0x00, 0x00, 0x00, 0x00, 0xaa, 0xbb])
|
||||
);
|
||||
});
|
||||
|
||||
it("extends an existing shorter object with zero gap", {
|
||||
timeout: 60_000,
|
||||
}, async () => {
|
||||
await storage.set(key, new Uint8Array([0x01, 0x02]));
|
||||
await storage.setPartial(key, 5, new Uint8Array([0xcc]));
|
||||
const got = await storage.get(key);
|
||||
expect(got).toEqual(
|
||||
new Uint8Array([0x01, 0x02, 0x00, 0x00, 0x00, 0xcc])
|
||||
);
|
||||
});
|
||||
|
||||
it("overwrites overlap and preserves surrounding bytes", {
|
||||
timeout: 60_000,
|
||||
}, async () => {
|
||||
await storage.set(key, new Uint8Array([1, 2, 3, 4, 5, 6]));
|
||||
await storage.setPartial(key, 2, new Uint8Array([0xff, 0xff]));
|
||||
const got = await storage.get(key);
|
||||
expect(got).toEqual(new Uint8Array([1, 2, 0xff, 0xff, 5, 6]));
|
||||
});
|
||||
|
||||
it("zero-length writes are a no-op", { timeout: 60_000 }, async () => {
|
||||
await storage.set(key, new Uint8Array([0x01, 0x02, 0x03]));
|
||||
await storage.setPartial(key, 1, new Uint8Array(0));
|
||||
const got = await storage.get(key);
|
||||
expect(got).toEqual(new Uint8Array([0x01, 0x02, 0x03]));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user