From 90426607a4e5e339fba0bd20be74a9eb3433d24f Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Sun, 19 Mar 2023 02:13:44 +0100 Subject: [PATCH] Add a way to print messages, and add a proper test for rate limiting --- tests/test.js | 71 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/tests/test.js b/tests/test.js index 31576e9..b10e41b 100644 --- a/tests/test.js +++ b/tests/test.js @@ -3,8 +3,12 @@ const { RateLimiter } = require("../generated/ratelimiter"); async function asyncRunTest(fn, ...args) { try { - await fn(...args); - console.log(`✅ ${fn.name}(${args})`) + let msg = await fn(...args); + if (msg) { + console.log(`✅ ${fn.name}(${args}): ${msg}`); + } else { + console.log(`✅ ${fn.name}(${args})`); + } } catch (ex) { console.log(`❌ ${fn.name}(${args})`) console.error(ex); @@ -13,14 +17,25 @@ async function asyncRunTest(fn, ...args) { } function runTest(fn, ...args) { try { - fn(...args); - console.log(`✅ ${fn.name}(${args})`); + let msg = fn(...args); + if (msg) { + console.log(`✅ ${fn.name}(${args}): ${msg}`); + } else { + console.log(`✅ ${fn.name}(${args})`); + } } catch (ex) { console.log(`❌ ${fn.name}(${args})`); console.error(ex); process.exitCode++; } } +async function delay(time) { + await new Promise((resolve, reject) => { + setTimeout(() => { + resolve(); + }, time); + }); +} function test_Construct(limit) { let rl = new RateLimiter(limit); @@ -43,6 +58,51 @@ async function test_TaskLimit(tasks, limit) { } } +async function test_LimitEnforcement(tasks, limit) { + let rl = new RateLimiter(limit); + let value = 0; + let time = 50; + + let records = []; + let t = setInterval(() => { + records.push([ + value, Date.now() + ]); + }, 25); + + let p = new Array(); + for (let idx = 0; idx < tasks; idx++) { + p.push(rl.queue(async () => { + await delay(time); + value++; + })); + } + await Promise.all(p); + + clearInterval(t); + + let totalTime = 0; + let totalValue = 0; + for (let n = 1; n < records.length; n++) { + let pRecord = records[n - 1]; + let cRecord = records[n]; + + let deltaTime = cRecord[1] - pRecord[1]; + let deltaValue = cRecord[0] - pRecord[0]; + + totalTime += deltaTime; + totalValue += deltaValue; + } + let averageChange = totalValue / totalTime; + let normalizedChange = averageChange * time; + // setTimeout loses accuracy over time, not sure what the solution is. Accepting +-1 for now. + if ((normalizedChange < (limit - 1.)) || (normalizedChange > (limit + 1.))) { + throw new Error(`Outside acceptable range (${normalizedChange} is not equal to ${limit}).`); + } else { + return `Within acceptable range (${normalizedChange} is roughly equal to ${limit}).` + } +} + (async function() { process.exitCode = 0; for (let limit = 1; limit <= 64; limit *= 2) { @@ -53,4 +113,7 @@ async function test_TaskLimit(tasks, limit) { await asyncRunTest(test_TaskLimit, tasks, limit); } } + for (let limit = 1; limit <= 10; limit++) { + await asyncRunTest(test_LimitEnforcement, 100, limit); + } })();