* chore: bump node in DEPS to v24.16.0
* chore: remove upstreamed patch
Node.js restored fs patchability in the ESM loader upstream, making
the fix_lazyload_fs_in_esm_loaders_to_apply_asar_patches.patch
obsolete (the patch's exact change is now in lib/internal/modules/
esm/{load,resolve,translators}.js).
Ref: https://github.com/nodejs/node/pull/62835
Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit 72638dbe1f6a60f76570c1cfb99d088768ec19e0)
* fix(patch): re-add experimental_fetch member after upstream cleanup
Upstream removed the experimental_fetch field from EnvironmentOptions,
but Electron's patch still registers --experimental-fetch as a CLI
option bound to that field. Re-add the member so the option compiles.
Ref: https://github.com/nodejs/node/pull/62759
Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit 6fd93703ca7fbe3b6860b84d812e8318614e7b35)
* fix(patch): cast const away when freeing uv_cpu_info_t.model
libuv 1.52.1 typed uv_cpu_info_t.model as const char*, but uv__free
takes void*. Electron builds with -Werror,-Wincompatible-pointer-types-
discards-qualifiers, so add a cast. The memory is allocated via strdup
so the cast is safe.
Ref: https://github.com/nodejs/node/pull/61829
Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit 90d1009b3fea0996aa68f70aaacbfe78266f8c3d)
* fix(patch): silence sign-compare warning in sessionVarintGetSafe
Cast int nBuf to size_t when comparing with sizeof(aCopy) so the
bundled sqlite3 amalgamation compiles under -Werror,-Wsign-compare.
Ref: https://github.com/nodejs/node/pull/62699
Co-Authored-By: Claude <noreply@anthropic.com>
* test: move root package.json aside in node spec runner
third_party/electron_node lives under Chromium's src/, whose package.json
("type": "module") is always an ancestor of the Node.js test tree. Upstream
assumes no package.json sits above the tests, so that ancestor changes how
test files and fixtures resolve their module type: it disables module-syntax
detection (breaking test-compile-cache-typescript-esm) and emits
MODULE_TYPELESS_PACKAGE_JSON warnings that break tests asserting clean stderr
(test-esm-detect-ambiguous, test-esm-import-meta-main-eval,
test-output-coverage-with-mock).
Move src/package.json aside for the duration of the run so the environment
matches upstream exactly, then restore it. The original is kept in a sibling
backup file so an interrupted/killed run self-heals on the next invocation
rather than leaving src/package.json missing.
Ref: Unable to locate reference
Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit 29abd0cebaea89c04be8806ac8c01941061dbfe6)
* fix(patch): mark test-macos-app-sandbox as flaky
The test copies the Electron binary into a standalone .app bundle and
code-signs it; under parallel suite runs this races with dyld resolving
the Electron Framework rpath and intermittently aborts (SIGABRT). It
passes reliably when run alone. Mark it flaky so flakes don't fail CI.
Ref: Unable to locate reference
Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit 3853529f14a0cece021b5b123ce1b4b7ae2cea78)
* test: disable test-tls-set-default-ca-certificates-extra-override
setDefaultCACertificates() round-trips the default CA set through
BoringSSL's X509_STORE, which dedups a duplicate-subject root (DigiCert
Global Root CA) that OpenSSL keeps. The set therefore loses one cert on
re-add (149 -> 148), so the test's assertEqualCerts round-trip check
fails under Electron's BoringSSL. The sibling -recovery test is disabled
for the same reason.
Ref: https://github.com/nodejs/node/pull/58822
Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit 3dbc596e17b84c81503653a3034a82a1ad5ac88f)
* fix(patch): mark test-runner watch tests as flaky
test-run-watch-repeatedly, test-run-watch-run-duration and
test-run-watch-without-file race under parallel suite load: the watcher
fires an extra re-run before the assertion, so the expected single-run
output ("tests 1") arrives with accumulated subtests. All three pass in
isolation.
Ref: https://github.com/nodejs/node/issues/44898
Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit 0f9c327b375e3224dae49bfecbb311f5a54990e4)
* chore(patches): update libuv const-cast patch management
Combine the Windows libuv cpu_info const-cast update into the existing
chore_cast_const_away_when_freeing_uv_cpu_info_t_model.patch and keep
a single patch-management commit for the final exported patch series.
Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit c590614cb51f5f88f63ade4777555f438554fe3c)
* fix(patch): add UV_LOOP_INTERRUPT_ON_IO_CHANGE option
Ref: https://github.com/libuv/libuv/pull/3308
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: update patches (trivial only)
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: update patches
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(patch): adapt GetIsolate removal for the inspector NetworkAgent
Adapts api_remove_deprecated_getisolate.patch for the inspector NetworkAgent:
adapt the GetIsolate removal to the NetworkAgent member helpers, qualify the
v8 Maybe helpers in network_agent, and drop duplicate inspector helper
definitions.
Ref: https://github.com/nodejs/node/pull/62162
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(patch): guard vm contextual-store strict assertion for Chromium's V8
test-vm-global-contextual-store was added upstream in nodejs/node#62571. It
asserts that an undeclared strict-mode contextual store (`"use strict"; z = 42`)
throws a ReferenceError. Chromium's V8 removed
v8::PropertyCallbackInfo<T>::This(), so Electron's contextify setter cannot
distinguish a contextual store from an explicit `globalThis.x = v` store; it
keeps the original behavior (writing to the sandbox) so explicit global stores
in vm modules keep working (test-vm-module-referrer-realm). Guard the
strict-mode ReferenceError assertion in the new test under Electron.
Ref: https://github.com/nodejs/node/pull/62571
Ref: https://github.com/nodejs/node/issues/60616
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Claude <noreply@anthropic.com>
151 lines
4.6 KiB
JavaScript
151 lines
4.6 KiB
JavaScript
const minimist = require('minimist');
|
|
|
|
const cp = require('node:child_process');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const utils = require('./lib/utils');
|
|
const DISABLED_TESTS = require('./node-disabled-tests.json');
|
|
|
|
const args = minimist(process.argv.slice(2), {
|
|
boolean: ['default', 'validateDisabled'],
|
|
string: ['jUnitDir']
|
|
});
|
|
|
|
const BASE = path.resolve(__dirname, '../..');
|
|
|
|
const ROOT_PACKAGE_JSON = path.resolve(BASE, 'package.json');
|
|
const NODE_DIR = path.resolve(BASE, 'third_party', 'electron_node');
|
|
const JUNIT_DIR = args.jUnitDir ? path.resolve(args.jUnitDir) : null;
|
|
const TAP_FILE_NAME = 'test.tap';
|
|
|
|
if (!require.main) {
|
|
throw new Error('Must call the node spec runner directly');
|
|
}
|
|
|
|
const defaultOptions = [
|
|
'tools/test.py',
|
|
'-p',
|
|
'tap',
|
|
'--logfile',
|
|
TAP_FILE_NAME,
|
|
'--mode=debug',
|
|
'default',
|
|
`--skip-tests=${DISABLED_TESTS.join(',')}`,
|
|
'--flaky-tests=dontcare',
|
|
'--measure-flakiness=9',
|
|
'--shell',
|
|
utils.getAbsoluteElectronExec(),
|
|
'-J'
|
|
];
|
|
|
|
// The upstream Node.js test suite assumes there is no package.json above the
|
|
// test tree. In Electron, third_party/electron_node lives under Chromium's
|
|
// src/, whose package.json ("type": "module") is always an ancestor. That
|
|
// changes how Node resolves the module type of test files and fixtures: it
|
|
// disables module-syntax detection (breaking e.g.
|
|
// test-compile-cache-typescript-esm) and emits MODULE_TYPELESS_PACKAGE_JSON
|
|
// warnings that break tests asserting clean stderr (e.g. test-esm-detect-
|
|
// ambiguous, test-esm-import-meta-main-eval, test-output-coverage-with-mock).
|
|
//
|
|
// While the suite runs we move src/package.json aside so the environment
|
|
// matches upstream exactly, then restore it when done. The original contents
|
|
// are kept in a sibling backup file so an interrupted/killed run self-heals on
|
|
// the next invocation rather than leaving src/package.json missing.
|
|
const ROOT_PACKAGE_JSON_BACKUP = `${ROOT_PACKAGE_JSON}.spec-runner-backup`;
|
|
|
|
const stashPackageJson = () => {
|
|
// This won't always exist in CI.
|
|
if (!fs.existsSync(ROOT_PACKAGE_JSON)) {
|
|
return;
|
|
}
|
|
fs.copyFileSync(ROOT_PACKAGE_JSON, ROOT_PACKAGE_JSON_BACKUP);
|
|
fs.rmSync(ROOT_PACKAGE_JSON);
|
|
};
|
|
|
|
const restorePackageJson = () => {
|
|
if (!fs.existsSync(ROOT_PACKAGE_JSON_BACKUP)) {
|
|
return;
|
|
}
|
|
fs.copyFileSync(ROOT_PACKAGE_JSON_BACKUP, ROOT_PACKAGE_JSON);
|
|
fs.rmSync(ROOT_PACKAGE_JSON_BACKUP);
|
|
};
|
|
|
|
const getCustomOptions = () => {
|
|
let customOptions = ['tools/test.py'];
|
|
|
|
// Add all custom arguments.
|
|
const extra = process.argv.slice(2);
|
|
if (extra) {
|
|
customOptions = customOptions.concat(extra);
|
|
}
|
|
|
|
// Necessary or Node.js will try to run from out/Release/node.
|
|
customOptions = customOptions.concat(['--shell', utils.getAbsoluteElectronExec()]);
|
|
|
|
return customOptions;
|
|
};
|
|
|
|
async function main() {
|
|
// Optionally validate that all disabled specs still exist.
|
|
if (args.validateDisabled) {
|
|
const missing = [];
|
|
for (const test of DISABLED_TESTS) {
|
|
const js = path.join(NODE_DIR, 'test', `${test}.js`);
|
|
const mjs = path.join(NODE_DIR, 'test', `${test}.mjs`);
|
|
if (!fs.existsSync(js) && !fs.existsSync(mjs)) {
|
|
missing.push(test);
|
|
}
|
|
}
|
|
|
|
if (missing.length > 0) {
|
|
console.error(`Found ${missing.length} missing disabled specs: \n${missing.join('\n')}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log(`All ${DISABLED_TESTS.length} disabled specs exist.`);
|
|
process.exit(0);
|
|
}
|
|
|
|
const options = args.default ? defaultOptions : getCustomOptions();
|
|
|
|
// Recover src/package.json if a previous run was interrupted, then move it
|
|
// aside for the duration of this run.
|
|
restorePackageJson();
|
|
stashPackageJson();
|
|
|
|
// Make sure src/package.json is put back even if we exit abnormally.
|
|
process.on('exit', restorePackageJson);
|
|
process.on('SIGINT', () => process.exit(130));
|
|
process.on('SIGTERM', () => process.exit(143));
|
|
|
|
const testChild = cp.spawn('python3', options, {
|
|
env: {
|
|
...process.env,
|
|
ELECTRON_RUN_AS_NODE: 'true',
|
|
ELECTRON_EAGER_ASAR_HOOK_FOR_TESTING: 'true'
|
|
},
|
|
cwd: NODE_DIR,
|
|
stdio: 'inherit'
|
|
});
|
|
|
|
testChild.on('exit', (testCode) => {
|
|
restorePackageJson();
|
|
|
|
if (JUNIT_DIR) {
|
|
fs.mkdirSync(JUNIT_DIR);
|
|
const converterStream = require('tap-xunit')();
|
|
fs.createReadStream(path.resolve(NODE_DIR, TAP_FILE_NAME))
|
|
.pipe(converterStream)
|
|
.pipe(fs.createWriteStream(path.resolve(JUNIT_DIR, 'nodejs.xml')))
|
|
.on('close', () => {
|
|
process.exit(testCode);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error('An unhandled error occurred in the node spec runner', err);
|
|
process.exit(1);
|
|
});
|