blob: b2c0b8d8672254686aaccb1b70f77487b2807d8f [file] [log] [blame] [edit]
#include "inventory/modbus_inventory.hpp"
#include "modbus_server_tester.hpp"
#include "port/base_port.hpp"
#include "test_base.hpp"
#include <xyz/openbmc_project/Inventory/Source/Modbus/FRU/client.hpp>
#include <gtest/gtest.h>
using namespace std::literals;
using namespace testing;
using InventorySourceIntf =
sdbusplus::client::xyz::openbmc_project::inventory::source::modbus::FRU<>;
namespace ModbusIntf = phosphor::modbus::rtu;
namespace PortIntf = phosphor::modbus::rtu::port;
namespace PortConfigIntf = PortIntf::config;
namespace InventoryIntf = phosphor::modbus::rtu::inventory;
namespace InventoryConfigIntf = InventoryIntf::config;
class MockPort : public PortIntf::BasePort
{
public:
MockPort(sdbusplus::async::context& ctx,
const PortConfigIntf::Config& config,
const std::string& devicePath) : BasePort(ctx, config, devicePath)
{}
};
class InventoryTest : public BaseTest
{
public:
static constexpr const char* clientDevicePath =
"/tmp/ttyInventoryTestPort0";
static constexpr const char* serverDevicePath =
"/tmp/ttyInventoryTestPort1";
static constexpr const auto deviceName = "Test1";
static constexpr auto serviceName = "xyz.openbmc_project.TestModbusRTU";
PortConfigIntf::Config portConfig;
InventoryTest() : BaseTest(clientDevicePath, serverDevicePath, serviceName)
{
portConfig.name = "TestPort1";
portConfig.portMode = PortConfigIntf::PortMode::rs485;
portConfig.baudRate = 115200;
portConfig.rtsDelay = 1;
}
auto testInventorySourceCreation(std::string objPath)
-> sdbusplus::async::task<void>
{
InventoryConfigIntf::Config::port_address_map_t addressMap;
addressMap[portConfig.name] = {{.start = TestIntf::testDeviceAddress,
.end = TestIntf::testDeviceAddress}};
InventoryConfigIntf::Config deviceConfig = {
.name = deviceName,
.addressMap = addressMap,
.registers = {{"Model",
TestIntf::testReadHoldingRegisterModelOffset,
TestIntf::testReadHoldingRegisterModelCount}},
.parity = ModbusIntf::Parity::none,
.baudRate = 115200};
InventoryIntf::Device::serial_port_map_t ports;
ports[portConfig.name] =
std::make_unique<MockPort>(ctx, portConfig, clientDevicePath);
auto inventoryDevice =
std::make_unique<InventoryIntf::Device>(ctx, deviceConfig, ports);
co_await inventoryDevice->probePorts();
// Create InventorySource client interface to read back D-Bus properties
auto properties = co_await InventorySourceIntf(ctx)
.service(serviceName)
.path(objPath)
.properties();
constexpr auto defaultInventoryValue = "Unknown";
EXPECT_EQ(properties.name,
std::format("{} {} {}", deviceName,
TestIntf::testDeviceAddress, portConfig.name))
<< "Name mismatch";
EXPECT_EQ(properties.address, TestIntf::testDeviceAddress)
<< "Address mismatch";
EXPECT_EQ(properties.link_tty, portConfig.name) << "Link TTY mismatch";
EXPECT_EQ(properties.model, TestIntf::testReadHoldingRegisterModelStr)
<< "Model mismatch";
EXPECT_EQ(properties.serial_number, defaultInventoryValue)
<< "Part Number mismatch";
co_return;
}
};
TEST_F(InventoryTest, TestAddInventorySource)
{
auto objPath =
std::format("{}/{}_{}_{}", InventorySourceIntf::namespace_path,
deviceName, TestIntf::testDeviceAddress, portConfig.name);
ctx.spawn(testInventorySourceCreation(objPath));
ctx.spawn(sdbusplus::async::sleep_for(ctx, 1s) |
sdbusplus::async::execution::then([&]() { ctx.request_stop(); }));
ctx.run();
}