diff --git a/node.gyp b/node.gyp index 08f8059c0059..c58f4812e2e1 100644 --- a/node.gyp +++ b/node.gyp @@ -1511,6 +1511,61 @@ ], }, # embedtest + { + 'target_name': 'shared_embedtest', + 'type': 'executable', + + 'dependencies': [ + '<(node_lib_target_name)', + ], + + # Don't depend on node.gypi - it otherwise links to + # the static libraries and resolve symbols at build time. + 'include_dirs': [ + 'deps/v8/include', + ], + + 'sources': [ + 'test/embedding/shared_embedtest.cc', + ], + 'conditions': [ + [ 'node_shared=="true"', { + 'defines': [ + 'USING_V8_SHARED', + 'USING_V8_PLATFORM_SHARED', + ], + 'defines!': [ + 'BUILDING_V8_PLATFORM_SHARED=1', + 'BUILDING_V8_SHARED=1', + ], + }, { + # Only test shared embedding when Node is built as shared library. + 'type': 'none', + }], + # Only test platforms known to work. + ['OS not in "mac win linux"', { + 'type': 'none', + }], + ['OS=="win"', { + 'libraries': [ + 'Dbghelp.lib', + 'winmm.lib', + 'Ws2_32.lib', + ], + }], + ['OS=="mac"', { + 'xcode_settings': { + 'OTHER_LDFLAGS': [ '-Wl,-rpath,@loader_path', ], + } + }], + ['OS=="linux"', { + 'ldflags': [ + '-Wl,-rpath,\\$$ORIGIN' + ], + }], + ], + }, # shared_embedtest + { 'target_name': 'overlapped-checker', 'type': 'executable', diff --git a/test/common/index.js b/test/common/index.js index 6cfebae8f499..6b0dafffef13 100755 --- a/test/common/index.js +++ b/test/common/index.js @@ -51,6 +51,8 @@ if (isMainThread) const noop = () => {}; +// Whether the executable is linked against the shared library i.e. libnode. +const usesSharedLibrary = process.config.variables.node_shared; const hasCrypto = Boolean(process.versions.openssl) && !process.env.NODE_SKIP_CRYPTO; @@ -923,6 +925,13 @@ function sleepSync(ms) { Atomics.wait(i32, 0, 0, ms); } +function resolveBuiltBinary(binary) { + if (isWindows) { + binary += '.exe'; + } + return path.join(path.dirname(process.execPath), binary); +} + const common = { allowGlobals, buildType, @@ -967,6 +976,7 @@ const common = { printSkipMessage, pwdCommand, requireNoPackageJSONAbove, + resolveBuiltBinary, runWithInvalidFD, skip, skipIf32Bits, @@ -975,6 +985,7 @@ const common = { skipIfSQLiteMissing, spawnPromisified, sleepSync, + usesSharedLibrary, get enoughTestMem() { return require('os').totalmem() > 0x70000000; /* 1.75 Gb */ diff --git a/test/embedding/shared_embedtest.cc b/test/embedding/shared_embedtest.cc new file mode 100644 index 000000000000..f071f43c5b76 --- /dev/null +++ b/test/embedding/shared_embedtest.cc @@ -0,0 +1,60 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +class Wrappable : public v8::Object::Wrappable { + public: + void Trace(cppgc::Visitor* visitor) const override { + v8::Object::Wrappable::Trace(visitor); + } +}; + +int main(int argc, char* argv[]) { + std::unique_ptr platform = v8::platform::NewDefaultPlatform(); + v8::V8::InitializePlatform(platform.get()); + cppgc::InitializeProcess(platform->GetPageAllocator()); + v8::V8::Initialize(); + + auto heap = v8::CppHeap::Create(platform.get(), v8::CppHeapCreateParams{{}}); + v8::Isolate::CreateParams create_params; + create_params.array_buffer_allocator = + v8::ArrayBuffer::Allocator::NewDefaultAllocator(); + create_params.cpp_heap = heap.release(); + + v8::Isolate* isolate = v8::Isolate::New(create_params); + { + v8::Isolate::Scope isolate_scope(isolate); + v8::HandleScope handle_scope(isolate); + v8::Local context = v8::Context::New(isolate); + v8::Context::Scope context_scope(context); + + v8::Local obj = v8::Object::New(isolate); + Wrappable* wrappable = cppgc::MakeGarbageCollected( + isolate->GetCppHeap()->GetAllocationHandle()); + v8::Object::Wrap( + isolate, obj, wrappable); + v8::Local source = + v8::String::NewFromUtf8Literal(isolate, "'Hello' + ', World!'"); + v8::Local script = + v8::Script::Compile(context, source).ToLocalChecked(); + v8::Local result = script->Run(context).ToLocalChecked(); + v8::String::Utf8Value utf8(isolate, result); + printf("%s\n", *utf8); + } + + isolate->Dispose(); + cppgc::ShutdownProcess(); + v8::V8::Dispose(); + v8::V8::DisposePlatform(); + delete create_params.array_buffer_allocator; + + return 0; +} diff --git a/test/embedding/test-embedding-create-require-fs.js b/test/embedding/test-embedding-create-require-fs.js new file mode 100644 index 000000000000..28a09f60d99e --- /dev/null +++ b/test/embedding/test-embedding-create-require-fs.js @@ -0,0 +1,17 @@ +'use strict'; + +// Tests that createRequire() works correctly with local fs in embedded environments. +// The createRequire() call is in embedtest.cc. + +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const { spawnSyncAndExit } = require('../common/child_process'); + +const fixturePath = JSON.stringify(fixtures.path('exit.js')); +spawnSyncAndExit( + common.resolveBuiltBinary('embedtest'), + [`require(${fixturePath})`, 92], + { + status: 92, + signal: null, + }); diff --git a/test/embedding/test-embedding-create-require-internal.js b/test/embedding/test-embedding-create-require-internal.js new file mode 100644 index 000000000000..d88ae4e39a17 --- /dev/null +++ b/test/embedding/test-embedding-create-require-internal.js @@ -0,0 +1,15 @@ +'use strict'; + +// Tests that createRequire() from embedded environments still cannot access internals. +// The createRequire() call is in embedtest.cc. + +const common = require('../common'); +const { spawnSyncAndExit } = require('../common/child_process'); + +spawnSyncAndExit( + common.resolveBuiltBinary('embedtest'), + ['require("lib/internal/test/binding")'], + { + status: 1, + signal: null, + }); diff --git a/test/embedding/test-embedding-disable-node-env-vars.js b/test/embedding/test-embedding-disable-node-env-vars.js new file mode 100644 index 000000000000..13492e916947 --- /dev/null +++ b/test/embedding/test-embedding-disable-node-env-vars.js @@ -0,0 +1,27 @@ +'use strict'; + +// Tests node::ProcessInitializationFlags::kDisableNodeOptionsEnv works correctly. + +const common = require('../common'); +const { spawnSyncAndExit } = require('../common/child_process'); +const os = require('os'); + +if (process.config.variables.node_without_node_options) { + common.skip('NODE_REPL_EXTERNAL_MODULE cannot be tested with --without-node-options'); +} + +const embedtest = common.resolveBuiltBinary('embedtest'); +spawnSyncAndExit( + embedtest, + ['require("os")'], + { + env: { + ...process.env, + 'NODE_REPL_EXTERNAL_MODULE': 'fs', + }, + }, + { + status: 9, + signal: null, + stderr: `${embedtest}: NODE_REPL_EXTERNAL_MODULE can't be used with kDisableNodeOptionsEnv${os.EOL}`, + }); diff --git a/test/embedding/test-embedding-exit-code.js b/test/embedding/test-embedding-exit-code.js new file mode 100644 index 000000000000..35cd7ffc1253 --- /dev/null +++ b/test/embedding/test-embedding-exit-code.js @@ -0,0 +1,14 @@ +'use strict'; + +// Tests that process.exitCode works correctly in embedded environments. + +const common = require('../common'); +const { spawnSyncAndExit } = require('../common/child_process'); + +spawnSyncAndExit( + common.resolveBuiltBinary('embedtest'), + ['process.exitCode = 8'], + { + status: 8, + signal: null, + }); diff --git a/test/embedding/test-embedding-load-environment-basic.js b/test/embedding/test-embedding-load-environment-basic.js new file mode 100644 index 000000000000..2627dd34fc1f --- /dev/null +++ b/test/embedding/test-embedding-load-environment-basic.js @@ -0,0 +1,16 @@ +'use strict'; + +// Tests node::LoadEnvironment() with main_script_source_utf8 works. + +const common = require('../common'); +const { spawnSyncAndAssert } = require('../common/child_process'); + +const embedtest = common.resolveBuiltBinary('embedtest'); + +spawnSyncAndAssert( + embedtest, + ['console.log(42)'], + { + trim: true, + stdout: '42', + }); diff --git a/test/embedding/test-embedding-load-environment-utf8.js b/test/embedding/test-embedding-load-environment-utf8.js new file mode 100644 index 000000000000..dfc5d52a86f6 --- /dev/null +++ b/test/embedding/test-embedding-load-environment-utf8.js @@ -0,0 +1,17 @@ +'use strict'; + +// Test node::LoadEnvironment() works with non-ASCII source code. The variable +// comes from embedtest.cc. + +const common = require('../common'); +const { spawnSyncAndAssert } = require('../common/child_process'); + +const embedtest = common.resolveBuiltBinary('embedtest'); + +spawnSyncAndAssert( + embedtest, + ['console.log(embedVars.nön_ascıı)'], + { + trim: true, + stdout: '🏳️‍🌈', + }); diff --git a/test/embedding/test-embedding-snapshot-as-file.js b/test/embedding/test-embedding-snapshot-as-file.js new file mode 100644 index 000000000000..5a9b4b1d9283 --- /dev/null +++ b/test/embedding/test-embedding-snapshot-as-file.js @@ -0,0 +1,50 @@ +'use strict'; + +// Tests node::EmbedderSnapshotData::FromFile() works correctly. +// The snapshot is created in embedtest.cc. + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fixtures = require('../common/fixtures'); + +const { + spawnSyncAndAssert, + spawnSyncAndExitWithoutError, +} = require('../common/child_process'); + +const snapshotFixture = fixtures.path('snapshot', 'echo-args.js'); +const embedtest = common.resolveBuiltBinary('embedtest'); + +const buildSnapshotExecArgs = [ + `eval(require("fs").readFileSync(${JSON.stringify(snapshotFixture)}, "utf8"))`, + 'arg1', 'arg2', +]; +const snapshotBlobArgs = [ + '--embedder-snapshot-blob', tmpdir.resolve('embedder-snapshot.blob'), +]; + +const runSnapshotExecArgs = ['arg3', 'arg4']; + +tmpdir.refresh(); + +// Build the snapshot with the --embedder-snapshot-as-file flag. +spawnSyncAndExitWithoutError( + embedtest, + ['--', ...buildSnapshotExecArgs, ...snapshotBlobArgs, '--embedder-snapshot-as-file', '--embedder-snapshot-create'], + { cwd: tmpdir.path }); + +// Run the snapshot and check the serialized and refreshed argv values. +spawnSyncAndAssert( + embedtest, + ['--', ...runSnapshotExecArgs, ...snapshotBlobArgs ], + { cwd: tmpdir.path }, + { + stdout(output) { + assert.deepStrictEqual(JSON.parse(output), { + originalArgv: [embedtest, '__node_anonymous_main', ...buildSnapshotExecArgs], + currentArgv: [embedtest, ...runSnapshotExecArgs], + }); + return true; + }, + }); diff --git a/test/embedding/test-embedding-snapshot-basic.js b/test/embedding/test-embedding-snapshot-basic.js new file mode 100644 index 000000000000..8ace784116df --- /dev/null +++ b/test/embedding/test-embedding-snapshot-basic.js @@ -0,0 +1,50 @@ +'use strict'; + +// Tests snapshot support in embedded environments. +// See embedtest.cc for the API usage. + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fixtures = require('../common/fixtures'); + +const { + spawnSyncAndAssert, + spawnSyncAndExitWithoutError, +} = require('../common/child_process'); + +const snapshotFixture = fixtures.path('snapshot', 'echo-args.js'); +const embedtest = common.resolveBuiltBinary('embedtest'); + +const buildSnapshotExecArgs = [ + `eval(require("fs").readFileSync(${JSON.stringify(snapshotFixture)}, "utf8"))`, + 'arg1', 'arg2', +]; +const snapshotBlobArgs = [ + '--embedder-snapshot-blob', tmpdir.resolve('embedder-snapshot.blob'), +]; + +const runSnapshotExecArgs = ['arg3', 'arg4']; + +tmpdir.refresh(); + +// Build the snapshot with the default flags. +spawnSyncAndExitWithoutError( + embedtest, + ['--', ...buildSnapshotExecArgs, ...snapshotBlobArgs, '--embedder-snapshot-create'], + { cwd: tmpdir.path }); + +// Run the snapshot and check the serialized and refreshed argv values. +spawnSyncAndAssert( + embedtest, + ['--', ...runSnapshotExecArgs, ...snapshotBlobArgs ], + { cwd: tmpdir.path }, + { + stdout(output) { + assert.deepStrictEqual(JSON.parse(output), { + originalArgv: [embedtest, '__node_anonymous_main', ...buildSnapshotExecArgs], + currentArgv: [embedtest, ...runSnapshotExecArgs], + }); + return true; + }, + }); diff --git a/test/embedding/test-embedding-snapshot-vm.js b/test/embedding/test-embedding-snapshot-vm.js new file mode 100644 index 000000000000..0d60059056ad --- /dev/null +++ b/test/embedding/test-embedding-snapshot-vm.js @@ -0,0 +1,43 @@ +'use strict'; + +// Tests creating vm contexts after snapshot deserialization works +// in embedded environments. + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const fixtures = require('../common/fixtures'); + +const { + spawnSyncAndAssert, + spawnSyncAndExitWithoutError, +} = require('../common/child_process'); + +const snapshotFixture = fixtures.path('snapshot', 'create-vm.js'); +const embedtest = common.resolveBuiltBinary('embedtest'); + +const buildSnapshotExecArgs = [ + `eval(require("fs").readFileSync(${JSON.stringify(snapshotFixture)}, "utf8"))`, + 'arg1', 'arg2', +]; +const snapshotBlobArgs = [ + '--embedder-snapshot-blob', tmpdir.resolve('embedder-snapshot.blob'), +]; + +const runSnapshotExecArgs = ['arg3', 'arg4']; + +tmpdir.refresh(); + +// Build the snapshot with the vm-creating code in serialized main funciton. +spawnSyncAndExitWithoutError( + embedtest, + ['--', ...buildSnapshotExecArgs, ...snapshotBlobArgs, '--embedder-snapshot-create'], + { cwd: tmpdir.path }); + +// Run the snapshot that creates a vm context from the snapshot. +spawnSyncAndAssert( + embedtest, + ['--', ...runSnapshotExecArgs, ...snapshotBlobArgs ], + { cwd: tmpdir.path }, + { + stdout: /value: 42/, + }); diff --git a/test/embedding/test-embedding-snapshot-without-code-cache.js b/test/embedding/test-embedding-snapshot-without-code-cache.js new file mode 100644 index 000000000000..577ace1188ff --- /dev/null +++ b/test/embedding/test-embedding-snapshot-without-code-cache.js @@ -0,0 +1,50 @@ +'use strict'; + +// Tests node::SnapshotFlags::kWithoutCodeCache. See +// embedtest.cc for more details. + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fixtures = require('../common/fixtures'); + +const { + spawnSyncAndAssert, + spawnSyncAndExitWithoutError, +} = require('../common/child_process'); + +const snapshotFixture = fixtures.path('snapshot', 'echo-args.js'); +const embedtest = common.resolveBuiltBinary('embedtest'); + +const buildSnapshotExecArgs = [ + `eval(require("fs").readFileSync(${JSON.stringify(snapshotFixture)}, "utf8"))`, + 'arg1', 'arg2', +]; +const snapshotBlobArgs = [ + '--embedder-snapshot-blob', tmpdir.resolve('embedder-snapshot.blob'), +]; + +const runSnapshotExecArgs = ['arg3', 'arg4']; + +tmpdir.refresh(); + +// Build the snapshot with the --without-code-cache flag. +spawnSyncAndExitWithoutError( + embedtest, + ['--', ...buildSnapshotExecArgs, ...snapshotBlobArgs, '--without-code-cache', '--embedder-snapshot-create'], + { cwd: tmpdir.path }); + +// Run the snapshot and check the serialized and refreshed argv values. +spawnSyncAndAssert( + embedtest, + ['--', ...runSnapshotExecArgs, ...snapshotBlobArgs ], + { cwd: tmpdir.path }, + { + stdout(output) { + assert.deepStrictEqual(JSON.parse(output), { + originalArgv: [embedtest, '__node_anonymous_main', ...buildSnapshotExecArgs], + currentArgv: [embedtest, ...runSnapshotExecArgs], + }); + return true; + }, + }); diff --git a/test/embedding/test-embedding-snapshot-worker.js b/test/embedding/test-embedding-snapshot-worker.js new file mode 100644 index 000000000000..c6f665eed4d1 --- /dev/null +++ b/test/embedding/test-embedding-snapshot-worker.js @@ -0,0 +1,43 @@ +'use strict'; + +// Tests creating workers after snapshot deserialization works +// in embedded environments. + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const fixtures = require('../common/fixtures'); + +const { + spawnSyncAndAssert, + spawnSyncAndExitWithoutError, +} = require('../common/child_process'); + +const snapshotFixture = fixtures.path('snapshot', 'create-worker.js'); +const embedtest = common.resolveBuiltBinary('embedtest'); + +const buildSnapshotExecArgs = [ + `eval(require("fs").readFileSync(${JSON.stringify(snapshotFixture)}, "utf8"))`, + 'arg1', 'arg2', +]; +const snapshotBlobArgs = [ + '--embedder-snapshot-blob', tmpdir.resolve('embedder-snapshot.blob'), +]; + +const runSnapshotExecArgs = ['arg3', 'arg4']; + +tmpdir.refresh(); + +// Build the snapshot with the worker-creating code in serialized main funciton. +spawnSyncAndExitWithoutError( + embedtest, + ['--', ...buildSnapshotExecArgs, ...snapshotBlobArgs, '--embedder-snapshot-create'], + { cwd: tmpdir.path }); + +// Run the snapshot that creates a worker from the snapshot. +spawnSyncAndAssert( + embedtest, + ['--', ...runSnapshotExecArgs, ...snapshotBlobArgs ], + { cwd: tmpdir.path }, + { + stdout: /value: 42/, + }); diff --git a/test/embedding/test-embedding-throw.js b/test/embedding/test-embedding-throw.js new file mode 100644 index 000000000000..8aacade67d40 --- /dev/null +++ b/test/embedding/test-embedding-throw.js @@ -0,0 +1,14 @@ +'use strict'; + +// Tests that uncaught exceptions are handled correctly in embedded environments. + +const common = require('../common'); +const { spawnSyncAndExit } = require('../common/child_process'); + +spawnSyncAndExit( + common.resolveBuiltBinary('embedtest'), + ['throw new Error()'], + { + status: 1, + signal: null, + }); diff --git a/test/embedding/test-embedding.js b/test/embedding/test-embedding.js deleted file mode 100644 index 49706079fd8b..000000000000 --- a/test/embedding/test-embedding.js +++ /dev/null @@ -1,172 +0,0 @@ -'use strict'; -const common = require('../common'); -const fixtures = require('../common/fixtures'); -const tmpdir = require('../common/tmpdir'); -const assert = require('assert'); -const { - spawnSyncAndAssert, - spawnSyncAndExit, - spawnSyncAndExitWithoutError, -} = require('../common/child_process'); -const path = require('path'); -const fs = require('fs'); -const os = require('os'); - -tmpdir.refresh(); -common.allowGlobals(global.require); -common.allowGlobals(global.embedVars); - -function resolveBuiltBinary(binary) { - if (common.isWindows) { - binary += '.exe'; - } - return path.join(path.dirname(process.execPath), binary); -} - -const binary = resolveBuiltBinary('embedtest'); - -spawnSyncAndAssert( - binary, - ['console.log(42)'], - { - trim: true, - stdout: '42', - }); - -spawnSyncAndAssert( - binary, - ['console.log(embedVars.nön_ascıı)'], - { - trim: true, - stdout: '🏳️‍🌈', - }); - -spawnSyncAndExit( - binary, - ['throw new Error()'], - { - status: 1, - signal: null, - }); - -spawnSyncAndExit( - binary, - ['require("lib/internal/test/binding")'], - { - status: 1, - signal: null, - }); - -spawnSyncAndExit( - binary, - ['process.exitCode = 8'], - { - status: 8, - signal: null, - }); - -const fixturePath = JSON.stringify(fixtures.path('exit.js')); -spawnSyncAndExit( - binary, - [`require(${fixturePath})`, 92], - { - status: 92, - signal: null, - }); - -function getReadFileCodeForPath(path) { - return `(require("fs").readFileSync(${JSON.stringify(path)}, "utf8"))`; -} - -// Basic snapshot support -for (const extraSnapshotArgs of [ - [], ['--embedder-snapshot-as-file'], ['--without-code-cache'], -]) { - // readSync + eval since snapshots don't support userland require() (yet) - const snapshotFixture = fixtures.path('snapshot', 'echo-args.js'); - const blobPath = tmpdir.resolve('embedder-snapshot.blob'); - const buildSnapshotExecArgs = [ - `eval(${getReadFileCodeForPath(snapshotFixture)})`, 'arg1', 'arg2', - ]; - const embedTestBuildArgs = [ - '--embedder-snapshot-blob', blobPath, '--embedder-snapshot-create', - ...extraSnapshotArgs, - ]; - const buildSnapshotArgs = [ - ...buildSnapshotExecArgs, - ...embedTestBuildArgs, - ]; - - const runSnapshotExecArgs = [ - 'arg3', 'arg4', - ]; - const embedTestRunArgs = [ - '--embedder-snapshot-blob', blobPath, - ...extraSnapshotArgs, - ]; - const runSnapshotArgs = [ - ...runSnapshotExecArgs, - ...embedTestRunArgs, - ]; - - fs.rmSync(blobPath, { force: true }); - spawnSyncAndExitWithoutError( - binary, - [ '--', ...buildSnapshotArgs ], - { cwd: tmpdir.path }); - spawnSyncAndAssert( - binary, - [ '--', ...runSnapshotArgs ], - { cwd: tmpdir.path }, - { - stdout(output) { - assert.deepStrictEqual(JSON.parse(output), { - originalArgv: [binary, '__node_anonymous_main', ...buildSnapshotExecArgs], - currentArgv: [binary, ...runSnapshotExecArgs], - }); - return true; - }, - }); -} - -// Create workers and vm contexts after deserialization -{ - const snapshotFixture = fixtures.path('snapshot', 'create-worker-and-vm.js'); - const blobPath = tmpdir.resolve('embedder-snapshot.blob'); - const buildSnapshotArgs = [ - `eval(${getReadFileCodeForPath(snapshotFixture)})`, - '--embedder-snapshot-blob', blobPath, '--embedder-snapshot-create', - ]; - const runEmbeddedArgs = [ - '--embedder-snapshot-blob', blobPath, - ]; - - fs.rmSync(blobPath, { force: true }); - - spawnSyncAndExitWithoutError( - binary, - [ '--', ...buildSnapshotArgs ], - { cwd: tmpdir.path }); - spawnSyncAndExitWithoutError( - binary, - [ '--', ...runEmbeddedArgs ], - { cwd: tmpdir.path }); -} - -// Guarantee NODE_REPL_EXTERNAL_MODULE won't bypass kDisableNodeOptionsEnv -if (!process.config.variables.node_without_node_options) { - spawnSyncAndExit( - binary, - ['require("os")'], - { - env: { - ...process.env, - 'NODE_REPL_EXTERNAL_MODULE': 'fs', - }, - }, - { - status: 9, - signal: null, - stderr: `${binary}: NODE_REPL_EXTERNAL_MODULE can't be used with kDisableNodeOptionsEnv${os.EOL}`, - }); -} diff --git a/test/embedding/test-shared-embedding-v8.js b/test/embedding/test-shared-embedding-v8.js new file mode 100644 index 000000000000..4d03a9d4b480 --- /dev/null +++ b/test/embedding/test-shared-embedding-v8.js @@ -0,0 +1,25 @@ +'use strict'; + +// This tests the V8 parts in the shared library work correctly. +// TODO(joyeecheung): also test that the Node.js parts work correctly, +// which can be done in embedtest just built in shared library mode. + +const common = require('../common'); + +if (!common.usesSharedLibrary) { + common.skip('Only tests builds linking against Node.js shared library'); +} + +const { spawnSyncAndAssert } = require('../common/child_process'); +const fs = require('fs'); + +const binary = common.resolveBuiltBinary('shared_embedtest'); + +if (!fs.existsSync(binary)) { + common.skip('shared_embedtest binary not built'); +} + +spawnSyncAndAssert(binary, { + trim: true, + stdout: 'Hello, World!', +}); diff --git a/test/embedding/testcfg.py b/test/embedding/testcfg.py index a4b90f490c67..f63bc393a6a8 100644 --- a/test/embedding/testcfg.py +++ b/test/embedding/testcfg.py @@ -3,4 +3,4 @@ import testpy def GetConfiguration(context, root): - return testpy.SimpleTestConfiguration(context, root, 'embedding') + return testpy.ParallelTestConfiguration(context, root, 'embedding') diff --git a/test/fixtures/snapshot/create-vm.js b/test/fixtures/snapshot/create-vm.js new file mode 100644 index 000000000000..72f4eee45ef5 --- /dev/null +++ b/test/fixtures/snapshot/create-vm.js @@ -0,0 +1,11 @@ +const { + setDeserializeMainFunction, +} = require('v8').startupSnapshot; +const assert = require('assert'); + +setDeserializeMainFunction(() => { + const vm = require('vm'); + const result = vm.runInNewContext('21+21'); + console.log(`value: ${result}`); + assert.strictEqual(result, 42); +}); diff --git a/test/fixtures/snapshot/create-worker-and-vm.js b/test/fixtures/snapshot/create-worker.js similarity index 70% rename from test/fixtures/snapshot/create-worker-and-vm.js rename to test/fixtures/snapshot/create-worker.js index 4dd2aa940247..d27c145dae30 100644 --- a/test/fixtures/snapshot/create-worker-and-vm.js +++ b/test/fixtures/snapshot/create-worker.js @@ -4,17 +4,19 @@ const { const assert = require('assert'); setDeserializeMainFunction(() => { - const vm = require('vm'); const { Worker } = require('worker_threads'); - assert.strictEqual(vm.runInNewContext('21+21'), 42); const worker = new Worker( 'require("worker_threads").parentPort.postMessage({value: 21 + 21})', { eval: true }); const messages = []; - worker.on('message', message => messages.push(message)); + worker.on('message', (message) => { + console.log('Worker message:', message); + messages.push(message); + }); process.on('beforeExit', () => { + console.log('Process beforeExit, messages:', messages); assert.deepStrictEqual(messages, [{value:42}]); - }) + }); });