forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dart_lifecycle_unittests.cc
147 lines (124 loc) · 4.94 KB
/
dart_lifecycle_unittests.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/common/task_runners.h"
#include "flutter/fml/paths.h"
#include "flutter/fml/synchronization/count_down_latch.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/runtime/dart_vm_lifecycle.h"
#include "flutter/runtime/runtime_test.h"
namespace flutter {
namespace testing {
using DartLifecycleTest = RuntimeTest;
TEST_F(DartLifecycleTest, CanStartAndShutdownVM) {
auto settings = CreateSettingsForFixture();
settings.leak_vm = false;
settings.enable_observatory = false;
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
{
auto vm_ref = DartVMRef::Create(settings);
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
}
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
TEST_F(DartLifecycleTest, CanStartAndShutdownVMOverAndOver) {
auto settings = CreateSettingsForFixture();
settings.leak_vm = false;
settings.enable_observatory = false;
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
auto count = DartVM::GetVMLaunchCount();
for (size_t i = 0; i < 10; i++) {
auto vm_ref = DartVMRef::Create(settings);
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
ASSERT_EQ(DartVM::GetVMLaunchCount(), count + 1);
count = DartVM::GetVMLaunchCount();
}
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
static std::shared_ptr<DartIsolate> CreateAndRunRootIsolate(
const Settings& settings,
const DartVMData& vm,
fml::RefPtr<fml::TaskRunner> task_runner,
std::string entrypoint) {
FML_CHECK(entrypoint.size() > 0);
TaskRunners runners("io.flutter.test", task_runner, task_runner, task_runner,
task_runner);
auto isolate_weak = DartIsolate::CreateRootIsolate(
vm.GetSettings(), // settings
vm.GetIsolateSnapshot(), // isolate_snapshot
vm.GetSharedSnapshot(), // shared_snapshot
runners, // task_runners
{}, // window
{}, // io_manager
{}, // image_decoder
"main.dart", // advisory_script_uri
entrypoint.c_str(), // advisory_script_entrypoint
nullptr, // flags
settings.isolate_create_callback, // isolate create callback
settings.isolate_shutdown_callback // isolate shutdown callback
);
auto isolate = isolate_weak.lock();
if (!isolate) {
FML_LOG(ERROR) << "Could not create valid isolate.";
return nullptr;
}
if (DartVM::IsRunningPrecompiledCode()) {
if (!isolate->PrepareForRunningFromPrecompiledCode()) {
FML_LOG(ERROR)
<< "Could not prepare to run the isolate from precompiled code.";
return nullptr;
}
} else {
if (!isolate->PrepareForRunningFromKernels(
settings.application_kernels())) {
FML_LOG(ERROR) << "Could not prepare isolate from application kernels.";
return nullptr;
}
}
if (isolate->GetPhase() != DartIsolate::Phase::Ready) {
FML_LOG(ERROR) << "Isolate was not ready.";
return nullptr;
}
if (!isolate->Run(entrypoint, {}, settings.root_isolate_create_callback)) {
FML_LOG(ERROR) << "Could not run entrypoint: " << entrypoint << ".";
return nullptr;
}
if (isolate->GetPhase() != DartIsolate::Phase::Running) {
FML_LOG(ERROR) << "Isolate was not Running.";
return nullptr;
}
return isolate;
}
// TODO(chinmaygarde): This unit-test is flaky and indicates thread un-safety
// during shutdown. https://github.com/flutter/flutter/issues/36782
TEST_F(DartLifecycleTest, DISABLED_ShuttingDownTheVMShutsDownAllIsolates) {
auto settings = CreateSettingsForFixture();
settings.leak_vm = false;
// Make sure the service protocol launches
settings.enable_observatory = true;
for (size_t i = 0; i < 3; i++) {
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
const auto last_launch_count = DartVM::GetVMLaunchCount();
auto vm_ref = DartVMRef::Create(settings);
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
ASSERT_EQ(last_launch_count + 1, DartVM::GetVMLaunchCount());
const size_t isolate_count = 5;
fml::CountDownLatch latch(isolate_count);
auto vm_data = vm_ref.GetVMData();
auto thread_task_runner = GetThreadTaskRunner();
for (size_t i = 0; i < isolate_count; ++i) {
thread_task_runner->PostTask(
[vm_data, &settings, &latch, thread_task_runner]() {
ASSERT_TRUE(CreateAndRunRootIsolate(settings, *vm_data.get(),
thread_task_runner,
"testIsolateShutdown"));
latch.CountDown();
});
}
latch.Wait();
}
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
} // namespace testing
} // namespace flutter