-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: skip less scenarios for test-linux-perf.js #27364
Conversation
This comment has been minimized.
This comment has been minimized.
These changes should suffice, thank you for looking into this!
The failing test is caused by #27346, which will be fixed once we pick v8/v8@d915b8d (I requested a upstream backport to 7.4, waiting for response. If backport upstream is not possible, I'll cherry-pick and open a PR). Not sure if we should wait until the issue is fixed on master before landing this PR, since it's exposing a legitimate failure. |
This comment has been minimized.
This comment has been minimized.
1d512ee
to
51eb65a
Compare
This comment has been minimized.
This comment has been minimized.
51eb65a
to
938dc91
Compare
@mmarchini do you know what this means?
|
Yeah, I noticed this version of V8 is optimizing functionOne faster than before. Increasing sampling frequency might help, but will still be flaky. Or we could run the fixture script a few times (5, 10) and search for frames on the output of all executions. Let me see if we can improve this somehow first, if not we can try alternative solutions. |
Thanks. Since this is run only once and only for V8 updates, IMO it could be a "pummel" test. We can extend it's timeout, or generate synthetic CPU load if needed. |
Ok, I was able to rewrite it in a way it's guaranteed to work: diff --git a/test/fixtures/linux-perf.js b/test/fixtures/linux-perf.js
index 011ef19777..90ea2f2e33 100644
--- a/test/fixtures/linux-perf.js
+++ b/test/fixtures/linux-perf.js
@@ -1,26 +1,17 @@
'use strict';
-const crypto = require('crypto');
+const { spawnSync } = require("child_process");
+const sleepTime = new Number(process.argv[2] || "0.1");
+const repeat = new Number(process.argv[3]) || 5;
-// Functions should be complex enough for V8 to run them a few times before
-// compiling, but not complex enough to always stay in interpreted mode. They
-// should also take some time to run, otherwise Linux perf might miss them
-// entirely even when sampling at a high frequency.
-function functionOne(i) {
- for (let j=i; j > 0; j--) {
- crypto.createHash('md5').update(functionTwo(i, j)).digest("hex");
- }
+function functionOne() {
+ functionTwo();
}
-function functionTwo(x, y) {
- let data = ((((x * y) + (x / y)) * y) ** (x + 1)).toString();
- if (x % 2 == 0) {
- return crypto.createHash('md5').update(data.repeat((x % 100) + 1)).digest("hex");
- } else {
- return crypto.createHash('md5').update(data.repeat((y % 100) + 1)).digest("hex");
- }
+function functionTwo() {
+ spawnSync('sleep', [`${sleepTime}`]);
}
-for (let i = 0; i < 1000; i++) {
- functionOne(i);
+for (let i = 0; i < repeat; i++) {
+ functionOne();
}
diff --git a/test/v8-updates/test-linux-perf.js b/test/v8-updates/test-linux-perf.js
index 98f8f6c527..526dfbcd4e 100644
--- a/test/v8-updates/test-linux-perf.js
+++ b/test/v8-updates/test-linux-perf.js
@@ -22,16 +22,53 @@ tmpdir.refresh();
if (process.config.variables.node_shared)
common.skip("can't test Linux perf with shared libraries yet");
-const perfArgs = [
+if (!common.isLinux)
+ common.skip('only testing Linux for now');
+
+const frequency = 99;
+
+const repeat = 5;
+
+// Expected number of samples we'll capture per repeat
+const sampleCount = 10;
+const sleepTime = sampleCount * (1.0 / frequency);
+
+const perfFlags = [
'record',
- '-F999',
+ `-F${frequency}`,
'-g',
- '--',
- process.execPath,
+];
+
+const nodeCommonFlags = [
'--perf-basic-prof',
'--interpreted-frames-native-stack',
'--no-turbo-inlining', // Otherwise simple functions might get inlined.
+];
+
+const perfInterpretedFramesArgs = [
+ ...perfFlags,
+ '--',
+ process.execPath,
+ ...nodeCommonFlags,
+ '--no-opt',
+ fixtures.path('linux-perf.js'),
+ `${sleepTime}`,
+ `${repeat}`,
+];
+
+const perfCompiledFramesArgs = [
+ ...perfFlags,
+ '--',
+ process.execPath,
+ ...nodeCommonFlags,
+ '--always-opt',
fixtures.path('linux-perf.js'),
+ `${sleepTime}`,
+ `${repeat}`,
+];
+
+const perfArgsList = [
+ perfInterpretedFramesArgs, perfCompiledFramesArgs
];
const perfScriptArgs = [
@@ -44,25 +81,27 @@ const options = {
maxBuffer: Infinity
};
-if (!common.isLinux)
- common.skip('only testing Linux for now');
+let output = "";
+
+for (let perfArgs of perfArgsList) {
+ const perf = spawnSync('perf', perfArgs, options);
+ assert.ifError(perf.error);
+ if (perf.status !== 0)
+ throw new Error(`Failed to execute 'perf': ${perf.stderr}`);
-const perf = spawnSync('perf', perfArgs, options);
-assert.ifError(perf.error);
-if (perf.status !== 0)
- throw new Error(`Failed to execute 'perf': ${perf.stderr}`);
+ const perfScript = spawnSync('perf', perfScriptArgs, options);
+ assert.ifError(perfScript.error);
+ if (perfScript.status !== 0)
+ throw new Error(`Failed to execute perf script: ${perfScript.stderr}`);
-const perfScript = spawnSync('perf', perfScriptArgs, options);
-assert.ifError(perfScript.error);
-if (perfScript.status !== 0)
- throw new Error(`Failed to execute perf script: ${perfScript.stderr}`);
+ output += perfScript.stdout;
+}
const interpretedFunctionOneRe = /InterpretedFunction:functionOne/;
const compiledFunctionOneRe = /LazyCompile:\*functionOne/;
const interpretedFunctionTwoRe = /InterpretedFunction:functionTwo/;
const compiledFunctionTwoRe = /LazyCompile:\*functionTwo/;
-const output = perfScript.stdout;
assert.ok(output.match(interpretedFunctionOneRe),
"Couldn't find interpreted functionOne()"); Essentially we'll run the fixture two times, one with optimizations disabled ( I ran this 100 times (with a frequency of 99, which is way lower than what we're using today) and there was no failures. |
60131c1
to
898b33d
Compare
Co-authored-by: Matheus Marchini <mat@mmarchini.me> PR-URL: nodejs#27364 Refs: nodejs/build#1774 Reviewed-By: Matheus Marchini <mat@mmarchini.me> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
b1979fa
to
546d6cd
Compare
Co-authored-by: Matheus Marchini <mat@mmarchini.me> PR-URL: #27364 Refs: nodejs/build#1774 Reviewed-By: Matheus Marchini <mat@mmarchini.me> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Co-authored-by: Matheus Marchini <mat@mmarchini.me> PR-URL: #27364 Refs: nodejs/build#1774 Reviewed-By: Matheus Marchini <mat@mmarchini.me> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Refs: nodejs/build#1774
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes