Files
WebDrop/web/src/core-bridge/worker/frameStash.test.ts
T

75 lines
3.1 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import type { QueuedFrame } from '../database';
import { FrameStash } from './frameStash';
const frame = (index: number): QueuedFrame => ({ key: `k${index}`, resourceId: 'r', itemId: 'i', index, bytes: new Uint8Array(10), extraHeaders: {}, createdAt: index });
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
function fakeDisk(writeMs = 5) {
const stored = new Set<string>(); const writes: string[] = []; const removes: string[] = [];
return {
stored, writes, removes,
put: async (f: QueuedFrame) => { await sleep(writeMs); stored.add(f.key); writes.push(f.key); },
remove: async (key: string) => { stored.delete(key); removes.push(key); },
};
}
describe('FrameStash', () => {
it('宽限期内就被确认的帧:根本不写盘', async () => {
const disk = fakeDisk(5);
const stash = new FrameStash(disk.put, disk.remove, 8, 100, 4);
const frames = [0, 1, 2, 3].map(frame);
for (const f of frames) await stash.add(f);
await sleep(20);
for (const f of frames) stash.accepted(f);
await stash.drain();
expect(disk.writes).toEqual([]);
expect(disk.stored.size).toBe(0);
});
it('超过宽限期还没确认的帧会写入,之后确认时再删除', async () => {
const disk = fakeDisk(1);
const stash = new FrameStash(disk.put, disk.remove, 8, 30, 4);
const first = frame(0); await stash.add(first);
await sleep(80);
expect(disk.stored.has('k0')).toBe(true);
stash.accepted(first);
await sleep(10);
expect(disk.stored.has('k0')).toBe(false);
});
it('断网时(一直不确认)drain 之后全部帧都已落盘,续传才有东西可发', async () => {
const disk = fakeDisk(1);
const stash = new FrameStash(disk.put, disk.remove, 3, 5000, 4);
for (let index = 0; index < 10; index += 1) await stash.add(frame(index));
await stash.drain();
expect(disk.stored.size).toBe(10);
});
it('积压超过上限时 add 会等待写盘,不让内存里越堆越多', async () => {
const disk = fakeDisk(30);
const stash = new FrameStash(disk.put, disk.remove, 2, 5000, 1);
let added = 0;
const producer = (async () => { for (let index = 0; index < 6; index += 1) { await stash.add(frame(index)); added += 1; } })();
await sleep(40);
expect(added).toBeLessThan(6);
await producer; await stash.drain();
expect(disk.stored.size).toBe(6);
});
it('取消后不会再写入新的帧', async () => {
const disk = fakeDisk(5);
const stash = new FrameStash(disk.put, disk.remove, 8, 20, 4);
await stash.add(frame(0)); await stash.add(frame(1));
await stash.discard();
const before = disk.writes.length;
await sleep(60);
expect(disk.writes.length).toBe(before);
});
it('写盘失败会让加密端停下来并抛出', async () => {
const stash = new FrameStash(async () => { throw new Error('quota'); }, async () => {}, 1, 0, 0);
await expect((async () => { for (let index = 0; index < 5; index += 1) await stash.add(frame(index)); await stash.drain(); })()).rejects.toThrow('quota');
});
});