test: expand histogram test coverage

Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode
PR-URL: https://github.com/nodejs/node/pull/65825
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
James M Snell committed 2026-09-14 16:12:38 +00:00
1 parent c327212373
commit c1e2478bcd
4 files changed
+120

No files matched your search

@@ -0,0 +1,21 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { once } = require('events');
const { Worker } = require('worker_threads');
const worker = new Worker(`
const { parentPort } = require('worker_threads');
const { createHistogram } = require('perf_hooks');
const histogram = createHistogram({ highest: 200000, figures: 5 });
for (let i = 1; i <= 100000; i++) histogram.record(i);
histogram.qrde({ bins: 1000, dequantize: 'all' });
parentPort.postMessage('scheduled');
`, { eval: true });
(async () => {
assert.deepStrictEqual(await once(worker, 'message'), ['scheduled']);
assert.strictEqual(await worker.terminate(), 1);
})().then(common.mustCall());
@@ -9,6 +9,16 @@ function assertClose(actual, expected, tolerance = 1e-12) {
`${actual} != ${expected}`);
}
function recordRepeated(histogram, options, value, count) {
const block = createHistogram(options);
block.record(value);
while (count > 0) {
if (count % 2 === 1) histogram.add(block);
count = Math.floor(count / 2);
if (count > 0) block.add(block);
}
}
(async () => {
const empty = createHistogram();
const emptyResult = await empty.qrde();
@@ -23,6 +33,9 @@ function assertClose(actual, expected, tolerance = 1e-12) {
assert.strictEqual(emptyResult.corrections, 0);
assert.strictEqual(emptyResult.dequantize, 'hdr');
assert.throws(() => empty.qrde.call({}), {
code: 'ERR_INVALID_THIS',
});
assert.throws(() => empty.qrde(null), {
code: 'ERR_INVALID_ARG_TYPE',
});
@@ -219,4 +232,18 @@ function assertClose(actual, expected, tolerance = 1e-12) {
await largeCount.qrde({ bins: 2, dequantize: 'none' });
assert.strictEqual(largeCountResult.count, (1n << 53n) + 1n);
assertClose(largeCountResult.quantiles[1], 2);
// Exercise correction across the exact-to-asymptotic beta CDF threshold.
const correctionOptions = { highest: 131071, figures: 5 };
const correction = createHistogram(correctionOptions);
recordRepeated(correction, correctionOptions, 1, 26239);
recordRepeated(correction, correctionOptions, 131071, 973761);
const count = 1_000_000;
const threshold = (1 - Math.sqrt(1 - 100_000 / (count + 1))) / 2;
const corrected = await correction.qrde({
probabilities: [0, threshold - 1e-10, threshold + 1e-10, 1],
dequantize: 'none',
});
assert.strictEqual(corrected.corrections, 1);
assert.strictEqual(corrected.quantiles[1], corrected.quantiles[2]);
})().then(common.mustCall());
@@ -49,6 +49,11 @@ const {
assert.strictEqual(histogram.snapshot().count, 0);
histogram.record(10n);
assert.strictEqual(histogram.snapshot().maxBigInt, 10n);
for (const value of [0n, 2n ** 63n]) {
assert.throws(() => histogram.record(value), {
code: 'ERR_OUT_OF_RANGE',
});
}
assert.throws(() => new histogram.constructor(), {
code: 'ERR_ILLEGAL_CONSTRUCTOR',
@@ -142,6 +147,19 @@ const {
highest: 10,
}), { code: 'ERR_OUT_OF_RANGE' });
for (const [name, value] of [
['lowest', 0n],
['lowest', 2n ** 63n],
['highest', 0n],
['highest', 2n ** 63n],
]) {
assert.throws(() => createSlidingWindowHistogram({
chunks: 2,
recordsPerChunk: 1,
[name]: value,
}), { code: 'ERR_OUT_OF_RANGE' });
}
for (const bounds of [
{ lowest: 1n },
{ lowest: 1n, highest: 100 },
@@ -0,0 +1,54 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const {
createJSHeapSnapshot,
validateByRetainingPathFromNodes,
} = require('../common/heap');
const {
createHistogram,
createSlidingWindowHistogram,
} = require('perf_hooks');
(async () => {
const uncached = createHistogram();
const cached = createHistogram();
cached.record(1);
cached.record(1000);
await cached.qrde({ cache: true });
const sliding = createSlidingWindowHistogram({
chunks: 2,
recordsPerChunk: 1,
});
const nodes = createJSHeapSnapshot();
const snapshots = validateByRetainingPathFromNodes(
nodes,
'Node / Histogram',
[{ node_name: 'Node / qrde_snapshot', edge_name: 'qrde_snapshot' }],
);
assert.strictEqual(snapshots.length, 1);
assert.ok(snapshots[0].self_size > 0);
const windows = validateByRetainingPathFromNodes(
nodes,
'Node / SlidingWindowHistogram',
[],
);
for (const [edgeName, nodeName] of [
['chunks', 'Node / chunks'],
['generations', 'Node / generations'],
['spare', 'Node / Histogram'],
]) {
validateByRetainingPathFromNodes(windows, 'Node / SlidingWindowHistogram', [
{ node_name: nodeName, edge_name: edgeName },
]);
}
// Keep all three wrappers live through snapshot generation.
assert.strictEqual(uncached.count, 0);
assert.strictEqual(cached.count, 2);
assert.strictEqual(sliding.snapshot().count, 0);
})().then(common.mustCall());