node/test/parallel/test-process-threadCpuUsage-worker-threads.js
Paolo Insogna e027791c6d
process: add threadCpuUsage
PR-URL: https://github.com/nodejs/node/pull/56467
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2025-02-21 14:14:02 +00:00

92 lines
2.6 KiB
JavaScript

'use strict';
const { mustCall, platformTimeout, hasCrypto, skip, isSunOS } = require('../common');
if (!hasCrypto) {
skip('missing crypto');
};
// This block can be removed once SmartOS support is fixed in
// https://github.com/libuv/libuv/issues/4706
// The behavior on SunOS is tested in
// test/parallel/test-process-threadCpuUsage-main-thread.js
if (isSunOS) {
skip('Operation not supported yet on SmartOS');
}
const { ok } = require('assert');
const { randomBytes, createHash } = require('crypto');
const { once } = require('events');
const { Worker, parentPort, workerData } = require('worker_threads');
const FREQUENCIES = [100, 500, 1000];
function performLoad() {
const buffer = randomBytes(1e8);
// Do some work
return setInterval(() => {
createHash('sha256').update(buffer).end(buffer);
}, platformTimeout(workerData?.frequency ?? 100));
}
function getUsages() {
return { process: process.cpuUsage(), thread: process.threadCpuUsage() };
}
function validateResults(results) {
// This test should have checked that the CPU usage of each thread is greater
// than the previous one, while the process one was not.
// Unfortunately, the real values are not really predictable on the CI so we
// just check that all the values are positive numbers.
for (let i = 0; i < 3; i++) {
ok(typeof results[i].process.user === 'number');
ok(results[i].process.user >= 0);
ok(typeof results[i].process.system === 'number');
ok(results[i].process.system >= 0);
ok(typeof results[i].thread.user === 'number');
ok(results[i].thread.user >= 0);
ok(typeof results[i].thread.system === 'number');
ok(results[i].thread.system >= 0);
}
}
// The main thread will spawn three more threads, then after a while it will ask all of them to
// report the thread CPU usage and exit.
if (!workerData?.frequency) { // Do not use isMainThread here otherwise test will not run in --worker mode
const workers = [];
for (const frequency of FREQUENCIES) {
workers.push(new Worker(__filename, { workerData: { frequency } }));
}
setTimeout(mustCall(async () => {
clearInterval(interval);
const results = [getUsages()];
for (const worker of workers) {
const statusPromise = once(worker, 'message');
worker.postMessage('done');
const [status] = await statusPromise;
results.push(status);
worker.terminate();
}
validateResults(results);
}), platformTimeout(5000));
} else {
parentPort.on('message', () => {
clearInterval(interval);
parentPort.postMessage(getUsages());
process.exit(0);
});
}
// Perform load on each thread
const interval = performLoad();