blob: ce06f1e4603f27df3750658d8e3f96765be43ce0 [file] [log] [blame]
// Copyright 2022 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 "src/virtualization/bin/guest_manager/guest_manager.h"
#include <lib/sys/cpp/testing/component_context_provider.h>
#include <test/placeholders/cpp/fidl.h>
#include "fuchsia/virtualization/cpp/fidl.h"
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
namespace {
class GuestManagerTest : public gtest::TestLoopFixture {
public:
sys::testing::ComponentContextProvider provider_;
};
TEST_F(GuestManagerTest, LaunchFailInvalidPath) {
GuestManager manager(provider_.context(), "/pkg/", "invalid_path.cfg");
bool launch_callback_called = false;
manager.LaunchGuest({}, {}, [&launch_callback_called](auto res) {
ASSERT_TRUE(res.is_err());
ASSERT_EQ(ZX_ERR_INVALID_ARGS, res.err());
launch_callback_called = true;
});
ASSERT_TRUE(launch_callback_called);
}
TEST_F(GuestManagerTest, LaunchFailInvalidConfig) {
GuestManager manager(provider_.context(), "/pkg/", "data/configs/bad_schema_invalid_field.cfg");
bool launch_callback_called = false;
manager.LaunchGuest({}, {}, [&launch_callback_called](auto res) {
ASSERT_TRUE(res.is_err());
ASSERT_EQ(ZX_ERR_INVALID_ARGS, res.err());
launch_callback_called = true;
});
ASSERT_TRUE(launch_callback_called);
}
TEST_F(GuestManagerTest, LaunchAndApplyUserGuestConfig) {
GuestManager manager(provider_.context(), "/pkg/", "data/configs/valid_guest.cfg");
fuchsia::virtualization::GuestConfig user_guest_config;
user_guest_config.mutable_cmdline_add()->emplace_back("extra_cmd_line_arg=0");
user_guest_config.mutable_block_devices()->push_back({
"data/configs/valid_guest.cfg",
fuchsia::virtualization::BlockMode::READ_ONLY,
fuchsia::virtualization::BlockFormat::FILE,
{},
});
fuchsia::virtualization::GuestPtr guest;
bool launch_callback_called = false;
manager.LaunchGuest(std::move(user_guest_config), guest.NewRequest(),
[&launch_callback_called](auto res) {
ASSERT_FALSE(res.is_err());
launch_callback_called = true;
});
ASSERT_TRUE(launch_callback_called);
bool get_callback_called = false;
manager.Get([&get_callback_called](fuchsia::virtualization::GuestConfig config) {
const fuchsia::virtualization::BlockSpec& spec0 = config.block_devices()[0];
ASSERT_EQ("data", spec0.id);
ASSERT_EQ(fuchsia::virtualization::BlockFormat::FILE, spec0.format);
const fuchsia::virtualization::BlockSpec& spec1 = config.block_devices()[1];
ASSERT_EQ("data/configs/valid_guest.cfg", spec1.id);
ASSERT_EQ(fuchsia::virtualization::BlockFormat::FILE, spec1.format);
ASSERT_EQ(2u, config.block_devices().size());
ASSERT_EQ("test cmdline extra_cmd_line_arg=0", config.cmdline());
ASSERT_EQ(fuchsia::virtualization::KernelType::ZIRCON, config.kernel_type());
ASSERT_TRUE(config.kernel());
ASSERT_TRUE(config.ramdisk());
ASSERT_EQ(4u, config.cpus());
get_callback_called = true;
});
ASSERT_TRUE(get_callback_called);
}
TEST_F(GuestManagerTest, DoubleLaunchFail) {
bool launch_callback_called = false;
GuestManager manager(provider_.context(), "/pkg/", "data/configs/valid_guest.cfg");
fuchsia::virtualization::GuestConfig user_guest_config;
fuchsia::virtualization::GuestPtr guest;
manager.LaunchGuest(std::move(user_guest_config), guest.NewRequest(),
[&launch_callback_called](auto res) {
ASSERT_FALSE(res.is_err());
launch_callback_called = true;
});
ASSERT_TRUE(launch_callback_called);
launch_callback_called = false;
manager.LaunchGuest(std::move(user_guest_config), guest.NewRequest(),
[&launch_callback_called](auto res) {
ASSERT_TRUE(res.is_err());
ASSERT_EQ(ZX_ERR_ALREADY_EXISTS, res.err());
launch_callback_called = true;
});
ASSERT_TRUE(launch_callback_called);
}
TEST_F(GuestManagerTest, LaunchAndGetInfo) {
bool get_callback_called = false;
GuestManager manager(provider_.context(), "/pkg/", "data/configs/valid_guest.cfg");
manager.GetGuestInfo([&get_callback_called](auto info) {
ASSERT_EQ(info.guest_status, fuchsia::virtualization::GuestStatus::NOT_STARTED);
get_callback_called = true;
});
ASSERT_TRUE(get_callback_called);
bool launch_callback_called = false;
fuchsia::virtualization::GuestConfig user_guest_config;
fuchsia::virtualization::GuestPtr guest;
manager.LaunchGuest(std::move(user_guest_config), guest.NewRequest(),
[&launch_callback_called](auto res) {
ASSERT_FALSE(res.is_err());
launch_callback_called = true;
});
ASSERT_TRUE(launch_callback_called);
get_callback_called = false;
manager.GetGuestInfo([&get_callback_called](auto info) {
ASSERT_EQ(info.guest_status, fuchsia::virtualization::GuestStatus::STARTED);
get_callback_called = true;
});
ASSERT_TRUE(get_callback_called);
}
TEST_F(GuestManagerTest, ConnectToGuest) {
bool connect_callback_called = false;
GuestManager manager(provider_.context(), "/pkg/", "data/configs/valid_guest.cfg");
fuchsia::virtualization::GuestPtr guest;
manager.ConnectToGuest(guest.NewRequest(), [&connect_callback_called](auto res) {
ASSERT_TRUE(res.is_err());
ASSERT_EQ(ZX_ERR_UNAVAILABLE, res.err());
connect_callback_called = true;
});
ASSERT_TRUE(connect_callback_called);
guest.Unbind();
bool launch_callback_called = false;
fuchsia::virtualization::GuestConfig user_guest_config;
manager.LaunchGuest(std::move(user_guest_config), guest.NewRequest(),
[&launch_callback_called](auto res) {
ASSERT_FALSE(res.is_err());
launch_callback_called = true;
});
ASSERT_TRUE(launch_callback_called);
guest.Unbind();
connect_callback_called = false;
manager.ConnectToGuest(guest.NewRequest(), [&connect_callback_called](auto res) {
ASSERT_FALSE(res.is_err());
connect_callback_called = true;
});
ASSERT_TRUE(connect_callback_called);
}
} // namespace