blob: dda91c12dbb1de42bd621bd4d560bc7f200e4128 [file] [log] [blame] [edit]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "rmad/udev/udev_utils.h"
#include <memory>
#include <utility>
#include <brillo/udev/mock_udev.h>
#include <brillo/udev/mock_udev_device.h>
#include <brillo/udev/mock_udev_enumerate.h>
#include <brillo/udev/mock_udev_list_entry.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "rmad/udev/udev_device.h"
using testing::_;
using testing::ByMove;
using testing::Eq;
using testing::Invoke;
using testing::NiceMock;
using testing::Return;
using testing::StrictMock;
namespace rmad {
class UdevUtilsTest : public testing::Test {
public:
UdevUtilsTest() = default;
~UdevUtilsTest() override = default;
};
TEST_F(UdevUtilsTest, EnumerateBlockDevices) {
// Mock UdevListEntry.
auto entry2 = std::make_unique<StrictMock<brillo::MockUdevListEntry>>();
EXPECT_CALL(*entry2, GetNext()).WillOnce(Return(ByMove(nullptr)));
EXPECT_CALL(*entry2, GetName()).WillOnce(Return("/sys/test/path2"));
auto entry1 = std::make_unique<StrictMock<brillo::MockUdevListEntry>>();
EXPECT_CALL(*entry1, GetNext()).WillOnce(Return(ByMove(std::move(entry2))));
EXPECT_CALL(*entry1, GetName()).WillOnce(Return("/sys/test/path1"));
// Mock UdevEnumerate.
auto enumerate = std::make_unique<StrictMock<brillo::MockUdevEnumerate>>();
EXPECT_CALL(*enumerate, AddMatchSubsystem(_)).WillOnce(Return(true));
EXPECT_CALL(*enumerate, ScanDevices()).WillOnce(Return(true));
EXPECT_CALL(*enumerate, GetListEntry())
.WillOnce(Return(ByMove(std::move(entry1))));
// Mock Udev.
auto udev = std::make_unique<StrictMock<brillo::MockUdev>>();
EXPECT_CALL(*udev, CreateEnumerate())
.WillOnce(Return(ByMove(std::move(enumerate))));
EXPECT_CALL(*udev, CreateDeviceFromSysPath(_))
.Times(2)
.WillRepeatedly(Invoke([](const char* sys_path) {
// Mock UdevDevice.
auto device = std::make_unique<NiceMock<brillo::MockUdevDevice>>();
ON_CALL(*device, GetSysPath()).WillByDefault(Return(sys_path));
return device;
}));
auto udev_utils = std::make_unique<UdevUtilsImpl>(std::move(udev));
std::vector<std::unique_ptr<UdevDevice>> devices =
udev_utils->EnumerateBlockDevices();
EXPECT_EQ(2, devices.size());
EXPECT_EQ("/sys/test/path1", devices[0]->GetSysPath());
EXPECT_EQ("/sys/test/path2", devices[1]->GetSysPath());
}
TEST_F(UdevUtilsTest, GetBlockDeviceFromDevicePath) {
// Mock UdevListEntry.
auto entry2 = std::make_unique<StrictMock<brillo::MockUdevListEntry>>();
EXPECT_CALL(*entry2, GetNext()).WillOnce(Return(ByMove(nullptr)));
EXPECT_CALL(*entry2, GetName()).WillOnce(Return("/sys/test/path2"));
auto entry1 = std::make_unique<StrictMock<brillo::MockUdevListEntry>>();
EXPECT_CALL(*entry1, GetNext()).WillOnce(Return(ByMove(std::move(entry2))));
EXPECT_CALL(*entry1, GetName()).WillOnce(Return("/sys/test/path1"));
// Mock UdevEnumerate.
auto enumerate = std::make_unique<StrictMock<brillo::MockUdevEnumerate>>();
EXPECT_CALL(*enumerate, AddMatchSubsystem(_)).WillOnce(Return(true));
EXPECT_CALL(*enumerate, ScanDevices()).WillOnce(Return(true));
EXPECT_CALL(*enumerate, GetListEntry())
.WillOnce(Return(ByMove(std::move(entry1))));
// Mock Udev.
auto udev = std::make_unique<StrictMock<brillo::MockUdev>>();
EXPECT_CALL(*udev, CreateEnumerate())
.WillOnce(Return(ByMove(std::move(enumerate))));
EXPECT_CALL(*udev, CreateDeviceFromSysPath(_))
.Times(2)
.WillRepeatedly(Invoke([](const char* sys_path) {
// Mock UdevDevice. For mock convenience, make device node same as
// sysfs path.
auto device = std::make_unique<NiceMock<brillo::MockUdevDevice>>();
ON_CALL(*device, GetDeviceNode()).WillByDefault(Return(sys_path));
return device;
}));
auto udev_utils = std::make_unique<UdevUtilsImpl>(std::move(udev));
std::unique_ptr<UdevDevice> device;
EXPECT_TRUE(
udev_utils->GetBlockDeviceFromDevicePath("/sys/test/path2", &device));
EXPECT_EQ("/sys/test/path2", device->GetDeviceNode());
}
} // namespace rmad