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 cb635c2

Browse filesBrowse files
committed
test: add extended embedder cctest
Add an embedder cctest that also covers a multi-Environment situation, including worker_threads-style inspector support. Co-authored-by: Joyee Cheung <joyeec9h3@gmail.com> 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 1a70820 commit cb635c2
Copy full SHA for cb635c2

File tree

Expand file treeCollapse file tree

6 files changed

+182
-43
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+182
-43
lines changed
Open diff view settings
Collapse file

‎Makefile‎

Copy file name to clipboardExpand all lines: Makefile
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ coverage-report-js:
278278
# Runs the C++ tests using the built `cctest` executable.
279279
cctest: all
280280
@out/$(BUILDTYPE)/$@ --gtest_filter=$(GTEST_FILTER)
281-
@out/$(BUILDTYPE)/embedtest "require('./test/embedding/test.js')"
281+
@out/$(BUILDTYPE)/embedtest "require('./test/embedding/test-embedding.js')"
282282

283283
.PHONY: list-gtests
284284
list-gtests:
@@ -534,7 +534,7 @@ test-ci: | clear-stalled bench-addons-build build-addons build-js-native-api-tes
534534
$(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \
535535
--mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \
536536
$(TEST_CI_ARGS) $(CI_JS_SUITES) $(CI_NATIVE_SUITES) $(CI_DOC)
537-
out/Release/embedtest 'require("./test/embedding/test.js")'
537+
out/Release/embedtest 'require("./test/embedding/test-embedding.js")'
538538
@echo "Clean up any leftover processes, error if found."
539539
ps awwx | grep Release/node | grep -v grep | cat
540540
@PS_OUT=`ps awwx | grep Release/node | grep -v grep | awk '{print $$1}'`; \
Collapse file

‎test/cctest/test_environment.cc‎

Copy file name to clipboardExpand all lines: test/cctest/test_environment.cc
+140-22Lines changed: 140 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,10 @@ TEST_F(EnvironmentTest, SetImmediateCleanup) {
266266
EXPECT_EQ(env_arg, *env);
267267
called++;
268268
});
269-
(*env)->SetUnrefImmediate([&](node::Environment* env_arg) {
269+
(*env)->SetImmediate([&](node::Environment* env_arg) {
270270
EXPECT_EQ(env_arg, *env);
271271
called_unref++;
272-
});
272+
}, node::CallbackFlags::kUnrefed);
273273
}
274274

275275
EXPECT_EQ(called, 1);
@@ -307,25 +307,143 @@ TEST_F(EnvironmentTest, BufferWithFreeCallbackIsDetached) {
307307
CHECK_EQ(ab->ByteLength(), 0);
308308
}
309309

310-
TEST_F(EnvironmentTest, SetImmediateCleanup) {
311-
int called = 0;
312-
int called_unref = 0;
313-
314-
{
315-
const v8::HandleScope handle_scope(isolate_);
316-
const Argv argv;
317-
Env env {handle_scope, argv};
318-
319-
(*env)->SetImmediate([&](node::Environment* env_arg) {
320-
EXPECT_EQ(env_arg, *env);
321-
called++;
322-
});
323-
(*env)->SetImmediate([&](node::Environment* env_arg) {
324-
EXPECT_EQ(env_arg, *env);
325-
called_unref++;
326-
}, node::CallbackFlags::kUnrefed);
327-
}
310+
#if HAVE_INSPECTOR
311+
TEST_F(EnvironmentTest, InspectorMultipleEmbeddedEnvironments) {
312+
// Tests that child Environments can be created through the public API
313+
// that are accessible by the inspector.
314+
// This test sets a global variable in the child Environment, and reads it
315+
// back both through the inspector and inside the child Environment, and
316+
// makes sure that those correspond to the value that was originally set.
317+
const v8::HandleScope handle_scope(isolate_);
318+
const Argv argv;
319+
Env env {handle_scope, argv};
328320

329-
EXPECT_EQ(called, 1);
330-
EXPECT_EQ(called_unref, 0);
321+
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
322+
node::LoadEnvironment(*env,
323+
"'use strict';\n"
324+
"const { Worker } = require('worker_threads');\n"
325+
"const { Session } = require('inspector');\n"
326+
327+
"const session = new Session();\n"
328+
"session.connect();\n"
329+
"session.on('NodeWorker.attachedToWorker', (\n"
330+
" ({ params: { workerInfo, sessionId } }) => {\n"
331+
" session.post('NodeWorker.sendMessageToWorker', {\n"
332+
" sessionId,\n"
333+
" message: JSON.stringify({\n"
334+
" id: 1,\n"
335+
" method: 'Runtime.evaluate',\n"
336+
" params: {\n"
337+
" expression: 'global.variableFromParent = 42;'\n"
338+
" }\n"
339+
" })\n"
340+
" });\n"
341+
" session.on('NodeWorker.receivedMessageFromWorker',\n"
342+
" ({ params: { message } }) => {\n"
343+
" global.messageFromWorker = \n"
344+
" JSON.parse(message).result.result.value;\n"
345+
" });\n"
346+
" }));\n"
347+
"session.post('NodeWorker.enable', { waitForDebuggerOnStart: false });\n")
348+
.ToLocalChecked();
349+
350+
struct ChildEnvironmentData {
351+
node::ThreadId thread_id;
352+
std::unique_ptr<node::InspectorParentHandle> inspector_parent_handle;
353+
node::MultiIsolatePlatform* platform;
354+
int32_t extracted_value = -1;
355+
uv_async_t thread_stopped_async;
356+
};
357+
358+
ChildEnvironmentData data;
359+
data.thread_id = node::AllocateEnvironmentThreadId();
360+
data.inspector_parent_handle =
361+
GetInspectorParentHandle(*env, data.thread_id, "file:///embedded.js");
362+
CHECK(data.inspector_parent_handle);
363+
data.platform = GetMultiIsolatePlatform(*env);
364+
CHECK_NOT_NULL(data.platform);
365+
366+
bool thread_stopped = false;
367+
int err = uv_async_init(
368+
&current_loop, &data.thread_stopped_async, [](uv_async_t* async) {
369+
*static_cast<bool*>(async->data) = true;
370+
uv_close(reinterpret_cast<uv_handle_t*>(async), nullptr);
371+
});
372+
CHECK_EQ(err, 0);
373+
data.thread_stopped_async.data = &thread_stopped;
374+
375+
uv_thread_t thread;
376+
err = uv_thread_create(&thread, [](void* arg) {
377+
ChildEnvironmentData* data = static_cast<ChildEnvironmentData*>(arg);
378+
std::shared_ptr<node::ArrayBufferAllocator> aba =
379+
node::ArrayBufferAllocator::Create();
380+
uv_loop_t loop;
381+
uv_loop_init(&loop);
382+
v8::Isolate* isolate = NewIsolate(aba.get(), &loop, data->platform);
383+
CHECK_NOT_NULL(isolate);
384+
385+
{
386+
v8::Isolate::Scope isolate_scope(isolate);
387+
v8::HandleScope handle_scope(isolate);
388+
389+
v8::Local<v8::Context> context = node::NewContext(isolate);
390+
CHECK(!context.IsEmpty());
391+
v8::Context::Scope context_scope(context);
392+
393+
node::IsolateData* isolate_data = node::CreateIsolateData(
394+
isolate,
395+
&loop,
396+
data->platform);
397+
CHECK_NOT_NULL(isolate_data);
398+
node::Environment* environment = node::CreateEnvironment(
399+
isolate_data,
400+
context,
401+
{ "dummy" },
402+
{},
403+
node::EnvironmentFlags::kNoFlags,
404+
data->thread_id);
405+
CHECK_NOT_NULL(environment);
406+
407+
v8::Local<v8::Value> extracted_value = LoadEnvironment(
408+
environment,
409+
"return global.variableFromParent;",
410+
std::move(data->inspector_parent_handle)).ToLocalChecked();
411+
412+
uv_run(&loop, UV_RUN_DEFAULT);
413+
CHECK(extracted_value->IsInt32());
414+
data->extracted_value = extracted_value.As<v8::Int32>()->Value();
415+
416+
node::FreeEnvironment(environment);
417+
node::FreeIsolateData(isolate_data);
418+
}
419+
420+
data->platform->UnregisterIsolate(isolate);
421+
isolate->Dispose();
422+
uv_run(&loop, UV_RUN_DEFAULT);
423+
CHECK_EQ(uv_loop_close(&loop), 0);
424+
425+
uv_async_send(&data->thread_stopped_async);
426+
}, &data);
427+
CHECK_EQ(err, 0);
428+
429+
bool more;
430+
do {
431+
uv_run(&current_loop, UV_RUN_DEFAULT);
432+
data.platform->DrainTasks(isolate_);
433+
more = uv_loop_alive(&current_loop);
434+
} while (!thread_stopped || more);
435+
436+
uv_thread_join(&thread);
437+
438+
v8::Local<v8::Value> from_inspector =
439+
context->Global()->Get(
440+
context,
441+
v8::String::NewFromOneByte(
442+
isolate_,
443+
reinterpret_cast<const uint8_t*>("messageFromWorker"),
444+
v8::NewStringType::kNormal).ToLocalChecked())
445+
.ToLocalChecked();
446+
CHECK_EQ(data.extracted_value, 42);
447+
CHECK_EQ(from_inspector->IntegerValue(context).FromJust(), 42);
331448
}
449+
#endif // HAVE_INSPECTOR
Collapse file

‎test/embedding/test-embedding.js‎

Copy file name to clipboard
+33Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
const common = require('../common');
3+
const fixtures = require('../common/fixtures');
4+
const assert = require('assert');
5+
const child_process = require('child_process');
6+
const path = require('path');
7+
8+
common.allowGlobals(global.require);
9+
let binary = process.features.debug ?
10+
'out/Debug/embedtest' : 'out/Release/embedtest';
11+
if (common.isWindows) {
12+
binary += '.exe';
13+
}
14+
binary = path.resolve(__dirname, '..', '..', binary);
15+
16+
assert.strictEqual(
17+
child_process.spawnSync(binary, ['console.log(42)'])
18+
.stdout.toString().trim(),
19+
'42');
20+
21+
assert.strictEqual(
22+
child_process.spawnSync(binary, ['throw new Error()']).status,
23+
1);
24+
25+
assert.strictEqual(
26+
child_process.spawnSync(binary, ['process.exitCode = 8']).status,
27+
8);
28+
29+
30+
const fixturePath = JSON.stringify(fixtures.path('exit.js'));
31+
assert.strictEqual(
32+
child_process.spawnSync(binary, [`require(${fixturePath})`, 92]).status,
33+
92);
Collapse file

‎test/embedding/test.js‎

Copy file name to clipboardExpand all lines: test/embedding/test.js
-19Lines changed: 0 additions & 19 deletions
This file was deleted.
Collapse file

‎test/embedding/testcfg.py‎

Copy file name to clipboard
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import sys, os
2+
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
3+
import testpy
4+
5+
def GetConfiguration(context, root):
6+
return testpy.SimpleTestConfiguration(context, root, 'embedding')
Collapse file

‎tools/test.py‎

Copy file name to clipboardExpand all lines: tools/test.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,7 @@ def PrintCrashed(code):
14861486
'addons',
14871487
'benchmark',
14881488
'doctool',
1489+
'embedding',
14891490
'internet',
14901491
'js-native-api',
14911492
'node-api',

0 commit comments

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