blob: ef35fc57e91a17602e334b6e3cf7f032f7b8a35c [file] [log] [blame]
Jagpal Singh Gillcf77ef52025-09-02 15:19:29 -07001#include "device/device_factory.hpp"
2#include "modbus_server_tester.hpp"
3#include "port/base_port.hpp"
Jagpal Singh Gill2fa10f42025-12-08 10:35:14 -08004#include "test_base.hpp"
Jagpal Singh Gillcf77ef52025-09-02 15:19:29 -07005
6#include <xyz/openbmc_project/Software/Version/client.hpp>
7
8#include <gtest/gtest.h>
9
10using namespace std::literals;
11using namespace testing;
12using SoftwareIntf =
13 sdbusplus::client::xyz::openbmc_project::software::Version<>;
14
Jagpal Singh Gillcf77ef52025-09-02 15:19:29 -070015namespace ModbusIntf = phosphor::modbus::rtu;
16namespace PortIntf = phosphor::modbus::rtu::port;
17namespace PortConfigIntf = PortIntf::config;
18namespace DeviceIntf = phosphor::modbus::rtu::device;
19namespace DeviceConfigIntf = DeviceIntf::config;
20
21class 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
30class 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 Gill2fa10f42025-12-08 10:35:14 -080045class FirmwareTest : public BaseTest
Jagpal Singh Gillcf77ef52025-09-02 15:19:29 -070046{
47 public:
Jagpal Singh Gill2fa10f42025-12-08 10:35:14 -080048 static constexpr auto clientDevicePath = "/tmp/ttyFirmwareTestPort0";
49 static constexpr auto serverDevicePath = "/tmp/ttyFirmwareTestPort1";
Jagpal Singh Gillcf77ef52025-09-02 15:19:29 -070050 static constexpr auto portName = "TestPort0";
Jagpal Singh Gillcf77ef52025-09-02 15:19:29 -070051 static constexpr auto serviceName =
52 "xyz.openbmc_project.TestModbusRTUFirmware";
53 static constexpr auto firmwareName = "TestVersion";
Jagpal Singh Gill2fa10f42025-12-08 10:35:14 -080054 PortConfigIntf::Config portConfig;
55 std::string deviceName;
56 std::string objectPath;
Jagpal Singh Gillcf77ef52025-09-02 15:19:29 -070057 std::unique_ptr<MockPort> mockPort;
58
Jagpal Singh Gill2fa10f42025-12-08 10:35:14 -080059 FirmwareTest() : BaseTest(clientDevicePath, serverDevicePath, serviceName)
Jagpal Singh Gillcf77ef52025-09-02 15:19:29 -070060 {
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 Gillcf77ef52025-09-02 15:19:29 -070071 mockPort =
72 std::make_unique<MockPort>(ctx, portConfig, clientDevicePath);
Jagpal Singh Gillcf77ef52025-09-02 15:19:29 -070073 }
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 Gillcf77ef52025-09-02 15:19:29 -0700117};
118
119TEST_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}