Skip to content

Commit 9da3c37

Browse files
committed
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.
1 parent 58f5da2 commit 9da3c37

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
@@ -1400,6 +1400,61 @@
14001400
],
14011401
}, # embedtest
14021402

1403+
{
1404+
'target_name': 'shared_embedtest',
1405+
'type': 'executable',
1406+
1407+
'dependencies': [
1408+
'<(node_lib_target_name)',
1409+
],
1410+
1411+
# Don't depend on node.gypi - it otherwise links to
1412+
# the static libraries and resolve symbols at build time.
1413+
'include_dirs': [
1414+
'deps/v8/include',
1415+
],
1416+
1417+
'sources': [
1418+
'test/embedding/shared_embedtest.cc',
1419+
],
1420+
'conditions': [
1421+
[ 'node_shared=="true"', {
1422+
'defines': [
1423+
'USING_V8_SHARED',
1424+
'USING_V8_PLATFORM_SHARED',
1425+
],
1426+
'defines!': [
1427+
'BUILDING_V8_PLATFORM_SHARED=1',
1428+
'BUILDING_V8_SHARED=1',
1429+
],
1430+
}, {
1431+
# Only test shared embedding when Node is built as shared library.
1432+
'type': 'none',
1433+
}],
1434+
# Only test platforms known to work.
1435+
['OS not in "mac win linux"', {
1436+
'type': 'none',
1437+
}],
1438+
['OS=="win"', {
1439+
'libraries': [
1440+
'Dbghelp.lib',
1441+
'winmm.lib',
1442+
'Ws2_32.lib',
1443+
],
1444+
}],
1445+
['OS=="mac"', {
1446+
'xcode_settings': {
1447+
'OTHER_LDFLAGS': [ '-Wl,-rpath,@loader_path', ],
1448+
}
1449+
}],
1450+
['OS=="linux"', {
1451+
'ldflags': [
1452+
'-Wl,-rpath,\\$$ORIGIN'
1453+
],
1454+
}],
1455+
],
1456+
}, # shared_embedtest
1457+
14031458
{
14041459
'target_name': 'overlapped-checker',
14051460
'type': 'executable',

test/common/index.js

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

6363
const noop = () => {};
6464

65+
// Whether the executable is linked against the shared library i.e. libnode.
66+
const usesSharedLibrary = process.config.variables.node_shared;
6567
const hasCrypto = Boolean(process.versions.openssl) &&
6668
!process.env.NODE_SKIP_CRYPTO;
6769

@@ -950,6 +952,13 @@ function sleepSync(ms) {
950952
Atomics.wait(i32, 0, 0, ms);
951953
}
952954

955+
function resolveBuiltBinary(binary) {
956+
if (isWindows) {
957+
binary += '.exe';
958+
}
959+
return path.join(path.dirname(process.execPath), binary);
960+
}
961+
953962
const common = {
954963
allowGlobals,
955964
buildType,
@@ -995,6 +1004,7 @@ const common = {
9951004
printSkipMessage,
9961005
pwdCommand,
9971006
requireNoPackageJSONAbove,
1007+
resolveBuiltBinary,
9981008
runWithInvalidFD,
9991009
skip,
10001010
skipIf32Bits,
@@ -1003,6 +1013,7 @@ const common = {
10031013
skipIfSQLiteMissing,
10041014
spawnPromisified,
10051015
sleepSync,
1016+
usesSharedLibrary,
10061017

10071018
get enoughTestMem() {
10081019
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)