mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 10:15:07 +08:00
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:
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());
|
||||
Reference in new issue
Block a user