| Jagpal Singh Gill | cf77ef5 | 2025-09-02 15:19:29 -0700 | [diff] [blame] | 1 | #include "device/device_factory.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 | cf77ef5 | 2025-09-02 15:19:29 -0700 | [diff] [blame] | 5 | |
| 6 | #include <xyz/openbmc_project/Software/Version/client.hpp> |
| 7 | |
| 8 | #include <gtest/gtest.h> |
| 9 | |
| 10 | using namespace std::literals; |
| 11 | using namespace testing; |
| 12 | using SoftwareIntf = |
| 13 | sdbusplus::client::xyz::openbmc_project::software::Version<>; |
| 14 | |
| Jagpal Singh Gill | cf77ef5 | 2025-09-02 15:19:29 -0700 | [diff] [blame] | 15 | namespace ModbusIntf = phosphor::modbus::rtu; |
| 16 | namespace PortIntf = phosphor::modbus::rtu::port; |
| 17 | namespace PortConfigIntf = PortIntf::config; |
| 18 | namespace DeviceIntf = phosphor::modbus::rtu::device; |
| 19 | namespace DeviceConfigIntf = DeviceIntf::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 | |
| 30 | class TestFirmware : public DeviceIntf::DeviceFirmware |
| 31 | { |
| 32 | public: |
| 33 | TestFirmware(sdbusplus::async::context& ctx, |
| 34 | const DeviceConfigIntf::Config& config, |
| 35 | PortIntf::BasePort& serialPort) : |
| 36 | DeviceIntf::DeviceFirmware(ctx, config, serialPort) |
| 37 | {} |
| 38 | |
| 39 | auto getObjectPath() -> sdbusplus::message::object_path |
| 40 | { |
| 41 | return objectPath; |
| 42 | } |
| 43 | }; |
| 44 | |
| Jagpal Singh Gill | 2fa10f4 | 2025-12-08 10:35:14 -0800 | [diff] [blame] | 45 | class FirmwareTest : public BaseTest |
| Jagpal Singh Gill | cf77ef5 | 2025-09-02 15:19:29 -0700 | [diff] [blame] | 46 | { |
| 47 | public: |
| Jagpal Singh Gill | 2fa10f4 | 2025-12-08 10:35:14 -0800 | [diff] [blame] | 48 | static constexpr auto clientDevicePath = "/tmp/ttyFirmwareTestPort0"; |
| 49 | static constexpr auto serverDevicePath = "/tmp/ttyFirmwareTestPort1"; |
| Jagpal Singh Gill | cf77ef5 | 2025-09-02 15:19:29 -0700 | [diff] [blame] | 50 | static constexpr auto portName = "TestPort0"; |
| Jagpal Singh Gill | cf77ef5 | 2025-09-02 15:19:29 -0700 | [diff] [blame] | 51 | static constexpr auto serviceName = |
| 52 | "xyz.openbmc_project.TestModbusRTUFirmware"; |
| 53 | static constexpr auto firmwareName = "TestVersion"; |
| Jagpal Singh Gill | 2fa10f4 | 2025-12-08 10:35:14 -0800 | [diff] [blame] | 54 | PortConfigIntf::Config portConfig; |
| 55 | std::string deviceName; |
| 56 | std::string objectPath; |
| Jagpal Singh Gill | cf77ef5 | 2025-09-02 15:19:29 -0700 | [diff] [blame] | 57 | std::unique_ptr<MockPort> mockPort; |
| 58 | |
| Jagpal Singh Gill | 2fa10f4 | 2025-12-08 10:35:14 -0800 | [diff] [blame] | 59 | FirmwareTest() : BaseTest(clientDevicePath, serverDevicePath, serviceName) |
| Jagpal Singh Gill | cf77ef5 | 2025-09-02 15:19:29 -0700 | [diff] [blame] | 60 | { |
| 61 | portConfig.name = portName; |
| 62 | portConfig.portMode = PortConfigIntf::PortMode::rs485; |
| 63 | portConfig.baudRate = baudRate; |
| 64 | portConfig.rtsDelay = 1; |
| 65 | |
| 66 | deviceName = std::format("ResorviorPumpUnit_{}_{}", |
| 67 | TestIntf::testDeviceAddress, portName); |
| 68 | objectPath = |
| 69 | std::format("{}/{}", SoftwareIntf::namespace_path, deviceName); |
| 70 | |
| Jagpal Singh Gill | cf77ef5 | 2025-09-02 15:19:29 -0700 | [diff] [blame] | 71 | mockPort = |
| 72 | std::make_unique<MockPort>(ctx, portConfig, clientDevicePath); |
| Jagpal Singh Gill | cf77ef5 | 2025-09-02 15:19:29 -0700 | [diff] [blame] | 73 | } |
| 74 | |
| 75 | auto testFirmwareVersion( |
| 76 | std::string objectPath, |
| 77 | DeviceConfigIntf::FirmwareRegister firmwareRegister, |
| 78 | std::string expectedVersion) -> sdbusplus::async::task<void> |
| 79 | { |
| 80 | DeviceConfigIntf::DeviceFactoryConfig deviceFactoryConfig = { |
| 81 | { |
| 82 | .address = TestIntf::testDeviceAddress, |
| 83 | .parity = ModbusIntf::Parity::none, |
| 84 | .baudRate = baudRate, |
| 85 | .name = deviceName, |
| 86 | .portName = portConfig.name, |
| 87 | .inventoryPath = sdbusplus::message::object_path( |
| 88 | "xyz/openbmc_project/Inventory/ResorviorPumpUnit"), |
| 89 | .sensorRegisters = {}, |
| 90 | .statusRegisters = {}, |
| 91 | .firmwareRegisters = {firmwareRegister}, |
| 92 | }, |
| 93 | DeviceConfigIntf::DeviceType::reservoirPumpUnit, |
| 94 | DeviceConfigIntf::DeviceModel::RDF040DSS5193E0, |
| 95 | }; |
| 96 | |
| 97 | auto deviceFirmware = |
| 98 | std::make_unique<TestFirmware>(ctx, deviceFactoryConfig, *mockPort); |
| 99 | |
| 100 | co_await deviceFirmware->readVersionRegister(); |
| 101 | |
| 102 | EXPECT_TRUE(deviceFirmware->getObjectPath().str.starts_with(objectPath)) |
| 103 | << "Invalid ObjectPath"; |
| 104 | |
| 105 | auto softwarePath = deviceFirmware->getObjectPath().str; |
| 106 | |
| 107 | auto properties = co_await SoftwareIntf(ctx) |
| 108 | .service(serviceName) |
| 109 | .path(softwarePath) |
| 110 | .properties(); |
| 111 | |
| 112 | EXPECT_EQ(properties.version, expectedVersion) |
| 113 | << "Firmware version mismatch"; |
| 114 | |
| 115 | co_return; |
| 116 | } |
| Jagpal Singh Gill | cf77ef5 | 2025-09-02 15:19:29 -0700 | [diff] [blame] | 117 | }; |
| 118 | |
| 119 | TEST_F(FirmwareTest, TestFirmwareVersion) |
| 120 | { |
| 121 | const DeviceConfigIntf::FirmwareRegister firmwareRegister = { |
| 122 | .name = "", |
| 123 | .type = DeviceConfigIntf::FirmwareRegisterType::version, |
| 124 | .offset = TestIntf::testReadHoldingRegisterFirmwareVersionOffset, |
| 125 | .size = TestIntf::testReadHoldingRegisterFirmwareVersionCount}; |
| 126 | |
| 127 | ctx.spawn(testFirmwareVersion( |
| 128 | objectPath, firmwareRegister, |
| 129 | TestIntf::testReadHoldingRegisterFirmwareVersionStr)); |
| 130 | |
| 131 | ctx.spawn(sdbusplus::async::sleep_for(ctx, 1s) | |
| 132 | sdbusplus::async::execution::then([&]() { ctx.request_stop(); })); |
| 133 | |
| 134 | ctx.run(); |
| 135 | } |