'use strict'; const common = require('../common'); const tmpdir = require('../common/tmpdir'); const fs = require('fs'); const assert = require('assert'); const util = require('util'); const { join } = require('path'); const { spawnSync } = require('child_process'); // Test that --prof also tracks Worker threads. // Refs: https://github.com/nodejs/node/issues/24016 if (process.argv[2] === 'child') { let files = fs.readdirSync(tmpdir.path); const plog = files.filter((name) => /\.log$/.test(name))[0]; if (plog === undefined) { console.error('`--prof` did not produce a profile log for parent thread!'); process.exit(1); } const pingpong = ` let counter = 0; const { Worker, parentPort } = require('worker_threads'); parentPort.on('message', (m) => { if (counter++ === 1024) process.exit(0); parentPort.postMessage( m.toString().split('').reverse().toString().replace(/,/g, '')); }); `; const { Worker } = require('worker_threads'); const data = 'x'.repeat(1024); const w = new Worker(pingpong, { eval: true }); w.on('message', (m) => { w.postMessage(m.toString().split('').reverse().toString().replace(/,/g, '')); }); w.on('exit', common.mustCall(() => { files = fs.readdirSync(tmpdir.path); const wlog = files.filter((name) => /\.log$/.test(name) && name !== plog)[0]; if (wlog === undefined) { console.error('`--prof` did not produce a profile log' + ' for worker thread!'); process.exit(1); } process.exit(0); })); w.postMessage(data); } else { tmpdir.refresh(); const spawnResult = spawnSync( process.execPath, ['--prof', __filename, 'child'], { cwd: tmpdir.path, encoding: 'utf8', timeout: 30_000 }); assert.strictEqual(spawnResult.stderr.toString(), '', `child exited with an error: \ ${util.inspect(spawnResult)}`); assert.strictEqual(spawnResult.signal, null, `child exited with signal: ${util.inspect(spawnResult)}`); assert.strictEqual(spawnResult.status, 0, `child exited with non-zero status: \ ${util.inspect(spawnResult)}`); const files = fs.readdirSync(tmpdir.path); const logfiles = files.filter((name) => /\.log$/.test(name)); assert.strictEqual(logfiles.length, 2); // Parent thread + child thread. for (const logfile of logfiles) { const lines = fs.readFileSync( join(tmpdir.path, logfile), 'utf8').split('\n'); const ticks = lines.filter((line) => /^tick,/.test(line)).length; // Test that at least 15 ticks have been recorded for both parent and child // threads. When not tracking Worker threads, only 1 or 2 ticks would // have been recorded. // When running locally on x64 Linux, this number is usually at least 200 // for both threads, so 15 seems like a very safe threshold. assert(ticks >= 15, `${ticks} >= 15`); } }