2
2
// Use of this source code is governed by a BSD-style license that can be
3
3
// found in the LICENSE file.
4
4
5
- #include " flutter/fml/make_copyable.h"
6
5
#include " flutter/fml/mapping.h"
7
- #include " flutter/fml/paths.h"
8
6
#include " flutter/fml/synchronization/count_down_latch.h"
9
7
#include " flutter/fml/synchronization/waitable_event.h"
10
8
#include " flutter/fml/thread.h"
11
9
#include " flutter/runtime/dart_isolate.h"
12
10
#include " flutter/runtime/dart_vm.h"
13
11
#include " flutter/runtime/dart_vm_lifecycle.h"
14
12
#include " flutter/runtime/runtime_test.h"
13
+ #include " flutter/testing/dart_isolate_runner.h"
15
14
#include " flutter/testing/testing.h"
16
15
#include " flutter/testing/thread_test.h"
17
16
#include " third_party/tonic/converter/dart_converter.h"
@@ -96,199 +95,18 @@ TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) {
96
95
ASSERT_EQ (destruction_callback_count, 1u );
97
96
}
98
97
99
- class AutoIsolateShutdown {
100
- public:
101
- AutoIsolateShutdown () = default ;
102
-
103
- AutoIsolateShutdown (std::shared_ptr<DartIsolate> isolate,
104
- fml::RefPtr<fml::TaskRunner> runner)
105
- : isolate_(std::move(isolate)), runner_(std::move(runner)) {}
106
-
107
- ~AutoIsolateShutdown () {
108
- if (!IsValid ()) {
109
- return ;
110
- }
111
- fml::AutoResetWaitableEvent latch;
112
- fml::TaskRunner::RunNowOrPostTask (
113
- runner_, [isolate = std::move (isolate_), &latch]() {
114
- if (!isolate->Shutdown ()) {
115
- FML_LOG (ERROR) << " Could not shutdown isolate." ;
116
- FML_CHECK (false );
117
- }
118
- latch.Signal ();
119
- });
120
- latch.Wait ();
121
- }
122
-
123
- bool IsValid () const { return isolate_ != nullptr && runner_; }
124
-
125
- FML_WARN_UNUSED_RESULT
126
- bool RunInIsolateScope (std::function<bool (void )> closure) {
127
- if (!IsValid ()) {
128
- return false ;
129
- }
130
-
131
- bool result = false ;
132
- fml::AutoResetWaitableEvent latch;
133
- fml::TaskRunner::RunNowOrPostTask (
134
- runner_, [this , &result, &latch, closure]() {
135
- tonic::DartIsolateScope scope (isolate_->isolate ());
136
- tonic::DartApiScope api_scope;
137
- if (closure) {
138
- result = closure ();
139
- }
140
- latch.Signal ();
141
- });
142
- latch.Wait ();
143
- return true ;
144
- }
145
-
146
- DartIsolate* get () {
147
- FML_CHECK (isolate_);
148
- return isolate_.get ();
149
- }
150
-
151
- private:
152
- std::shared_ptr<DartIsolate> isolate_;
153
- fml::RefPtr<fml::TaskRunner> runner_;
154
-
155
- FML_DISALLOW_COPY_AND_ASSIGN (AutoIsolateShutdown);
156
- };
157
-
158
- static void RunDartCodeInIsolate (DartVMRef& vm_ref,
159
- std::unique_ptr<AutoIsolateShutdown>& result,
160
- const Settings& settings,
161
- fml::RefPtr<fml::TaskRunner> task_runner,
162
- std::string entrypoint,
163
- const std::vector<std::string>& args) {
164
- FML_CHECK (task_runner->RunsTasksOnCurrentThread ());
165
-
166
- if (!vm_ref) {
167
- return ;
168
- }
169
-
170
- TaskRunners task_runners (GetCurrentTestName (), //
171
- task_runner, //
172
- task_runner, //
173
- task_runner, //
174
- task_runner //
175
- );
176
-
177
- auto vm_data = vm_ref.GetVMData ();
178
-
179
- if (!vm_data) {
180
- return ;
181
- }
182
-
183
- auto weak_isolate = DartIsolate::CreateRootIsolate (
184
- vm_data->GetSettings (), // settings
185
- vm_data->GetIsolateSnapshot (), // isolate snapshot
186
- std::move (task_runners), // task runners
187
- nullptr , // window
188
- {}, // snapshot delegate
189
- {}, // io manager
190
- {}, // unref queue
191
- {}, // image decoder
192
- " main.dart" , // advisory uri
193
- " main" , // advisory entrypoint
194
- nullptr , // flags
195
- settings.isolate_create_callback , // isolate create callback
196
- settings.isolate_shutdown_callback // isolate shutdown callback
197
- );
198
-
199
- auto root_isolate =
200
- std::make_unique<AutoIsolateShutdown>(weak_isolate.lock (), task_runner);
201
-
202
- if (!root_isolate->IsValid ()) {
203
- FML_LOG (ERROR) << " Could not create isolate." ;
204
- return ;
205
- }
206
-
207
- if (root_isolate->get ()->GetPhase () != DartIsolate::Phase::LibrariesSetup) {
208
- FML_LOG (ERROR) << " Created isolate is in unexpected phase." ;
209
- return ;
210
- }
211
-
212
- if (!DartVM::IsRunningPrecompiledCode ()) {
213
- auto kernel_file_path =
214
- fml::paths::JoinPaths ({GetFixturesPath (), " kernel_blob.bin" });
215
-
216
- if (!fml::IsFile (kernel_file_path)) {
217
- FML_LOG (ERROR) << " Could not locate kernel file." ;
218
- return ;
219
- }
220
-
221
- auto kernel_file = fml::OpenFile (kernel_file_path.c_str (), false ,
222
- fml::FilePermission::kRead );
223
-
224
- if (!kernel_file.is_valid ()) {
225
- FML_LOG (ERROR) << " Kernel file descriptor was invalid." ;
226
- return ;
227
- }
228
-
229
- auto kernel_mapping = std::make_unique<fml::FileMapping>(kernel_file);
230
-
231
- if (kernel_mapping->GetMapping () == nullptr ) {
232
- FML_LOG (ERROR) << " Could not setup kernel mapping." ;
233
- return ;
234
- }
235
-
236
- if (!root_isolate->get ()->PrepareForRunningFromKernel (
237
- std::move (kernel_mapping))) {
238
- FML_LOG (ERROR)
239
- << " Could not prepare to run the isolate from the kernel file." ;
240
- return ;
241
- }
242
- } else {
243
- if (!root_isolate->get ()->PrepareForRunningFromPrecompiledCode ()) {
244
- FML_LOG (ERROR)
245
- << " Could not prepare to run the isolate from precompiled code." ;
246
- return ;
247
- }
248
- }
249
-
250
- if (root_isolate->get ()->GetPhase () != DartIsolate::Phase::Ready) {
251
- FML_LOG (ERROR) << " Isolate is in unexpected phase." ;
252
- return ;
253
- }
254
-
255
- if (!root_isolate->get ()->Run (entrypoint, args,
256
- settings.root_isolate_create_callback )) {
257
- FML_LOG (ERROR) << " Could not run the method \" " << entrypoint
258
- << " \" in the isolate." ;
259
- return ;
260
- }
261
-
262
- root_isolate->get ()->AddIsolateShutdownCallback (
263
- settings.root_isolate_shutdown_callback );
264
-
265
- result = std::move (root_isolate);
266
- }
267
-
268
- static std::unique_ptr<AutoIsolateShutdown> RunDartCodeInIsolate (
269
- DartVMRef& vm_ref,
270
- const Settings& settings,
271
- fml::RefPtr<fml::TaskRunner> task_runner,
272
- std::string entrypoint,
273
- const std::vector<std::string>& args) {
274
- std::unique_ptr<AutoIsolateShutdown> result;
275
- fml::AutoResetWaitableEvent latch;
276
- fml::TaskRunner::RunNowOrPostTask (
277
- task_runner, fml::MakeCopyable ([&]() mutable {
278
- RunDartCodeInIsolate (vm_ref, result, settings, task_runner, entrypoint,
279
- args);
280
- latch.Signal ();
281
- }));
282
- latch.Wait ();
283
- return result;
284
- }
285
-
286
98
TEST_F (DartIsolateTest, IsolateCanLoadAndRunDartCode) {
287
99
ASSERT_FALSE (DartVMRef::IsInstanceRunning ());
288
100
const auto settings = CreateSettingsForFixture ();
289
101
auto vm_ref = DartVMRef::Create (settings);
290
- auto isolate = RunDartCodeInIsolate (vm_ref, settings, GetCurrentTaskRunner (),
291
- " main" , {});
102
+ TaskRunners task_runners (GetCurrentTestName (), //
103
+ GetCurrentTaskRunner (), //
104
+ GetCurrentTaskRunner (), //
105
+ GetCurrentTaskRunner (), //
106
+ GetCurrentTaskRunner () //
107
+ );
108
+ auto isolate = RunDartCodeInIsolate (vm_ref, settings, task_runners, " main" ,
109
+ {}, GetFixturesPath ());
292
110
ASSERT_TRUE (isolate);
293
111
ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
294
112
}
@@ -297,17 +115,30 @@ TEST_F(DartIsolateTest, IsolateCannotLoadAndRunUnknownDartEntrypoint) {
297
115
ASSERT_FALSE (DartVMRef::IsInstanceRunning ());
298
116
const auto settings = CreateSettingsForFixture ();
299
117
auto vm_ref = DartVMRef::Create (settings);
300
- auto isolate = RunDartCodeInIsolate (vm_ref, settings, GetCurrentTaskRunner (),
301
- " thisShouldNotExist" , {});
118
+ TaskRunners task_runners (GetCurrentTestName (), //
119
+ GetCurrentTaskRunner (), //
120
+ GetCurrentTaskRunner (), //
121
+ GetCurrentTaskRunner (), //
122
+ GetCurrentTaskRunner () //
123
+ );
124
+ auto isolate =
125
+ RunDartCodeInIsolate (vm_ref, settings, task_runners, " thisShouldNotExist" ,
126
+ {}, GetFixturesPath ());
302
127
ASSERT_FALSE (isolate);
303
128
}
304
129
305
130
TEST_F (DartIsolateTest, CanRunDartCodeCodeSynchronously) {
306
131
ASSERT_FALSE (DartVMRef::IsInstanceRunning ());
307
132
const auto settings = CreateSettingsForFixture ();
308
133
auto vm_ref = DartVMRef::Create (settings);
309
- auto isolate = RunDartCodeInIsolate (vm_ref, settings, GetCurrentTaskRunner (),
310
- " main" , {});
134
+ TaskRunners task_runners (GetCurrentTestName (), //
135
+ GetCurrentTaskRunner (), //
136
+ GetCurrentTaskRunner (), //
137
+ GetCurrentTaskRunner (), //
138
+ GetCurrentTaskRunner () //
139
+ );
140
+ auto isolate = RunDartCodeInIsolate (vm_ref, settings, task_runners, " main" ,
141
+ {}, GetFixturesPath ());
311
142
312
143
ASSERT_TRUE (isolate);
313
144
ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
@@ -330,8 +161,16 @@ TEST_F(DartIsolateTest, CanRegisterNativeCallback) {
330
161
})));
331
162
const auto settings = CreateSettingsForFixture ();
332
163
auto vm_ref = DartVMRef::Create (settings);
333
- auto isolate = RunDartCodeInIsolate (vm_ref, settings, CreateNewThread (),
334
- " canRegisterNativeCallback" , {});
164
+ auto thread = CreateNewThread ();
165
+ TaskRunners task_runners (GetCurrentTestName (), //
166
+ thread, //
167
+ thread, //
168
+ thread, //
169
+ thread //
170
+ );
171
+ auto isolate =
172
+ RunDartCodeInIsolate (vm_ref, settings, task_runners,
173
+ " canRegisterNativeCallback" , {}, GetFixturesPath ());
335
174
ASSERT_TRUE (isolate);
336
175
ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
337
176
latch.Wait ();
@@ -353,8 +192,16 @@ TEST_F(DartIsolateTest, CanSaveCompilationTrace) {
353
192
354
193
const auto settings = CreateSettingsForFixture ();
355
194
auto vm_ref = DartVMRef::Create (settings);
356
- auto isolate = RunDartCodeInIsolate (vm_ref, settings, CreateNewThread (),
357
- " testCanSaveCompilationTrace" , {});
195
+ auto thread = CreateNewThread ();
196
+ TaskRunners task_runners (GetCurrentTestName (), //
197
+ thread, //
198
+ thread, //
199
+ thread, //
200
+ thread //
201
+ );
202
+ auto isolate = RunDartCodeInIsolate (vm_ref, settings, task_runners,
203
+ " testCanSaveCompilationTrace" , {},
204
+ GetFixturesPath ());
358
205
ASSERT_TRUE (isolate);
359
206
ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
360
207
@@ -384,8 +231,16 @@ TEST_F(DartIsolateTest, CanLaunchSecondaryIsolates) {
384
231
child_shutdown_latch.Signal ();
385
232
};
386
233
auto vm_ref = DartVMRef::Create (settings);
387
- auto isolate = RunDartCodeInIsolate (vm_ref, settings, CreateNewThread (),
388
- " testCanLaunchSecondaryIsolate" , {});
234
+ auto thread = CreateNewThread ();
235
+ TaskRunners task_runners (GetCurrentTestName (), //
236
+ thread, //
237
+ thread, //
238
+ thread, //
239
+ thread //
240
+ );
241
+ auto isolate = RunDartCodeInIsolate (vm_ref, settings, task_runners,
242
+ " testCanLaunchSecondaryIsolate" , {},
243
+ GetFixturesPath ());
389
244
ASSERT_TRUE (isolate);
390
245
ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
391
246
child_shutdown_latch.Wait (); // wait for child isolate to shutdown first
@@ -405,8 +260,16 @@ TEST_F(DartIsolateTest, CanRecieveArguments) {
405
260
406
261
const auto settings = CreateSettingsForFixture ();
407
262
auto vm_ref = DartVMRef::Create (settings);
408
- auto isolate = RunDartCodeInIsolate (vm_ref, settings, CreateNewThread (),
409
- " testCanRecieveArguments" , {" arg1" });
263
+ auto thread = CreateNewThread ();
264
+ TaskRunners task_runners (GetCurrentTestName (), //
265
+ thread, //
266
+ thread, //
267
+ thread, //
268
+ thread //
269
+ );
270
+ auto isolate = RunDartCodeInIsolate (vm_ref, settings, task_runners,
271
+ " testCanRecieveArguments" , {" arg1" },
272
+ GetFixturesPath ());
410
273
ASSERT_TRUE (isolate);
411
274
ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
412
275
0 commit comments