| Jagpal Singh Gill | cad9ecf | 2025-10-22 19:53:16 -0700 | [diff] [blame] | 1 | #include "inventory/modbus_inventory.hpp" |
| 2 | #include "modbus_server_tester.hpp" |
| 3 | #include "port/base_port.hpp" |
| Jagpal Singh Gill | 2fa10f4 | 2025-12-08 10:35:14 -0800 | [diff] [blame] | 4 | #include "test_base.hpp" |
| Jagpal Singh Gill | cad9ecf | 2025-10-22 19:53:16 -0700 | [diff] [blame] | 5 | |
| 6 | #include <xyz/openbmc_project/Inventory/Source/Modbus/FRU/client.hpp> |
| 7 | |
| 8 | #include <gtest/gtest.h> |
| 9 | |
| 10 | using namespace std::literals; |
| 11 | using namespace testing; |
| 12 | using InventorySourceIntf = |
| 13 | sdbusplus::client::xyz::openbmc_project::inventory::source::modbus::FRU<>; |
| 14 | |
| Jagpal Singh Gill | cad9ecf | 2025-10-22 19:53:16 -0700 | [diff] [blame] | 15 | namespace ModbusIntf = phosphor::modbus::rtu; |
| 16 | namespace PortIntf = phosphor::modbus::rtu::port; |
| 17 | namespace PortConfigIntf = PortIntf::config; |
| 18 | namespace InventoryIntf = phosphor::modbus::rtu::inventory; |
| 19 | namespace InventoryConfigIntf = InventoryIntf::config; |
| 20 | |
| 21 | class MockPort : public PortIntf::BasePort |
| 22 | { |
| 23 | public: |
| 24 | MockPort(sdbusplus::async::context& ctx, |
| 25 | const PortConfigIntf::Config& config, |
| 26 | const std::string& devicePath) : BasePort(ctx, config, devicePath) |
| 27 | {} |
| 28 | }; |
| 29 | |
| Jagpal Singh Gill | 2fa10f4 | 2025-12-08 10:35:14 -0800 | [diff] [blame] | 30 | class InventoryTest : public BaseTest |
| Jagpal Singh Gill | cad9ecf | 2025-10-22 19:53:16 -0700 | [diff] [blame] | 31 | { |
| 32 | public: |
| Jagpal Singh Gill | cad9ecf | 2025-10-22 19:53:16 -0700 | [diff] [blame] | 33 | static constexpr const char* clientDevicePath = |
| 34 | "/tmp/ttyInventoryTestPort0"; |
| 35 | static constexpr const char* serverDevicePath = |
| 36 | "/tmp/ttyInventoryTestPort1"; |
| Jagpal Singh Gill | cad9ecf | 2025-10-22 19:53:16 -0700 | [diff] [blame] | 37 | static constexpr const auto deviceName = "Test1"; |
| 38 | static constexpr auto serviceName = "xyz.openbmc_project.TestModbusRTU"; |
| Jagpal Singh Gill | 2fa10f4 | 2025-12-08 10:35:14 -0800 | [diff] [blame] | 39 | PortConfigIntf::Config portConfig; |
| Jagpal Singh Gill | cad9ecf | 2025-10-22 19:53:16 -0700 | [diff] [blame] | 40 | |
| Jagpal Singh Gill | 2fa10f4 | 2025-12-08 10:35:14 -0800 | [diff] [blame] | 41 | InventoryTest() : BaseTest(clientDevicePath, serverDevicePath, serviceName) |
| Jagpal Singh Gill | cad9ecf | 2025-10-22 19:53:16 -0700 | [diff] [blame] | 42 | { |
| 43 | portConfig.name = "TestPort1"; |
| 44 | portConfig.portMode = PortConfigIntf::PortMode::rs485; |
| 45 | portConfig.baudRate = 115200; |
| 46 | portConfig.rtsDelay = 1; |
| Jagpal Singh Gill | cad9ecf | 2025-10-22 19:53:16 -0700 | [diff] [blame] | 47 | } |
| 48 | |
| 49 | auto testInventorySourceCreation(std::string objPath) |
| 50 | -> sdbusplus::async::task<void> |
| 51 | { |
| 52 | InventoryConfigIntf::Config::port_address_map_t addressMap; |
| 53 | addressMap[portConfig.name] = {{.start = TestIntf::testDeviceAddress, |
| 54 | .end = TestIntf::testDeviceAddress}}; |
| 55 | InventoryConfigIntf::Config deviceConfig = { |
| 56 | .name = deviceName, |
| 57 | .addressMap = addressMap, |
| 58 | .registers = {{"Model", |
| 59 | TestIntf::testReadHoldingRegisterModelOffset, |
| 60 | TestIntf::testReadHoldingRegisterModelCount}}, |
| 61 | .parity = ModbusIntf::Parity::none, |
| 62 | .baudRate = 115200}; |
| 63 | InventoryIntf::Device::serial_port_map_t ports; |
| 64 | ports[portConfig.name] = |
| 65 | std::make_unique<MockPort>(ctx, portConfig, clientDevicePath); |
| 66 | |
| 67 | auto inventoryDevice = |
| 68 | std::make_unique<InventoryIntf::Device>(ctx, deviceConfig, ports); |
| 69 | |
| 70 | co_await inventoryDevice->probePorts(); |
| 71 | |
| 72 | // Create InventorySource client interface to read back D-Bus properties |
| 73 | auto properties = co_await InventorySourceIntf(ctx) |
| 74 | .service(serviceName) |
| 75 | .path(objPath) |
| 76 | .properties(); |
| 77 | |
| 78 | constexpr auto defaultInventoryValue = "Unknown"; |
| 79 | |
| 80 | EXPECT_EQ(properties.name, |
| 81 | std::format("{} {} {}", deviceName, |
| 82 | TestIntf::testDeviceAddress, portConfig.name)) |
| 83 | << "Name mismatch"; |
| 84 | EXPECT_EQ(properties.address, TestIntf::testDeviceAddress) |
| 85 | << "Address mismatch"; |
| 86 | EXPECT_EQ(properties.link_tty, portConfig.name) << "Link TTY mismatch"; |
| 87 | EXPECT_EQ(properties.model, TestIntf::testReadHoldingRegisterModelStr) |
| 88 | << "Model mismatch"; |
| 89 | EXPECT_EQ(properties.serial_number, defaultInventoryValue) |
| 90 | << "Part Number mismatch"; |
| 91 | |
| 92 | co_return; |
| 93 | } |
| Jagpal Singh Gill | cad9ecf | 2025-10-22 19:53:16 -0700 | [diff] [blame] | 94 | }; |
| 95 | |
| 96 | TEST_F(InventoryTest, TestAddInventorySource) |
| 97 | { |
| 98 | auto objPath = |
| 99 | std::format("{}/{}_{}_{}", InventorySourceIntf::namespace_path, |
| 100 | deviceName, TestIntf::testDeviceAddress, portConfig.name); |
| 101 | |
| 102 | ctx.spawn(testInventorySourceCreation(objPath)); |
| 103 | |
| 104 | ctx.spawn(sdbusplus::async::sleep_for(ctx, 1s) | |
| 105 | sdbusplus::async::execution::then([&]() { ctx.request_stop(); })); |
| 106 | |
| 107 | ctx.run(); |
| 108 | } |