Flutter Engine
dart_lifecycle_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/common/task_runners.h"
6 #include "flutter/fml/paths.h"
7 #include "flutter/fml/synchronization/count_down_latch.h"
8 #include "flutter/fml/synchronization/waitable_event.h"
9 #include "flutter/runtime/dart_vm.h"
10 #include "flutter/runtime/dart_vm_lifecycle.h"
11 #include "flutter/runtime/isolate_configuration.h"
12 #include "flutter/testing/fixture_test.h"
13 
14 namespace flutter {
15 namespace testing {
16 
18 
19 TEST_F(DartLifecycleTest, CanStartAndShutdownVM) {
20  auto settings = CreateSettingsForFixture();
21  settings.leak_vm = false;
22  settings.enable_observatory = false;
23  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
24  {
25  auto vm_ref = DartVMRef::Create(settings);
26  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
27  }
28  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
29 }
30 
31 TEST_F(DartLifecycleTest, CanStartAndShutdownVMOverAndOver) {
32  auto settings = CreateSettingsForFixture();
33  settings.leak_vm = false;
34  settings.enable_observatory = false;
35  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
36  auto count = DartVM::GetVMLaunchCount();
37  for (size_t i = 0; i < 10; i++) {
38  auto vm_ref = DartVMRef::Create(settings);
39  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
40  ASSERT_EQ(DartVM::GetVMLaunchCount(), count + 1);
41  count = DartVM::GetVMLaunchCount();
42  }
43  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
44 }
45 
46 static std::shared_ptr<DartIsolate> CreateAndRunRootIsolate(
47  const Settings& settings,
48  const DartVMData& vm,
49  fml::RefPtr<fml::TaskRunner> task_runner,
50  std::string entrypoint) {
51  FML_CHECK(entrypoint.size() > 0);
52  TaskRunners runners("io.flutter.test", task_runner, task_runner, task_runner,
53  task_runner);
54 
55  auto isolate_configuration =
57 
58  auto isolate =
60  vm.GetSettings(), // settings
61  vm.GetIsolateSnapshot(), // isolate_snapshot
62  runners, // task_runners
63  {}, // window
64  {}, // snapshot_delegate
65  {}, // hint_freed_delegate
66  {}, // io_manager
67  {}, // unref_queue
68  {}, // image_decoder
69  "main.dart", // advisory_script_uri
70  entrypoint.c_str(), // advisory_script_entrypoint
71  DartIsolate::Flags{}, // flags
72  settings.isolate_create_callback, // isolate create callback
73  settings.isolate_shutdown_callback, // isolate shutdown callback,
74  entrypoint, // dart entrypoint
75  std::nullopt, // dart entrypoint library
76  std::move(isolate_configuration) // isolate configuration
77  )
78  .lock();
79 
80  if (!isolate) {
81  FML_LOG(ERROR) << "Could not launch the root isolate.";
82  return nullptr;
83  }
84 
85  return isolate;
86 }
87 
88 // TODO(chinmaygarde): This unit-test is flaky and indicates thread un-safety
89 // during shutdown. https://github.com/flutter/flutter/issues/36782
90 TEST_F(DartLifecycleTest, DISABLED_ShuttingDownTheVMShutsDownAllIsolates) {
91  auto settings = CreateSettingsForFixture();
92  settings.leak_vm = false;
93  // Make sure the service protocol launches
94  settings.enable_observatory = true;
95 
96  auto thread_task_runner = CreateNewThread();
97 
98  for (size_t i = 0; i < 3; i++) {
99  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
100 
101  const auto last_launch_count = DartVM::GetVMLaunchCount();
102 
103  auto vm_ref = DartVMRef::Create(settings);
104 
105  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
106  ASSERT_EQ(last_launch_count + 1, DartVM::GetVMLaunchCount());
107 
108  const size_t isolate_count = 5;
109 
110  fml::CountDownLatch latch(isolate_count);
111  auto vm_data = vm_ref.GetVMData();
112  for (size_t i = 0; i < isolate_count; ++i) {
113  thread_task_runner->PostTask(
114  [vm_data, &settings, &latch, thread_task_runner]() {
115  ASSERT_TRUE(CreateAndRunRootIsolate(settings, *vm_data.get(),
116  thread_task_runner,
117  "testIsolateShutdown"));
118  latch.CountDown();
119  });
120  }
121 
122  latch.Wait();
123  }
124  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
125 }
126 
127 } // namespace testing
128 } // namespace flutter
const Settings & GetSettings() const
The settings object from which the Dart snapshots were inferred.
Definition: dart_vm_data.cc:51
fml::closure isolate_shutdown_callback
Definition: settings.h:181
fml::closure isolate_create_callback
Definition: settings.h:177
Provides thread-safe access to data that is necessary to bootstrap a new Dart VM instance. All snapshots referenced by this object are read-only.
Definition: dart_vm_data.h:18
static std::weak_ptr< DartIsolate > CreateRunningRootIsolate(const Settings &settings, fml::RefPtr< const DartSnapshot > isolate_snapshot, TaskRunners task_runners, std::unique_ptr< PlatformConfiguration > platform_configuration, fml::WeakPtr< SnapshotDelegate > snapshot_delegate, fml::WeakPtr< HintFreedDelegate > hint_freed_delegate, fml::WeakPtr< IOManager > io_manager, fml::RefPtr< SkiaUnrefQueue > skia_unref_queue, fml::WeakPtr< ImageDecoder > image_decoder, std::string advisory_script_uri, std::string advisory_script_entrypoint, Flags flags, const fml::closure &isolate_create_callback, const fml::closure &isolate_shutdown_callback, std::optional< std::string > dart_entrypoint, std::optional< std::string > dart_entrypoint_library, std::unique_ptr< IsolateConfiguration > isolate_configration)
Creates an instance of a root isolate and returns a weak pointer to the same. The isolate instance ma...
Definition: dart_isolate.cc:76
#define FML_LOG(severity)
Definition: logging.h:65
static bool IsInstanceRunning()
static DartVMRef Create(Settings settings, fml::RefPtr< DartSnapshot > vm_snapshot=nullptr, fml::RefPtr< DartSnapshot > isolate_snapshot=nullptr)
static std::unique_ptr< IsolateConfiguration > InferFromSettings(const Settings &settings, std::shared_ptr< AssetManager > asset_manager=nullptr, fml::RefPtr< fml::TaskRunner > io_worker=nullptr)
Attempts to infer the isolate configuration from the Settings object. If the VM is configured for AOT...
TEST_F(BackdropFilterLayerTest, PaintingEmptyLayerDies)
static std::shared_ptr< DartIsolate > CreateAndRunRootIsolate(const Settings &settings, const DartVMData &vm, fml::RefPtr< fml::TaskRunner > task_runner, std::string entrypoint)
static size_t GetVMLaunchCount()
The number of times the VM has been launched in the process. This call is inherently racy because the...
Definition: dart_vm.cc:261
#define FML_CHECK(condition)
Definition: logging.h:68
fml::RefPtr< const DartSnapshot > GetIsolateSnapshot() const
Get the isolate snapshot necessary to launch isolates in the Dart VM. The Dart VM instance in which t...
Definition: dart_vm_data.cc:59