From 2061efe613cda68dd04d3e5600da50263ee83be3 Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Tue, 15 Jan 2019 14:56:55 -0800 Subject: [PATCH] Add runttime unittest that loads and runs an isolate from the kernel. --- runtime/dart_isolate_unittests.cc | 129 ++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/runtime/dart_isolate_unittests.cc b/runtime/dart_isolate_unittests.cc index a68318bf4b8c9..21452214c24b6 100644 --- a/runtime/dart_isolate_unittests.cc +++ b/runtime/dart_isolate_unittests.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "flutter/fml/mapping.h" +#include "flutter/fml/paths.h" #include "flutter/fml/thread.h" #include "flutter/runtime/dart_isolate.h" #include "flutter/runtime/dart_vm.h" @@ -81,4 +83,131 @@ TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) { ASSERT_EQ(destruction_callback_count, 1u); } +class AutoIsolateShutdown { + public: + AutoIsolateShutdown(std::shared_ptr isolate) + : isolate_(std::move(isolate)) {} + + ~AutoIsolateShutdown() { + if (isolate_) { + FML_LOG(INFO) << "Shutting down isolate."; + if (!isolate_->Shutdown()) { + FML_LOG(ERROR) << "Could not shutdown isolate."; + } + } + } + + bool IsValid() const { return isolate_ != nullptr; } + + blink::DartIsolate* get() { + FML_CHECK(isolate_); + return isolate_.get(); + } + + private: + std::shared_ptr isolate_; + + FML_DISALLOW_COPY_AND_ASSIGN(AutoIsolateShutdown); +}; + +std::unique_ptr RunDartCodeInIsolate( + fml::RefPtr task_runner, + std::string entrypoint) { + Settings settings = {}; + settings.task_observer_add = [](intptr_t, fml::closure) {}; + settings.task_observer_remove = [](intptr_t) {}; + + auto vm = DartVM::ForProcess(settings); + + if (!vm) { + return {}; + } + TaskRunners task_runners(CURRENT_TEST_NAME, // + task_runner, // + task_runner, // + task_runner, // + task_runner // + ); + + auto weak_isolate = DartIsolate::CreateRootIsolate( + vm.get(), // vm + vm->GetIsolateSnapshot(), // isolate snapshot + vm->GetSharedSnapshot(), // shared snapshot + std::move(task_runners), // task runners + nullptr, // window + {}, // snapshot delegate + {}, // io manager + "main.dart", // advisory uri + "main" // advisory entrypoint + ); + + auto root_isolate = + std::make_unique(weak_isolate.lock()); + + if (!root_isolate->IsValid()) { + FML_LOG(ERROR) << "Could not create isolate."; + return {}; + } + + if (root_isolate->get()->GetPhase() != DartIsolate::Phase::LibrariesSetup) { + FML_LOG(ERROR) << "Created isolate is in unexpected phase."; + return {}; + } + + 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 {}; + } + + 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 {}; + } + + auto kernel_mapping = std::make_unique(kernel_file); + + 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()->GetPhase() != DartIsolate::Phase::Ready) { + FML_LOG(ERROR) << "Isolate is in unexpected phase."; + return {}; + } + + if (!root_isolate->get()->Run(entrypoint)) { + FML_LOG(ERROR) << "Could not run the method \"" << entrypoint + << "\" in the isolate."; + return {}; + } + + return root_isolate; +} + +TEST_F(DartIsolateTest, IsolateCanLoadAndRunDartCode) { + auto isolate = RunDartCodeInIsolate(GetCurrentTaskRunner(), "main"); + ASSERT_TRUE(isolate); + ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running); +} + +TEST_F(DartIsolateTest, IsolateCannotLoadAndRunUnknownDartEntrypoint) { + auto isolate = + RunDartCodeInIsolate(GetCurrentTaskRunner(), "thisShouldNotExist"); + ASSERT_FALSE(isolate); +} + } // namespace blink