-
Notifications
You must be signed in to change notification settings - Fork 30.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6f946c9
commit 5b09f78
Showing
8 changed files
with
269 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
'use strict'; | ||
|
||
require('../common'); | ||
|
||
const { ok, throws, notStrictEqual } = require('assert'); | ||
|
||
function validateResult(result) { | ||
notStrictEqual(result, null); | ||
|
||
ok(Number.isFinite(result.user)); | ||
ok(Number.isFinite(result.system)); | ||
|
||
ok(result.user >= 0); | ||
ok(result.system >= 0); | ||
} | ||
|
||
// Test that process.threadCpuUsage() works on the main thread | ||
{ | ||
const result = process.threadCpuUsage(); | ||
|
||
// Validate the result of calling with no previous value argument. | ||
validateResult(process.threadCpuUsage()); | ||
|
||
// Validate the result of calling with a previous value argument. | ||
validateResult(process.threadCpuUsage(result)); | ||
|
||
// Ensure the results are >= the previous. | ||
let thisUsage; | ||
let lastUsage = process.threadCpuUsage(); | ||
for (let i = 0; i < 10; i++) { | ||
thisUsage = process.threadCpuUsage(); | ||
validateResult(thisUsage); | ||
ok(thisUsage.user >= lastUsage.user); | ||
ok(thisUsage.system >= lastUsage.system); | ||
lastUsage = thisUsage; | ||
} | ||
} | ||
|
||
// Test argument validaton | ||
{ | ||
throws( | ||
() => process.threadCpuUsage(123), | ||
{ | ||
code: 'ERR_INVALID_ARG_TYPE', | ||
name: 'TypeError', | ||
message: 'The "prevValue" argument must be of type object. Received type number (123)' | ||
} | ||
); | ||
|
||
throws( | ||
() => process.threadCpuUsage([]), | ||
{ | ||
code: 'ERR_INVALID_ARG_TYPE', | ||
name: 'TypeError', | ||
message: 'The "prevValue" argument must be of type object. Received an instance of Array' | ||
} | ||
); | ||
|
||
throws( | ||
() => process.threadCpuUsage({ user: -123 }), | ||
{ | ||
code: 'ERR_INVALID_ARG_VALUE', | ||
name: 'RangeError', | ||
message: "The property 'prevValue.user' is invalid. Received -123" | ||
} | ||
); | ||
|
||
throws( | ||
() => process.threadCpuUsage({ user: 0, system: 'bar' }), | ||
{ | ||
code: 'ERR_INVALID_ARG_TYPE', | ||
name: 'TypeError', | ||
message: "The \"prevValue.system\" property must be of type number. Received type string ('bar')" | ||
} | ||
); | ||
} |
89 changes: 89 additions & 0 deletions
89
test/parallel/test-process-threadCpuUsage-worker-threads.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
'use strict'; | ||
|
||
const { mustCall, platformTimeout, hasCrypto, skip } = require('../common'); | ||
const { ok, deepStrictEqual } = require('assert'); | ||
const { randomBytes, createHash } = require('crypto'); | ||
const { once } = require('events'); | ||
const { Worker, isMainThread, parentPort, threadId } = require('worker_threads'); | ||
|
||
if (!hasCrypto) { | ||
skip('missing crypto'); | ||
}; | ||
|
||
function performLoad() { | ||
const buffer = randomBytes(1e8); | ||
const index = threadId + 1; | ||
|
||
// Do some work | ||
return setInterval(() => { | ||
createHash('sha256').update(buffer).end(buffer); | ||
}, platformTimeout(index ** 2 * 100)); | ||
} | ||
|
||
function getUsages() { | ||
return { threadId, process: process.cpuUsage(), thread: process.threadCpuUsage() }; | ||
} | ||
|
||
function validateResults(results) { | ||
for (let i = 0; i < 4; i++) { | ||
deepStrictEqual(results[i].threadId, i); | ||
} | ||
|
||
for (let i = 0; i < 3; i++) { | ||
const processDifference = results[i].process.user / results[i + 1].process.user; | ||
const threadDifference = results[i].thread.user / results[i + 1].thread.user; | ||
|
||
// | ||
// All process CPU usages should be the same. Technically they should have returned the same | ||
// value but since we measure it at different times they vary a little bit. | ||
// Let's allow a tolerance of 20% | ||
// | ||
ok(processDifference > 0.8); | ||
ok(processDifference < 1.2); | ||
|
||
// | ||
// Each thread is configured so that the performLoad schedules a new hash with an interval two times bigger of the | ||
// previous thread. In theory this should give each thread a load about half of the previous one. | ||
// But since we can't really predict CPU scheduling, we just check a monotonic increasing sequence. | ||
// | ||
ok(threadDifference > 1.2); | ||
Check failure on line 49 in test/parallel/test-process-threadCpuUsage-worker-threads.js GitHub Actions / test-macOS (macos-13)
|
||
} | ||
} | ||
|
||
|
||
// 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 (isMainThread) { | ||
const workers = []; | ||
for (let i = 0; i < 3; i++) { | ||
workers.push(new Worker(__filename)); | ||
} | ||
|
||
setTimeout(mustCall(async () => { | ||
clearInterval(interval); | ||
|
||
const results = [getUsages()]; | ||
|
||
for (const worker of workers) { | ||
const statusPromise = once(worker, 'message'); | ||
const exitPromise = once(worker, 'exit'); | ||
|
||
worker.postMessage('done'); | ||
const [status] = await statusPromise; | ||
results.push(status); | ||
await exitPromise; | ||
} | ||
|
||
validateResults(results); | ||
}), platformTimeout(5000)); | ||
|
||
} else { | ||
parentPort.on('message', () => { | ||
clearInterval(interval); | ||
parentPort.postMessage(getUsages()); | ||
process.exit(0); | ||
}); | ||
} | ||
|
||
// Perform load on each thread | ||
const interval = performLoad(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
interface CpuUsageValue { | ||
user: number; | ||
system: number; | ||
} | ||
|
||
declare namespace InternalProcessBinding { | ||
interface Process { | ||
cpuUsage(previousValue?: CpuUsageValue): CpuUsageValue; | ||
threadCpuUsage(previousValue?: CpuUsageValue): CpuUsageValue; | ||
} | ||
} | ||
|
||
export interface ProcessBinding { | ||
process: InternalProcessBinding.Process; | ||
} |