90 lines
2.8 KiB
JavaScript
90 lines
2.8 KiB
JavaScript
// Rôle : teste les rafales d'estimations, la concurrence et le nettoyage du quota.
|
|
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { createQuotaRefresh } from "../website/src/features/toolboxes/storage/quotaRefresh.js";
|
|
|
|
function setup(estimate) {
|
|
const timers = new Map();
|
|
const results = [];
|
|
let id = 0;
|
|
const refresh = createQuotaRefresh({
|
|
estimate,
|
|
onResult: (result) => results.push(result),
|
|
schedule: (callback) => { timers.set(++id, callback); return id; },
|
|
cancel: (key) => timers.delete(key)
|
|
});
|
|
function tick() {
|
|
assert.equal(timers.size, 1);
|
|
const [key, callback] = timers.entries().next().value;
|
|
timers.delete(key);
|
|
return callback();
|
|
}
|
|
return { ...refresh, timers, results, tick };
|
|
}
|
|
|
|
test("one hundred refresh requests trigger one estimate", async () => {
|
|
let calls = 0;
|
|
const refresh = setup(async () => { calls++; return { usage: 12 }; });
|
|
for (let i = 0; i < 100; i++) refresh.request();
|
|
await refresh.tick();
|
|
assert.equal(calls, 1);
|
|
assert.deepEqual(refresh.results, [{ usage: 12 }]);
|
|
assert.equal(refresh.timers.size, 0);
|
|
});
|
|
|
|
test("writes during estimation schedule one follow-up and discard the stale result", async () => {
|
|
let finish;
|
|
let calls = 0;
|
|
const refresh = setup(() => {
|
|
calls++;
|
|
return new Promise((resolve) => { finish = resolve; });
|
|
});
|
|
refresh.request();
|
|
const first = refresh.tick();
|
|
for (let i = 0; i < 100; i++) refresh.request();
|
|
assert.equal(calls, 1);
|
|
assert.equal(refresh.timers.size, 0);
|
|
finish({ usage: 1 });
|
|
await first;
|
|
assert.deepEqual(refresh.results, []);
|
|
const second = refresh.tick();
|
|
finish({ usage: 2 });
|
|
await second;
|
|
assert.equal(calls, 2);
|
|
assert.deepEqual(refresh.results, [{ usage: 2 }]);
|
|
});
|
|
|
|
test("dispose cancels scheduled work and ignores in-flight results", async () => {
|
|
let finish;
|
|
const refresh = setup(() => new Promise((resolve) => { finish = resolve; }));
|
|
refresh.request();
|
|
refresh.dispose();
|
|
refresh.request();
|
|
assert.equal(refresh.timers.size, 0);
|
|
const active = setup(() => new Promise((resolve) => { finish = resolve; }));
|
|
active.request();
|
|
const task = active.tick();
|
|
active.dispose();
|
|
finish({ usage: 5 });
|
|
await task;
|
|
assert.deepEqual(active.results, []);
|
|
assert.equal(active.timers.size, 0);
|
|
});
|
|
|
|
test("a failed estimate preserves the last result and allows recovery", async () => {
|
|
let fail = false;
|
|
const refresh = setup(async () => {
|
|
if (fail) throw new Error("unavailable");
|
|
return { usage: 3 };
|
|
});
|
|
refresh.request();
|
|
await refresh.tick();
|
|
fail = true;
|
|
refresh.request();
|
|
await refresh.tick();
|
|
assert.deepEqual(refresh.results, [{ usage: 3 }]);
|
|
fail = false;
|
|
refresh.request();
|
|
await refresh.tick();
|
|
assert.equal(refresh.results.length, 2);
|
|
});
|