blob: e70b1914fc16f97e5cebeac51e62ff6106831577 [file]
#include "MCTPEndpoint.hpp"
#include "Utils.hpp"
#include <cstdint>
#include <stdexcept>
#include <vector>
#include <gtest/gtest.h>
TEST(I2CMCTPDDevice, matchEmptyConfig)
{
SensorData config{};
EXPECT_FALSE(I2CMCTPDDevice::match(config));
}
TEST(I2CMCTPDDevice, matchIrrelevantConfig)
{
SensorData config{{"xyz.openbmc_project.Configuration.NVME1000", {}}};
EXPECT_FALSE(I2CMCTPDDevice::match(config));
}
TEST(I2CMCTPDDevice, matchRelevantConfig)
{
SensorData config{{"xyz.openbmc_project.Configuration.MCTPI2CTarget", {}}};
EXPECT_TRUE(I2CMCTPDDevice::match(config));
}
TEST(I2CMCTPDDevice, fromBadIfaceNoType)
{
SensorBaseConfigMap iface{{}};
EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(I2CMCTPDDevice, fromBadIfaceWrongType)
{
SensorBaseConfigMap iface{{"Type", "NVME1000"}};
EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(I2CMCTPDDevice, fromBadIfaceNoAddress)
{
SensorBaseConfigMap iface{
{"Bus", "0"},
{"Name", "test"},
{"Type", "MCTPI2CTarget"},
};
EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(I2CMCTPDDevice, fromBadIfaceBadAddress)
{
SensorBaseConfigMap iface{
{"Address", "not a number"},
{"Bus", "0"},
{"Name", "test"},
{"Type", "MCTPI2CTarget"},
};
EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(I2CMCTPDDevice, fromBadIfaceNoBus)
{
SensorBaseConfigMap iface{
{"Address", "0x1d"},
{"Name", "test"},
{"Type", "MCTPI2CTarget"},
};
EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(I2CMCTPDDevice, fromBadIfaceBadBus)
{
SensorBaseConfigMap iface{
{"Address", "0x1d"},
{"Bus", "not a number"},
{"Name", "test"},
{"Type", "MCTPI2CTarget"},
};
EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(I2CMCTPDDevice, fromBadIfaceNoName)
{
SensorBaseConfigMap iface{
{"Address", "0x1d"},
{"Bus", "0"},
{"Type", "MCTPI2CTarget"},
};
EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, matchEmptyConfig)
{
SensorData config{};
EXPECT_FALSE(USBMCTPDDevice::match(config));
}
TEST(USBMCTPDDevice, matchIrrelevantConfig)
{
SensorData config{{"xyz.openbmc_project.Configuration.MCTPI2CTarget", {}}};
EXPECT_FALSE(USBMCTPDDevice::match(config));
}
TEST(USBMCTPDDevice, matchRelevantConfig)
{
SensorData config{{"xyz.openbmc_project.Configuration.MCTPUSBDevice", {}}};
EXPECT_TRUE(USBMCTPDDevice::match(config));
}
// A device is located by walking down from a root hub, so a configuration
// has to name every step of the way: which root hub, which ports to follow,
// and which interface of which configuration of the device found at the end.
// Each test below takes this away or spoils one of those.
static SensorBaseConfigMap usbDeviceConfig()
{
return {
{"Configuration", "1"}, {"Interface", "0"},
{"Name", "test"}, {"Port", std::vector<uint64_t>{1, 2, 1}},
{"RootHubPosition", "0"}, {"Type", "MCTPUSBDevice"},
};
}
TEST(USBMCTPDDevice, fromBadIfaceNoType)
{
SensorBaseConfigMap iface{{}};
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, fromBadIfaceWrongType)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface["Type"] = "MCTPI2CTarget";
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, fromBadIfaceNoName)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface.erase("Name");
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, fromBadIfaceNoRootHubPosition)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface.erase("RootHubPosition");
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, fromBadIfaceNoPort)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface.erase("Port");
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, fromBadIfaceNoConfiguration)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface.erase("Configuration");
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, fromBadIfaceNoInterface)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface.erase("Interface");
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, fromBadIfaceBadRootHubPosition)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface["RootHubPosition"] = "not a number";
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, fromBadIfaceTrailingRootHubPosition)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface["RootHubPosition"] = "1abc";
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
// Which positions exist depends on the SOC, so a position that names no host
// controller is only found once the SOC is, and leaves the configuration
// unused rather than raising.
TEST(USBMCTPDDevice, fromIfaceRootHubPositionWithNoController)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface["RootHubPosition"] = "2";
EXPECT_EQ(USBMCTPDDevice::from({}, iface), nullptr);
}
// An empty port list names the root hub itself rather than a device on it.
TEST(USBMCTPDDevice, fromBadIfaceEmptyPort)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface["Port"] = std::vector<uint64_t>{};
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, fromBadIfaceBadConfiguration)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface["Configuration"] = "not a number";
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
// from_chars stops at the first character it cannot use rather than failing,
// so a value has to be rejected on what is left over as well.
TEST(USBMCTPDDevice, fromBadIfaceTrailingConfiguration)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface["Configuration"] = "1abc";
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, fromBadIfaceBadInterface)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface["Interface"] = "not a number";
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}
TEST(USBMCTPDDevice, fromBadIfaceTrailingInterface)
{
SensorBaseConfigMap iface = usbDeviceConfig();
iface["Interface"] = "0abc";
EXPECT_THROW(USBMCTPDDevice::from({}, iface), std::invalid_argument);
}