1'use strict'; 2const common = require('../common'); 3const tmpdir = require('../common/tmpdir'); 4const fs = require('fs'); 5const assert = require('assert'); 6const util = require('util'); 7const { join } = require('path'); 8const { spawnSync } = require('child_process'); 9 10// Test that --prof also tracks Worker threads. 11// Refs: https://github.com/nodejs/node/issues/24016 12 13if (process.argv[2] === 'child') { 14 const fs = require('fs'); 15 let files = fs.readdirSync(tmpdir.path); 16 const plog = files.filter((name) => /\.log$/.test(name))[0]; 17 if (plog === undefined) { 18 console.error('`--prof` did not produce a profile log for parent thread!'); 19 process.exit(1); 20 } 21 const pingpong = ` 22 let counter = 0; 23 const fs = require('fs'); 24 const { Worker, parentPort } = require('worker_threads'); 25 parentPort.on('message', (m) => { 26 if (counter++ === 10) 27 process.exit(0); 28 parentPort.postMessage( 29 fs.readFileSync(m.toString()).slice(0, 1024 * 1024)); 30 }); 31 `; 32 33 const { Worker } = require('worker_threads'); 34 const w = new Worker(pingpong, { eval: true }); 35 w.on('message', (m) => { 36 w.postMessage(process.execPath); 37 }); 38 39 w.on('exit', common.mustCall(() => { 40 files = fs.readdirSync(tmpdir.path); 41 const wlog = files.filter((name) => /\.log$/.test(name) && name !== plog)[0]; 42 if (wlog === undefined) { 43 console.error('`--prof` did not produce a profile log' + 44 ' for worker thread!'); 45 process.exit(1); 46 } 47 process.exit(0); 48 })); 49 w.postMessage(process.execPath); 50} else { 51 tmpdir.refresh(); 52 const spawnResult = spawnSync( 53 process.execPath, ['--prof', __filename, 'child'], 54 { cwd: tmpdir.path, encoding: 'utf8', timeout: 30_000 }); 55 assert.strictEqual(spawnResult.stderr.toString(), '', 56 `child exited with an error: \ 57 ${util.inspect(spawnResult)}`); 58 assert.strictEqual(spawnResult.signal, null, 59 `child exited with signal: ${util.inspect(spawnResult)}`); 60 assert.strictEqual(spawnResult.status, 0, 61 `child exited with non-zero status: \ 62 ${util.inspect(spawnResult)}`); 63 const files = fs.readdirSync(tmpdir.path); 64 const logfiles = files.filter((name) => /\.log$/.test(name)); 65 assert.strictEqual(logfiles.length, 2); // Parent thread + child thread. 66 67 for (const logfile of logfiles) { 68 const lines = fs.readFileSync( 69 join(tmpdir.path, logfile), 'utf8').split('\n'); 70 const ticks = lines.filter((line) => /^tick,/.test(line)).length; 71 72 // Test that at least 15 ticks have been recorded for both parent and child 73 // threads. When not tracking Worker threads, only 1 or 2 ticks would 74 // have been recorded. 75 // When running locally on x64 Linux, this number is usually at least 200 76 // for both threads, so 15 seems like a very safe threshold. 77 assert(ticks >= 15, `${ticks} >= 15`); 78 } 79} 80