Browse Source

test: make test-tick-processor.js non-flaky

Wait for a sought-for symbol to appear instead of just hard-killing
subprocesses at 2s timeout.

Fix: #4427
PR-URL: https://github.com/nodejs/node/pull/8542
Reviewed-By: Rich Trott <rtrott@gmail.com>
v6.x
Fedor Indutny 9 years ago
committed by Jeremiah Senkpiel
parent
commit
82b7894d3b
  1. 56
      test/fixtures/tick-processor-base.js
  2. 6
      test/parallel/parallel.status
  3. 33
      test/parallel/test-tick-processor-builtin.js
  4. 33
      test/parallel/test-tick-processor-cpp-core.js
  5. 28
      test/parallel/test-tick-processor-unknown.js
  6. 66
      test/parallel/test-tick-processor.js

56
test/fixtures/tick-processor-base.js

@ -0,0 +1,56 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const cp = require('child_process');
const path = require('path');
common.refreshTmpDir();
const LOG_FILE = path.join(common.tmpDir, 'tick-processor.log');
const RETRY_TIMEOUT = 750;
function runTest(test) {
const proc = cp.spawn(process.execPath, [
'--no_logfile_per_isolate',
'--logfile=-',
'--prof',
'-pe', test.code
], {
stdio: [ null, 'pipe', 'inherit' ]
});
let ticks = '';
proc.stdout.on('data', chunk => ticks += chunk);
// Try to match after timeout
setTimeout(() => {
match(test.pattern, proc, () => ticks);
}, RETRY_TIMEOUT);
}
function match(pattern, parent, ticks) {
// Store current ticks log
fs.writeFileSync(LOG_FILE, ticks());
const proc = cp.spawn(process.execPath, [
'--prof-process',
'--call-graph-size=10',
LOG_FILE
], {
stdio: [ null, 'pipe', 'inherit' ]
});
let out = '';
proc.stdout.on('data', chunk => out += chunk);
proc.stdout.on('end', () => {
// Retry after timeout
if (!pattern.test(out))
return setTimeout(() => match(pattern, parent, ticks), RETRY_TIMEOUT);
parent.kill('SIGTERM');
fs.unlinkSync(LOG_FILE);
});
}
exports.runTest = runTest;

6
test/parallel/parallel.status

@ -7,13 +7,17 @@ prefix parallel
[true] # This section applies to all platforms [true] # This section applies to all platforms
[$system==win32] [$system==win32]
test-tick-processor : PASS,FLAKY
[$system==linux] [$system==linux]
test-tick-processor : PASS,FLAKY test-tick-processor : PASS,FLAKY
[$system==macos] [$system==macos]
[$arch==arm || $arch==arm64]
test-tick-processor-builtin : PASS,FLAKY
test-tick-processor-cpp-core : PASS,FLAKY
test-tick-processor-unknown : PASS,FLAKY
[$system==solaris] # Also applies to SmartOS [$system==solaris] # Also applies to SmartOS
test-debug-signal-cluster : PASS,FLAKY test-debug-signal-cluster : PASS,FLAKY

33
test/parallel/test-tick-processor-builtin.js

@ -0,0 +1,33 @@
'use strict';
const common = require('../common');
const path = require('path');
// TODO(mhdawson) Currently the test-tick-processor functionality in V8
// depends on addresses being smaller than a full 64 bits. Aix supports
// the full 64 bits and the result is that it does not process the
// addresses correctly and runs out of memory
// Disabling until we get a fix upstreamed into V8
if (common.isAix) {
common.skip('Aix address range too big for scripts.');
return;
}
const base = require(path.join(common.fixturesDir, 'tick-processor-base.js'));
if (common.isWindows ||
common.isSunOS ||
common.isAix ||
common.isLinuxPPCBE ||
common.isFreeBSD) {
common.skip('C++ symbols are not mapped for this os.');
return;
}
base.runTest({
pattern: /Builtin_DateNow/,
code: `function f() {
this.ts = Date.now();
setImmediate(function() { new f(); });
};
f();`
});

33
test/parallel/test-tick-processor-cpp-core.js

@ -0,0 +1,33 @@
'use strict';
const common = require('../common');
const path = require('path');
// TODO(mhdawson) Currently the test-tick-processor functionality in V8
// depends on addresses being smaller than a full 64 bits. Aix supports
// the full 64 bits and the result is that it does not process the
// addresses correctly and runs out of memory
// Disabling until we get a fix upstreamed into V8
if (common.isAix) {
common.skip('Aix address range too big for scripts.');
return;
}
const base = require(path.join(common.fixturesDir, 'tick-processor-base.js'));
if (common.isWindows ||
common.isSunOS ||
common.isAix ||
common.isLinuxPPCBE ||
common.isFreeBSD) {
common.skip('C++ symbols are not mapped for this os.');
return;
}
base.runTest({
pattern: /RunInDebugContext/,
code: `function f() {
require(\'vm\').runInDebugContext(\'Debug\');
setImmediate(function() { f(); });
};
f();`
});

28
test/parallel/test-tick-processor-unknown.js

@ -0,0 +1,28 @@
'use strict';
const common = require('../common');
const path = require('path');
// TODO(mhdawson) Currently the test-tick-processor functionality in V8
// depends on addresses being smaller than a full 64 bits. Aix supports
// the full 64 bits and the result is that it does not process the
// addresses correctly and runs out of memory
// Disabling until we get a fix upstreamed into V8
if (common.isAix) {
common.skip('Aix address range too big for scripts.');
return;
}
const base = require(path.join(common.fixturesDir, 'tick-processor-base.js'));
// Unknown checked for to prevent flakiness, if pattern is not found,
// then a large number of unknown ticks should be present
base.runTest({
pattern: /LazyCompile.*\[eval\]:1|.*% UNKNOWN/,
code: `function f() {
for (var i = 0; i < 1000000; i++) {
i++;
}
setImmediate(function() { f(); });
};
f();`
});

66
test/parallel/test-tick-processor.js

@ -1,66 +0,0 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const assert = require('assert');
const cp = require('child_process');
// TODO(mhdawson) Currently the test-tick-processor functionality in V8
// depends on addresses being smaller than a full 64 bits. Aix supports
// the full 64 bits and the result is that it does not process the
// addresses correctly and runs out of memory
// Disabling until we get a fix upstreamed into V8
if (common.isAix) {
common.skip('Aix address range too big for scripts.');
return;
}
common.refreshTmpDir();
process.chdir(common.tmpDir);
// Unknown checked for to prevent flakiness, if pattern is not found,
// then a large number of unknown ticks should be present
runTest(/LazyCompile.*\[eval\]:1|.*% UNKNOWN/,
`function f() {
for (var i = 0; i < 1000000; i++) {
i++;
}
setImmediate(function() { f(); });
};
setTimeout(function() { process.exit(0); }, 2000);
f();`);
if (common.isWindows ||
common.isSunOS ||
common.isAix ||
common.isLinuxPPCBE ||
common.isFreeBSD) {
common.skip('C++ symbols are not mapped for this os.');
return;
}
runTest(/RunInDebugContext/,
`function f() {
require(\'vm\').runInDebugContext(\'Debug\');
setImmediate(function() { f(); });
};
setTimeout(function() { process.exit(0); }, 2000);
f();`);
runTest(/Builtin_DateNow/,
`function f() {
this.ts = Date.now();
setImmediate(function() { new f(); });
};
setTimeout(function() { process.exit(0); }, 2000);
f();`);
function runTest(pattern, code) {
cp.execFileSync(process.execPath, ['-prof', '-pe', code]);
var matches = fs.readdirSync(common.tmpDir);
assert.strictEqual(matches.length, 1, 'There should be a single log file.');
var log = matches[0];
var out = cp.execSync(process.execPath +
' --prof-process --call-graph-size=10 ' + log,
{encoding: 'utf8'});
assert(pattern.test(out), `${pattern} not matching ${out}`);
fs.unlinkSync(log);
}
Loading…
Cancel
Save