Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4af336d

Browse filesBrowse files
committed
src,test: add full-featured embedder API test
Backport-PR-URL: #35241 PR-URL: #30467 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
1 parent b8c9048 commit 4af336d
Copy full SHA for 4af336d

File tree

Expand file treeCollapse file tree

6 files changed

+226
-2
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+226
-2
lines changed
Open diff view settings
Collapse file

‎Makefile‎

Copy file name to clipboardExpand all lines: Makefile
+8-2Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ coverage-clean:
212212
$(RM) out/$(BUILDTYPE)/obj.target/node/src/tracing/*.gcno
213213
$(RM) out/$(BUILDTYPE)/obj.target/cctest/src/*.gcno
214214
$(RM) out/$(BUILDTYPE)/obj.target/cctest/test/cctest/*.gcno
215+
$(RM) out/$(BUILDTYPE)/obj.target/embedtest/src/*.gcno
216+
$(RM) out/$(BUILDTYPE)/obj.target/embedtest/test/embedding/*.gcno
215217

216218
.PHONY: coverage
217219
# Build and test with code coverage reporting. Leave the lib directory
@@ -250,8 +252,8 @@ coverage-test: coverage-build
250252
TEST_CI_ARGS="$(TEST_CI_ARGS) --type=coverage" $(MAKE) $(COVTESTS)
251253
$(MAKE) coverage-report-js
252254
-(cd out && "../gcovr/scripts/gcovr" \
253-
--gcov-exclude='.*\b(deps|usr|out|cctest)\b' -v -r Release/obj.target \
254-
--html --html-detail -o ../coverage/cxxcoverage.html \
255+
--gcov-exclude='.*\b(deps|usr|out|cctest|embedding)\b' -v \
256+
-r Release/obj.target --html --html-detail -o ../coverage/cxxcoverage.html \
255257
--gcov-executable="$(GCOV)")
256258
@echo -n "Javascript coverage %: "
257259
@grep -B1 Lines coverage/index.html | head -n1 \
@@ -276,6 +278,7 @@ coverage-report-js:
276278
# Runs the C++ tests using the built `cctest` executable.
277279
cctest: all
278280
@out/$(BUILDTYPE)/$@ --gtest_filter=$(GTEST_FILTER)
281+
@out/$(BUILDTYPE)/embedtest "require('./test/embedding/test.js')"
279282

280283
.PHONY: list-gtests
281284
list-gtests:
@@ -531,6 +534,7 @@ test-ci: | clear-stalled bench-addons-build build-addons build-js-native-api-tes
531534
$(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \
532535
--mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \
533536
$(TEST_CI_ARGS) $(CI_JS_SUITES) $(CI_NATIVE_SUITES) $(CI_DOC)
537+
out/Release/embedtest 'require("./test/embedding/test.js")'
534538
@echo "Clean up any leftover processes, error if found."
535539
ps awwx | grep Release/node | grep -v grep | cat
536540
@PS_OUT=`ps awwx | grep Release/node | grep -v grep | awk '{print $$1}'`; \
@@ -1274,6 +1278,8 @@ LINT_CPP_FILES = $(filter-out $(LINT_CPP_EXCLUDE), $(wildcard \
12741278
test/addons/*/*.h \
12751279
test/cctest/*.cc \
12761280
test/cctest/*.h \
1281+
test/embedding/*.cc \
1282+
test/embedding/*.h \
12771283
test/js-native-api/*/*.cc \
12781284
test/js-native-api/*/*.h \
12791285
test/node-api/*/*.cc \
Collapse file

‎node.gyp‎

Copy file name to clipboardExpand all lines: node.gyp
+56Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,62 @@
12361236
],
12371237
}, # cctest
12381238

1239+
{
1240+
'target_name': 'embedtest',
1241+
'type': 'executable',
1242+
1243+
'dependencies': [
1244+
'<(node_lib_target_name)',
1245+
'deps/histogram/histogram.gyp:histogram',
1246+
'deps/uvwasi/uvwasi.gyp:uvwasi',
1247+
'node_dtrace_header',
1248+
'node_dtrace_ustack',
1249+
'node_dtrace_provider',
1250+
],
1251+
1252+
'includes': [
1253+
'node.gypi'
1254+
],
1255+
1256+
'include_dirs': [
1257+
'src',
1258+
'tools/msvs/genfiles',
1259+
'deps/v8/include',
1260+
'deps/cares/include',
1261+
'deps/uv/include',
1262+
'deps/uvwasi/include',
1263+
'test/embedding',
1264+
],
1265+
1266+
'sources': [
1267+
'src/node_snapshot_stub.cc',
1268+
'src/node_code_cache_stub.cc',
1269+
'test/embedding/embedtest.cc',
1270+
],
1271+
1272+
'conditions': [
1273+
['OS=="solaris"', {
1274+
'ldflags': [ '-I<(SHARED_INTERMEDIATE_DIR)' ]
1275+
}],
1276+
# Skip cctest while building shared lib node for Windows
1277+
[ 'OS=="win" and node_shared=="true"', {
1278+
'type': 'none',
1279+
}],
1280+
[ 'node_shared=="true"', {
1281+
'xcode_settings': {
1282+
'OTHER_LDFLAGS': [ '-Wl,-rpath,@loader_path', ],
1283+
},
1284+
}],
1285+
['OS=="win"', {
1286+
'libraries': [
1287+
'Dbghelp.lib',
1288+
'winmm.lib',
1289+
'Ws2_32.lib',
1290+
],
1291+
}],
1292+
],
1293+
}, # embedtest
1294+
12391295
# TODO(joyeecheung): do not depend on node_lib,
12401296
# instead create a smaller static library node_lib_base that does
12411297
# just enough for node_native_module.cc and the cache builder to
Collapse file

‎src/node_code_cache_stub.cc‎

Copy file name to clipboardExpand all lines: src/node_code_cache_stub.cc
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// This file is part of the embedder test, which is intentionally built without
2+
// NODE_WANT_INTERNALS, so we define it here manually.
3+
#define NODE_WANT_INTERNALS 1
4+
15
#include "node_native_module_env.h"
26

37
// The stub here is used when configure is run without `--code-cache-path`.
Collapse file

‎src/node_snapshot_stub.cc‎

Copy file name to clipboardExpand all lines: src/node_snapshot_stub.cc
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// This file is part of the embedder test, which is intentionally built without
2+
// NODE_WANT_INTERNALS, so we define it here manually.
3+
#define NODE_WANT_INTERNALS 1
4+
15
#include "node_main_instance.h"
26

37
namespace node {
Collapse file

‎test/embedding/embedtest.cc‎

Copy file name to clipboard
+135Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#include "node.h"
2+
#include "uv.h"
3+
#include <assert.h>
4+
5+
// Note: This file is being referred to from doc/api/embedding.md, and excerpts
6+
// from it are included in the documentation. Try to keep these in sync.
7+
8+
using node::ArrayBufferAllocator;
9+
using node::Environment;
10+
using node::IsolateData;
11+
using node::MultiIsolatePlatform;
12+
using v8::Context;
13+
using v8::HandleScope;
14+
using v8::Isolate;
15+
using v8::Local;
16+
using v8::Locker;
17+
using v8::MaybeLocal;
18+
using v8::SealHandleScope;
19+
using v8::Value;
20+
using v8::V8;
21+
22+
static int RunNodeInstance(MultiIsolatePlatform* platform,
23+
const std::vector<std::string>& args,
24+
const std::vector<std::string>& exec_args);
25+
26+
int main(int argc, char** argv) {
27+
std::vector<std::string> args(argv, argv + argc);
28+
std::vector<std::string> exec_args;
29+
std::vector<std::string> errors;
30+
int exit_code = node::InitializeNodeWithArgs(&args, &exec_args, &errors);
31+
for (const std::string& error : errors)
32+
fprintf(stderr, "%s: %s\n", args[0].c_str(), error.c_str());
33+
if (exit_code != 0) {
34+
return exit_code;
35+
}
36+
37+
std::unique_ptr<MultiIsolatePlatform> platform =
38+
MultiIsolatePlatform::Create(4);
39+
V8::InitializePlatform(platform.get());
40+
V8::Initialize();
41+
42+
int ret = RunNodeInstance(platform.get(), args, exec_args);
43+
44+
V8::Dispose();
45+
V8::ShutdownPlatform();
46+
return ret;
47+
}
48+
49+
int RunNodeInstance(MultiIsolatePlatform* platform,
50+
const std::vector<std::string>& args,
51+
const std::vector<std::string>& exec_args) {
52+
int exit_code = 0;
53+
uv_loop_t loop;
54+
int ret = uv_loop_init(&loop);
55+
if (ret != 0) {
56+
fprintf(stderr, "%s: Failed to initialize loop: %s\n",
57+
args[0].c_str(),
58+
uv_err_name(ret));
59+
return 1;
60+
}
61+
62+
std::shared_ptr<ArrayBufferAllocator> allocator =
63+
ArrayBufferAllocator::Create();
64+
65+
Isolate* isolate = NewIsolate(allocator.get(), &loop, platform);
66+
if (isolate == nullptr) {
67+
fprintf(stderr, "%s: Failed to initialize V8 Isolate\n", args[0].c_str());
68+
return 1;
69+
}
70+
71+
{
72+
Locker locker(isolate);
73+
Isolate::Scope isolate_scope(isolate);
74+
75+
std::unique_ptr<IsolateData, decltype(&node::FreeIsolateData)> isolate_data(
76+
node::CreateIsolateData(isolate, &loop, platform, allocator.get()),
77+
node::FreeIsolateData);
78+
79+
HandleScope handle_scope(isolate);
80+
Local<Context> context = node::NewContext(isolate);
81+
if (context.IsEmpty()) {
82+
fprintf(stderr, "%s: Failed to initialize V8 Context\n", args[0].c_str());
83+
return 1;
84+
}
85+
86+
Context::Scope context_scope(context);
87+
std::unique_ptr<Environment, decltype(&node::FreeEnvironment)> env(
88+
node::CreateEnvironment(isolate_data.get(), context, args, exec_args),
89+
node::FreeEnvironment);
90+
91+
MaybeLocal<Value> loadenv_ret = node::LoadEnvironment(
92+
env.get(),
93+
"const publicRequire ="
94+
" require('module').createRequire(process.cwd() + '/');"
95+
"globalThis.require = publicRequire;"
96+
"require('vm').runInThisContext(process.argv[1]);");
97+
98+
if (loadenv_ret.IsEmpty()) // There has been a JS exception.
99+
return 1;
100+
101+
{
102+
SealHandleScope seal(isolate);
103+
bool more;
104+
do {
105+
uv_run(&loop, UV_RUN_DEFAULT);
106+
107+
platform->DrainTasks(isolate);
108+
more = uv_loop_alive(&loop);
109+
if (more) continue;
110+
111+
node::EmitBeforeExit(env.get());
112+
more = uv_loop_alive(&loop);
113+
} while (more == true);
114+
}
115+
116+
exit_code = node::EmitExit(env.get());
117+
118+
node::Stop(env.get());
119+
}
120+
121+
bool platform_finished = false;
122+
platform->AddIsolateFinishedCallback(isolate, [](void* data) {
123+
*static_cast<bool*>(data) = true;
124+
}, &platform_finished);
125+
platform->UnregisterIsolate(isolate);
126+
isolate->Dispose();
127+
128+
// Wait until the platform has cleaned up all relevant resources.
129+
while (!platform_finished)
130+
uv_run(&loop, UV_RUN_ONCE);
131+
int err = uv_loop_close(&loop);
132+
assert(err == 0);
133+
134+
return exit_code;
135+
}
Collapse file

‎test/embedding/test.js‎

Copy file name to clipboard
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const child_process = require('child_process');
5+
6+
common.allowGlobals(global.require);
7+
8+
assert.strictEqual(
9+
child_process.spawnSync(process.execPath, ['console.log(42)'])
10+
.stdout.toString().trim(),
11+
'42');
12+
13+
assert.strictEqual(
14+
child_process.spawnSync(process.execPath, ['throw new Error()']).status,
15+
1);
16+
17+
assert.strictEqual(
18+
child_process.spawnSync(process.execPath, ['process.exitCode = 8']).status,
19+
8);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.