Flutter Engine
The Flutter Engine
dart_plugin_registrant_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/runtime/dart_isolate.h"
6
7#include <cstdlib>
8#include "flutter/fml/paths.h"
9#include "flutter/runtime/dart_plugin_registrant.h"
10#include "flutter/runtime/dart_vm.h"
11#include "flutter/runtime/dart_vm_lifecycle.h"
12#include "flutter/testing/dart_isolate_runner.h"
13#include "flutter/testing/fixture_test.h"
14#include "flutter/testing/testing.h"
15
16// CREATE_NATIVE_ENTRY is leaky by design
17// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)
18
19namespace flutter {
20namespace testing {
21
22const std::string kKernelFileName = "plugin_registrant_kernel_blob.bin";
23const std::string kElfFileName = "plugin_registrant_app_elf_snapshot.so";
24
25class DartIsolateTest : public FixtureTest {
26 public:
28
29 void OverrideDartPluginRegistrant(const std::string& override_value) {
30 dart_plugin_registrant_library_ = override_value;
33 }
34
35 void SetUp() override {
36 std::string source_path = GetSourcePath();
37 if (source_path[0] != '/') {
38 // On windows we need an extra '/' prefix.
39 source_path = "/" + source_path;
40 }
41 std::string registrant_uri = std::string("file://") + source_path +
42 "flutter/runtime/fixtures/dart_tool/"
43 "flutter_build/dart_plugin_registrant.dart";
44 OverrideDartPluginRegistrant(registrant_uri);
45 }
46
47 void TearDown() override {
49 }
50
52};
53
54TEST_F(DartIsolateTest, DartPluginRegistrantIsPresent) {
55 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
56
57 std::vector<std::string> messages;
59
60 AddNativeCallback(
61 "PassMessage",
62 CREATE_NATIVE_ENTRY(([&latch, &messages](Dart_NativeArguments args) {
65 messages.push_back(message);
66 latch.Signal();
67 })));
68
69 auto settings = CreateSettingsForFixture();
70 auto did_throw_exception = false;
71 settings.unhandled_exception_callback = [&](const std::string& error,
72 const std::string& stack_trace) {
73 did_throw_exception = true;
74 return true;
75 };
76
77 auto vm_ref = DartVMRef::Create(settings);
78 auto thread = CreateNewThread();
79 TaskRunners task_runners(GetCurrentTestName(), //
80 thread, //
81 thread, //
82 thread, //
83 thread //
84 );
85
86 auto kernel_path =
88 auto isolate =
89 RunDartCodeInIsolate(vm_ref, settings, task_runners,
90 "mainForPluginRegistrantTest", {}, kernel_path);
91
92 ASSERT_TRUE(isolate);
93 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
94
95 latch.Wait();
96
97 ASSERT_EQ(messages.size(), 1u);
98 ASSERT_EQ(messages[0], "_PluginRegistrant.register() was called");
99}
100
101TEST_F(DartIsolateTest, DartPluginRegistrantFromBackgroundIsolate) {
102 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
103
104 std::vector<std::string> messages;
106
107 AddNativeCallback(
108 "PassMessage",
109 CREATE_NATIVE_ENTRY(([&latch, &messages](Dart_NativeArguments args) {
112 messages.push_back(message);
113 latch.Signal();
114 })));
115
116 auto settings = CreateSettingsForFixture();
117 auto did_throw_exception = false;
118 settings.unhandled_exception_callback = [&](const std::string& error,
119 const std::string& stack_trace) {
120 did_throw_exception = true;
121 return true;
122 };
123
124 auto vm_ref = DartVMRef::Create(settings);
125 auto thread = CreateNewThread();
126 TaskRunners task_runners(GetCurrentTestName(), //
127 thread, //
128 thread, //
129 thread, //
130 thread //
131 );
132
133 auto kernel_path =
135 auto isolate = RunDartCodeInIsolate(
136 vm_ref, settings, task_runners,
137 "callDartPluginRegistrantFromBackgroundIsolate", {}, kernel_path);
138
139 ASSERT_TRUE(isolate);
140 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
141
142 latch.Wait();
143
144 ASSERT_EQ(messages.size(), 1u);
145 ASSERT_EQ(messages[0],
146 "_PluginRegistrant.register() was called on background isolate");
147}
148
149TEST_F(DartIsolateTest, DartPluginRegistrantNotFromBackgroundIsolate) {
150 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
151
152 std::vector<std::string> messages;
154
155 AddNativeCallback(
156 "PassMessage",
157 CREATE_NATIVE_ENTRY(([&latch, &messages](Dart_NativeArguments args) {
160 messages.push_back(message);
161 latch.Signal();
162 })));
163
164 auto settings = CreateSettingsForFixture();
165 auto did_throw_exception = false;
166 settings.unhandled_exception_callback = [&](const std::string& error,
167 const std::string& stack_trace) {
168 did_throw_exception = true;
169 return true;
170 };
171
172 auto vm_ref = DartVMRef::Create(settings);
173 auto thread = CreateNewThread();
174 TaskRunners task_runners(GetCurrentTestName(), //
175 thread, //
176 thread, //
177 thread, //
178 thread //
179 );
180
181 auto kernel_path =
183 auto isolate = RunDartCodeInIsolate(
184 vm_ref, settings, task_runners,
185 "dontCallDartPluginRegistrantFromBackgroundIsolate", {}, kernel_path);
186
187 ASSERT_TRUE(isolate);
188 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
189
190 latch.Wait();
191
192 ASSERT_EQ(messages.size(), 1u);
193 ASSERT_EQ(
194 messages[0],
195 "_PluginRegistrant.register() was not called on background isolate");
196}
197
198TEST_F(DartIsolateTest, DartPluginRegistrantWhenRegisteringBackgroundIsolate) {
199 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
200
201 std::vector<std::string> messages;
203
204 AddNativeCallback(
205 "PassMessage",
206 CREATE_NATIVE_ENTRY(([&latch, &messages](Dart_NativeArguments args) {
209 messages.push_back(message);
210 latch.Signal();
211 })));
212
213 auto settings = CreateSettingsForFixture();
214 auto did_throw_exception = false;
215 settings.unhandled_exception_callback = [&](const std::string& error,
216 const std::string& stack_trace) {
217 did_throw_exception = true;
218 return true;
219 };
220
221 auto vm_ref = DartVMRef::Create(settings);
222 auto thread = CreateNewThread();
223 TaskRunners task_runners(GetCurrentTestName(), //
224 thread, //
225 thread, //
226 thread, //
227 thread //
228 );
229
230 auto kernel_path =
232 auto isolate = RunDartCodeInIsolate(
233 vm_ref, settings, task_runners,
234 "registerBackgroundIsolateCallsDartPluginRegistrant", {}, kernel_path);
235
236 ASSERT_TRUE(isolate);
237 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
238
239 latch.Wait();
240
241 ASSERT_EQ(messages.size(), 1u);
242 ASSERT_EQ(messages[0],
243 "_PluginRegistrant.register() was called on background isolate");
244}
245
246} // namespace testing
247} // namespace flutter
248
249// NOLINTEND(clang-analyzer-core.StackAddressEscape)
static DartVMRef Create(const Settings &settings, fml::RefPtr< const DartSnapshot > vm_snapshot=nullptr, fml::RefPtr< const DartSnapshot > isolate_snapshot=nullptr)
static bool IsInstanceRunning()
void OverrideDartPluginRegistrant(const std::string &override_value)
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
struct _Dart_NativeArguments * Dart_NativeArguments
Definition: dart_api.h:3019
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
Win32Message message
fml::RefPtr< fml::TaskRunner > CreateNewThread(const std::string &name)
std::string GetCurrentTestName()
Gets the name of the currently running test. This is useful in generating logs or assets based on tes...
Definition: testing.cc:15
TEST_F(DisplayListTest, Defaults)
const char * GetFixturesPath()
Returns the directory containing the test fixture for the target if this target has fixtures configur...
const char * GetSourcePath()
std::unique_ptr< AutoIsolateShutdown > RunDartCodeInIsolate(DartVMRef &vm_ref, const Settings &settings, const TaskRunners &task_runners, std::string entrypoint, const std::vector< std::string > &args, const std::string &kernel_file_path, fml::WeakPtr< IOManager > io_manager, std::shared_ptr< VolatilePathTracker > volatile_path_tracker, std::unique_ptr< PlatformConfiguration > platform_configuration)
const char * dart_plugin_registrant_library_override
std::string JoinPaths(std::initializer_list< std::string > components)
Definition: paths.cc:14
#define CREATE_NATIVE_ENTRY(native_entry)