'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();