build,test: setup perfetto tests on windows build

Signed-off-by: Chengzhong Wu <cwu631@bloomberg.net>
PR-URL: https://github.com/nodejs/node/pull/66731
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
This commit is contained in:
Chengzhong Wu authored and GitHub committed 2026-10-23 22:01:33 +00:00
1 parent 84f8e2f3a9
commit ca277a6294
7 files changed
+83 -43

No files matched your search

+1
View File
@@ -123,6 +123,7 @@ tools/*/*.i.tmp
# === Rules for tools/perfetto ===
/tools/perfetto/trace_processor_shell
/tools/perfetto/trace_processor_shell.exe
# === Rules for test artifacts ===
/*.tap
+1 -1
View File
@@ -349,7 +349,7 @@ TRACE_PROCESSOR_SHELL_DEPS = deps/perfetto/VERSION
endif
$(TRACE_PROCESSOR_SHELL_PATH): $(TRACE_PROCESSOR_SHELL_DEPS)
@tools/perfetto/get_trace_processor $@
@$(PYTHON) tools/perfetto/get_trace_processor.py $@
.PHONY: test
# This does not run tests of third-party libraries inside deps.
+5 -3
View File
@@ -4,7 +4,8 @@
// binary format.
// This depends on perfetto's `trace_processor_shell` converts to pftrace format
// to JSON format. Run `make tools/perfetto/trace_processor_shell` to download
// it, or point `TRACE_PROCESSOR_SHELL_PATH` at an existing build of it.
// it (`vcbuild test` does so on Windows), or point `TRACE_PROCESSOR_SHELL_PATH`
// at an existing build of it.
const assert = require('assert');
const { spawnSync } = require('child_process');
@@ -14,7 +15,8 @@ const common = require('./');
const traceProcessor = path.resolve(
__dirname, '..', '..',
process.env.TRACE_PROCESSOR_SHELL_PATH || 'tools/perfetto/trace_processor_shell');
process.env.TRACE_PROCESSOR_SHELL_PATH ||
`tools/perfetto/trace_processor_shell${common.isWindows ? '.exe' : ''}`);
// The JSON form of a trace runs about three times the size of the trace it was
// converted from, and the traces these tests produce are a few hundred KiB at
@@ -29,7 +31,7 @@ const defaultTraceFileName = `node_trace.1.${traceFileExt}`;
function checkTraceProcessor() {
if (common.hasPerfetto && !fs.existsSync(traceProcessor)) {
assert.fail('trace_processor_shell is missing, ' +
'run `make tools/perfetto/trace_processor_shell` to download it');
'run `python3 tools/perfetto/get_trace_processor.py` to download it');
}
}
+5 -3
View File
@@ -2,10 +2,12 @@
When the `node` binary is built with configure flag `--with-perfetto`,
the tests in this folder depends on `tools/perfetto/trace_processor_shell`,
which is downloaded with `tools/perfetto/get_trace_processor` via
which is downloaded with `tools/perfetto/get_trace_processor.py` via
`make tools/perfetto/trace_processor_shell`, to convert Perfetto binary trace
files to JSON format. Set `TRACE_PROCESSOR_SHELL_PATH` to use an existing build
of the tool instead of downloading a release.
files to JSON format. On Windows, `vcbuild.bat` downloads
`tools/perfetto/trace_processor_shell.exe` with the same script before running
the tests. Set `TRACE_PROCESSOR_SHELL_PATH` to use an existing build of the
tool instead of downloading a release.
Refer to <https://perfetto.dev/docs/reference/trace-processor-cli>
for help of the `trace_processor_shell` CLI.
-36
View File
@@ -1,36 +0,0 @@
#!/bin/sh
# Downloads perfetto's trace_processor_shell, matching the SDK version vendored
# in deps/perfetto. The trace events tests read back the binary traces that
# perfetto builds write through this tool.
set -e
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
version=$(cat "$script_dir/../../deps/perfetto/VERSION")
trace_processor="${1:-$script_dir/trace_processor_shell}"
# Perfetto names its release archives <os>-<arch>, which does not match uname.
case "$(uname -s)" in
Darwin) os=mac ;;
Linux) os=linux ;;
*) echo "No perfetto release for $(uname -s)" >&2; exit 1 ;;
esac
case "$(uname -m)" in
x86_64 | amd64) arch=amd64 ;;
arm64 | aarch64) arch=arm64 ;;
*) echo "No perfetto release for $(uname -m)" >&2; exit 1 ;;
esac
url="https://github.com/google/perfetto/releases/download/v$version/$os-$arch.zip"
archive=$(mktemp)
rm -f "$trace_processor"
echo "Downloading $url"
curl -sSfL -o "$archive" "$url"
unzip -q -j -o "$archive" '*/trace_processor_shell' -d "$script_dir"
rm -f "$archive"
chmod +x "$trace_processor"
# The archive carries the release's own mtime. Make decides whether the tool is
# current by comparing it against deps/perfetto/VERSION, so it has to come out
# newer than the version file it was downloaded for.
touch "$trace_processor"
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env python3
# Downloads perfetto's trace_processor_shell, matching the SDK version vendored
# in deps/perfetto. The trace events tests read back the binary traces that
# perfetto builds write through this tool.
import io
import os
import platform
import sys
import urllib.request
import zipfile
script_dir = os.path.dirname(os.path.abspath(__file__))
version_file = os.path.join(script_dir, '..', '..', 'deps', 'perfetto', 'VERSION')
is_windows = platform.system() == 'Windows'
# Perfetto names its release archives <os>-<arch>, which does not match what
# platform reports.
OS_NAMES = {'Darwin': 'mac', 'Linux': 'linux'}
ARCH_NAMES = {'x86_64': 'amd64', 'arm64': 'arm64', 'aarch64': 'arm64'}
def release_name():
# Perfetto releases only an x64 build for Windows. Windows on arm64 runs it
# under emulation.
if is_windows:
return 'windows-amd64'
os_name = OS_NAMES.get(platform.system())
arch = ARCH_NAMES.get(platform.machine())
if os_name is None or arch is None:
sys.exit(f'No perfetto release for {platform.system()} {platform.machine()}')
return f'{os_name}-{arch}'
def main():
exe = 'trace_processor_shell.exe' if is_windows else 'trace_processor_shell'
trace_processor = sys.argv[1] if len(sys.argv) > 1 else os.path.join(script_dir, exe)
# The tool is current when it is newer than the version file it was
# downloaded for, so a version bump re-downloads it.
if (os.path.exists(trace_processor) and
os.path.getmtime(trace_processor) > os.path.getmtime(version_file)):
return
with open(version_file) as f:
version = f.read().strip()
name = release_name()
url = f'https://github.com/google/perfetto/releases/download/v{version}/{name}.zip'
print(f'Downloading {url}')
with urllib.request.urlopen(url) as response:
archive = zipfile.ZipFile(io.BytesIO(response.read()))
print(f'Extracting {name}/{exe} to {trace_processor}')
with open(trace_processor, 'wb') as dst:
dst.write(archive.read(f'{name}/{exe}'))
os.chmod(trace_processor, 0o755)
if __name__ == '__main__':
main()
+10
View File
@@ -85,6 +85,7 @@ set compile_commands=
set cfg=
set v8temporal=
set v8windbg=
set with_perfetto=
set exit_code=0
:next-arg
@@ -116,6 +117,7 @@ if /i "%1"=="pgo-generate" set pgo_generate=1&goto arg-ok
if /i "%1"=="pgo-use" set pgo_use=1&goto arg-ok
if /i "%1"=="v8temporal" set v8temporal=1&goto arg-ok
if /i "%1"=="v8windbg" set v8windbg=1&goto arg-ok
if /i "%1"=="with-perfetto" set with_perfetto=1&goto arg-ok
if /i "%1"=="licensertf" set licensertf=1&goto arg-ok
if /i "%1"=="test" set test_args=%test_args% %common_test_suites%&set lint_cpp=1&set lint_js=1&set lint_md=1&goto arg-ok
if /i "%1"=="test-ci-native" set test_args=%test_args% %test_ci_args% -p tap --logfile test.tap %CI_NATIVE_SUITES% %CI_DOC%&set build_addons=1&set build_js_native_api_tests=1&set build_node_api_tests=1&set build_ffi_tests=1&set cctest_args=%cctest_args% --gtest_output=xml:cctest.junit.xml&goto arg-ok
@@ -272,6 +274,7 @@ if defined compile_commands set configure_flags=%configure_flags% -C
if defined cfg set configure_flags=%configure_flags% --control-flow-guard
if defined v8temporal set configure_flags=%configure_flags% --v8-enable-temporal-support
if defined v8windbg set configure_flags=%configure_flags% --enable-v8windbg
if defined with_perfetto set configure_flags=%configure_flags% --with-perfetto
if "%target_arch%"=="x86" (
echo "32-bit Windows builds are not supported anymore."
@@ -826,6 +829,13 @@ echo running 'cctest %cctest_args%'
"%config%\cctest" %cctest_args%
if %errorlevel% neq 0 set exit_code=%errorlevel%
:run-test-py
@rem Download trace_processor_shell for perfetto builds.
if defined TRACE_PROCESSOR_SHELL_PATH goto run-test-py-start
findstr /r /c:"v8_use_perfetto.: 1," config.gypi >nul 2>&1
if errorlevel 1 goto run-test-py-start
python tools\perfetto\get_trace_processor.py
if errorlevel 1 exit /b 1
:run-test-py-start
echo running 'python tools\test.py %test_args%'
python tools\test.py %test_args%
if %errorlevel% neq 0 set exit_code=%errorlevel%