shell_unittests.cc 10.1 KB
Newer Older
M
Michael Goderbauer 已提交
1
// Copyright 2013 The Flutter Authors. All rights reserved.
2 3 4 5 6 7 8 9 10
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#define FML_USED_ON_EMBEDDER

#include <functional>
#include <future>
#include <memory>

11
#include "flutter/fml/make_copyable.h"
12
#include "flutter/fml/message_loop.h"
13
#include "flutter/fml/synchronization/count_down_latch.h"
14
#include "flutter/fml/synchronization/waitable_event.h"
15 16
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/common/rasterizer.h"
17
#include "flutter/shell/common/shell_test.h"
18
#include "flutter/shell/common/thread_host.h"
19
#include "flutter/testing/testing.h"
20

21
namespace flutter {
22
namespace testing {
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
static bool ValidateShell(Shell* shell) {
  if (!shell) {
    return false;
  }

  if (!shell->IsSetup()) {
    return false;
  }

  {
    fml::AutoResetWaitableEvent latch;
    fml::TaskRunner::RunNowOrPostTask(
        shell->GetTaskRunners().GetPlatformTaskRunner(), [shell, &latch]() {
          shell->GetPlatformView()->NotifyCreated();
          latch.Signal();
        });
    latch.Wait();
  }

  {
    fml::AutoResetWaitableEvent latch;
    fml::TaskRunner::RunNowOrPostTask(
        shell->GetTaskRunners().GetPlatformTaskRunner(), [shell, &latch]() {
          shell->GetPlatformView()->NotifyDestroyed();
          latch.Signal();
        });
    latch.Wait();
  }

  return true;
}

56
TEST_F(ShellTest, InitializeWithInvalidThreads) {
57
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
58 59
  Settings settings = CreateSettingsForFixture();
  TaskRunners task_runners("test", nullptr, nullptr, nullptr, nullptr);
60 61 62
  auto shell = Shell::Create(
      std::move(task_runners), settings,
      [](Shell& shell) {
63 64
        return std::make_unique<ShellTestPlatformView>(shell,
                                                       shell.GetTaskRunners());
65 66 67 68 69
      },
      [](Shell& shell) {
        return std::make_unique<Rasterizer>(shell.GetTaskRunners());
      });
  ASSERT_FALSE(shell);
70
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
71 72
}

73
TEST_F(ShellTest, InitializeWithDifferentThreads) {
74
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
75
  Settings settings = CreateSettingsForFixture();
76 77 78
  ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
                         ThreadHost::Type::Platform | ThreadHost::Type::GPU |
                             ThreadHost::Type::IO | ThreadHost::Type::UI);
79 80 81 82
  TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(),
                           thread_host.gpu_thread->GetTaskRunner(),
                           thread_host.ui_thread->GetTaskRunner(),
                           thread_host.io_thread->GetTaskRunner());
83 84 85
  auto shell = Shell::Create(
      std::move(task_runners), settings,
      [](Shell& shell) {
86 87
        return std::make_unique<ShellTestPlatformView>(shell,
                                                       shell.GetTaskRunners());
88 89 90 91
      },
      [](Shell& shell) {
        return std::make_unique<Rasterizer>(shell.GetTaskRunners());
      });
92
  ASSERT_TRUE(ValidateShell(shell.get()));
93 94 95
  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
  shell.reset();
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
96 97
}

98
TEST_F(ShellTest, InitializeWithSingleThread) {
99
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
100
  Settings settings = CreateSettingsForFixture();
101 102
  ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
                         ThreadHost::Type::Platform);
103
  auto task_runner = thread_host.platform_thread->GetTaskRunner();
104 105
  TaskRunners task_runners("test", task_runner, task_runner, task_runner,
                           task_runner);
106 107 108
  auto shell = Shell::Create(
      std::move(task_runners), settings,
      [](Shell& shell) {
109 110
        return std::make_unique<ShellTestPlatformView>(shell,
                                                       shell.GetTaskRunners());
111 112 113 114
      },
      [](Shell& shell) {
        return std::make_unique<Rasterizer>(shell.GetTaskRunners());
      });
115
  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
116
  ASSERT_TRUE(ValidateShell(shell.get()));
117 118
  shell.reset();
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
119 120
}

121
TEST_F(ShellTest, InitializeWithSingleThreadWhichIsTheCallingThread) {
122
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
123
  Settings settings = CreateSettingsForFixture();
124 125
  fml::MessageLoop::EnsureInitializedForCurrentThread();
  auto task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();
126 127
  TaskRunners task_runners("test", task_runner, task_runner, task_runner,
                           task_runner);
128 129 130
  auto shell = Shell::Create(
      std::move(task_runners), settings,
      [](Shell& shell) {
131 132
        return std::make_unique<ShellTestPlatformView>(shell,
                                                       shell.GetTaskRunners());
133 134 135 136
      },
      [](Shell& shell) {
        return std::make_unique<Rasterizer>(shell.GetTaskRunners());
      });
137
  ASSERT_TRUE(ValidateShell(shell.get()));
138 139 140
  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
  shell.reset();
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
141 142
}

143 144
TEST_F(ShellTest,
       InitializeWithMultipleThreadButCallingThreadAsPlatformThread) {
145
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
146
  Settings settings = CreateSettingsForFixture();
147
  ThreadHost thread_host(
148
      "io.flutter.test." + GetCurrentTestName() + ".",
149 150
      ThreadHost::Type::GPU | ThreadHost::Type::IO | ThreadHost::Type::UI);
  fml::MessageLoop::EnsureInitializedForCurrentThread();
151 152 153 154 155
  TaskRunners task_runners("test",
                           fml::MessageLoop::GetCurrent().GetTaskRunner(),
                           thread_host.gpu_thread->GetTaskRunner(),
                           thread_host.ui_thread->GetTaskRunner(),
                           thread_host.io_thread->GetTaskRunner());
156 157 158
  auto shell = Shell::Create(
      std::move(task_runners), settings,
      [](Shell& shell) {
159 160
        return std::make_unique<ShellTestPlatformView>(shell,
                                                       shell.GetTaskRunners());
161 162 163 164 165
      },
      [](Shell& shell) {
        return std::make_unique<Rasterizer>(shell.GetTaskRunners());
      });
  ASSERT_TRUE(ValidateShell(shell.get()));
166 167 168
  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
  shell.reset();
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
169 170
}

171
TEST_F(ShellTest, InitializeWithGPUAndPlatformThreadsTheSame) {
172
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
173
  Settings settings = CreateSettingsForFixture();
174
  ThreadHost thread_host(
175
      "io.flutter.test." + GetCurrentTestName() + ".",
176
      ThreadHost::Type::Platform | ThreadHost::Type::IO | ThreadHost::Type::UI);
177
  TaskRunners task_runners(
178 179 180 181 182 183 184 185 186
      "test",
      thread_host.platform_thread->GetTaskRunner(),  // platform
      thread_host.platform_thread->GetTaskRunner(),  // gpu
      thread_host.ui_thread->GetTaskRunner(),        // ui
      thread_host.io_thread->GetTaskRunner()         // io
  );
  auto shell = Shell::Create(
      std::move(task_runners), settings,
      [](Shell& shell) {
187 188
        return std::make_unique<ShellTestPlatformView>(shell,
                                                       shell.GetTaskRunners());
189 190 191 192
      },
      [](Shell& shell) {
        return std::make_unique<Rasterizer>(shell.GetTaskRunners());
      });
193
  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
194
  ASSERT_TRUE(ValidateShell(shell.get()));
195 196
  shell.reset();
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
197 198
}

199
TEST_F(ShellTest, FixturesAreFunctional) {
200
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
201 202 203 204
  const auto settings = CreateSettingsForFixture();
  auto shell = Shell::Create(
      GetTaskRunnersForFixture(), settings,
      [](Shell& shell) {
205 206
        return std::make_unique<ShellTestPlatformView>(shell,
                                                       shell.GetTaskRunners());
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
      },
      [](Shell& shell) {
        return std::make_unique<Rasterizer>(shell.GetTaskRunners());
      });
  ASSERT_TRUE(ValidateShell(shell.get()));

  auto configuration = RunConfiguration::InferFromSettings(settings);
  ASSERT_TRUE(configuration.IsValid());
  configuration.SetEntrypoint("fixturesAreFunctionalMain");

  fml::AutoResetWaitableEvent main_latch;
  AddNativeCallback(
      "SayHiFromFixturesAreFunctionalMain",
      CREATE_NATIVE_ENTRY([&main_latch](auto args) { main_latch.Signal(); }));

  fml::AutoResetWaitableEvent latch;
  fml::TaskRunner::RunNowOrPostTask(
      shell->GetTaskRunners().GetUITaskRunner(),
      fml::MakeCopyable([&latch, config = std::move(configuration),
                         engine = shell->GetEngine()]() mutable {
        ASSERT_TRUE(engine);
        ASSERT_EQ(engine->Run(std::move(config)), Engine::RunStatus::Success);
        latch.Signal();
      }));

  latch.Wait();
  main_latch.Wait();
234 235 236
  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
  shell.reset();
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
237 238
}

239 240 241 242 243 244
TEST_F(ShellTest, SecondaryIsolateBindingsAreSetupViaShellSettings) {
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
  const auto settings = CreateSettingsForFixture();
  auto shell = Shell::Create(
      GetTaskRunnersForFixture(), settings,
      [](Shell& shell) {
245 246
        return std::make_unique<ShellTestPlatformView>(shell,
                                                       shell.GetTaskRunners());
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
      },
      [](Shell& shell) {
        return std::make_unique<Rasterizer>(shell.GetTaskRunners());
      });
  ASSERT_TRUE(ValidateShell(shell.get()));

  auto configuration = RunConfiguration::InferFromSettings(settings);
  ASSERT_TRUE(configuration.IsValid());
  configuration.SetEntrypoint("testCanLaunchSecondaryIsolate");

  fml::CountDownLatch latch(2);
  AddNativeCallback("NotifyNative", CREATE_NATIVE_ENTRY([&latch](auto args) {
                      latch.CountDown();
                    }));

  fml::TaskRunner::RunNowOrPostTask(
      shell->GetTaskRunners().GetUITaskRunner(),
      fml::MakeCopyable([config = std::move(configuration),
                         engine = shell->GetEngine()]() mutable {
        ASSERT_TRUE(engine);
        ASSERT_EQ(engine->Run(std::move(config)), Engine::RunStatus::Success);
      }));

  latch.Wait();

  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
  shell.reset();
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}

277
}  // namespace testing
278
}  // namespace flutter