blob: 4a61204f4723c325113d5a750123b77a23da0ba5 [file] [log] [blame]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "lvmd/lvmd.h"
#include <optional>
#include <tuple>
#include <brillo/blkdev_utils/lvm_device.h>
#include <brillo/blkdev_utils/mock_lvm.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <lvmd/proto_bindings/lvmd.pb.h>
using ::testing::Eq;
using ::testing::InSequence;
using ::testing::Ref;
using ::testing::Return;
namespace lvmd {
MATCHER_P2(DictValueMatch, key, value, "") {
return *arg.FindString(key) == value;
}
class LvmdTest : public ::testing::Test {
public:
LvmdTest() = default;
LvmdTest(const LvmdTest&) = delete;
LvmdTest& operator=(const LvmdTest&) = delete;
void SetUp() override {
auto lvm = std::make_unique<brillo::MockLogicalVolumeManager>();
lvm_ptr_ = lvm.get();
lvmd_ = std::make_unique<Lvmd>(std::move(lvm));
}
protected:
brillo::MockLogicalVolumeManager* lvm_ptr_;
std::unique_ptr<Lvmd> lvmd_;
};
TEST_F(LvmdTest, CreateLogicalVolumesEmpty) {
brillo::ErrorPtr err;
CreateLogicalVolumesRequest request;
CreateLogicalVolumesResponse response;
EXPECT_TRUE(lvmd_->CreateLogicalVolumes(&err, request, &response));
}
TEST_F(LvmdTest, CreateLogicalVolumesLvmCallCheck) {
brillo::ErrorPtr err;
CreateLogicalVolumesRequest request;
CreateLogicalVolumesResponse response;
std::ignore = request.add_logical_volume_infos();
auto opt_lv = std::make_optional<brillo::LogicalVolume>("", "", nullptr);
EXPECT_CALL(*lvm_ptr_, CreateLogicalVolume(_, _, _)).WillOnce(Return(opt_lv));
EXPECT_TRUE(lvmd_->CreateLogicalVolumes(&err, request, &response));
}
TEST_F(LvmdTest, CreateLogicalVolumesLvmFailureCheck) {
brillo::ErrorPtr err;
CreateLogicalVolumesRequest request;
CreateLogicalVolumesResponse response;
std::ignore = request.add_logical_volume_infos();
std::optional<brillo::LogicalVolume> opt_lv;
EXPECT_CALL(*lvm_ptr_, CreateLogicalVolume(_, _, _)).WillOnce(Return(opt_lv));
EXPECT_FALSE(lvmd_->CreateLogicalVolumes(&err, request, &response));
}
TEST_F(LvmdTest, CreateLogicalVolumesSuccessfulLvsPopulated) {
brillo::ErrorPtr err;
CreateLogicalVolumesRequest request;
CreateLogicalVolumesResponse response;
for (const auto& name : {"lv1", "lv2", "some-more-lv1", "some-more-lv2"}) {
auto* lv_info = request.add_logical_volume_infos();
lv_info->mutable_lv_config()->set_name(name);
}
{
InSequence seq;
{
std::optional<brillo::LogicalVolume> opt_lv;
EXPECT_CALL(*lvm_ptr_,
CreateLogicalVolume(_, _, DictValueMatch("name", "lv1")))
.WillOnce((Return(opt_lv)));
}
{
auto opt_lv =
std::make_optional<brillo::LogicalVolume>("lv2", "some-vg", nullptr);
EXPECT_CALL(*lvm_ptr_,
CreateLogicalVolume(_, _, DictValueMatch("name", "lv2")))
.WillOnce((Return(opt_lv)));
}
{
std::optional<brillo::LogicalVolume> opt_lv;
EXPECT_CALL(*lvm_ptr_, CreateLogicalVolume(_, _, _))
.WillRepeatedly((Return(opt_lv)));
}
EXPECT_FALSE(lvmd_->CreateLogicalVolumes(&err, request, &response));
}
ASSERT_TRUE(response.has_logical_volume_list());
EXPECT_EQ(response.logical_volume_list().logical_volume_size(), 1);
EXPECT_EQ(response.logical_volume_list().logical_volume().at(0).name(),
"lv2");
}
TEST_F(LvmdTest, RemoveLogicalVolumesEmpty) {
brillo::ErrorPtr err;
RemoveLogicalVolumesRequest request;
RemoveLogicalVolumesResponse response;
EXPECT_TRUE(lvmd_->RemoveLogicalVolumes(&err, request, &response));
}
TEST_F(LvmdTest, RemoveLogicalVolumesLvmCallCheck) {
brillo::ErrorPtr err;
RemoveLogicalVolumesRequest request;
RemoveLogicalVolumesResponse response;
std::ignore = request.mutable_logical_volume_list()->add_logical_volume();
EXPECT_CALL(*lvm_ptr_, RemoveLogicalVolume(_, _)).WillOnce((Return(true)));
EXPECT_TRUE(lvmd_->RemoveLogicalVolumes(&err, request, &response));
}
TEST_F(LvmdTest, RemoveLogicalVolumesLvmFailureCheck) {
brillo::ErrorPtr err;
RemoveLogicalVolumesRequest request;
RemoveLogicalVolumesResponse response;
std::ignore = request.mutable_logical_volume_list()->add_logical_volume();
EXPECT_CALL(*lvm_ptr_, RemoveLogicalVolume(_, _)).WillOnce((Return(false)));
EXPECT_FALSE(lvmd_->RemoveLogicalVolumes(&err, request, &response));
}
TEST_F(LvmdTest, RemoveLogicalVolumesFailedLvsPopulated) {
brillo::ErrorPtr err;
RemoveLogicalVolumesRequest request;
RemoveLogicalVolumesResponse response;
for (const auto& name : {"lv1", "lv2"}) {
auto* lv = request.mutable_logical_volume_list()->add_logical_volume();
lv->set_name(name);
}
{
InSequence seq;
EXPECT_CALL(*lvm_ptr_, RemoveLogicalVolume(_, "lv1"))
.WillOnce((Return(true)));
EXPECT_CALL(*lvm_ptr_, RemoveLogicalVolume(_, "lv2"))
.WillOnce(Return(false));
EXPECT_FALSE(lvmd_->RemoveLogicalVolumes(&err, request, &response));
}
ASSERT_TRUE(response.has_logical_volume_list());
EXPECT_EQ(response.logical_volume_list().logical_volume_size(), 1);
EXPECT_EQ(response.logical_volume_list().logical_volume().at(0).name(),
"lv2");
}
} // namespace lvmd