blob: 238f8d9ac78078f0a56bca28ce58562ea25d4cc8 [file] [log] [blame]
// Copyright 2018 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 "garnet/bin/guest/integration_tests/enclosed_guest.h"
static constexpr char kGuestMgrUrl[] = "guestmgr";
static constexpr char kRealm[] = "realmguestintegrationtest";
static constexpr zx::duration kLoopTimeout = zx::sec(5);
static constexpr zx::duration kLoopConditionStep = zx::msec(10);
namespace {
bool RunLoopUntil(async::Loop* loop, fit::function<bool()> condition) {
const zx::time deadline = zx::deadline_after(kLoopTimeout);
while (zx::clock::get_monotonic() < deadline) {
if (condition()) {
return true;
}
loop->Run(zx::deadline_after(kLoopConditionStep));
loop->ResetQuit();
}
return condition();
}
} // namespace
zx_status_t EnclosedGuest::Start(fuchsia::guest::LaunchInfo guest_launch_info) {
real_services_->ConnectToService(real_env_.NewRequest());
auto services = component::testing::EnvironmentServices::Create(
real_env_, loop_.dispatcher());
fuchsia::sys::LaunchInfo launch_info;
launch_info.url = kGuestMgrUrl;
zx_status_t status = services->AddServiceWithLaunchInfo(
std::move(launch_info), fuchsia::guest::EnvironmentManager::Name_);
if (status != ZX_OK) {
return status;
}
enclosing_environment_ = component::testing::EnclosingEnvironment::Create(
kRealm, real_env_, std::move(services));
bool environment_running = RunLoopUntil(
&loop_, [this] { return enclosing_environment_->is_running(); });
if (!environment_running) {
return ZX_ERR_BAD_STATE;
}
enclosing_environment_->ConnectToService(environment_manager_.NewRequest());
environment_manager_->Create(guest_launch_info.url,
environment_controller_.NewRequest());
environment_controller_->LaunchInstance(std::move(guest_launch_info),
instance_controller_.NewRequest(),
[this](uint32_t cid) {
guest_cid_ = cid;
loop_.Quit();
});
loop_.Run();
zx::socket socket;
instance_controller_->GetSerial(
[&socket](zx::socket s) { socket = std::move(s); });
bool socket_valid = RunLoopUntil(&loop_, [&] { return socket.is_valid(); });
if (!socket_valid) {
return ZX_ERR_BAD_STATE;
}
return serial_.Start(std::move(socket));
}