diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index eb96631316d..c9914e4c215 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -391,6 +391,8 @@ FILE: ../../../flutter/runtime/runtime_controller.cc FILE: ../../../flutter/runtime/runtime_controller.h FILE: ../../../flutter/runtime/runtime_delegate.cc FILE: ../../../flutter/runtime/runtime_delegate.h +FILE: ../../../flutter/runtime/runtime_test.cc +FILE: ../../../flutter/runtime/runtime_test.h FILE: ../../../flutter/runtime/service_protocol.cc FILE: ../../../flutter/runtime/service_protocol.h FILE: ../../../flutter/runtime/start_up.cc diff --git a/engine/src/flutter/runtime/BUILD.gn b/engine/src/flutter/runtime/BUILD.gn index e01cf5d8f20..9aeba8e6e3c 100644 --- a/engine/src/flutter/runtime/BUILD.gn +++ b/engine/src/flutter/runtime/BUILD.gn @@ -104,16 +104,18 @@ executable("runtime_unittests") { "dart_isolate_unittests.cc", "dart_service_isolate_unittests.cc", "dart_vm_unittests.cc", + "runtime_test.cc", + "runtime_test.h", ] deps = [ + ":libdart", ":runtime", ":runtime_fixtures", "$flutter_root/common", "$flutter_root/fml", "$flutter_root/lib/snapshot", "$flutter_root/testing", - "//third_party/dart/runtime:libdart_jit", "//third_party/skia", "//third_party/tonic", ] diff --git a/engine/src/flutter/runtime/dart_isolate_unittests.cc b/engine/src/flutter/runtime/dart_isolate_unittests.cc index 76de89deb06..59bd9d61bb1 100644 --- a/engine/src/flutter/runtime/dart_isolate_unittests.cc +++ b/engine/src/flutter/runtime/dart_isolate_unittests.cc @@ -7,27 +7,24 @@ #include "flutter/fml/thread.h" #include "flutter/runtime/dart_isolate.h" #include "flutter/runtime/dart_vm.h" +#include "flutter/runtime/runtime_test.h" #include "flutter/testing/testing.h" #include "flutter/testing/thread_test.h" #include "third_party/tonic/scopes/dart_isolate_scope.h" -#if FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG -#define SKIP_IF_AOT() GTEST_SKIP() -#else -#define SKIP_IF_AOT() (void)0 -#endif - #define CURRENT_TEST_NAME \ std::string { \ ::testing::UnitTest::GetInstance()->current_test_info()->name() \ } namespace blink { +namespace testing { -using DartIsolateTest = ::testing::ThreadTest; +using DartIsolateTest = RuntimeTest; TEST_F(DartIsolateTest, RootIsolateCreationAndShutdown) { Settings settings = {}; + SetSnapshotsAndAssets(settings); settings.task_observer_add = [](intptr_t, fml::closure) {}; settings.task_observer_remove = [](intptr_t) {}; auto vm = DartVM::ForProcess(settings); @@ -130,7 +127,7 @@ class AutoIsolateShutdown { FML_DISALLOW_COPY_AND_ASSIGN(AutoIsolateShutdown); }; -std::unique_ptr RunDartCodeInIsolate( +static std::unique_ptr RunDartCodeInIsolate( fml::RefPtr task_runner, std::string entrypoint) { Settings settings = {}; @@ -174,34 +171,42 @@ std::unique_ptr RunDartCodeInIsolate( return {}; } - auto kernel_file_path = - fml::paths::JoinPaths({testing::GetFixturesPath(), "kernel_blob.bin"}); + if (!DartVM::IsRunningPrecompiledCode()) { + auto kernel_file_path = fml::paths::JoinPaths( + {::testing::GetFixturesPath(), "kernel_blob.bin"}); - if (!fml::IsFile(kernel_file_path)) { - FML_LOG(ERROR) << "Could not locate kernel file."; - return {}; - } + if (!fml::IsFile(kernel_file_path)) { + FML_LOG(ERROR) << "Could not locate kernel file."; + return {}; + } - auto kernel_file = fml::OpenFile(kernel_file_path.c_str(), false, - fml::FilePermission::kRead); + auto kernel_file = fml::OpenFile(kernel_file_path.c_str(), false, + fml::FilePermission::kRead); - if (!kernel_file.is_valid()) { - FML_LOG(ERROR) << "Kernel file descriptor was invalid."; - return {}; - } + if (!kernel_file.is_valid()) { + FML_LOG(ERROR) << "Kernel file descriptor was invalid."; + return {}; + } - auto kernel_mapping = std::make_unique(kernel_file); + auto kernel_mapping = std::make_unique(kernel_file); - if (kernel_mapping->GetMapping() == nullptr) { - FML_LOG(ERROR) << "Could not setup kernel mapping."; - return {}; - } + if (kernel_mapping->GetMapping() == nullptr) { + FML_LOG(ERROR) << "Could not setup kernel mapping."; + return {}; + } - if (!root_isolate->get()->PrepareForRunningFromKernel( - std::move(kernel_mapping))) { - FML_LOG(ERROR) - << "Could not prepare to run the isolate from the kernel file."; - return {}; + if (!root_isolate->get()->PrepareForRunningFromKernel( + std::move(kernel_mapping))) { + FML_LOG(ERROR) + << "Could not prepare to run the isolate from the kernel file."; + return {}; + } + } else { + if (!root_isolate->get()->PrepareForRunningFromPrecompiledCode()) { + FML_LOG(ERROR) + << "Could not prepare to run the isolate from precompiled code."; + return {}; + } } if (root_isolate->get()->GetPhase() != DartIsolate::Phase::Ready) { @@ -219,21 +224,18 @@ std::unique_ptr RunDartCodeInIsolate( } TEST_F(DartIsolateTest, IsolateCanLoadAndRunDartCode) { - SKIP_IF_AOT(); auto isolate = RunDartCodeInIsolate(GetCurrentTaskRunner(), "main"); ASSERT_TRUE(isolate); ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running); } TEST_F(DartIsolateTest, IsolateCannotLoadAndRunUnknownDartEntrypoint) { - SKIP_IF_AOT(); auto isolate = RunDartCodeInIsolate(GetCurrentTaskRunner(), "thisShouldNotExist"); ASSERT_FALSE(isolate); } TEST_F(DartIsolateTest, CanRunDartCodeCodeSynchronously) { - SKIP_IF_AOT(); auto isolate = RunDartCodeInIsolate(GetCurrentTaskRunner(), "main"); ASSERT_TRUE(isolate); @@ -247,4 +249,5 @@ TEST_F(DartIsolateTest, CanRunDartCodeCodeSynchronously) { })); } +} // namespace testing } // namespace blink diff --git a/engine/src/flutter/runtime/dart_vm_unittests.cc b/engine/src/flutter/runtime/dart_vm_unittests.cc index 21e3d3d3fa5..a0cfdfbbc5f 100644 --- a/engine/src/flutter/runtime/dart_vm_unittests.cc +++ b/engine/src/flutter/runtime/dart_vm_unittests.cc @@ -14,7 +14,6 @@ TEST(DartVM, SimpleInitialization) { auto vm = DartVM::ForProcess(settings); ASSERT_TRUE(vm); ASSERT_EQ(vm, DartVM::ForProcess(settings)); - ASSERT_FALSE(DartVM::IsRunningPrecompiledCode()); } TEST(DartVM, SimpleIsolateNameServer) { diff --git a/engine/src/flutter/runtime/fixtures/simple_main.dart b/engine/src/flutter/runtime/fixtures/simple_main.dart index 5d6a46eb7f1..308e033efb1 100644 --- a/engine/src/flutter/runtime/fixtures/simple_main.dart +++ b/engine/src/flutter/runtime/fixtures/simple_main.dart @@ -5,10 +5,12 @@ void main() { } +@pragma('vm:entry-point') void sayHi() { print("Hi"); } +@pragma('vm:entry-point') void throwExceptionNow() { throw("Hello"); } diff --git a/engine/src/flutter/runtime/runtime_test.cc b/engine/src/flutter/runtime/runtime_test.cc new file mode 100644 index 00000000000..002971e8853 --- /dev/null +++ b/engine/src/flutter/runtime/runtime_test.cc @@ -0,0 +1,87 @@ +// 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/runtime/runtime_test.h" + +#include "flutter/runtime/dart_vm.h" +#include "flutter/testing/testing.h" + +namespace blink { +namespace testing { + +RuntimeTest::RuntimeTest() = default; + +RuntimeTest::~RuntimeTest() = default; + +static std::unique_ptr GetMapping(const fml::UniqueFD& directory, + const char* path, + bool executable) { + fml::UniqueFD file = fml::OpenFile(directory, path, false /* create */, + fml::FilePermission::kRead); + if (!file.is_valid()) { + return nullptr; + } + + using Prot = fml::FileMapping::Protection; + std::unique_ptr mapping; + if (executable) { + mapping = std::make_unique( + file, std::initializer_list{Prot::kRead, Prot::kExecute}); + } else { + mapping = std::make_unique( + file, std::initializer_list{Prot::kRead}); + } + + if (mapping->GetSize() == 0 || mapping->GetMapping() == nullptr) { + return nullptr; + } + + return mapping; +} + +void RuntimeTest::SetSnapshotsAndAssets(Settings& settings) { + if (!assets_dir_.is_valid()) { + return; + } + + settings.assets_dir = assets_dir_.get(); + + // In JIT execution, all snapshots are present within the binary itself and + // don't need to be explicitly suppiled by the embedder. + if (DartVM::IsRunningPrecompiledCode()) { + settings.vm_snapshot_data = [this]() { + return GetMapping(assets_dir_, "vm_snapshot_data", false); + }; + + settings.isolate_snapshot_data = [this]() { + return GetMapping(assets_dir_, "isolate_snapshot_data", false); + }; + + if (DartVM::IsRunningPrecompiledCode()) { + settings.vm_snapshot_instr = [this]() { + return GetMapping(assets_dir_, "vm_snapshot_instr", true); + }; + + settings.isolate_snapshot_instr = [this]() { + return GetMapping(assets_dir_, "isolate_snapshot_instr", true); + }; + } + } +} + +// |testing::ThreadTest| +void RuntimeTest::SetUp() { + assets_dir_ = fml::OpenDirectory(::testing::GetFixturesPath(), false, + fml::FilePermission::kRead); + ThreadTest::SetUp(); +} + +// |testing::ThreadTest| +void RuntimeTest::TearDown() { + ThreadTest::TearDown(); + assets_dir_.reset(); +} + +} // namespace testing +} // namespace blink diff --git a/engine/src/flutter/runtime/runtime_test.h b/engine/src/flutter/runtime/runtime_test.h new file mode 100644 index 00000000000..86dfc5174c4 --- /dev/null +++ b/engine/src/flutter/runtime/runtime_test.h @@ -0,0 +1,37 @@ +// 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. + +#ifndef FLUTTER_RUNTIME_RUNTIME_TEST_H_ +#define FLUTTER_RUNTIME_RUNTIME_TEST_H_ + +#include "flutter/common/settings.h" +#include "flutter/fml/macros.h" +#include "flutter/testing/thread_test.h" + +namespace blink { +namespace testing { + +class RuntimeTest : public ::testing::ThreadTest { + public: + RuntimeTest(); + + ~RuntimeTest(); + + void SetSnapshotsAndAssets(Settings& settings); + + protected: + // |testing::ThreadTest| + void SetUp() override; + + // |testing::ThreadTest| + void TearDown() override; + + private: + fml::UniqueFD assets_dir_; +}; + +} // namespace testing +} // namespace blink + +#endif // FLUTTER_RUNTIME_RUNTIME_TEST_H_ diff --git a/engine/src/flutter/testing/thread_test.cc b/engine/src/flutter/testing/thread_test.cc index 513dbfd1a7e..978d9af532b 100644 --- a/engine/src/flutter/testing/thread_test.cc +++ b/engine/src/flutter/testing/thread_test.cc @@ -8,6 +8,7 @@ namespace testing { +// |testing::Test| void ThreadTest::SetUp() { thread_ = std::make_unique(); thread_task_runner_ = thread_->GetTaskRunner(); @@ -16,6 +17,7 @@ void ThreadTest::SetUp() { current_task_runner_ = fml::MessageLoop::GetCurrent().GetTaskRunner(); } +// |testing::Test| void ThreadTest::TearDown() { thread_task_runner_ = nullptr; thread_ = nullptr; diff --git a/engine/src/flutter/testing/thread_test.h b/engine/src/flutter/testing/thread_test.h index 8b4487c1b79..e4af5e1241b 100644 --- a/engine/src/flutter/testing/thread_test.h +++ b/engine/src/flutter/testing/thread_test.h @@ -22,8 +22,10 @@ class ThreadTest : public Test { fml::RefPtr GetThreadTaskRunner(); protected: + // |testing::Test| void SetUp() override; + // |testing::Test| void TearDown() override; private: