Skip to content

Commit

Permalink
Improve CslGc test
Browse files Browse the repository at this point in the history
  • Loading branch information
marcusbfs committed Jan 30, 2025
1 parent fec96d2 commit b65e55e
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 12 deletions.
76 changes: 64 additions & 12 deletions test/CslGc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,79 @@ import * as lib from "@mlabs-haskell/cardano-data-lite";

import process from "process";

export const testExternalMemLeakImpl = config => async () => {
export const testExternalMemLeakImpl = (config) => async () => {
const debug = false;

const debugLog = (...args) => {
if (debug) {
console.log(...args);
}
};

const {
numIterations,
refIteration,
smoothingWindowSize,
maxError,
delay,
numArrays,
arrSize
} = config;

if (refIteration >= numIterations) {
throw new Error("refIteration must be less than numIterations.");
}

let externalMemUpperBound = null;
let referenceExternalMem = null;

const lastMeasurements = [];

for (let i = 0; i < config.numIterations; i++) {
// console.log(`\nIteration ${i}`);
for (let i = 0; i < numIterations; i++) {
debugLog(`\n--- Iteration ${i} ---`);

for (let j = 0; j < config.numArrays; j++) {
let bytes = new Uint8Array(Array(config.arrSize).fill(0));
for (let j = 0; j < numArrays; j++) {
const bytes = new Uint8Array(Array(arrSize).fill(0));
lib.PlutusData.new_bytes(bytes);
}

await new Promise(r => setTimeout(r, config.delay));
await new Promise(resolve => setTimeout(resolve, delay));

const memUsage = process.memoryUsage();
// console.log(memUsage);
const currentExternalMem = process.memoryUsage().external;
lastMeasurements.push(currentExternalMem);

if (i == config.refIteration) {
externalMemUpperBound = memUsage.external * (1 + config.maxError / 100);
if (lastMeasurements.length > smoothingWindowSize) {
lastMeasurements.shift();
}
if (i > config.refIteration && memUsage.external > externalMemUpperBound) {
throw new Error("External memory leak detected.");

const avgExternalMem = lastMeasurements.reduce((a, b) => a + b, 0) / lastMeasurements.length;

debugLog(`Current external memory: ${currentExternalMem}`);
debugLog(`Rolling average external memory: ${avgExternalMem}`);

if (i === refIteration) {
referenceExternalMem = avgExternalMem;
externalMemUpperBound = referenceExternalMem * (1 + maxError / 100);
debugLog(
`\nReference external memory set at iteration ${i}: ${referenceExternalMem}\n` +
`Upper bound set to: ${externalMemUpperBound} (maxError ${maxError}%)`
);
}

if (referenceExternalMem !== null && i > refIteration) {
if (avgExternalMem > externalMemUpperBound) {
console.error(
`\n=== Potential Memory Leak Detected ===\n` +
`Iteration: ${i}\n` +
`Rolling average external usage (${avgExternalMem}) exceeded upper bound (${externalMemUpperBound}).`
);
throw new Error("External memory leak detected.");
} else {
debugLog(`Iteration ${i} within acceptable bounds.`);
}
}
}

debugLog(`\nAll ${numIterations} iterations completed without detecting a leak.`);
};

2 changes: 2 additions & 0 deletions test/CslGc.purs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ suite =
testExternalMemLeak
{ numIterations: 15
, refIteration: 5
, smoothingWindowSize: 3
, maxError: 50
, delay: 1200
, numArrays: 20
Expand All @@ -29,6 +30,7 @@ suite =
type CslGcTestConfig =
{ numIterations :: Int
, refIteration :: Int
, smoothingWindowSize :: Int
, maxError :: Int -- percent
, delay :: Int -- msec
, numArrays :: Int
Expand Down

0 comments on commit b65e55e

Please sign in to comment.