Skip to content

Commit 16e46dc

Browse files
joyeecheungaduh95
authored andcommitted
build,test: add tests for binary linked with shared libnode
This adds tests to ensure the V8 parts (v8, libplatform, cppgc) in shared libnode works correctly. PR-URL: #61463 Refs: #61144 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Richard Lau <richard.lau@ibm.com>
1 parent feedfd5 commit 16e46dc

File tree

5 files changed

+152
-9
lines changed

5 files changed

+152
-9
lines changed

node.gyp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,61 @@
13411341
],
13421342
}, # embedtest
13431343

1344+
{
1345+
'target_name': 'shared_embedtest',
1346+
'type': 'executable',
1347+
1348+
'dependencies': [
1349+
'<(node_lib_target_name)',
1350+
],
1351+
1352+
# Don't depend on node.gypi - it otherwise links to
1353+
# the static libraries and resolve symbols at build time.
1354+
'include_dirs': [
1355+
'deps/v8/include',
1356+
],
1357+
1358+
'sources': [
1359+
'test/embedding/shared_embedtest.cc',
1360+
],
1361+
'conditions': [
1362+
[ 'node_shared=="true"', {
1363+
'defines': [
1364+
'USING_V8_SHARED',
1365+
'USING_V8_PLATFORM_SHARED',
1366+
],
1367+
'defines!': [
1368+
'BUILDING_V8_PLATFORM_SHARED=1',
1369+
'BUILDING_V8_SHARED=1',
1370+
],
1371+
}, {
1372+
# Only test shared embedding when Node is built as shared library.
1373+
'type': 'none',
1374+
}],
1375+
# Only test platforms known to work.
1376+
['OS not in "mac win linux"', {
1377+
'type': 'none',
1378+
}],
1379+
['OS=="win"', {
1380+
'libraries': [
1381+
'Dbghelp.lib',
1382+
'winmm.lib',
1383+
'Ws2_32.lib',
1384+
],
1385+
}],
1386+
['OS=="mac"', {
1387+
'xcode_settings': {
1388+
'OTHER_LDFLAGS': [ '-Wl,-rpath,@loader_path', ],
1389+
}
1390+
}],
1391+
['OS=="linux"', {
1392+
'ldflags': [
1393+
'-Wl,-rpath,\\$$ORIGIN'
1394+
],
1395+
}],
1396+
],
1397+
}, # shared_embedtest
1398+
13441399
{
13451400
'target_name': 'overlapped-checker',
13461401
'type': 'executable',

test/common/index.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ if (isMainThread)
5151

5252
const noop = () => {};
5353

54+
// Whether the executable is linked against the shared library i.e. libnode.
55+
const usesSharedLibrary = process.config.variables.node_shared;
5456
const hasCrypto = Boolean(process.versions.openssl) &&
5557
!process.env.NODE_SKIP_CRYPTO;
5658

@@ -923,6 +925,13 @@ function sleepSync(ms) {
923925
Atomics.wait(i32, 0, 0, ms);
924926
}
925927

928+
function resolveBuiltBinary(binary) {
929+
if (isWindows) {
930+
binary += '.exe';
931+
}
932+
return path.join(path.dirname(process.execPath), binary);
933+
}
934+
926935
const common = {
927936
allowGlobals,
928937
buildType,
@@ -966,6 +975,7 @@ const common = {
966975
printSkipMessage,
967976
pwdCommand,
968977
requireNoPackageJSONAbove,
978+
resolveBuiltBinary,
969979
runWithInvalidFD,
970980
skip,
971981
skipIf32Bits,
@@ -974,6 +984,7 @@ const common = {
974984
skipIfSQLiteMissing,
975985
spawnPromisified,
976986
sleepSync,
987+
usesSharedLibrary,
977988

978989
get enoughTestMem() {
979990
return require('os').totalmem() > 0x70000000; /* 1.75 Gb */

test/embedding/shared_embedtest.cc

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <libplatform/libplatform.h>
2+
#include <v8-cppgc.h>
3+
#include <v8.h>
4+
5+
#include <cppgc/allocation.h>
6+
#include <cppgc/default-platform.h>
7+
#include <cppgc/garbage-collected.h>
8+
#include <cppgc/heap.h>
9+
#include <cppgc/member.h>
10+
#include <cppgc/platform.h>
11+
#include <cppgc/visitor.h>
12+
13+
class Wrappable : public v8::Object::Wrappable {
14+
public:
15+
void Trace(cppgc::Visitor* visitor) const override {
16+
v8::Object::Wrappable::Trace(visitor);
17+
}
18+
};
19+
20+
int main(int argc, char* argv[]) {
21+
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
22+
v8::V8::InitializePlatform(platform.get());
23+
cppgc::InitializeProcess(platform->GetPageAllocator());
24+
v8::V8::Initialize();
25+
26+
auto heap = v8::CppHeap::Create(platform.get(), v8::CppHeapCreateParams{{}});
27+
v8::Isolate::CreateParams create_params;
28+
create_params.array_buffer_allocator =
29+
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
30+
create_params.cpp_heap = heap.release();
31+
32+
v8::Isolate* isolate = v8::Isolate::New(create_params);
33+
{
34+
v8::Isolate::Scope isolate_scope(isolate);
35+
v8::HandleScope handle_scope(isolate);
36+
v8::Local<v8::Context> context = v8::Context::New(isolate);
37+
v8::Context::Scope context_scope(context);
38+
39+
v8::Local<v8::Object> obj = v8::Object::New(isolate);
40+
Wrappable* wrappable = cppgc::MakeGarbageCollected<Wrappable>(
41+
isolate->GetCppHeap()->GetAllocationHandle());
42+
v8::Object::Wrap<v8::CppHeapPointerTag::kDefaultTag>(
43+
isolate, obj, wrappable);
44+
v8::Local<v8::String> source =
45+
v8::String::NewFromUtf8Literal(isolate, "'Hello' + ', World!'");
46+
v8::Local<v8::Script> script =
47+
v8::Script::Compile(context, source).ToLocalChecked();
48+
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
49+
v8::String::Utf8Value utf8(isolate, result);
50+
printf("%s\n", *utf8);
51+
}
52+
53+
isolate->Dispose();
54+
cppgc::ShutdownProcess();
55+
v8::V8::Dispose();
56+
v8::V8::DisposePlatform();
57+
delete create_params.array_buffer_allocator;
58+
59+
return 0;
60+
}

test/embedding/test-embedding.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,14 @@ const {
88
spawnSyncAndExit,
99
spawnSyncAndExitWithoutError,
1010
} = require('../common/child_process');
11-
const path = require('path');
1211
const fs = require('fs');
1312
const os = require('os');
1413

1514
tmpdir.refresh();
1615
common.allowGlobals(global.require);
1716
common.allowGlobals(global.embedVars);
1817

19-
function resolveBuiltBinary(binary) {
20-
if (common.isWindows) {
21-
binary += '.exe';
22-
}
23-
return path.join(path.dirname(process.execPath), binary);
24-
}
25-
26-
const binary = resolveBuiltBinary('embedtest');
18+
const binary = common.resolveBuiltBinary('embedtest');
2719

2820
spawnSyncAndAssert(
2921
binary,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
3+
// This tests the V8 parts in the shared library work correctly.
4+
// TODO(joyeecheung): also test that the Node.js parts work correctly,
5+
// which can be done in embedtest just built in shared library mode.
6+
7+
const common = require('../common');
8+
9+
if (!common.usesSharedLibrary) {
10+
common.skip('Only tests builds linking against Node.js shared library');
11+
}
12+
13+
const { spawnSyncAndAssert } = require('../common/child_process');
14+
const fs = require('fs');
15+
16+
const binary = common.resolveBuiltBinary('shared_embedtest');
17+
18+
if (!fs.existsSync(binary)) {
19+
common.skip('shared_embedtest binary not built');
20+
}
21+
22+
spawnSyncAndAssert(binary, {
23+
trim: true,
24+
stdout: 'Hello, World!',
25+
});

0 commit comments

Comments
 (0)