Coalesce quota refreshes and consolidate shared helpers
Some checks failed
Deploy Sokko G / deploy (push) Failing after 2s
Some checks failed
Deploy Sokko G / deploy (push) Failing after 2s
This commit is contained in:
parent
a4cf633ab4
commit
748415082b
19 changed files with 216 additions and 64 deletions
90
tests/quota-refresh.test.mjs
Normal file
90
tests/quota-refresh.test.mjs
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
// 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);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue