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  UIDartState::Context context(runners);
59  context.advisory_script_uri = "main.dart";
60  context.advisory_script_entrypoint = entrypoint.c_str();
61  auto isolate =
63  vm.GetSettings(), // settings
64  vm.GetIsolateSnapshot(), // isolate_snapshot
65  {}, // platform configuration
66  DartIsolate::Flags{}, // flags
67  settings.isolate_create_callback, // isolate create callback
68  settings.isolate_shutdown_callback, // isolate shutdown callback,
69  entrypoint, // dart entrypoint
70  std::nullopt, // dart entrypoint library
71  std::move(isolate_configuration), // isolate configuration
72  std::move(context) // engine context
73  )
74  .lock();
75 
76  if (!isolate) {
77  FML_LOG(ERROR) << "Could not launch the root isolate.";
78  return nullptr;
79  }
80 
81  return isolate;
82 }
83 
84 // TODO(chinmaygarde): This unit-test is flaky and indicates thread un-safety
85 // during shutdown. https://github.com/flutter/flutter/issues/36782
86 TEST_F(DartLifecycleTest, DISABLED_ShuttingDownTheVMShutsDownAllIsolates) {
87  auto settings = CreateSettingsForFixture();
88  settings.leak_vm = false;
89  // Make sure the service protocol launches
90  settings.enable_observatory = true;
91 
92  auto thread_task_runner = CreateNewThread();
93 
94  for (size_t i = 0; i < 3; i++) {
95  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
96 
97  const auto last_launch_count = DartVM::GetVMLaunchCount();
98 
99  auto vm_ref = DartVMRef::Create(settings);
100 
101  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
102  ASSERT_EQ(last_launch_count + 1, DartVM::GetVMLaunchCount());
103 
104  const size_t isolate_count = 5;
105 
106  fml::CountDownLatch latch(isolate_count);
107  auto vm_data = vm_ref.GetVMData();
108  for (size_t i = 0; i < isolate_count; ++i) {
109  thread_task_runner->PostTask(
110  [vm_data, &settings, &latch, thread_task_runner]() {
111  ASSERT_TRUE(CreateAndRunRootIsolate(settings, *vm_data.get(),
112  thread_task_runner,
113  "testIsolateShutdown"));
114  latch.CountDown();
115  });
116  }
117 
118  latch.Wait();
119  }
120  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
121 }
122 
123 } // namespace testing
124 } // 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:223
fml::closure isolate_create_callback
Definition: settings.h:219
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
#define FML_LOG(severity)
Definition: logging.h:65
static bool IsInstanceRunning()
static DartVMRef Create(Settings settings, fml::RefPtr< const DartSnapshot > vm_snapshot=nullptr, fml::RefPtr< const 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...
The subset of state which is owned by the shell or engine and passed through the RuntimeController in...
Definition: ui_dart_state.h:43
TEST_F(BackdropFilterLayerTest, PaintingEmptyLayerDies)
std::string advisory_script_entrypoint
Definition: ui_dart_state.h:88
static std::shared_ptr< DartIsolate > CreateAndRunRootIsolate(const Settings &settings, const DartVMData &vm, fml::RefPtr< fml::TaskRunner > task_runner, std::string entrypoint)
static std::weak_ptr< DartIsolate > CreateRunningRootIsolate(const Settings &settings, fml::RefPtr< const DartSnapshot > isolate_snapshot, std::unique_ptr< PlatformConfiguration > platform_configuration, 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, const UIDartState::Context &context, const DartIsolate *spawning_isolate=nullptr)
Creates an instance of a root isolate and returns a weak pointer to the same. The isolate instance ma...
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:264
#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