2022-02-18 20:23:47 +00:00
|
|
|
import { execa } from 'execa';
|
|
|
|
import { fileURLToPath } from 'url';
|
|
|
|
import v8 from 'v8';
|
|
|
|
import dev from '../../packages/astro/dist/core/dev/index.js';
|
|
|
|
import { loadConfig } from '../../packages/astro/dist/core/config.js';
|
|
|
|
import prettyBytes from 'pretty-bytes';
|
|
|
|
|
|
|
|
/** URL directory containing the entire project. */
|
|
|
|
const projDir = new URL('./project/', import.meta.url);
|
|
|
|
|
|
|
|
function mean(numbers) {
|
2022-02-18 20:24:55 +00:00
|
|
|
var total = 0,
|
|
|
|
i;
|
2022-02-18 20:23:47 +00:00
|
|
|
for (i = 0; i < numbers.length; i += 1) {
|
2022-02-18 20:24:55 +00:00
|
|
|
total += numbers[i];
|
2022-02-18 20:23:47 +00:00
|
|
|
}
|
|
|
|
return total / numbers.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
function median(numbers) {
|
|
|
|
// median of [3, 5, 4, 4, 1, 1, 2, 3] = 3
|
2022-02-18 20:24:55 +00:00
|
|
|
var median = 0,
|
|
|
|
numsLen = numbers.length;
|
2022-02-18 20:23:47 +00:00
|
|
|
numbers.sort();
|
|
|
|
|
|
|
|
if (
|
2022-02-18 20:24:55 +00:00
|
|
|
numsLen % 2 ===
|
|
|
|
0 // is even
|
2022-02-18 20:23:47 +00:00
|
|
|
) {
|
2022-02-18 20:24:55 +00:00
|
|
|
// average of two middle numbers
|
|
|
|
median = (numbers[numsLen / 2 - 1] + numbers[numsLen / 2]) / 2;
|
|
|
|
} else {
|
|
|
|
// is odd
|
|
|
|
// middle number only
|
|
|
|
median = numbers[(numsLen - 1) / 2];
|
2022-02-18 20:23:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return median;
|
|
|
|
}
|
|
|
|
|
|
|
|
let config = await loadConfig({
|
2022-02-18 20:24:55 +00:00
|
|
|
cwd: fileURLToPath(projDir),
|
2022-02-18 20:23:47 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
config.buildOptions.experimentalStaticBuild = true;
|
|
|
|
|
2022-02-18 20:24:55 +00:00
|
|
|
const server = await dev(config, { logging: 'error' });
|
2022-02-18 20:23:47 +00:00
|
|
|
|
|
|
|
// Prime the server so initial memory is created
|
|
|
|
await fetch(`http://localhost:3000/page-0`);
|
|
|
|
|
|
|
|
const sizes = [];
|
|
|
|
|
|
|
|
function addSize() {
|
|
|
|
sizes.push(v8.getHeapStatistics().total_heap_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function run() {
|
|
|
|
addSize();
|
2022-02-18 20:24:55 +00:00
|
|
|
for (let i = 0; i < 100; i++) {
|
2022-02-18 20:23:47 +00:00
|
|
|
let path = `/page-${i}`;
|
|
|
|
await fetch(`http://localhost:3000${path}`);
|
|
|
|
}
|
|
|
|
addSize();
|
|
|
|
}
|
|
|
|
|
2022-02-18 20:24:55 +00:00
|
|
|
for (let i = 0; i < 100; i++) {
|
2022-02-18 20:23:47 +00:00
|
|
|
await run();
|
|
|
|
}
|
|
|
|
|
|
|
|
let lastThirthy = sizes.slice(sizes.length - 30);
|
|
|
|
let averageOfLastThirty = mean(lastThirthy);
|
|
|
|
let medianOfAll = median(sizes);
|
|
|
|
|
|
|
|
// If the trailing average is higher than the median, see if it's more than 5% higher
|
2022-02-18 20:24:55 +00:00
|
|
|
if (averageOfLastThirty > medianOfAll) {
|
2022-02-18 20:23:47 +00:00
|
|
|
let percentage = Math.abs(averageOfLastThirty - medianOfAll) / medianOfAll;
|
2022-02-18 22:06:56 +00:00
|
|
|
if (percentage > 0.1) {
|
2022-02-18 20:24:55 +00:00
|
|
|
throw new Error(
|
2022-02-18 22:06:56 +00:00
|
|
|
`The average towards the end (${prettyBytes(averageOfLastThirty)}) is more than 10% higher than the median of all runs (${prettyBytes(
|
2022-02-18 20:24:55 +00:00
|
|
|
medianOfAll
|
|
|
|
)}). This tells us that memory continues to grow and a leak is likely.`
|
|
|
|
);
|
2022-02-18 20:23:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
await server.stop();
|