From d2d14afee8bee97be541285996c36a749984cba4 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Sun, 25 Oct 2026 00:55:10 +0000 Subject: [PATCH 01/16] tools: update nixpkgs-unstable to 901c54c08bdc20e00c2b3c73716b97497b1 --- tools/nix/pkgs-26.05.nix | 4 ++-- tools/nix/pkgs.nix | 11 +++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/tools/nix/pkgs-26.05.nix b/tools/nix/pkgs-26.05.nix index cc752d342dd1..efe2f96ef6d3 100644 --- a/tools/nix/pkgs-26.05.nix +++ b/tools/nix/pkgs-26.05.nix @@ -1,10 +1,10 @@ arg: let repo = "https://github.com/NixOS/nixpkgs"; - rev = "42966a9c76f2cdb95b108c9fac939a27b0b8f2c5"; + rev = "752cbac9446602fbb78bdd1c3597455a3dd38432"; nixpkgs = import (builtins.fetchTarball { url = "${repo}/archive/${rev}.tar.gz"; - sha256 = "0i0n2r8hsskzzkhkjgp61r5q94wj644i2jdw733gn4f5ffr61qvk"; + sha256 = "0h4w0f8nkmpmmpjky3blvc2r147s515pc0z4hisywln4ryryr29z"; }) arg; in # Unstable channel no longer supports Intel architecture for macOS. We can use the 26.05 channel diff --git a/tools/nix/pkgs.nix b/tools/nix/pkgs.nix index 4d50ecb80bb4..850cfa995177 100644 --- a/tools/nix/pkgs.nix +++ b/tools/nix/pkgs.nix @@ -1,10 +1,10 @@ arg: let repo = "https://github.com/NixOS/nixpkgs"; - rev = "f20cd90e28fe0403873f473b29e42662cd86e8c4"; + rev = "901c54c08bdc20e00c2b3c73716b97497b1b3c74"; nixpkgs = import (builtins.fetchTarball { url = "${repo}/archive/${rev}.tar.gz"; - sha256 = "1vv6crfchmhjk5j61zgajggc3cgkalak2rvng07g41cvlcf6ldhj"; + sha256 = "0bicjz6w8n0ahwxxj837rbg494siw57vfk7ff3w8v3gvnykzxlia"; }) arg; in # Unstable channel no longer supports Intel architecture for macOS. We can use the 26.05 channel @@ -22,12 +22,7 @@ else boringssl = let - inherit (nixpkgs) callPackage lib writeTextFile; - # TODO: remove this override once nixpkgs.boringssl is 0.20261020.0 or newer. - boringssl = callPackage (builtins.fetchurl { - url = "${repo}/raw/1c17f6e5f086bf6b259e7a28f68657ed8548a25a/pkgs/by-name/bo/boringssl/package.nix"; - sha256 = "10cw2np6shjanxa2vzfxsrbyz451g1b6qan2v9c1ln75i3n5zn8a"; - }) { }; + inherit (nixpkgs) boringssl lib writeTextFile; in # BoringSSL does not install the openssl.pc metadata required by configure. # https://boringssl-review.googlesource.com/c/boringssl/+/104208 From 7f8f35972d30aefbfe4b07a10cba3bb8c6c78c75 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 26 Oct 2026 12:14:21 +0100 Subject: [PATCH 02/16] tools: update nixpkgs-unstable to f4b794aaffc0e3d45da81088d492b118224b --- tools/nix/openssl-matrix.nix | 1 + tools/nix/pkgs.nix | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/nix/openssl-matrix.nix b/tools/nix/openssl-matrix.nix index b035f893568b..76389da8cba1 100644 --- a/tools/nix/openssl-matrix.nix +++ b/tools/nix/openssl-matrix.nix @@ -16,6 +16,7 @@ openssl_3 openssl_3_6 openssl_4_0 + openssl_4_1 ; openssl_fips = import ./openssl-fips.nix { }; diff --git a/tools/nix/pkgs.nix b/tools/nix/pkgs.nix index 850cfa995177..b57635ca1001 100644 --- a/tools/nix/pkgs.nix +++ b/tools/nix/pkgs.nix @@ -1,10 +1,10 @@ arg: let repo = "https://github.com/NixOS/nixpkgs"; - rev = "901c54c08bdc20e00c2b3c73716b97497b1b3c74"; + rev = "f4b794aaffc0e3d45da81088d492b118224bb476"; nixpkgs = import (builtins.fetchTarball { url = "${repo}/archive/${rev}.tar.gz"; - sha256 = "0bicjz6w8n0ahwxxj837rbg494siw57vfk7ff3w8v3gvnykzxlia"; + sha256 = "0vqwmj02vmvw40kvdlf71vn5as7f4kfwrrcw778nbg3k6a1y5q8k"; }) arg; in # Unstable channel no longer supports Intel architecture for macOS. We can use the 26.05 channel @@ -18,6 +18,8 @@ else # OpenSSL 3.0.x was removed from unstable, but we want to keep testing it. inherit (import ./pkgs-26.05.nix arg) openssl_3 + openssl_3_6 + openssl_4_0 ; boringssl = From 4a562b6fe5713f4eeba1ab88cb3df6283bb2b402 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sun, 25 Oct 2026 09:42:40 +0100 Subject: [PATCH 03/16] tools: cross-compile Perfetto tools for Jenkins CI Signed-off-by: Antoine du Hamel --- .../workflows/cross-build-perfetto-tools.yml | 103 ++++++++++++++++++ .github/workflows/tools.yml | 13 ++- Makefile | 6 + tools/dep_updaters/update-nixpkgs-pin.sh | 16 ++- tools/nix/cross-compile-perfetto.nix | 69 ++++++++++++ tools/perfetto/get_trace_processor.py | 55 ++++++++-- tools/perfetto/trace_processor_shell.json | 10 ++ 7 files changed, 257 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/cross-build-perfetto-tools.yml create mode 100644 tools/nix/cross-compile-perfetto.nix create mode 100644 tools/perfetto/trace_processor_shell.json diff --git a/.github/workflows/cross-build-perfetto-tools.yml b/.github/workflows/cross-build-perfetto-tools.yml new file mode 100644 index 000000000000..2bb7a627a694 --- /dev/null +++ b/.github/workflows/cross-build-perfetto-tools.yml @@ -0,0 +1,103 @@ +# This action uses the following secrets: +# CACHIX_AUTH_TOKEN: Write access to nodejs.cachix.org – without it, the cache is read-only. +name: Cross build Perfetto tools + +on: + push: + branches: + - main + - canary + - v[0-9]+.x-staging + - v[0-9]+.x + paths-ignore: + - '**.md' + - eslint.config.mjs + - '**/eslint.config_partial.mjs' + - android-configure + - android-configure.py + - android-patches/** + - benchmarks/** + - codecov.yml + - doc/** + - pyproject.yml + - tsconfig.json + - test/internet/** + - tools/actions/** + - tools/dep_updaters/** + - tools/doc/** + - tools/eslint-rules/** + - tools/eslint/** + - tools/lint-md/** + - typings/** + - vcbuild.bat + - .** + - '!.github/workflows/cross-build-perfetto-tools.yml' + pull_request: + paths-ignore: + - '**.md' + - eslint.config.mjs + - '**/eslint.config_partial.mjs' + - android-configure + - android-configure.py + - android-patches/** + - benchmarks/** + - codecov.yml + - doc/** + - pyproject.yml + - tsconfig.json + - test/internet/** + - tools/actions/** + - tools/dep_updaters/** + - tools/doc/** + - tools/eslint-rules/** + - tools/eslint/** + - tools/lint-md/** + - typings/** + - vcbuild.bat + - .** + - '!.github/workflows/cross-build-perfetto-tools.yml' + types: [opened, synchronize, reopened, ready_for_review] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + cross-build: + if: github.event.pull_request.draft == false + name: Cross-build and validate trace_processor_shell.json + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + sparse-checkout: | + shell.nix + tools/nix/ + tools/perfetto/trace_processor_shell.json + sparse-checkout-cone-mode: false + + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 + with: + extra_nix_config: sandbox = true + + - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 + with: + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + name: nodejs + + - name: Cross-build and validate trace_processor_shell.json + run: | + EXPECTED="$( + nix-build \ + -I "nixpkgs=tools/nix/pkgs.nix" \ + --no-out-link "tools/nix/cross-compile-perfetto.nix" + )" ACTUAL=./tools/perfetto/trace_processor_shell.json node -e ' + assert.deepStrictEqual( + require(process.env.ACTUAL), + require(process.env.EXPECTED), + );' + diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index ec996d6f5db4..04caa5657b41 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -59,7 +59,7 @@ jobs: pull-requests: read if: github.repository == 'nodejs/node' || github.event_name == 'workflow_dispatch' # cannot use ubuntu-slim here because some update scripts require Docker - runs-on: ubuntu-latest + runs-on: ${{ matrix.runs-on || 'ubuntu-slim' }} strategy: fail-fast: false # Prevent other jobs from aborting if one fails matrix: @@ -215,11 +215,13 @@ jobs: # Node.js can be built with the same env along the whole release line life – or # at least we can detect and document necessary updates. label: tools, dont-land-on-v22.x, dont-land-on-v24.x, dont-land-on-v26.x + runs-on: ubuntu-24.04-arm # Cross-compiles Perfetto run: | ./tools/dep_updaters/update-nixpkgs-pin.sh > temp-output cat temp-output tail -n1 temp-output | grep "NEW_VERSION=" >> "$GITHUB_ENV" || true rm temp-output + ./tools/nix/cross-build-perfetto.sh - id: nghttp2 subsystem: deps label: dependencies @@ -292,6 +294,7 @@ jobs: - id: undici subsystem: deps label: dependencies + runs-on: ubuntu-latest # Needs Docker to build the WASM run: | ./tools/dep_updaters/update-undici.sh > temp-output cat temp-output @@ -353,6 +356,14 @@ jobs: - name: Set up Nix if: matrix.id == 'nixpkgs-unstable' && (github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id) && steps.check-pr.outputs.hasNonBotCommits != 'true' uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 + # Pushes the trace_processor_shell builds, so build-trace-processor.yml gets the + # same binary whose hash update-nixpkgs-pin.sh recorded. + - name: Set up Cachix + if: matrix.id == 'nixpkgs-unstable' && (github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id) && steps.check-pr.outputs.hasNonBotCommits != 'true' + uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 + with: + name: nodejs + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - run: ${{ matrix.run }} if: (github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id) && steps.check-pr.outputs.hasNonBotCommits != 'true' env: diff --git a/Makefile b/Makefile index 361fed3df4c6..309944002307 100644 --- a/Makefile +++ b/Makefile @@ -345,8 +345,14 @@ TRACE_PROCESSOR_SHELL_PATH ?= tools/perfetto/trace_processor_shell # re-downloads it. An overridden path is a build we do not manage and may not # be writable, so it gets no prerequisite and is left alone once it exists. ifeq ($(TRACE_PROCESSOR_SHELL_PATH),tools/perfetto/trace_processor_shell) +# Platforms without a perfetto release get a binary built from +# tools/perfetto/trace_processor_shell.json instead. +ifneq ($(filter ppc64le s390x,$(ARCHTYPE)),) +TRACE_PROCESSOR_SHELL_DEPS = tools/perfetto/trace_processor_shell.json +else TRACE_PROCESSOR_SHELL_DEPS = deps/perfetto/VERSION endif +endif $(TRACE_PROCESSOR_SHELL_PATH): $(TRACE_PROCESSOR_SHELL_DEPS) @$(PYTHON) tools/perfetto/get_trace_processor.py $@ diff --git a/tools/dep_updaters/update-nixpkgs-pin.sh b/tools/dep_updaters/update-nixpkgs-pin.sh index 2128742ac029..55caec002312 100755 --- a/tools/dep_updaters/update-nixpkgs-pin.sh +++ b/tools/dep_updaters/update-nixpkgs-pin.sh @@ -7,6 +7,8 @@ BASE_DIR=$(cd "$(dirname "$0")/../.." && pwd) NIXPKGS_PIN_FILE="$BASE_DIR/tools/nix/pkgs.nix" NIXPKGS_COMPAT_PIN_FILE="$BASE_DIR/tools/nix/pkgs-26.05.nix" OPENSSL_MATRIX_FILE="$BASE_DIR/tools/nix/openssl-matrix.nix" +TRACE_PROCESSOR_FILE_GENERATOR="$BASE_DIR/tools/nix/cross-compile-perfetto.nix" +TRACE_PROCESSOR_FILE="$BASE_DIR/tools/perfetto/trace_processor_shell.json" NIXPKGS_REPO=$(grep -m 1 'repo =' "$NIXPKGS_PIN_FILE" | awk -F'"' '{ print $2 }') CURRENT_VERSION_SHA1=$(grep -m 1 'rev =' "$NIXPKGS_PIN_FILE" | awk -F'"' '{ print $2 }') @@ -40,7 +42,7 @@ update_pkgs_file "$NIXPKGS_PIN_FILE" "$CURRENT_VERSION_SHA1" "$NEW_UPSTREAM_SHA1 # TODO: remove this when 26.05 is EOL (end of 2026) COMPAT_VERSION_SHA1=$(grep -m 1 'rev =' "$NIXPKGS_COMPAT_PIN_FILE" | awk -F'"' '{ print $2 }') COMPAT_UPSTREAM_SHA1=$(git ls-remote "$NIXPKGS_REPO.git" nixpkgs-26.05-darwin | awk '{print $1}') -update_pkgs_file "$NIXPKGS_COMPAT_PIN_FILE" "$COMPAT_VERSION_SHA1" "$COMPAT_UPSTREAM_SHA1" +# update_pkgs_file "$NIXPKGS_COMPAT_PIN_FILE" "$COMPAT_VERSION_SHA1" "$COMPAT_UPSTREAM_SHA1" # === Update openssl-matrix.nix === # When bumping the pin, we want to update the openssl-matrix.nix file to keep the list in sync nixpkgs @@ -106,12 +108,22 @@ nix-instantiate -I "nixpkgs=$NIXPKGS_PIN_FILE" --eval --strict --json -E " openssl_fips = import ./openssl-fips.nix { }; }"' > "$OPENSSL_MATRIX_FILE" +JSON=$( + nix-instantiate \ + -I "nixpkgs=$NIXPKGS_PIN_FILE" \ + --eval --strict --json \ + --arg jsonFile "$TRACE_PROCESSOR_FILE" \ + "$TRACE_PROCESSOR_FILE_GENERATOR" -A rawData \ + | jq +) +echo "$JSON" > "$TRACE_PROCESSOR_FILE" + cat -<-, which does not match what @@ -29,31 +33,58 @@ def release_name(): 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 None return f'{os_name}-{arch}' +def download(url): + print(f'Downloading {url}') + # Cachix's CDN rejects urllib's default User-Agent. + request = urllib.request.Request(url, headers={'User-Agent': 'node-get-trace-processor'}) + with urllib.request.urlopen(request) as response: + return response.read() + + +def download_from_cachix(): + name = f'{platform.system().lower()}-{platform.machine()}' + with open(cross_compile_info) as f: + entry = json.load(f).get(name, {}) + if 'storePath' not in entry: + sys.exit(f'No perfetto release for {platform.system()} {platform.machine()}') + + store_hash = os.path.basename(entry['storePath']).split('-', 1)[0] + # The download is checked against the committed hash, so it does not need + # HTTPS. + data = download('http://app.cachix.org/api/v1/cache/nodejs/serve/' + f'{store_hash}/bin/trace_processor_shell') + return data + + 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. + # The tool is current when it is newer than the files 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)): + os.path.getmtime(trace_processor) > max(os.path.getmtime(version_file), + os.path.getmtime(cross_compile_info))): 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' + if name is None: + data = download_from_cachix() + else: + with open(version_file) as f: + version = f.read().strip() + url = f'https://github.com/google/perfetto/releases/download/v{version}/{name}.zip' + archive = zipfile.ZipFile(io.BytesIO(download(url))) + print(f'Extracting {name}/{exe}') + data = archive.read(f'{name}/{exe}') - 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}') + print(f'Writing {trace_processor}') with open(trace_processor, 'wb') as dst: - dst.write(archive.read(f'{name}/{exe}')) + dst.write(data) os.chmod(trace_processor, 0o755) diff --git a/tools/perfetto/trace_processor_shell.json b/tools/perfetto/trace_processor_shell.json new file mode 100644 index 000000000000..21ead29e2cec --- /dev/null +++ b/tools/perfetto/trace_processor_shell.json @@ -0,0 +1,10 @@ +{ + "linux-ppc64le": { + "crossSystem": "powernv", + "storePath": "/nix/store/yhnsk9d4b4qawb5iwj6j6ai101appa2m-perfetto-static-powerpc64le-unknown-linux-musl-59.1-tools/bin/trace_processor_shell" + }, + "linux-x390x": { + "crossSystem": "s390x", + "storePath": "/nix/store/h1fsvyhl9ff968182v573s0x7nxd01yy-perfetto-static-s390x-unknown-linux-musl-59.1-tools/bin/trace_processor_shell" + } +} From f1ae0466bd909cb866341059fc789374f2a3e09f Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 13 Oct 2026 13:00:16 +0200 Subject: [PATCH 04/16] test: skip trace-events tests inside unusual char dirs Refs: https://github.com/google/perfetto/issues/7590 Signed-off-by: Antoine du Hamel --- test/trace_events/test-trace-events-all.js | 5 +++++ test/trace_events/test-trace-events-api.js | 5 +++++ test/trace_events/test-trace-events-async-hooks-worker.js | 5 +++++ test/trace_events/test-trace-events-async-hooks.js | 5 +++++ test/trace_events/test-trace-events-bootstrap.js | 5 +++++ test/trace_events/test-trace-events-environment.js | 5 +++++ test/trace_events/test-trace-events-file-pattern.js | 5 +++++ test/trace_events/test-trace-events-fs-sync.js | 5 +++++ test/trace_events/test-trace-events-http.js | 5 +++++ test/trace_events/test-trace-events-net-abstract-socket.js | 5 +++++ test/trace_events/test-trace-events-net.js | 5 +++++ test/trace_events/test-trace-events-process-exit.js | 5 +++++ test/trace_events/test-trace-events-promises.js | 5 +++++ test/trace_events/test-trace-events-threadpool.js | 5 +++++ test/trace_events/test-trace-events-v8.js | 5 +++++ test/trace_events/test-trace-events-vm.js | 5 +++++ 16 files changed, 80 insertions(+) diff --git a/test/trace_events/test-trace-events-all.js b/test/trace_events/test-trace-events-all.js index fe422d03a77a..18979f0636d7 100644 --- a/test/trace_events/test-trace-events-all.js +++ b/test/trace_events/test-trace-events-all.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-api.js b/test/trace_events/test-trace-events-api.js index 6d50213d7750..55d0766c4f4e 100644 --- a/test/trace_events/test-trace-events-api.js +++ b/test/trace_events/test-trace-events-api.js @@ -2,6 +2,11 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const { isMainThread } = require('worker_threads'); if (!isMainThread) { diff --git a/test/trace_events/test-trace-events-async-hooks-worker.js b/test/trace_events/test-trace-events-async-hooks-worker.js index 4fdeb2138ebe..0539756dcf49 100644 --- a/test/trace_events/test-trace-events-async-hooks-worker.js +++ b/test/trace_events/test-trace-events-async-hooks-worker.js @@ -4,6 +4,11 @@ // affects the workers. const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + try { require('trace_events'); } catch { diff --git a/test/trace_events/test-trace-events-async-hooks.js b/test/trace_events/test-trace-events-async-hooks.js index c404402594a1..b0b1db50339f 100644 --- a/test/trace_events/test-trace-events-async-hooks.js +++ b/test/trace_events/test-trace-events-async-hooks.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-bootstrap.js b/test/trace_events/test-trace-events-bootstrap.js index dfead479bb7c..6a4589e8d0cd 100644 --- a/test/trace_events/test-trace-events-bootstrap.js +++ b/test/trace_events/test-trace-events-bootstrap.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-environment.js b/test/trace_events/test-trace-events-environment.js index 07561e58a948..43bb86b4fa0a 100644 --- a/test/trace_events/test-trace-events-environment.js +++ b/test/trace_events/test-trace-events-environment.js @@ -2,6 +2,11 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-file-pattern.js b/test/trace_events/test-trace-events-file-pattern.js index 4b053aeb60cb..8d1cf1942b0d 100644 --- a/test/trace_events/test-trace-events-file-pattern.js +++ b/test/trace_events/test-trace-events-file-pattern.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const tmpdir = require('../common/tmpdir'); const assert = require('assert'); const cp = require('child_process'); diff --git a/test/trace_events/test-trace-events-fs-sync.js b/test/trace_events/test-trace-events-fs-sync.js index 0fddb93dfda7..394494347f4d 100644 --- a/test/trace_events/test-trace-events-fs-sync.js +++ b/test/trace_events/test-trace-events-fs-sync.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-http.js b/test/trace_events/test-trace-events-http.js index 32c8bc7d1674..e70d92e710a3 100644 --- a/test/trace_events/test-trace-events-http.js +++ b/test/trace_events/test-trace-events-http.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-net-abstract-socket.js b/test/trace_events/test-trace-events-net-abstract-socket.js index 4f933be8dd8f..6ca2280fa8b7 100644 --- a/test/trace_events/test-trace-events-net-abstract-socket.js +++ b/test/trace_events/test-trace-events-net-abstract-socket.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-net.js b/test/trace_events/test-trace-events-net.js index 90d501984aa7..b31b189caa93 100644 --- a/test/trace_events/test-trace-events-net.js +++ b/test/trace_events/test-trace-events-net.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-process-exit.js b/test/trace_events/test-trace-events-process-exit.js index cb09c1e3cdcc..6e2db0fbe491 100644 --- a/test/trace_events/test-trace-events-process-exit.js +++ b/test/trace_events/test-trace-events-process-exit.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-promises.js b/test/trace_events/test-trace-events-promises.js index d633d55cab3d..5650c6133f37 100644 --- a/test/trace_events/test-trace-events-promises.js +++ b/test/trace_events/test-trace-events-promises.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-threadpool.js b/test/trace_events/test-trace-events-threadpool.js index d0cfeff7a868..8f6012e430e1 100644 --- a/test/trace_events/test-trace-events-threadpool.js +++ b/test/trace_events/test-trace-events-threadpool.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-v8.js b/test/trace_events/test-trace-events-v8.js index d6c3821407e2..031c25106a53 100644 --- a/test/trace_events/test-trace-events-v8.js +++ b/test/trace_events/test-trace-events-v8.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); diff --git a/test/trace_events/test-trace-events-vm.js b/test/trace_events/test-trace-events-vm.js index c2b9d95e0f04..00ef5d3928c8 100644 --- a/test/trace_events/test-trace-events-vm.js +++ b/test/trace_events/test-trace-events-vm.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +if (common.isInsideDirWithUnusualChars) { + common.skip('Test is broken in directories with unusual characters'); +} + const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); From 887e002ce5394227254b5dac4782e927d7f7b27d Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Fri, 4 Sep 2026 16:47:36 +0200 Subject: [PATCH 05/16] build: enable Perfetto by default Signed-off-by: Antoine du Hamel --- .github/workflows/benchmark.yml | 5 +- .github/workflows/test-linux-perfetto.yml | 73 ----------------------- .github/workflows/test-shared.yml | 5 +- configure.py | 12 ++-- shell.nix | 6 +- tools/nix/sharedLibDeps.nix | 4 +- tools/nix/v8.nix | 2 +- 7 files changed, 14 insertions(+), 93 deletions(-) delete mode 100644 .github/workflows/test-linux-perfetto.yml diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 9f4ed58447df..717f791a175f 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -71,14 +71,13 @@ jobs: include: - runner: ubuntu-24.04 system: x86_64-linux - perfetto: true - runner: ubuntu-24.04-arm system: aarch64-linux - runner: macos-15-intel system: x86_64-darwin - runner: macos-latest system: aarch64-darwin - name: '${{ matrix.system }}: with shared libraries${{ matrix.perfetto && '' and perfetto'' || '''' }}' + name: '${{ matrix.system }}: with shared libraries' runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -121,7 +120,6 @@ jobs: --pure --keep TAR_DIR --keep FLAKY_TESTS \ --keep SCCACHE_GHA_ENABLED --keep SCCACHE_GHA_RW_MODE \ --keep ACTIONS_CACHE_SERVICE_V2 --keep ACTIONS_RESULTS_URL --keep ACTIONS_RUNTIME_TOKEN \ - --arg withPerfetto ${{ matrix.perfetto || false }} \ --arg ccache '(import {}).sccache' \ --run ' make build-ci -j4 V=1 && sccache --stop-server @@ -137,7 +135,6 @@ jobs: nix-shell \ -I nixpkgs=./tools/nix/pkgs.nix \ --pure --keep SCCACHE_LOCAL_RW_MODE \ - --arg withPerfetto ${{ matrix.perfetto || false }} \ --arg ccache '(import {}).sccache' \ --run ' make build-ci -j4 V=1 ${{ contains(format(' {0} ', inputs.category), ' napi ') && '&& make bench-addons-build' || '' }} diff --git a/.github/workflows/test-linux-perfetto.yml b/.github/workflows/test-linux-perfetto.yml deleted file mode 100644 index edc7e5c3a772..000000000000 --- a/.github/workflows/test-linux-perfetto.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: Test Linux (with Perfetto) - -on: - workflow_dispatch: - pull_request: - # Only targeting paths specific to the vendored version of Perfetto, `test-shared` - # is taking care of rest of the coverage. - paths: - - .github/workflows/test-linux-perfetto.yml - - common.gypi - - configure.py - - deps/perfetto/** - - node.gyp - - node.gypi - - tools/v8_gypfiles/v8.gyp - types: [opened, synchronize, reopened, ready_for_review] - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -env: - PYTHON_VERSION: '3.15' - FLAKY_TESTS: keep_retrying - CLANG_VERSION: '19' - CC: ${{ (github.base_ref == 'main' || github.ref_name == 'main') && 'sccache' || '' }} clang-19 - CXX: ${{ (github.base_ref == 'main' || github.ref_name == 'main') && 'sccache' || '' }} clang++-19 - SCCACHE_GHA_ENABLED: ${{ github.base_ref == 'main' || github.ref_name == 'main' }} - SCCACHE_IDLE_TIMEOUT: '0' - RUSTC_VERSION: '1.88' - -permissions: - contents: read - -jobs: - test-perfetto: - if: github.event.pull_request.draft == false - runs-on: ubuntu-24.04-arm - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - path: node - - name: Install Clang ${{ env.CLANG_VERSION }} - uses: $/.github/actions/install-clang - with: - clang-version: ${{ env.CLANG_VERSION }} - - name: Install Rust ${{ env.RUSTC_VERSION }} - run: | - rustup override set "$RUSTC_VERSION" - rustup --version - - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: ${{ env.PYTHON_VERSION }} - allow-prereleases: true - - name: Set up sccache - if: github.base_ref == 'main' || github.ref_name == 'main' - uses: Mozilla-Actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11 - with: - version: v0.17.0 - - name: Build - working-directory: node - run: make build-ci -j4 V=1 CONFIG_FLAGS="--error-on-warn --v8-enable-temporal-support --with-perfetto" - - name: Get trace_processor - working-directory: node - run: make tools/perfetto/trace_processor_shell - - name: Test - working-directory: node - run: make test-ci -j1 V=1 TEST_CI_ARGS="-p actions --measure-flakiness 9" - - name: Ensure running tests did not cause any change in the tree - working-directory: node - run: git add -A && git diff --name-only --exit-code --staged diff --git a/.github/workflows/test-shared.yml b/.github/workflows/test-shared.yml index 6e10cf953387..d315f13a9b19 100644 --- a/.github/workflows/test-shared.yml +++ b/.github/workflows/test-shared.yml @@ -153,8 +153,6 @@ jobs: include: - runner: ubuntu-24.04 system: x86_64-linux - # Exercise the trace-event code against a perfetto-enabled V8. - perfetto: true # built separately in build-aarch64-linux-v8 # - runner: ubuntu-24.04-arm # system: aarch64-linux @@ -162,12 +160,11 @@ jobs: system: x86_64-darwin - runner: macos-latest system: aarch64-darwin - name: '${{ matrix.system }}: with shared libraries${{ matrix.perfetto && '' and perfetto'' || '''' }}' + name: '${{ matrix.system }}: with shared libraries' uses: $/.github/workflows/build-shared.yml with: runner: ${{ matrix.runner }} with-sccache: ${{ github.base_ref == 'main' || github.ref_name == 'main' }} - extra-nix-flags: ${{ matrix.perfetto && '--arg withPerfetto true' || '' }} secrets: CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} diff --git a/configure.py b/configure.py index 298c7eb1cb13..114f0430c5fb 100755 --- a/configure.py +++ b/configure.py @@ -1147,11 +1147,11 @@ default=None, help='disable the V8 inspector protocol') -parser.add_argument('--with-perfetto', +parser.add_argument('--without-perfetto', action='store_true', - dest='with_perfetto', + dest='without_perfetto', default=None, - help='enable perfetto support') + help='disable perfetto support') parser.add_argument('--shared', action='store_true', @@ -2253,7 +2253,7 @@ def configure_v8(o, configs): o['variables']['v8_enable_extensible_ro_snapshot'] = 0 o['variables']['v8_enable_temporal_support'] = 0 if options.v8_disable_temporal_support else 1 o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0 - o['variables']['v8_use_perfetto'] = 1 if options.with_perfetto else 0 + o['variables']['v8_use_perfetto'] = 0 if options.without_perfetto else 1 o['variables']['node_use_v8_platform'] = b(not options.without_v8_platform) o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8) o['variables']['force_dynamic_crt'] = 1 if options.shared else 0 @@ -2384,9 +2384,9 @@ def configure_lief(o): configure_library('lief', o, pkgname='LIEF') def configure_perfetto(o): - if not options.with_perfetto: + if options.without_perfetto: if options.shared_perfetto: - error('--shared-perfetto requires --with-perfetto') + error('--without-perfetto is incompatible with --shared-perfetto') o['variables']['node_shared_perfetto'] = b(False) return diff --git a/shell.nix b/shell.nix index cb5f0a8f102b..089aaf6a0a81 100644 --- a/shell.nix +++ b/shell.nix @@ -13,13 +13,13 @@ # Build options icu ? pkgs.icu, withAmaro ? true, + withFFI ? true, withLief ? true, + withPerfetto ? true, withQuic ? false, withSQLite ? true, - withFFI ? true, withSSL ? true, withTemporal ? true, - withPerfetto ? false, sharedLibDeps ? ( import ./tools/nix/sharedLibDeps.nix { inherit @@ -87,7 +87,7 @@ let "--v8-${if withTemporal then "enable" else "disable"}-temporal-support" ] ++ builtins.map (depName: "--shared-${depName}") sharedV8Deps - ++ pkgs.lib.optional withPerfetto "--with-perfetto"; + ++ pkgs.lib.optional (!withPerfetto) "--without-perfetto"; v8Derivation = if useSeparateDerivationForV8 == true then diff --git a/tools/nix/sharedLibDeps.nix b/tools/nix/sharedLibDeps.nix index 6a104497314e..97b7fb41bd29 100644 --- a/tools/nix/sharedLibDeps.nix +++ b/tools/nix/sharedLibDeps.nix @@ -1,11 +1,11 @@ { pkgs ? import ./pkgs.nix { }, + withFFI ? true, withLief ? true, + withPerfetto ? true, withQuic ? false, withSQLite ? true, withSSL ? true, - withFFI ? true, - withPerfetto ? false, withTemporal ? true, }: { diff --git a/tools/nix/v8.nix b/tools/nix/v8.nix index 8b9f1796e068..e757ebc69c04 100644 --- a/tools/nix/v8.nix +++ b/tools/nix/v8.nix @@ -59,7 +59,7 @@ let !(builtins.elem "--v8-disable-temporal-support" configureFlags) ) ../../deps/crates ++ lib.optional ( - builtins.elem "--with-perfetto" configureFlags && !useSharedPerfetto + !(builtins.elem "--without-perfetto" configureFlags) && !useSharedPerfetto ) ../../deps/perfetto ++ lib.optionals (icu != null) [ ../../tools/icu/icu_versions.json From d7dd35260be49514408cbd15a86a90f88712cb0d Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Thu, 10 Sep 2026 17:37:26 +0200 Subject: [PATCH 06/16] fixup! build: enable Perfetto by default except on incompatible platforms --- configure.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/configure.py b/configure.py index 114f0430c5fb..3bb126b5fe57 100755 --- a/configure.py +++ b/configure.py @@ -2253,7 +2253,7 @@ def configure_v8(o, configs): o['variables']['v8_enable_extensible_ro_snapshot'] = 0 o['variables']['v8_enable_temporal_support'] = 0 if options.v8_disable_temporal_support else 1 o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0 - o['variables']['v8_use_perfetto'] = 0 if options.without_perfetto else 1 + o['variables']['v8_use_perfetto'] = 0 if options.without_perfetto or not perfetto_supported() else 1 o['variables']['node_use_v8_platform'] = b(not options.without_v8_platform) o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8) o['variables']['force_dynamic_crt'] = 1 if options.shared else 0 @@ -2383,12 +2383,20 @@ def configure_lief(o): configure_library('lief', o, pkgname='LIEF') +def perfetto_supported(): + return flavor not in ('aix', 'cloudabi', 'openbsd', 'os400', 'solaris') + def configure_perfetto(o): if options.without_perfetto: if options.shared_perfetto: error('--without-perfetto is incompatible with --shared-perfetto') o['variables']['node_shared_perfetto'] = b(False) return + if options.without_perfetto is None and not perfetto_supported(): + warn(f'Perfetto is disabled for {flavor}: the bundled perfetto integration ' + 'is not available on this platform. Pass --without-perfetto to ' + 'silence this warning.') + return configure_library('perfetto', o) From c2f7d8a1606f23ef69f8e28a45cfcdbf2ecea0c9 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Wed, 23 Sep 2026 13:48:39 +0200 Subject: [PATCH 07/16] fixup! build: enable Perfetto by default add TRACE_PROCESSOR_SHELL_PATH as dependency of JS test --- Makefile | 7 +++++-- shell.nix | 5 ++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 309944002307..f081204590c0 100644 --- a/Makefile +++ b/Makefile @@ -321,7 +321,9 @@ v8: ## Build deps/v8. tools/make-v8.sh $(V8_ARCH).$(BUILDTYPE_LOWER) $(V8_BUILD_OPTIONS) .PHONY: jstest -jstest: build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests build-ffi-tests ## Run addon tests and JS tests. +## Run addon tests and JS tests. +jstest: build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests build-ffi-tests $(TRACE_PROCESSOR_SHELL_PATH)) + @out/$(BUILDTYPE)/cctest --gtest_list_tests $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \ $(TEST_CI_ARGS) \ --skip-tests=$(CI_SKIP_TESTS) \ @@ -354,6 +356,7 @@ TRACE_PROCESSOR_SHELL_DEPS = deps/perfetto/VERSION endif endif +# Set TRACE_PROCESSOR_SHELL_PATH=/dev/null to disable the download $(TRACE_PROCESSOR_SHELL_PATH): $(TRACE_PROCESSOR_SHELL_DEPS) @$(PYTHON) tools/perfetto/get_trace_processor.py $@ @@ -666,7 +669,7 @@ test-ci-js: | clear-stalled ## Build and test JavaScript with building anything .PHONY: test-ci # Related CI jobs: most CI tests, excluding node-test-commit-arm-fanned test-ci: LOGLEVEL := info ## Build and test everything (CI). -test-ci: | clear-stalled bench-addons-build build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests build-ffi-tests doc-only +test-ci: | clear-stalled bench-addons-build build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests build-ffi-tests doc-only $(TRACE_PROCESSOR_SHELL_PATH) out/Release/cctest --gtest_output=xml:out/junit/cctest.xml $(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \ --mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \ diff --git a/shell.nix b/shell.nix index 089aaf6a0a81..2a899aae88d7 100644 --- a/shell.nix +++ b/shell.nix @@ -149,6 +149,8 @@ pkgs.mkShell { ) ) ); + TRACE_PROCESSOR_SHELL_PATH = + if withPerfetto then "${pkgs.perfetto.tools}/bin/trace_processor_shell" else "/dev/null"; } // ( let @@ -177,9 +179,6 @@ pkgs.mkShell { // pkgs.lib.optionalAttrs (!withSQLite) { NOSQLITE = "1"; } - // pkgs.lib.optionalAttrs (withPerfetto) { - TRACE_PROCESSOR_SHELL_PATH = "${pkgs.perfetto.tools}/bin/trace_processor_shell"; - } // pkgs.lib.optionalAttrs (pkcs11 != false && pkcs11 != null) ( let pkcs11' = From dd45cc2765c6bc631faf7f98eb23677f38041321 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 3 Oct 2026 16:19:00 +0200 Subject: [PATCH 08/16] fixup! build: enable Perfetto by default --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f081204590c0..ed9d7e0df735 100644 --- a/Makefile +++ b/Makefile @@ -322,8 +322,7 @@ v8: ## Build deps/v8. .PHONY: jstest ## Run addon tests and JS tests. -jstest: build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests build-ffi-tests $(TRACE_PROCESSOR_SHELL_PATH)) - @out/$(BUILDTYPE)/cctest --gtest_list_tests +jstest: build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests build-ffi-tests $(TRACE_PROCESSOR_SHELL_PATH) $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \ $(TEST_CI_ARGS) \ --skip-tests=$(CI_SKIP_TESTS) \ From 5f37b82f02d841dd06cb2bcd5c3b3b73e4917d5b Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 3 Oct 2026 16:53:17 +0200 Subject: [PATCH 09/16] fixup! build: enable Perfetto by default --- Makefile | 43 +++++++++++++++++++------------------ configure.py | 4 ++-- shell.nix | 5 +++-- test/trace_events/README.md | 2 +- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index ed9d7e0df735..c01345a577d5 100644 --- a/Makefile +++ b/Makefile @@ -320,26 +320,7 @@ v8: ## Build deps/v8. export PATH="$(NO_BIN_OVERRIDE_PATH)" && \ tools/make-v8.sh $(V8_ARCH).$(BUILDTYPE_LOWER) $(V8_BUILD_OPTIONS) -.PHONY: jstest -## Run addon tests and JS tests. -jstest: build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests build-ffi-tests $(TRACE_PROCESSOR_SHELL_PATH) - $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \ - $(TEST_CI_ARGS) \ - --skip-tests=$(CI_SKIP_TESTS) \ - $(JS_SUITES) \ - $(NATIVE_SUITES) - -.PHONY: tooltest -tooltest: ## Test the various tools. - @$(PYTHON) -m unittest discover -s ./test/tools - -.PHONY: coverage-run-js -coverage-run-js: ## Run JavaScript tests with coverage. - $(RM) -r coverage/tmp - -NODE_V8_COVERAGE=coverage/tmp CI_SKIP_TESTS=$(COV_SKIP_TESTS) \ - TEST_CI_ARGS="$(TEST_CI_ARGS) --type=coverage" $(MAKE) jstest - $(MAKE) coverage-report-js - +ifneq ($(V8_USE_PERFETTO),0) TRACE_PROCESSOR_SHELL_PATH ?= tools/perfetto/trace_processor_shell # The downloaded copy has to match the vendored perfetto, so a version bump @@ -355,10 +336,30 @@ TRACE_PROCESSOR_SHELL_DEPS = deps/perfetto/VERSION endif endif -# Set TRACE_PROCESSOR_SHELL_PATH=/dev/null to disable the download $(TRACE_PROCESSOR_SHELL_PATH): $(TRACE_PROCESSOR_SHELL_DEPS) @$(PYTHON) tools/perfetto/get_trace_processor.py $@ +endif # + +.PHONY: jstest +jstest: build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests build-ffi-tests $(TRACE_PROCESSOR_SHELL_PATH) ## Run addon tests and JS tests. + $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \ + $(TEST_CI_ARGS) \ + --skip-tests=$(CI_SKIP_TESTS) \ + $(JS_SUITES) \ + $(NATIVE_SUITES) + +.PHONY: tooltest +tooltest: ## Test the various tools. + @$(PYTHON) -m unittest discover -s ./test/tools + +.PHONY: coverage-run-js +coverage-run-js: ## Run JavaScript tests with coverage. + $(RM) -r coverage/tmp + -NODE_V8_COVERAGE=coverage/tmp CI_SKIP_TESTS=$(COV_SKIP_TESTS) \ + TEST_CI_ARGS="$(TEST_CI_ARGS) --type=coverage" $(MAKE) jstest + $(MAKE) coverage-report-js + .PHONY: test # This does not run tests of third-party libraries inside deps. test: all ## Run default tests and build docs. diff --git a/configure.py b/configure.py index 3bb126b5fe57..ac146c7fee75 100755 --- a/configure.py +++ b/configure.py @@ -540,8 +540,7 @@ action='store_true', dest='shared_perfetto', default=None, - help='link to a shared perfetto SDK instead of the one in deps/perfetto ' - '(requires --with-perfetto)') + help='link to a shared perfetto SDK instead of the one in deps/perfetto') shared_optgroup.add_argument('--shared-perfetto-includes', action='store', @@ -3069,6 +3068,7 @@ def make_bin_override(): config = { 'BUILDTYPE': 'Debug' if options.debug else 'Release', 'NODE_TARGET_TYPE': variables['node_target_type'], + 'V8_USE_PERFETTO': str(variables['v8_use_perfetto']), } # Not needed for trivial case. Useless when it's a win32 path. diff --git a/shell.nix b/shell.nix index 2a899aae88d7..089aaf6a0a81 100644 --- a/shell.nix +++ b/shell.nix @@ -149,8 +149,6 @@ pkgs.mkShell { ) ) ); - TRACE_PROCESSOR_SHELL_PATH = - if withPerfetto then "${pkgs.perfetto.tools}/bin/trace_processor_shell" else "/dev/null"; } // ( let @@ -179,6 +177,9 @@ pkgs.mkShell { // pkgs.lib.optionalAttrs (!withSQLite) { NOSQLITE = "1"; } + // pkgs.lib.optionalAttrs (withPerfetto) { + TRACE_PROCESSOR_SHELL_PATH = "${pkgs.perfetto.tools}/bin/trace_processor_shell"; + } // pkgs.lib.optionalAttrs (pkcs11 != false && pkcs11 != null) ( let pkcs11' = diff --git a/test/trace_events/README.md b/test/trace_events/README.md index 6b78efd220b8..06b3ccb93aa0 100644 --- a/test/trace_events/README.md +++ b/test/trace_events/README.md @@ -1,6 +1,6 @@ # `trace_events` Tests -When the `node` binary is built with configure flag `--with-perfetto`, +When the `node` binary is not built with configure flag `--without-perfetto`, the tests in this folder depends on `tools/perfetto/trace_processor_shell`, which is downloaded with `tools/perfetto/get_trace_processor.py` via `make tools/perfetto/trace_processor_shell`, to convert Perfetto binary trace From 6a0d5ab5257f3ac565adb7b24358235296171f46 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 24 Oct 2026 10:59:56 +0200 Subject: [PATCH 10/16] fixup! fixup! build: enable Perfetto by default allow /dev/null value to opt-out of trace_processor tests --- test/common/trace_events.js | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/test/common/trace_events.js b/test/common/trace_events.js index cbb5dbdcc60a..171924c90521 100644 --- a/test/common/trace_events.js +++ b/test/common/trace_events.js @@ -5,18 +5,24 @@ // 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 (`vcbuild test` does so on Windows), or point `TRACE_PROCESSOR_SHELL_PATH` -// at an existing build of it. +// at an existing build of it. Point it at the null device (`/dev/null`, or +// `NUL` on Windows) to skip the tests that need it. const assert = require('assert'); const { spawnSync } = require('child_process'); const fs = require('fs'); +const { devNull } = require('os'); const path = require('path'); const common = require('./'); -const traceProcessor = path.resolve( - __dirname, '..', '..', - process.env.TRACE_PROCESSOR_SHELL_PATH || - `tools/perfetto/trace_processor_shell${common.isWindows ? '.exe' : ''}`); +const traceProcessor = ((p) => { + if (p !== undefined && common.isWindows && /^(?:\\\\\.\\)?nul$/i.test(p)) { + return false; + } + return p !== devNull && path.resolve( + __dirname, '..', '..', + p || `tools/perfetto/trace_processor_shell${common.isWindows ? '.exe' : ''}`); +})(process.env.TRACE_PROCESSOR_SHELL_PATH); // 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,9 +35,14 @@ const defaultTraceFileName = `node_trace.1.${traceFileExt}`; // Only perfetto traces need converting, so a missing `trace_processor_shell` // does not stop anything on a legacy build. function checkTraceProcessor() { - if (common.hasPerfetto && !fs.existsSync(traceProcessor)) { + if (!common.hasPerfetto) return; + if (!traceProcessor) { + common.skip('TRACE_PROCESSOR_SHELL_PATH points to the null device'); + } + if (!fs.existsSync(traceProcessor)) { assert.fail('trace_processor_shell is missing, ' + - 'run `python3 tools/perfetto/get_trace_processor.py` to download it'); + 'run `python3 tools/perfetto/get_trace_processor.py` to download it, ' + + 'or set TRACE_PROCESSOR_SHELL_PATH to the null device to skip this test'); } } From 75f32cb7ed53975625e5a8c57b6b0bced739e7d2 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 26 Oct 2026 12:42:36 +0100 Subject: [PATCH 11/16] fixup! tools: cross-compile Perfetto tools for Jenkins CI --- .github/workflows/cross-build-perfetto-tools.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cross-build-perfetto-tools.yml b/.github/workflows/cross-build-perfetto-tools.yml index 2bb7a627a694..9748c71ec61c 100644 --- a/.github/workflows/cross-build-perfetto-tools.yml +++ b/.github/workflows/cross-build-perfetto-tools.yml @@ -68,7 +68,7 @@ permissions: jobs: cross-build: if: github.event.pull_request.draft == false - name: Cross-build and validate trace_processor_shell.json + name: Cross-build trace_processor_shell and validate trace_processor_shell.json runs-on: ubuntu-24.04-arm steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -89,7 +89,7 @@ jobs: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} name: nodejs - - name: Cross-build and validate trace_processor_shell.json + - name: Cross-build trace_processor_shell and validate trace_processor_shell.json run: | EXPECTED="$( nix-build \ From f2f835b3ccac87e46541ccf700dc8b946c29e8ad Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 26 Oct 2026 14:45:42 +0100 Subject: [PATCH 12/16] fixup! tools: cross-compile Perfetto tools for Jenkins CI --- .github/workflows/cross-build-perfetto-tools.yml | 1 - .github/workflows/nix-changes.yml | 2 +- .github/workflows/tools.yml | 13 +------------ tools/dep_updaters/update-nixpkgs-pin.sh | 2 +- tools/perfetto/get_trace_processor.py | 9 ++++----- tools/perfetto/trace_processor_shell.json | 2 +- 6 files changed, 8 insertions(+), 21 deletions(-) diff --git a/.github/workflows/cross-build-perfetto-tools.yml b/.github/workflows/cross-build-perfetto-tools.yml index 9748c71ec61c..e4d7214a3190 100644 --- a/.github/workflows/cross-build-perfetto-tools.yml +++ b/.github/workflows/cross-build-perfetto-tools.yml @@ -100,4 +100,3 @@ jobs: require(process.env.ACTUAL), require(process.env.EXPECTED), );' - diff --git a/.github/workflows/nix-changes.yml b/.github/workflows/nix-changes.yml index f55a0b7df135..3b63f2d50320 100644 --- a/.github/workflows/nix-changes.yml +++ b/.github/workflows/nix-changes.yml @@ -48,7 +48,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 - persist-credentials: true # We need read access in case we need to fetch in `Compute requisites before change` step + persist-credentials: true # We need read access in case we need to fetch in `Compute requisites before change` step sparse-checkout: | shell.nix tools/nix/ diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index 04caa5657b41..ec996d6f5db4 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -59,7 +59,7 @@ jobs: pull-requests: read if: github.repository == 'nodejs/node' || github.event_name == 'workflow_dispatch' # cannot use ubuntu-slim here because some update scripts require Docker - runs-on: ${{ matrix.runs-on || 'ubuntu-slim' }} + runs-on: ubuntu-latest strategy: fail-fast: false # Prevent other jobs from aborting if one fails matrix: @@ -215,13 +215,11 @@ jobs: # Node.js can be built with the same env along the whole release line life – or # at least we can detect and document necessary updates. label: tools, dont-land-on-v22.x, dont-land-on-v24.x, dont-land-on-v26.x - runs-on: ubuntu-24.04-arm # Cross-compiles Perfetto run: | ./tools/dep_updaters/update-nixpkgs-pin.sh > temp-output cat temp-output tail -n1 temp-output | grep "NEW_VERSION=" >> "$GITHUB_ENV" || true rm temp-output - ./tools/nix/cross-build-perfetto.sh - id: nghttp2 subsystem: deps label: dependencies @@ -294,7 +292,6 @@ jobs: - id: undici subsystem: deps label: dependencies - runs-on: ubuntu-latest # Needs Docker to build the WASM run: | ./tools/dep_updaters/update-undici.sh > temp-output cat temp-output @@ -356,14 +353,6 @@ jobs: - name: Set up Nix if: matrix.id == 'nixpkgs-unstable' && (github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id) && steps.check-pr.outputs.hasNonBotCommits != 'true' uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 - # Pushes the trace_processor_shell builds, so build-trace-processor.yml gets the - # same binary whose hash update-nixpkgs-pin.sh recorded. - - name: Set up Cachix - if: matrix.id == 'nixpkgs-unstable' && (github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id) && steps.check-pr.outputs.hasNonBotCommits != 'true' - uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17 - with: - name: nodejs - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - run: ${{ matrix.run }} if: (github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id) && steps.check-pr.outputs.hasNonBotCommits != 'true' env: diff --git a/tools/dep_updaters/update-nixpkgs-pin.sh b/tools/dep_updaters/update-nixpkgs-pin.sh index 55caec002312..a742c377b402 100755 --- a/tools/dep_updaters/update-nixpkgs-pin.sh +++ b/tools/dep_updaters/update-nixpkgs-pin.sh @@ -42,7 +42,7 @@ update_pkgs_file "$NIXPKGS_PIN_FILE" "$CURRENT_VERSION_SHA1" "$NEW_UPSTREAM_SHA1 # TODO: remove this when 26.05 is EOL (end of 2026) COMPAT_VERSION_SHA1=$(grep -m 1 'rev =' "$NIXPKGS_COMPAT_PIN_FILE" | awk -F'"' '{ print $2 }') COMPAT_UPSTREAM_SHA1=$(git ls-remote "$NIXPKGS_REPO.git" nixpkgs-26.05-darwin | awk '{print $1}') -# update_pkgs_file "$NIXPKGS_COMPAT_PIN_FILE" "$COMPAT_VERSION_SHA1" "$COMPAT_UPSTREAM_SHA1" +update_pkgs_file "$NIXPKGS_COMPAT_PIN_FILE" "$COMPAT_VERSION_SHA1" "$COMPAT_UPSTREAM_SHA1" # === Update openssl-matrix.nix === # When bumping the pin, we want to update the openssl-matrix.nix file to keep the list in sync nixpkgs diff --git a/tools/perfetto/get_trace_processor.py b/tools/perfetto/get_trace_processor.py index 092c4c9b09aa..bf174c5fbb02 100755 --- a/tools/perfetto/get_trace_processor.py +++ b/tools/perfetto/get_trace_processor.py @@ -52,11 +52,10 @@ def download_from_cachix(): if 'storePath' not in entry: sys.exit(f'No perfetto release for {platform.system()} {platform.machine()}') - store_hash = os.path.basename(entry['storePath']).split('-', 1)[0] - # The download is checked against the committed hash, so it does not need - # HTTPS. - data = download('http://app.cachix.org/api/v1/cache/nodejs/serve/' - f'{store_hash}/bin/trace_processor_shell') + _, _, _, store_name, artifact = entry['storePath'].split('/', 4) + store_hash = store_name.split('-', 1)[0] + data = download('https://app.cachix.org/api/v1/cache/nodejs/serve/' + f'{store_hash}/{artifact}') return data diff --git a/tools/perfetto/trace_processor_shell.json b/tools/perfetto/trace_processor_shell.json index 21ead29e2cec..00faf6d8822a 100644 --- a/tools/perfetto/trace_processor_shell.json +++ b/tools/perfetto/trace_processor_shell.json @@ -3,7 +3,7 @@ "crossSystem": "powernv", "storePath": "/nix/store/yhnsk9d4b4qawb5iwj6j6ai101appa2m-perfetto-static-powerpc64le-unknown-linux-musl-59.1-tools/bin/trace_processor_shell" }, - "linux-x390x": { + "linux-s390x": { "crossSystem": "s390x", "storePath": "/nix/store/h1fsvyhl9ff968182v573s0x7nxd01yy-perfetto-static-s390x-unknown-linux-musl-59.1-tools/bin/trace_processor_shell" } From ee250acb5f9f96da22bbf6b0dbb318147513630a Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 26 Oct 2026 17:11:08 +0100 Subject: [PATCH 13/16] test: improve debug output for trace processor tests Signed-off-by: Antoine du Hamel --- test/common/trace_events.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/common/trace_events.js b/test/common/trace_events.js index 171924c90521..f4d0236d2680 100644 --- a/test/common/trace_events.js +++ b/test/common/trace_events.js @@ -54,9 +54,9 @@ function readTraceEvents(file) { const converted = spawnSync(traceProcessor, ['convert', 'json', file], { maxBuffer: kMaxTraceJsonBytes }); assert.ifError(converted.error); - assert.strictEqual( - converted.status, 0, - `trace_processor_shell failed: ${converted.stderr}`); + assert.partialDeepStrictEqual( + converted, { status: 0 }, + `trace_processor_shell failed`); return JSON.parse(converted.stdout.toString()).traceEvents; } From df0c1f5bd8f64f00ba528384535a3ee2e0e57f12 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 26 Oct 2026 17:43:04 +0100 Subject: [PATCH 14/16] fixup! test: improve debug output for trace processor tests --- test/common/trace_events.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/common/trace_events.js b/test/common/trace_events.js index f4d0236d2680..42bb1940f5ed 100644 --- a/test/common/trace_events.js +++ b/test/common/trace_events.js @@ -52,12 +52,12 @@ function readTraceEvents(file) { } const converted = spawnSync(traceProcessor, ['convert', 'json', file], - { maxBuffer: kMaxTraceJsonBytes }); + { maxBuffer: kMaxTraceJsonBytes, encoding: 'utf8' }); assert.ifError(converted.error); assert.partialDeepStrictEqual( converted, { status: 0 }, `trace_processor_shell failed`); - return JSON.parse(converted.stdout.toString()).traceEvents; + return JSON.parse(converted.stdout).traceEvents; } // A perfetto trace event carries the single category it was emitted with. The From 8d32da93203c7e505842359dc066d0fee0aa0aa0 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 26 Oct 2026 17:45:09 +0100 Subject: [PATCH 15/16] fixup! tools: cross-compile Perfetto tools for Jenkins CI --- tools/nix/cross-compile-perfetto.nix | 2 +- tools/perfetto/trace_processor_shell.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/nix/cross-compile-perfetto.nix b/tools/nix/cross-compile-perfetto.nix index 25368760d826..5a1631aebee4 100644 --- a/tools/nix/cross-compile-perfetto.nix +++ b/tools/nix/cross-compile-perfetto.nix @@ -35,7 +35,7 @@ let patches = [ (final.fetchpatch2 { url = "https://github.com/google/perfetto/pull/8256.patch"; - hash = "sha256-wOzOB1QgrTufSJyoiq/Ta4lVArGFGDmwhp8x19uLFKQ="; + hash = "sha256-uIfErjoYvCH8VzUwP1y6om2TVKGzsKhXLqfDe3O2i10="; }) ]; diff --git a/tools/perfetto/trace_processor_shell.json b/tools/perfetto/trace_processor_shell.json index 00faf6d8822a..12884d71775d 100644 --- a/tools/perfetto/trace_processor_shell.json +++ b/tools/perfetto/trace_processor_shell.json @@ -5,6 +5,6 @@ }, "linux-s390x": { "crossSystem": "s390x", - "storePath": "/nix/store/h1fsvyhl9ff968182v573s0x7nxd01yy-perfetto-static-s390x-unknown-linux-musl-59.1-tools/bin/trace_processor_shell" + "storePath": "/nix/store/gzzqr1h48ql1f0d2d85hdn80jib9hipp-perfetto-static-s390x-unknown-linux-musl-59.1-tools/bin/trace_processor_shell" } } From b068c67fbffc522c22080429b59e951323b4fe23 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 26 Oct 2026 23:15:24 +0100 Subject: [PATCH 16/16] fixup! tools: cross-compile Perfetto tools for Jenkins CI --- tools/nix/cross-compile-perfetto.nix | 4 ++-- tools/perfetto/trace_processor_shell.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/nix/cross-compile-perfetto.nix b/tools/nix/cross-compile-perfetto.nix index 5a1631aebee4..ecbb015d3d79 100644 --- a/tools/nix/cross-compile-perfetto.nix +++ b/tools/nix/cross-compile-perfetto.nix @@ -34,8 +34,8 @@ let perfetto.overrideAttrs (old: { patches = [ (final.fetchpatch2 { - url = "https://github.com/google/perfetto/pull/8256.patch"; - hash = "sha256-uIfErjoYvCH8VzUwP1y6om2TVKGzsKhXLqfDe3O2i10="; + url = "https://github.com/google/perfetto/commit/624afa18b239d8a28d0e24adde572abece09b32b.patch?full_index=1"; + hash = "sha256-wtKqzbK+ydUkL3BjBtz/CT2mbPpzD/P28uYQKj1sEO4="; }) ]; diff --git a/tools/perfetto/trace_processor_shell.json b/tools/perfetto/trace_processor_shell.json index 12884d71775d..b70b29c7966b 100644 --- a/tools/perfetto/trace_processor_shell.json +++ b/tools/perfetto/trace_processor_shell.json @@ -5,6 +5,6 @@ }, "linux-s390x": { "crossSystem": "s390x", - "storePath": "/nix/store/gzzqr1h48ql1f0d2d85hdn80jib9hipp-perfetto-static-s390x-unknown-linux-musl-59.1-tools/bin/trace_processor_shell" + "storePath": "/nix/store/vrc4f65ivcls8h1yr96wj73sw1br4yvw-perfetto-static-s390x-unknown-linux-musl-59.1-tools/bin/trace_processor_shell" } }