2020-08-25 19:36:37 +00:00
|
|
|
'use strict';
|
|
|
|
|
2020-10-14 19:57:43 +00:00
|
|
|
const { mustCall } = require('../common');
|
2020-08-25 19:36:37 +00:00
|
|
|
|
2020-10-14 19:57:43 +00:00
|
|
|
const TIMEOUT = 10;
|
|
|
|
const SPIN_DUR = 50;
|
2020-08-25 19:36:37 +00:00
|
|
|
|
|
|
|
const assert = require('assert');
|
|
|
|
const { performance } = require('perf_hooks');
|
|
|
|
const { Worker, parentPort } = require('worker_threads');
|
|
|
|
|
|
|
|
const { nodeTiming, eventLoopUtilization } = performance;
|
|
|
|
const elu = eventLoopUtilization();
|
|
|
|
|
|
|
|
// Take into account whether this test was started as a Worker.
|
|
|
|
if (nodeTiming.loopStart === -1) {
|
|
|
|
assert.strictEqual(nodeTiming.idleTime, 0);
|
|
|
|
assert.deepStrictEqual(elu, { idle: 0, active: 0, utilization: 0 });
|
|
|
|
assert.deepStrictEqual(eventLoopUtilization(elu),
|
|
|
|
{ idle: 0, active: 0, utilization: 0 });
|
|
|
|
assert.deepStrictEqual(eventLoopUtilization(elu, eventLoopUtilization()),
|
|
|
|
{ idle: 0, active: 0, utilization: 0 });
|
|
|
|
}
|
|
|
|
|
2020-11-05 13:11:44 +00:00
|
|
|
const nodeTimingProps = ['name', 'entryType', 'startTime', 'duration',
|
|
|
|
'nodeStart', 'v8Start', 'environment', 'loopStart',
|
|
|
|
'loopExit', 'bootstrapComplete', 'idleTime'];
|
|
|
|
for (const p of nodeTimingProps)
|
|
|
|
assert.ok(typeof JSON.parse(JSON.stringify(nodeTiming))[p] ===
|
|
|
|
typeof nodeTiming[p]);
|
|
|
|
|
2020-10-14 19:57:43 +00:00
|
|
|
setTimeout(mustCall(function r() {
|
2020-08-25 19:36:37 +00:00
|
|
|
const elu1 = eventLoopUtilization();
|
|
|
|
|
2020-10-14 19:57:43 +00:00
|
|
|
// Force idle time to accumulate before allowing test to continue.
|
|
|
|
if (elu1.idle <= 0)
|
|
|
|
return setTimeout(mustCall(r), 5);
|
|
|
|
|
2020-11-07 23:58:08 +00:00
|
|
|
const t = Date.now();
|
2022-02-03 06:35:32 +00:00
|
|
|
while (Date.now() - t < SPIN_DUR);
|
2020-08-25 19:36:37 +00:00
|
|
|
|
2020-11-07 23:58:08 +00:00
|
|
|
const elu2 = eventLoopUtilization(elu1);
|
|
|
|
const elu3 = eventLoopUtilization();
|
|
|
|
const elu4 = eventLoopUtilization(elu3, elu1);
|
2020-08-25 19:36:37 +00:00
|
|
|
|
2020-11-07 23:58:08 +00:00
|
|
|
assert.strictEqual(elu2.idle, 0);
|
2020-08-25 19:36:37 +00:00
|
|
|
assert.strictEqual(elu4.idle, 0);
|
2020-11-07 23:58:08 +00:00
|
|
|
assert.strictEqual(elu2.utilization, 1);
|
2020-08-25 19:36:37 +00:00
|
|
|
assert.strictEqual(elu4.utilization, 1);
|
2020-11-07 23:58:08 +00:00
|
|
|
assert.strictEqual(elu3.active - elu1.active, elu4.active);
|
|
|
|
assert.ok(elu2.active > SPIN_DUR - 10, `${elu2.active} <= ${SPIN_DUR - 10}`);
|
|
|
|
assert.ok(elu2.active < elu4.active, `${elu2.active} >= ${elu4.active}`);
|
|
|
|
assert.ok(elu3.active > elu2.active, `${elu3.active} <= ${elu2.active}`);
|
2020-10-14 19:57:43 +00:00
|
|
|
assert.ok(elu3.active > elu4.active, `${elu3.active} <= ${elu4.active}`);
|
2020-08-25 19:36:37 +00:00
|
|
|
|
2020-10-14 19:57:43 +00:00
|
|
|
setTimeout(mustCall(runIdleTimeTest), TIMEOUT);
|
|
|
|
}), 5);
|
2020-08-25 19:36:37 +00:00
|
|
|
|
|
|
|
function runIdleTimeTest() {
|
|
|
|
const idleTime = nodeTiming.idleTime;
|
|
|
|
const elu1 = eventLoopUtilization();
|
|
|
|
const sum = elu1.idle + elu1.active;
|
|
|
|
|
|
|
|
assert.ok(sum >= elu1.idle && sum >= elu1.active,
|
|
|
|
`idle: ${elu1.idle} active: ${elu1.active} sum: ${sum}`);
|
|
|
|
assert.strictEqual(elu1.idle, idleTime);
|
|
|
|
assert.strictEqual(elu1.utilization, elu1.active / sum);
|
|
|
|
|
2020-10-14 19:57:43 +00:00
|
|
|
setTimeout(mustCall(runCalcTest), TIMEOUT, elu1);
|
2020-08-25 19:36:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function runCalcTest(elu1) {
|
|
|
|
const now = performance.now();
|
|
|
|
const elu2 = eventLoopUtilization();
|
|
|
|
const elu3 = eventLoopUtilization(elu2, elu1);
|
|
|
|
const active_delta = elu2.active - elu1.active;
|
|
|
|
const idle_delta = elu2.idle - elu1.idle;
|
|
|
|
|
2020-10-14 19:57:43 +00:00
|
|
|
assert.ok(elu2.idle >= 0, `${elu2.idle} < 0`);
|
|
|
|
assert.ok(elu2.active >= 0, `${elu2.active} < 0`);
|
|
|
|
assert.ok(elu3.idle >= 0, `${elu3.idle} < 0`);
|
|
|
|
assert.ok(elu3.active >= 0, `${elu3.active} < 0`);
|
|
|
|
assert.ok(elu2.idle + elu2.active > elu1.idle + elu1.active,
|
|
|
|
`${elu2.idle + elu2.active} <= ${elu1.idle + elu1.active}`);
|
|
|
|
assert.ok(elu2.idle + elu2.active >= now - nodeTiming.loopStart,
|
|
|
|
`${elu2.idle + elu2.active} < ${now - nodeTiming.loopStart}`);
|
2020-08-25 19:36:37 +00:00
|
|
|
assert.strictEqual(elu3.active, elu2.active - elu1.active);
|
|
|
|
assert.strictEqual(elu3.idle, elu2.idle - elu1.idle);
|
|
|
|
assert.strictEqual(elu3.utilization,
|
|
|
|
active_delta / (idle_delta + active_delta));
|
|
|
|
|
2020-10-14 19:57:43 +00:00
|
|
|
setImmediate(mustCall(runWorkerTest));
|
2020-08-25 19:36:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function runWorkerTest() {
|
|
|
|
// Use argv to detect whether we're running as a Worker called by this test
|
|
|
|
// vs. this test also being called as a Worker.
|
|
|
|
if (process.argv[2] === 'iamalive') {
|
|
|
|
parentPort.postMessage(JSON.stringify(eventLoopUtilization()));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const elu1 = eventLoopUtilization();
|
|
|
|
const worker = new Worker(__filename, { argv: [ 'iamalive' ] });
|
|
|
|
|
2020-10-14 19:57:43 +00:00
|
|
|
worker.on('message', mustCall((msg) => {
|
2020-08-25 19:36:37 +00:00
|
|
|
const elu2 = eventLoopUtilization(elu1);
|
|
|
|
const data = JSON.parse(msg);
|
|
|
|
|
2020-10-14 19:57:43 +00:00
|
|
|
assert.ok(elu2.active + elu2.idle > data.active + data.idle,
|
|
|
|
`${elu2.active + elu2.idle} <= ${data.active + data.idle}`);
|
|
|
|
}));
|
2020-08-25 19:36:37 +00:00
|
|
|
}
|