blob: 376ffa6ceb7d03052036ee4bf4c725399a3c71b2 [file] [log] [blame]
// Copyright 2020 The Chromium OS 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 "cryptohome/storage/encrypted_container/logical_volume_backing_device.h"
#include <memory>
#include <string>
#include <vector>
#include <gtest/gtest.h>
#include <base/files/file_util.h>
#include <brillo/blkdev_utils/mock_lvm.h>
#include <brillo/blkdev_utils/lvm_device.h>
#include "cryptohome/storage/encrypted_container/backing_device.h"
namespace cryptohome {
namespace {
constexpr char kPhysicalVolumeReport[] =
"{\"report\": [{ \"pv\": [ {\"pv_name\":\"/dev/mmcblk0p1\", "
"\"vg_name\":\"stateful\"}]}]}";
constexpr char kThinpoolReport[] =
"{\"report\": [{ \"lv\": [ {\"lv_name\":\"thinpool\", "
"\"vg_name\":\"stateful\"}]}]}";
constexpr char kLogicalVolumeReport[] =
"{\"report\": [{ \"lv\": [ {\"lv_name\":\"foo\", "
"\"vg_name\":\"stateful\"}]}]}";
} // namespace
class LogicalVolumeBackingDeviceTest : public ::testing::Test {
public:
LogicalVolumeBackingDeviceTest()
: config_({.type = BackingDeviceType::kLogicalVolumeBackingDevice,
.name = "foo",
.size = 1024,
.logical_volume = {.thinpool_name = "thinpool",
.physical_volume =
base::FilePath("/dev/mmcblk0p1")}}),
lvm_command_runner_(std::make_shared<brillo::MockLvmCommandRunner>()),
backing_device_(std::make_unique<LogicalVolumeBackingDevice>(
config_,
std::make_unique<brillo::LogicalVolumeManager>(
lvm_command_runner_))) {}
~LogicalVolumeBackingDeviceTest() override = default;
void ExpectVolumeGroup() {
std::vector<std::string> pvdisplay = {
"/sbin/pvdisplay", "-C", "--reportformat", "json",
config_.logical_volume.physical_volume.value()};
EXPECT_CALL(*lvm_command_runner_.get(), RunProcess(pvdisplay, _))
.WillRepeatedly(
DoAll(SetArgPointee<1>(std::string(kPhysicalVolumeReport)),
Return(true)));
}
void ExpectThinpool() {
std::vector<std::string> thinpool_display = {
"/sbin/lvdisplay", "-S", "pool_lv=\"\"", "-C",
"--reportformat", "json", "stateful/thinpool"};
EXPECT_CALL(*lvm_command_runner_.get(), RunProcess(thinpool_display, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(std::string(kThinpoolReport)),
Return(true)));
}
void ExpectLogicalVolume() {
std::vector<std::string> thinpool_display = {
"/sbin/lvdisplay", "-S", "pool_lv!=\"\"", "-C",
"--reportformat", "json", "stateful/" + config_.name};
EXPECT_CALL(*lvm_command_runner_.get(), RunProcess(thinpool_display, _))
.WillRepeatedly(DoAll(
SetArgPointee<1>(std::string(kLogicalVolumeReport)), Return(true)));
}
protected:
BackingDeviceConfig config_;
std::shared_ptr<brillo::MockLvmCommandRunner> lvm_command_runner_;
std::unique_ptr<BackingDevice> backing_device_;
};
TEST_F(LogicalVolumeBackingDeviceTest, LogicalVolumeDeviceSetup) {
ExpectVolumeGroup();
ExpectLogicalVolume();
std::vector<std::string> lv_enable = {"lvchange", "-ay", "stateful/foo"};
EXPECT_CALL(*lvm_command_runner_.get(), RunCommand(lv_enable))
.Times(1)
.WillOnce(Return(true));
EXPECT_TRUE(backing_device_->Setup());
}
TEST_F(LogicalVolumeBackingDeviceTest, LogicalVolumeDeviceCreate) {
ExpectVolumeGroup();
ExpectThinpool();
std::vector<std::string> lv_create = {
"lvcreate", "--thin", "-V", "1024M", "-n",
config_.name, "stateful/thinpool"};
EXPECT_CALL(*lvm_command_runner_.get(), RunCommand(lv_create))
.Times(1)
.WillOnce(Return(true));
EXPECT_TRUE(backing_device_->Create());
}
TEST_F(LogicalVolumeBackingDeviceTest, LogicalVolumeDeviceTeardown) {
ExpectVolumeGroup();
ExpectLogicalVolume();
std::vector<std::string> lv_disable = {"lvchange", "-an", "stateful/foo"};
EXPECT_CALL(*lvm_command_runner_.get(), RunCommand(lv_disable))
.Times(1)
.WillOnce(Return(true));
EXPECT_TRUE(backing_device_->Teardown());
}
TEST_F(LogicalVolumeBackingDeviceTest, LogicalVolumeDevicePurge) {
ExpectVolumeGroup();
ExpectLogicalVolume();
std::vector<std::string> lv_disable = {"lvremove", "stateful/foo"};
EXPECT_CALL(*lvm_command_runner_.get(), RunCommand(lv_disable))
.Times(1)
.WillOnce(Return(true));
EXPECT_TRUE(backing_device_->Purge());
}
} // namespace cryptohome