#include "device/udev_linux/udev.h"
#include <vector>
#include "base/files/file_path.h"
#include "device/udev_linux/fake_udev_loader.h"
#include "device/udev_linux/udev_loader.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace device {
TEST(UdevTest, DecodeString) {
ASSERT_EQ("", UdevDecodeString(""));
ASSERT_EQ("\\", UdevDecodeString("\\x5c"));
ASSERT_EQ("\\x5", UdevDecodeString("\\x5"));
ASSERT_EQ("049f", UdevDecodeString("049f"));
ASSERT_EQ(
"HD Pro Webcam C920", UdevDecodeString("HD\\x20Pro\\x20Webcam\\x20C920"));
ASSERT_EQ("E-MU Systems,Inc.", UdevDecodeString("E-MU\\x20Systems\\x2cInc."));
}
TEST(UdevTest, Loader) {
ASSERT_NE(nullptr, UdevLoader::Get());
}
TEST(UdevTest, GetPropertyWithNone) {
testing::FakeUdevLoader fake_udev;
udev_device* device =
fake_udev.AddFakeDevice("Foo", "/device/foo",
"", std::nullopt,
std::nullopt, {},
{});
const std::string attr_value = UdevDeviceGetPropertyValue(device, "prop");
EXPECT_TRUE(attr_value.empty());
}
TEST(UdevTest, GetSysPropSimple) {
testing::FakeUdevLoader fake_udev;
std::map<std::string, std::string> props;
props.emplace("prop", "prop value");
udev_device* device = fake_udev.AddFakeDevice(
"Foo", "/device/foo",
"", std::nullopt, std::nullopt,
{}, std::move(props));
std::string attr_value = UdevDeviceGetPropertyValue(device, "prop");
EXPECT_EQ("prop value", attr_value);
attr_value = UdevDeviceGetPropertyValue(device, "unknown prop");
EXPECT_TRUE(attr_value.empty());
}
TEST(UdevTest, GetFullSysPropertiesList) {
testing::FakeUdevLoader fake_udev;
std::map<std::string, std::string> props = {
{"TAGS", ":powerd:"},
{"DEVNAME", "/dev/dri/card0"},
{"DEVTYPE", "drm_minor"},
{"HOTPLUG", "1"},
{"USEC_INITIALIZED", "1234567"},
{"MINOR", "0"},
{"ID_PATH_TAG", "pci-0000_00_02_0"},
{"PROPERTY", "456"},
{"DEVPATH", "/devices/pci0000:00/0000:00:02.0/drm/card0"},
{"ID_PATH", "pci-0000:00:02.0"},
{"SUBSYSTEM", "drm"},
{"CONNECTOR", "123"},
{"MAJOR", "226"},
{"SEQNUM", "1234"},
{"ACTION", "change"}};
udev_device* device = fake_udev.AddFakeDevice(
"/dev/dri/card0",
"/devices/pci0000:00/0000:00:02.0/drm/card0",
"drm", std::nullopt, std::nullopt,
{}, std::move(props));
udev_list_entry* prop_list = udev_device_get_properties_list_entry(device);
udev_list_entry* entry;
std::vector<std::string> output_prop_list;
udev_list_entry_foreach(entry, prop_list) {
output_prop_list.emplace_back(udev_list_entry_get_name(entry));
}
EXPECT_THAT(
output_prop_list,
testing::UnorderedElementsAre(
"ACTION", "CONNECTOR", "DEVNAME", "DEVPATH", "DEVTYPE", "HOTPLUG",
"ID_PATH", "ID_PATH_TAG", "MAJOR", "MINOR", "PROPERTY", "SEQNUM",
"SUBSYSTEM", "TAGS", "USEC_INITIALIZED"));
}
TEST(UdevTest, GetSysAttrNoAttrs) {
testing::FakeUdevLoader fake_udev;
udev_device* device = fake_udev.AddFakeDevice(
"Foo", "/device/foo",
"", std::nullopt, std::nullopt,
{}, {});
const std::string attr_value = UdevDeviceGetSysattrValue(device, "attr");
EXPECT_TRUE(attr_value.empty());
}
TEST(UdevTest, GetSysAttrSimple) {
testing::FakeUdevLoader fake_udev;
std::map<std::string, std::string> attrs;
attrs.emplace("attr", "attr value");
udev_device* device = fake_udev.AddFakeDevice(
"Foo", "/device/foo",
"", std::nullopt, std::nullopt,
std::move(attrs), {});
std::string attr_value = UdevDeviceGetSysattrValue(device, "attr");
EXPECT_EQ("attr value", attr_value);
attr_value = UdevDeviceGetSysattrValue(device, "unknown attr");
EXPECT_TRUE(attr_value.empty());
}
TEST(UdevTest, GetParent) {
testing::FakeUdevLoader fake_udev;
std::map<std::string, std::string> attrs;
udev_device* grandparent = fake_udev.AddFakeDevice(
"Foo", "/device/foo",
"", std::nullopt, std::nullopt,
{}, {});
udev_device* parent = fake_udev.AddFakeDevice(
"Foo", "/device/foo/bar",
"", std::nullopt, std::nullopt,
{}, {});
udev_device* device = fake_udev.AddFakeDevice(
"Foo", "/device/foo/bar/baz",
"", std::nullopt, std::nullopt,
{}, {});
EXPECT_EQ(parent, udev_device_get_parent(device));
EXPECT_EQ(grandparent, udev_device_get_parent(parent));
EXPECT_EQ(nullptr, udev_device_get_parent(grandparent));
}
TEST(UdevTest, GetSysAttrRecursiveOneLevel) {
testing::FakeUdevLoader fake_udev;
std::map<std::string, std::string> attrs;
attrs.emplace("attr", "attr value");
fake_udev.AddFakeDevice("Foo", "/device/foo",
"", std::nullopt,
std::nullopt, std::move(attrs),
{});
udev_device* device = fake_udev.AddFakeDevice(
"Foo", "/device/foo/bar",
"", std::nullopt, std::nullopt,
{}, {});
std::string attr_value = UdevDeviceGetSysattrValue(device, "attr");
EXPECT_TRUE(attr_value.empty());
attr_value = UdevDeviceRecursiveGetSysattrValue(device, "attr");
EXPECT_EQ("attr value", attr_value);
}
}