1 #include "node_internals.h"
2 #include "libplatform/libplatform.h"
3
4 #include <string>
5 #include "gtest/gtest.h"
6 #include "node_test_fixture.h"
7
8 // This task increments the given run counter and reposts itself until the
9 // repost counter reaches zero.
10 class RepostingTask : public v8::Task {
11 public:
RepostingTask(int repost_count,int * run_count,v8::Isolate * isolate,node::NodePlatform * platform)12 explicit RepostingTask(int repost_count,
13 int* run_count,
14 v8::Isolate* isolate,
15 node::NodePlatform* platform)
16 : repost_count_(repost_count),
17 run_count_(run_count),
18 isolate_(isolate),
19 platform_(platform) {}
20
21 // v8::Task implementation
Run()22 void Run() final {
23 ++*run_count_;
24 if (repost_count_ > 0) {
25 --repost_count_;
26 std::shared_ptr<v8::TaskRunner> task_runner =
27 platform_->GetForegroundTaskRunner(isolate_);
28 task_runner->PostTask(std::make_unique<RepostingTask>(
29 repost_count_, run_count_, isolate_, platform_));
30 }
31 }
32
33 private:
34 int repost_count_;
35 int* run_count_;
36 v8::Isolate* isolate_;
37 node::NodePlatform* platform_;
38 };
39
40 class PlatformTest : public EnvironmentTestFixture {};
41
TEST_F(PlatformTest,SkipNewTasksInFlushForegroundTasks)42 TEST_F(PlatformTest, SkipNewTasksInFlushForegroundTasks) {
43 v8::Isolate::Scope isolate_scope(isolate_);
44 const v8::HandleScope handle_scope(isolate_);
45 const Argv argv;
46 Env env {handle_scope, argv};
47 int run_count = 0;
48 std::shared_ptr<v8::TaskRunner> task_runner =
49 platform->GetForegroundTaskRunner(isolate_);
50 task_runner->PostTask(
51 std::make_unique<RepostingTask>(2, &run_count, isolate_, platform.get()));
52 EXPECT_TRUE(platform->FlushForegroundTasks(isolate_));
53 EXPECT_EQ(1, run_count);
54 EXPECT_TRUE(platform->FlushForegroundTasks(isolate_));
55 EXPECT_EQ(2, run_count);
56 EXPECT_TRUE(platform->FlushForegroundTasks(isolate_));
57 EXPECT_EQ(3, run_count);
58 EXPECT_FALSE(platform->FlushForegroundTasks(isolate_));
59 }
60
61 // Tests the registration of an abstract `IsolatePlatformDelegate` instance as
62 // opposed to the more common `uv_loop_s*` version of `RegisterIsolate`.
TEST_F(NodeZeroIsolateTestFixture,IsolatePlatformDelegateTest)63 TEST_F(NodeZeroIsolateTestFixture, IsolatePlatformDelegateTest) {
64 // Allocate isolate
65 v8::Isolate::CreateParams create_params;
66 create_params.array_buffer_allocator = allocator.get();
67 auto isolate = v8::Isolate::Allocate();
68 CHECK_NOT_NULL(isolate);
69
70 // Register *first*, then initialize
71 auto delegate = std::make_shared<node::PerIsolatePlatformData>(
72 isolate,
73 ¤t_loop);
74 platform->RegisterIsolate(isolate, delegate.get());
75 v8::Isolate::Initialize(isolate, create_params);
76
77 // Try creating Context + IsolateData + Environment
78 {
79 v8::Isolate::Scope isolate_scope(isolate);
80 v8::HandleScope handle_scope(isolate);
81
82 auto context = node::NewContext(isolate);
83 CHECK(!context.IsEmpty());
84 v8::Context::Scope context_scope(context);
85
86 std::unique_ptr<node::IsolateData, decltype(&node::FreeIsolateData)>
87 isolate_data{node::CreateIsolateData(isolate,
88 ¤t_loop,
89 platform.get()),
90 node::FreeIsolateData};
91 CHECK(isolate_data);
92
93 std::unique_ptr<node::Environment, decltype(&node::FreeEnvironment)>
94 environment{node::CreateEnvironment(isolate_data.get(),
95 context,
96 0, nullptr,
97 0, nullptr),
98 node::FreeEnvironment};
99 CHECK(environment);
100 }
101
102 // Graceful shutdown
103 delegate->Shutdown();
104 platform->UnregisterIsolate(isolate);
105 isolate->Dispose();
106 }
107
TEST_F(PlatformTest,TracingControllerNullptr)108 TEST_F(PlatformTest, TracingControllerNullptr) {
109 v8::TracingController* orig_controller = node::GetTracingController();
110 node::SetTracingController(nullptr);
111 EXPECT_EQ(node::GetTracingController(), nullptr);
112
113 v8::Isolate::Scope isolate_scope(isolate_);
114 const v8::HandleScope handle_scope(isolate_);
115 const Argv argv;
116 Env env {handle_scope, argv};
117
118 node::LoadEnvironment(*env, [&](const node::StartExecutionCallbackInfo& info)
119 -> v8::MaybeLocal<v8::Value> {
120 return v8::Null(isolate_);
121 });
122
123 node::SetTracingController(orig_controller);
124 EXPECT_EQ(node::GetTracingController(), orig_controller);
125 }
126