Initial Commit
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
import {
|
||||
getPublicKey,
|
||||
randomPrivateKey,
|
||||
} from "@suaveplan/crypto-curve/ed25519";
|
||||
import { Drive, type DriveStorage } from "@suaveplan/drive";
|
||||
import { MemoryStorage } from "@suaveplan/storage/memory";
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import { CHUNKS_CODES, ChunksError } from "./error-codes.js";
|
||||
import { chunksPlugin } from "./plugin.js";
|
||||
|
||||
function makeFailingStorage(failOn: (key: string) => boolean): DriveStorage {
|
||||
const inner = new MemoryStorage();
|
||||
return Object.assign(inner, {
|
||||
id: "default",
|
||||
set(key: string, value: Uint8Array): Promise<void> {
|
||||
if (failOn(key)) {
|
||||
throw new Error(`disk full for ${key}`);
|
||||
}
|
||||
return MemoryStorage.prototype.set.call(inner, key, value);
|
||||
},
|
||||
}) as unknown as DriveStorage;
|
||||
}
|
||||
|
||||
function makeFailingStorageNonError(
|
||||
failOn: (key: string) => boolean
|
||||
): DriveStorage {
|
||||
const inner = new MemoryStorage();
|
||||
return Object.assign(inner, {
|
||||
id: "default",
|
||||
set(key: string, value: Uint8Array): Promise<void> {
|
||||
if (failOn(key)) {
|
||||
const literal: unknown = "literal-throwable";
|
||||
throw literal;
|
||||
}
|
||||
return MemoryStorage.prototype.set.call(inner, key, value);
|
||||
},
|
||||
}) as unknown as DriveStorage;
|
||||
}
|
||||
|
||||
describe("CHUNKS-INGEST-FAILED — non-ChunksError storage failures wrap as INGEST_FAILED", () => {
|
||||
it("wraps a manifest-write Error into ChunksError(INGEST_FAILED)", {
|
||||
timeout: 5000,
|
||||
}, async () => {
|
||||
const privKey = randomPrivateKey();
|
||||
const pubKey = getPublicKey(privKey);
|
||||
const storage = makeFailingStorage((k) => k.startsWith("manifest:"));
|
||||
const drive = new Drive(storage);
|
||||
await drive.initialize();
|
||||
|
||||
const chunks = await drive.usePlugin(
|
||||
chunksPlugin({
|
||||
serverPrivKey: privKey,
|
||||
serverPubKey: pubKey,
|
||||
chunkSize: 1024,
|
||||
})
|
||||
);
|
||||
|
||||
await drive.write("test.txt", new TextEncoder().encode("hello"));
|
||||
|
||||
try {
|
||||
await chunks.ingest("test.txt");
|
||||
throw new Error("expected ingest to throw");
|
||||
} catch (e) {
|
||||
expect(e).toBeInstanceOf(ChunksError);
|
||||
expect((e as ChunksError).code).toBe(CHUNKS_CODES.INGEST_FAILED);
|
||||
expect((e as ChunksError).message).toContain("disk full");
|
||||
}
|
||||
|
||||
await drive.dispose();
|
||||
});
|
||||
|
||||
it("passes through a ChunksError thrown inside the ingest path without re-wrapping", {
|
||||
timeout: 5000,
|
||||
}, async () => {
|
||||
const privKey = randomPrivateKey();
|
||||
const pubKey = getPublicKey(privKey);
|
||||
const inner = new MemoryStorage();
|
||||
const chunksErrorStorage = Object.assign(inner, {
|
||||
id: "default",
|
||||
set(key: string, value: Uint8Array): Promise<void> {
|
||||
if (key.startsWith("manifest:")) {
|
||||
throw new ChunksError(
|
||||
CHUNKS_CODES.SIG_INVALID,
|
||||
"synthetic: bypass wrapping"
|
||||
);
|
||||
}
|
||||
return MemoryStorage.prototype.set.call(inner, key, value);
|
||||
},
|
||||
}) as unknown as DriveStorage;
|
||||
const drive = new Drive(chunksErrorStorage);
|
||||
await drive.initialize();
|
||||
|
||||
const chunks = await drive.usePlugin(
|
||||
chunksPlugin({
|
||||
serverPrivKey: privKey,
|
||||
serverPubKey: pubKey,
|
||||
chunkSize: 1024,
|
||||
})
|
||||
);
|
||||
|
||||
await drive.write("test.txt", new TextEncoder().encode("hello"));
|
||||
|
||||
try {
|
||||
await chunks.ingest("test.txt");
|
||||
throw new Error("expected ingest to throw");
|
||||
} catch (e) {
|
||||
expect(e).toBeInstanceOf(ChunksError);
|
||||
expect((e as ChunksError).code).toBe(CHUNKS_CODES.SIG_INVALID);
|
||||
expect((e as ChunksError).message).toContain(
|
||||
"synthetic: bypass wrapping"
|
||||
);
|
||||
}
|
||||
|
||||
await drive.dispose();
|
||||
});
|
||||
|
||||
it("wraps a non-Error throwable into ChunksError(INGEST_FAILED)", {
|
||||
timeout: 5000,
|
||||
}, async () => {
|
||||
const privKey = randomPrivateKey();
|
||||
const pubKey = getPublicKey(privKey);
|
||||
const storage = makeFailingStorageNonError((k) =>
|
||||
k.startsWith("manifest:")
|
||||
);
|
||||
const drive = new Drive(storage);
|
||||
await drive.initialize();
|
||||
|
||||
const chunks = await drive.usePlugin(
|
||||
chunksPlugin({
|
||||
serverPrivKey: privKey,
|
||||
serverPubKey: pubKey,
|
||||
chunkSize: 1024,
|
||||
})
|
||||
);
|
||||
|
||||
await drive.write("test.txt", new TextEncoder().encode("hello"));
|
||||
|
||||
try {
|
||||
await chunks.ingest("test.txt");
|
||||
throw new Error("expected ingest to throw");
|
||||
} catch (e) {
|
||||
expect(e).toBeInstanceOf(ChunksError);
|
||||
expect((e as ChunksError).code).toBe(CHUNKS_CODES.INGEST_FAILED);
|
||||
expect((e as ChunksError).message).toContain("literal-throwable");
|
||||
}
|
||||
|
||||
await drive.dispose();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user