blob: 7382f8acb0ec1bda1884aa96bc107461ab3a7a1e [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 "peridot/public/lib/modular_test_harness/cpp/test_harness_launcher.h"
#include "lib/async/cpp/task.h"
namespace modular {
namespace testing {
namespace {
constexpr char kTestHarnessUrl[] =
"fuchsia-pkg://fuchsia.com/modular_test_harness#meta/"
"modular_test_harness.cmx";
};
TestHarnessLauncher::TestHarnessLauncher() {
harness_launcher_thread_.reset(new std::thread(
[this](fidl::InterfaceRequest<fuchsia::modular::testing::TestHarness>
test_harness_req) {
LaunchTestHarness(std::move(test_harness_req));
},
test_harness_.NewRequest()));
}
TestHarnessLauncher::~TestHarnessLauncher() {
// Wait until the test harness thread's async::Loop is ready
{
std::unique_lock<std::mutex> lock(test_harness_loop_mutex_);
test_harness_loop_cv_.wait(
lock, [this] { return test_harness_loop_ != nullptr; });
}
// Tell the thread to kill the modular test harness -- the thread should exit
// once it gets an event that the modular test harness terminated.
async::PostTask(test_harness_loop_->dispatcher(),
[this] { test_harness_ctrl_->Kill(); });
// Wait for the thread to exit.
harness_launcher_thread_->join();
}
void TestHarnessLauncher::LaunchTestHarness(
fidl::InterfaceRequest<fuchsia::modular::testing::TestHarness>
test_harness_req) {
async::Loop loop(&kAsyncLoopConfigAttachToThread);
{
std::unique_lock<std::mutex> lock(test_harness_loop_mutex_);
test_harness_loop_ = &loop;
test_harness_loop_cv_.notify_one();
}
fuchsia::sys::LaunchInfo launch_info;
launch_info.url = kTestHarnessUrl;
test_harness_svc_ =
sys::ServiceDirectory::CreateWithRequest(&launch_info.directory_request);
auto svc = sys::ServiceDirectory::CreateFromNamespace();
svc->Connect<fuchsia::sys::Launcher>()->CreateComponent(
std::move(launch_info), test_harness_ctrl_.NewRequest());
test_harness_svc_->Connect(std::move(test_harness_req));
// Exit the loop (and therefore the thread), if the modular test harness
// component exits.
test_harness_ctrl_.events().OnTerminated =
[&](int64_t return_code, fuchsia::sys::TerminationReason reason) {
loop.Quit();
};
test_harness_ctrl_.set_error_handler([&](zx_status_t) { loop.Quit(); });
loop.Run();
}
} // namespace testing
} // namespace modular