1'use strict'; 2const common = require('../common'); 3const { isCPPSymbolsNotMapped } = require('./util'); 4const tmpdir = require('../common/tmpdir'); 5tmpdir.refresh(); 6 7if (!common.enoughTestCpu) 8 common.skip('test is CPU-intensive'); 9 10if (isCPPSymbolsNotMapped) { 11 common.skip('C++ symbols are not mapped for this OS.'); 12} 13 14// This test will produce a broken profile log. 15// ensure prof-polyfill not stuck in infinite loop 16// and success process 17 18 19const assert = require('assert'); 20const { spawn, spawnSync } = require('child_process'); 21const path = require('path'); 22const { writeFileSync } = require('fs'); 23 24const LOG_FILE = path.join(tmpdir.path, 'tick-processor.log'); 25const RETRY_TIMEOUT = 150; 26const BROKEN_PART = 'tick,'; 27const WARN_REG_EXP = /\(node:\d+\) \[BROKEN_PROFILE_FILE] Warning: Profile file .* is broken/; 28const WARN_DETAIL_REG_EXP = /".*tick," at the file end is broken/; 29 30const code = `function f() { 31 this.ts = Date.now(); 32 setImmediate(function() { new f(); }); 33 }; 34 f();`; 35 36const proc = spawn(process.execPath, [ 37 '--no_logfile_per_isolate', 38 '--logfile=-', 39 '--prof', 40 '-pe', code, 41], { 42 stdio: ['ignore', 'pipe', 'inherit'] 43}); 44 45let ticks = ''; 46proc.stdout.on('data', (chunk) => ticks += chunk); 47 48 49function runPolyfill(content) { 50 proc.kill(); 51 content += BROKEN_PART; 52 writeFileSync(LOG_FILE, content); 53 const child = spawnSync( 54 `${process.execPath}`, 55 [ 56 '--prof-process', LOG_FILE, 57 ]); 58 assert(WARN_REG_EXP.test(child.stderr.toString())); 59 assert(WARN_DETAIL_REG_EXP.test(child.stderr.toString())); 60 assert.strictEqual(child.status, 0); 61} 62 63setTimeout(() => runPolyfill(ticks), RETRY_TIMEOUT); 64