-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add node compat test cases (#27134)
This PR enables node compat test cases found passing by using the tool added in #27122 The percentage of passing test case increases from 16.16% to 30.43% by this change.
- Loading branch information
1 parent
feba98a
commit e05a305
Showing
527 changed files
with
30,399 additions
and
530 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
143 changes: 143 additions & 0 deletions
143
tests/node_compat/test/abort/test-addon-uv-handle-leak.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
// deno-fmt-ignore-file | ||
// deno-lint-ignore-file | ||
|
||
// Copyright Joyent and Node contributors. All rights reserved. MIT license. | ||
// Taken from Node 20.11.1 | ||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. | ||
|
||
'use strict'; | ||
const common = require('../common'); | ||
const assert = require('assert'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const cp = require('child_process'); | ||
const { spawnSync } = require('child_process'); | ||
|
||
// This is a sibling test to test/addons/uv-handle-leak. | ||
|
||
const bindingPath = path.resolve( | ||
__dirname, '..', 'addons', 'uv-handle-leak', 'build', | ||
`${common.buildType}/binding.node`); | ||
|
||
if (!fs.existsSync(bindingPath)) | ||
common.skip('binding not built yet'); | ||
|
||
if (process.argv[2] === 'child') { | ||
|
||
const { Worker } = require('worker_threads'); | ||
|
||
// The worker thread loads and then unloads `bindingPath`. Because of this the | ||
// symbols in `bindingPath` are lost when the worker thread quits, but the | ||
// number of open handles in the worker thread's event loop is assessed in the | ||
// main thread afterwards, and the names of the callbacks associated with the | ||
// open handles is retrieved at that time as well. Thus, we require | ||
// `bindingPath` here so that the symbols and their names survive the life | ||
// cycle of the worker thread. | ||
require(bindingPath); | ||
|
||
new Worker(` | ||
const binding = require(${JSON.stringify(bindingPath)}); | ||
binding.leakHandle(); | ||
binding.leakHandle(0); | ||
binding.leakHandle(0x42); | ||
`, { eval: true }); | ||
} else { | ||
const child = cp.spawnSync(process.execPath, [__filename, 'child']); | ||
const stderr = child.stderr.toString(); | ||
|
||
assert.strictEqual(child.stdout.toString(), ''); | ||
|
||
const lines = stderr.split('\n'); | ||
|
||
let state = 'initial'; | ||
|
||
// Parse output that is formatted like this: | ||
|
||
// uv loop at [0x559b65ed5770] has open handles: | ||
// [0x7f2de0018430] timer (active) | ||
// Close callback: 0x7f2df31de220 CloseCallback(uv_handle_s*) [...] | ||
// Data: 0x7f2df33df140 example_instance [...] | ||
// (First field): 0x7f2df33dedc0 vtable for ExampleOwnerClass [...] | ||
// [0x7f2de000b870] timer | ||
// Close callback: 0x7f2df31de220 CloseCallback(uv_handle_s*) [...] | ||
// Data: (nil) | ||
// [0x7f2de000b910] timer | ||
// Close callback: 0x7f2df31de220 CloseCallback(uv_handle_s*) [...] | ||
// Data: 0x42 | ||
// uv loop at [0x559b65ed5770] has 3 open handles in total | ||
|
||
function isGlibc() { | ||
try { | ||
const lddOut = spawnSync('ldd', [process.execPath]).stdout; | ||
const libcInfo = lddOut.toString().split('\n').map( | ||
(line) => line.match(/libc\.so.+=>\s*(\S+)\s/)).filter((info) => info); | ||
if (libcInfo.length === 0) | ||
return false; | ||
const nmOut = spawnSync('nm', ['-D', libcInfo[0][1]]).stdout; | ||
if (/gnu_get_libc_version/.test(nmOut)) | ||
return true; | ||
} catch { | ||
return false; | ||
} | ||
} | ||
|
||
|
||
if (!(common.isFreeBSD || | ||
common.isAIX || | ||
common.isIBMi || | ||
(common.isLinux && !isGlibc()) || | ||
common.isWindows)) { | ||
assert(stderr.includes('ExampleOwnerClass'), stderr); | ||
assert(stderr.includes('CloseCallback'), stderr); | ||
assert(stderr.includes('example_instance'), stderr); | ||
} | ||
|
||
while (lines.length > 0) { | ||
const line = lines.shift().trim(); | ||
if (line.length === 0) { | ||
continue; // Skip empty lines. | ||
} | ||
|
||
switch (state) { | ||
case 'initial': | ||
assert.match(line, /^uv loop at \[.+\] has open handles:$/); | ||
state = 'handle-start'; | ||
break; | ||
case 'handle-start': | ||
if (/^uv loop at \[.+\] has \d+ open handles in total$/.test(line)) { | ||
state = 'source-line'; | ||
break; | ||
} | ||
assert.match(line, /^\[.+\] timer( \(active\))?$/); | ||
state = 'close-callback'; | ||
break; | ||
case 'close-callback': | ||
assert.match(line, /^Close callback:/); | ||
state = 'data'; | ||
break; | ||
case 'data': | ||
assert.match(line, /^Data: .+$/); | ||
state = 'maybe-first-field'; | ||
break; | ||
case 'maybe-first-field': | ||
if (!/^\(First field\)/.test(line)) { | ||
lines.unshift(line); | ||
} | ||
state = 'handle-start'; | ||
break; | ||
case 'source-line': | ||
assert.match(line, /CheckedUvLoopClose/); | ||
state = 'assertion-failure'; | ||
break; | ||
case 'assertion-failure': | ||
assert.match(line, /Assertion failed:/); | ||
state = 'done'; | ||
break; | ||
case 'done': | ||
break; | ||
} | ||
} | ||
|
||
assert.strictEqual(state, 'done'); | ||
} |
20 changes: 20 additions & 0 deletions
20
tests/node_compat/test/benchmark/test-benchmark-async-hooks.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// deno-fmt-ignore-file | ||
// deno-lint-ignore-file | ||
|
||
// Copyright Joyent and Node contributors. All rights reserved. MIT license. | ||
// Taken from Node 20.11.1 | ||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. | ||
|
||
'use strict'; | ||
|
||
const common = require('../common'); | ||
|
||
if (!common.hasCrypto) | ||
common.skip('missing crypto'); | ||
|
||
if (!common.enoughTestMem) | ||
common.skip('Insufficient memory for async_hooks benchmark test'); | ||
|
||
const runBenchmark = require('../common/benchmark'); | ||
|
||
runBenchmark('async_hooks'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// deno-fmt-ignore-file | ||
// deno-lint-ignore-file | ||
|
||
// Copyright Joyent and Node contributors. All rights reserved. MIT license. | ||
// Taken from Node 20.11.1 | ||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. | ||
|
||
'use strict'; | ||
|
||
const common = require('../common'); | ||
|
||
if (!common.enoughTestMem) | ||
common.skip('Insufficient memory for HTTP benchmark test'); | ||
|
||
// Because the http benchmarks use hardcoded ports, this should be in sequential | ||
// rather than parallel to make sure it does not conflict with tests that choose | ||
// random available ports. | ||
|
||
const runBenchmark = require('../common/benchmark'); | ||
|
||
runBenchmark('http', { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// deno-fmt-ignore-file | ||
// deno-lint-ignore-file | ||
|
||
// Copyright Joyent and Node contributors. All rights reserved. MIT license. | ||
// Taken from Node 20.11.1 | ||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. | ||
|
||
'use strict'; | ||
|
||
const common = require('../common'); | ||
if (!common.hasCrypto) | ||
common.skip('missing crypto'); | ||
|
||
if (!common.enoughTestMem) | ||
common.skip('Insufficient memory for HTTP/2 benchmark test'); | ||
|
||
// Because the http benchmarks use hardcoded ports, this should be in sequential | ||
// rather than parallel to make sure it does not conflict with tests that choose | ||
// random available ports. | ||
|
||
const runBenchmark = require('../common/benchmark'); | ||
|
||
runBenchmark('http2', { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// deno-fmt-ignore-file | ||
// deno-lint-ignore-file | ||
|
||
// Copyright Joyent and Node contributors. All rights reserved. MIT license. | ||
// Taken from Node 20.11.1 | ||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. | ||
|
||
'use strict'; | ||
|
||
const common = require('../common'); | ||
|
||
if (!common.hasCrypto) | ||
common.skip('missing crypto'); | ||
|
||
if (!common.enoughTestMem) | ||
common.skip('Insufficient memory for TLS benchmark test'); | ||
|
||
// Because the TLS benchmarks use hardcoded ports, this should be in sequential | ||
// rather than parallel to make sure it does not conflict with tests that choose | ||
// random available ports. | ||
|
||
const runBenchmark = require('../common/benchmark'); | ||
|
||
runBenchmark('tls', { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// deno-fmt-ignore-file | ||
// deno-lint-ignore-file | ||
|
||
// Copyright Joyent and Node contributors. All rights reserved. MIT license. | ||
// Taken from Node 20.11.1 | ||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. | ||
|
||
'use strict'; | ||
|
||
const common = require('../common'); | ||
|
||
if (!common.enoughTestMem) | ||
common.skip('Insufficient memory for Worker benchmark test'); | ||
|
||
// Because the worker benchmarks can run on different threads, | ||
// this should be in sequential rather than parallel to make sure | ||
// it does not conflict with tests that choose random available ports. | ||
|
||
const runBenchmark = require('../common/benchmark'); | ||
|
||
runBenchmark('worker', { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 }); |
19 changes: 19 additions & 0 deletions
19
tests/node_compat/test/es-module/test-cjs-prototype-pollution.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// deno-fmt-ignore-file | ||
// deno-lint-ignore-file | ||
|
||
// Copyright Joyent and Node contributors. All rights reserved. MIT license. | ||
// Taken from Node 20.11.1 | ||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. | ||
|
||
'use strict'; | ||
|
||
const { mustNotCall, mustCall } = require('../common'); | ||
|
||
Object.defineProperties(Object.prototype, { | ||
then: { | ||
set: mustNotCall('set %Object.prototype%.then'), | ||
get: mustNotCall('get %Object.prototype%.then'), | ||
}, | ||
}); | ||
|
||
import('data:text/javascript,').then(mustCall()); |
29 changes: 29 additions & 0 deletions
29
tests/node_compat/test/es-module/test-esm-dynamic-import-mutating-fs.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// deno-fmt-ignore-file | ||
// deno-lint-ignore-file | ||
|
||
// Copyright Joyent and Node contributors. All rights reserved. MIT license. | ||
// Taken from Node 20.11.1 | ||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. | ||
|
||
'use strict'; | ||
const common = require('../common'); | ||
const tmpdir = require('../common/tmpdir'); | ||
|
||
const assert = require('node:assert'); | ||
const fs = require('node:fs/promises'); | ||
|
||
tmpdir.refresh(); | ||
const target = tmpdir.fileURL(`${Math.random()}.mjs`); | ||
|
||
(async () => { | ||
|
||
await assert.rejects(import(target), { code: 'ERR_MODULE_NOT_FOUND' }); | ||
|
||
await fs.writeFile(target, 'export default "actual target"\n'); | ||
|
||
const moduleRecord = await import(target); | ||
|
||
await fs.rm(target); | ||
|
||
assert.strictEqual(await import(target), moduleRecord); | ||
})().then(common.mustCall()); |
17 changes: 17 additions & 0 deletions
17
tests/node_compat/test/es-module/test-esm-loader-cache-clearing.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// deno-fmt-ignore-file | ||
// deno-lint-ignore-file | ||
|
||
// Copyright Joyent and Node contributors. All rights reserved. MIT license. | ||
// Taken from Node 20.11.1 | ||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. | ||
|
||
'use strict'; | ||
require('../common'); | ||
|
||
const { cache } = require; | ||
|
||
Object.keys(cache).forEach((key) => { | ||
delete cache[key]; | ||
}); | ||
// Require the same module again triggers the crash | ||
require('../common'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// deno-fmt-ignore-file | ||
// deno-lint-ignore-file | ||
|
||
// Copyright Joyent and Node contributors. All rights reserved. MIT license. | ||
// Taken from Node 20.11.1 | ||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. | ||
|
||
'use strict'; | ||
|
||
// This test ensures that JavaScript file that includes | ||
// a reserved Windows word can be loaded as ESM module | ||
|
||
const common = require('../common'); | ||
const tmpdir = require('../common/tmpdir'); | ||
const assert = require('assert'); | ||
const fs = require('fs').promises; | ||
const path = require('path'); | ||
|
||
const imp = (file) => { | ||
return import(path.relative(__dirname, file).replace(/\\/g, '/')); | ||
}; | ||
|
||
(async () => { | ||
tmpdir.refresh(); | ||
const rel = (file) => tmpdir.resolve(file); | ||
|
||
{ // Load a single script | ||
const file = rel('con.mjs'); | ||
await fs.writeFile(file, 'export default "ok"'); | ||
assert.strictEqual((await imp(file)).default, 'ok'); | ||
await fs.unlink(file); | ||
} | ||
|
||
{ // Load a module | ||
const entry = rel('entry.mjs'); | ||
const nmDir = rel('node_modules'); | ||
const mDir = rel('node_modules/con'); | ||
const pkg = rel('node_modules/con/package.json'); | ||
const script = rel('node_modules/con/index.mjs'); | ||
|
||
await fs.writeFile(entry, 'export {default} from "con"'); | ||
await fs.mkdir(nmDir); | ||
await fs.mkdir(mDir); | ||
await fs.writeFile(pkg, '{"main":"index.mjs"}'); | ||
await fs.writeFile(script, 'export default "ok"'); | ||
|
||
assert.strictEqual((await imp(entry)).default, 'ok'); | ||
await fs.unlink(script); | ||
await fs.unlink(pkg); | ||
await fs.rmdir(mDir); | ||
await fs.rmdir(nmDir); | ||
await fs.unlink(entry); | ||
} | ||
})().then(common.mustCall()); |
Oops, something went wrong.