Commit 1849eddb authored by Daniel's avatar Daniel Committed by Commit Bot

borealis: Integrating launch watcher into context manager

Integrating the launch watcher into the context manager so that the
startup process can await on borealis starting.

Tests: Built and ran tests, tested on DUT.
Bug: b/171662734
Change-Id: I917440d9c190242bc7d4e28120e716702496f60c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2497344
Commit-Queue: Daniel Ng <danielng@google.com>
Reviewed-by: default avatarNic Hollingum <hollingum@google.com>
Cr-Commit-Position: refs/heads/master@{#820648}
parent 848cbda8
...@@ -22,6 +22,7 @@ class BorealisContextManager : public KeyedService { ...@@ -22,6 +22,7 @@ class BorealisContextManager : public KeyedService {
kMountFailed = 1, kMountFailed = 1,
kDiskImageFailed = 2, kDiskImageFailed = 2,
kStartVmFailed = 3, kStartVmFailed = 3,
kAwaitBorealisStartupFailed = 4,
}; };
// An attempt to launch borealis. If the launch succeeds, holds a reference to // An attempt to launch borealis. If the launch succeeds, holds a reference to
......
...@@ -23,6 +23,8 @@ std::ostream& operator<<(std::ostream& stream, ...@@ -23,6 +23,8 @@ std::ostream& operator<<(std::ostream& stream,
return stream << "Disk Image Failed"; return stream << "Disk Image Failed";
case borealis::BorealisContextManager::kStartVmFailed: case borealis::BorealisContextManager::kStartVmFailed:
return stream << "Start VM Failed"; return stream << "Start VM Failed";
case borealis::BorealisContextManager::kAwaitBorealisStartupFailed:
return stream << "Await Borealis Startup Failed";
} }
} }
...@@ -50,11 +52,15 @@ void BorealisContextManagerImpl::StartBorealis(ResultCallback callback) { ...@@ -50,11 +52,15 @@ void BorealisContextManagerImpl::StartBorealis(ResultCallback callback) {
base::queue<std::unique_ptr<BorealisTask>> base::queue<std::unique_ptr<BorealisTask>>
BorealisContextManagerImpl::GetTasks() { BorealisContextManagerImpl::GetTasks() {
// We use a hard-coded name. When multi-instance becomes a feature we'll
// need to determine the name instead.
context_.set_vm_name("borealis");
base::queue<std::unique_ptr<BorealisTask>> task_queue; base::queue<std::unique_ptr<BorealisTask>> task_queue;
task_queue.push(std::make_unique<MountDlc>()); task_queue.push(std::make_unique<MountDlc>());
task_queue.push(std::make_unique<CreateDiskImage>()); task_queue.push(std::make_unique<CreateDiskImage>());
task_queue.push(std::make_unique<StartBorealisVm>()); task_queue.push(std::make_unique<StartBorealisVm>());
task_queue.push(std::make_unique<AwaitBorealisStartup>()); task_queue.push(std::make_unique<AwaitBorealisStartup>(context_.profile(),
context_.vm_name()));
return task_queue; return task_queue;
} }
......
...@@ -45,7 +45,7 @@ class BorealisLaunchWatcher : public chromeos::CiceroneClient::Observer { ...@@ -45,7 +45,7 @@ class BorealisLaunchWatcher : public chromeos::CiceroneClient::Observer {
std::string owner_id_; std::string owner_id_;
std::string vm_name_; std::string vm_name_;
base::TimeDelta timeout_ = base::TimeDelta::FromMilliseconds(5000); base::TimeDelta timeout_ = base::TimeDelta::FromMilliseconds(30000);
base::Optional<vm_tools::cicerone::ContainerStartedSignal> base::Optional<vm_tools::cicerone::ContainerStartedSignal>
container_started_signal_; container_started_signal_;
base::queue<OnLaunchCallback> callback_queue_; base::queue<OnLaunchCallback> callback_queue_;
......
...@@ -48,9 +48,6 @@ CreateDiskImage::~CreateDiskImage() = default; ...@@ -48,9 +48,6 @@ CreateDiskImage::~CreateDiskImage() = default;
void CreateDiskImage::Run(BorealisContext* context, void CreateDiskImage::Run(BorealisContext* context,
CompletionStatusCallback callback) { CompletionStatusCallback callback) {
// We use a hard-coded name. When multi-instance becomes a feature we'll
// need to determine the name instead.
context->set_vm_name("borealis");
vm_tools::concierge::CreateDiskImageRequest request; vm_tools::concierge::CreateDiskImageRequest request;
request.set_disk_path(context->vm_name()); request.set_disk_path(context->vm_name());
request.set_cryptohome_id( request.set_cryptohome_id(
...@@ -147,12 +144,32 @@ void StartBorealisVm::OnStartBorealisVm( ...@@ -147,12 +144,32 @@ void StartBorealisVm::OnStartBorealisVm(
base::NumberToString(response->status()) + ")"); base::NumberToString(response->status()) + ")");
} }
AwaitBorealisStartup::AwaitBorealisStartup(Profile* profile,
std::string vm_name)
: watcher_(profile, vm_name) {}
AwaitBorealisStartup::~AwaitBorealisStartup() = default;
void AwaitBorealisStartup::Run(BorealisContext* context, void AwaitBorealisStartup::Run(BorealisContext* context,
CompletionStatusCallback callback) { CompletionStatusCallback callback) {
// TODO(b/170696557): Refactor to use the LaunchWatcher which is not finished watcher_.AwaitLaunch(
// yet. In our case the name is hard-coded, so we can use that. base::BindOnce(&AwaitBorealisStartup::OnAwaitBorealisStartup,
context->set_container_name("penguin"); weak_factory_.GetWeakPtr(), context, std::move(callback)));
std::move(callback).Run(BorealisContextManager::kSuccess, "");
} }
BorealisLaunchWatcher& AwaitBorealisStartup::GetWatcherForTesting() {
return watcher_;
}
void AwaitBorealisStartup::OnAwaitBorealisStartup(
BorealisContext* context,
CompletionStatusCallback callback,
base::Optional<std::string> container) {
if (!container) {
std::move(callback).Run(BorealisContextManager::kAwaitBorealisStartupFailed,
"Awaiting for Borealis launch failed: timed out");
return;
}
context->set_container_name(container.value());
std::move(callback).Run(BorealisContextManager::kSuccess, "");
}
} // namespace borealis } // namespace borealis
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chrome/browser/chromeos/borealis/borealis_context_manager.h" #include "chrome/browser/chromeos/borealis/borealis_context_manager.h"
#include "chrome/browser/chromeos/borealis/borealis_launch_watcher.h"
#include "chromeos/dbus/concierge_client.h" #include "chromeos/dbus/concierge_client.h"
#include "chromeos/dbus/dlcservice/dlcservice_client.h" #include "chromeos/dbus/dlcservice/dlcservice_client.h"
...@@ -82,8 +83,18 @@ class StartBorealisVm : public BorealisTask { ...@@ -82,8 +83,18 @@ class StartBorealisVm : public BorealisTask {
// Waits for the startup daemon to signal completion. // Waits for the startup daemon to signal completion.
class AwaitBorealisStartup : public BorealisTask { class AwaitBorealisStartup : public BorealisTask {
public: public:
AwaitBorealisStartup(Profile* profile, std::string vm_name);
~AwaitBorealisStartup() override;
void Run(BorealisContext* context, void Run(BorealisContext* context,
CompletionStatusCallback callback) override; CompletionStatusCallback callback) override;
BorealisLaunchWatcher& GetWatcherForTesting();
private:
void OnAwaitBorealisStartup(BorealisContext* context,
CompletionStatusCallback callback,
base::Optional<std::string> container);
BorealisLaunchWatcher watcher_;
base::WeakPtrFactory<AwaitBorealisStartup> weak_factory_{this};
}; };
} // namespace borealis } // namespace borealis
......
...@@ -8,9 +8,11 @@ ...@@ -8,9 +8,11 @@
#include "chrome/browser/chromeos/borealis/borealis_context.h" #include "chrome/browser/chromeos/borealis/borealis_context.h"
#include "chrome/browser/chromeos/borealis/borealis_context_manager.h" #include "chrome/browser/chromeos/borealis/borealis_context_manager.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/dlcservice/fake_dlcservice_client.h" #include "chromeos/dbus/dlcservice/fake_dlcservice_client.h"
#include "chromeos/dbus/fake_cicerone_client.h"
#include "chromeos/dbus/fake_concierge_client.h" #include "chromeos/dbus/fake_concierge_client.h"
#include "content/public/test/browser_task_environment.h" #include "content/public/test/browser_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
...@@ -49,8 +51,11 @@ class BorealisTasksTest : public testing::Test { ...@@ -49,8 +51,11 @@ class BorealisTasksTest : public testing::Test {
chromeos::DBusThreadManager::Initialize(); chromeos::DBusThreadManager::Initialize();
fake_concierge_client_ = static_cast<chromeos::FakeConciergeClient*>( fake_concierge_client_ = static_cast<chromeos::FakeConciergeClient*>(
chromeos::DBusThreadManager::Get()->GetConciergeClient()); chromeos::DBusThreadManager::Get()->GetConciergeClient());
fake_cicerone_client_ = static_cast<chromeos::FakeCiceroneClient*>(
chromeos::DBusThreadManager::Get()->GetCiceroneClient());
CreateProfile(); CreateProfile();
context_ = BorealisContext::CreateBorealisContextForTesting(profile_.get()); context_ = BorealisContext::CreateBorealisContextForTesting(profile_.get());
context_->set_vm_name("borealis");
chromeos::DlcserviceClient::InitializeFake(); chromeos::DlcserviceClient::InitializeFake();
fake_dlcservice_client_ = static_cast<chromeos::FakeDlcserviceClient*>( fake_dlcservice_client_ = static_cast<chromeos::FakeDlcserviceClient*>(
...@@ -69,6 +74,7 @@ class BorealisTasksTest : public testing::Test { ...@@ -69,6 +74,7 @@ class BorealisTasksTest : public testing::Test {
content::BrowserTaskEnvironment task_environment_; content::BrowserTaskEnvironment task_environment_;
// Owned by chromeos::DBusThreadManager // Owned by chromeos::DBusThreadManager
chromeos::FakeConciergeClient* fake_concierge_client_; chromeos::FakeConciergeClient* fake_concierge_client_;
chromeos::FakeCiceroneClient* fake_cicerone_client_;
chromeos::FakeDlcserviceClient* fake_dlcservice_client_; chromeos::FakeDlcserviceClient* fake_dlcservice_client_;
private: private:
...@@ -164,6 +170,55 @@ TEST_F(BorealisTasksTest, ...@@ -164,6 +170,55 @@ TEST_F(BorealisTasksTest,
EXPECT_TRUE(fake_concierge_client_->start_termina_vm_called()); EXPECT_TRUE(fake_concierge_client_->start_termina_vm_called());
} }
TEST_F(BorealisTasksTest,
AwaitBorealisStartupSucceedsAndCallbackRanWithResults) {
vm_tools::cicerone::ContainerStartedSignal signal;
signal.set_owner_id(
chromeos::ProfileHelper::GetUserIdHashFromProfile(context_->profile()));
signal.set_vm_name(context_->vm_name());
signal.set_container_name("penguin");
testing::StrictMock<CallbackForTesting> callback;
EXPECT_CALL(callback, Callback(BorealisContextManager::kSuccess, _));
AwaitBorealisStartup task(context_->profile(), context_->vm_name());
task.Run(context_.get(), callback.GetCallback());
fake_cicerone_client_->NotifyContainerStarted(std::move(signal));
task_environment_.RunUntilIdle();
}
TEST_F(BorealisTasksTest,
AwaitBorealisStartupContainerAlreadyStartedAndCallbackRanWithResults) {
vm_tools::cicerone::ContainerStartedSignal signal;
signal.set_owner_id(
chromeos::ProfileHelper::GetUserIdHashFromProfile(context_->profile()));
signal.set_vm_name(context_->vm_name());
signal.set_container_name("penguin");
testing::StrictMock<CallbackForTesting> callback;
EXPECT_CALL(callback, Callback(BorealisContextManager::kSuccess, _));
AwaitBorealisStartup task(context_->profile(), context_->vm_name());
fake_cicerone_client_->NotifyContainerStarted(std::move(signal));
task.Run(context_.get(), callback.GetCallback());
task_environment_.RunUntilIdle();
}
TEST_F(BorealisTasksTest,
AwaitBorealisStartupTimesOutAndCallbackRanWithResults) {
testing::StrictMock<CallbackForTesting> callback;
EXPECT_CALL(
callback,
Callback(BorealisContextManager::kAwaitBorealisStartupFailed, StrNe("")));
AwaitBorealisStartup task(context_->profile(), context_->vm_name());
task.GetWatcherForTesting().SetTimeoutForTesting(
base::TimeDelta::FromMilliseconds(0));
task.Run(context_.get(), callback.GetCallback());
task_environment_.RunUntilIdle();
}
class BorealisTasksTestDlc : public BorealisTasksTest, class BorealisTasksTestDlc : public BorealisTasksTest,
public testing::WithParamInterface<std::string> {}; public testing::WithParamInterface<std::string> {};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment