* 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)
(cherry picked from commit 0409547133609051b1c9c26ce661230967a9b08a)
* 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)
(cherry picked from commit 46b28d26083e3d68b3d2dd03878b77ca0a97ee76)
* 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)
(cherry picked from commit 07827c6841805eada8c37b83831938db98d6aa57)
* 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>
(cherry picked from commit 379d109aae3ec89956c07c32a7c324235a15921c)
* 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)
(cherry picked from commit 3190c995cdf6826a18175151fb96fc76ca0f3387)
* 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)
(cherry picked from commit 2dfc1ae1d1e9b4a53ff365d96df29d598fc54e1f)
* 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)
(cherry picked from commit 44f40947b23acde6d1b09d6361f2f53943c3ad6b)
* 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)
(cherry picked from commit 792e1e5c6772408c22071d3019157d6d027fd353)
* 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)
(cherry picked from commit 0506b64d3f966c9d2a982c2fad7c2ccf17a7614c)
* 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>
(cherry picked from commit 31b7fb0e6d5012f3742ffc73a0d2c475f84b1676)
* fix(patch): update GetIsolate removal for inspector NetworkAgent refactor
Upstream refactored the inspector network agent helpers into
NetworkAgent:: methods, shifting where context->GetIsolate() appeared
and reorganizing node_contextify's PropertyDefinerCallback. Re-applied
the deprecated context->GetIsolate() -> v8::Isolate::GetCurrent()
replacements to the new structure.
Ref: https://github.com/nodejs/node/pull/62162
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix: drop dangling .patches entries for non-existent patch files
The cherry-pick of the cast-const fix (343078bf01) erroneously added
four entries to patches/node/.patches that reference patch files which
were never part of the 41-x-y branch (externalpointertypetag, thinlto
symbol preservation, v8 code cache, and startup snapshot generation).
The missing files caused `e sync` to abort while reading patches.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* chore: update patches (trivial only)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* test: disable test-vm-global-contextual-store
This new upstream test asserts that a strict-mode store to an undeclared
global in a vm context throws ReferenceError. Chromium's V8 contextify
global-proxy interceptor instead creates the property, so the assertion
is fundamentally incompatible with Electron's V8 and cannot be guarded
to pass.
Ref: https://github.com/nodejs/node/pull/62571
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);
|
|
});
|