1 #include "common/instance_id.hpp"
2 #include "mock_terminus_manager.hpp"
3 #include "platform-mc/platform_manager.hpp"
4 #include "test/test_instance_id.hpp"
5 
6 #include <sdeventplus/event.hpp>
7 
8 #include <bitset>
9 
10 #include <gtest/gtest.h>
11 
12 class PlatformManagerTest : public testing::Test
13 {
14   protected:
15     PlatformManagerTest() :
16         bus(pldm::utils::DBusHandler::getBus()),
17         event(sdeventplus::Event::get_default()), instanceIdDb(),
18         reqHandler(pldmTransport, event, instanceIdDb, false,
19                    std::chrono::seconds(1), 2, std::chrono::milliseconds(100)),
20         mockTerminusManager(event, reqHandler, instanceIdDb, termini, nullptr),
21         platformManager(mockTerminusManager, termini)
22     {}
23 
24     PldmTransport* pldmTransport = nullptr;
25     sdbusplus::bus_t& bus;
26     sdeventplus::Event event;
27     TestInstanceIdDb instanceIdDb;
28     pldm::requester::Handler<pldm::requester::Request> reqHandler;
29     pldm::platform_mc::MockTerminusManager mockTerminusManager;
30     pldm::platform_mc::PlatformManager platformManager;
31     std::map<pldm_tid_t, std::shared_ptr<pldm::platform_mc::Terminus>> termini;
32 };
33 
34 TEST_F(PlatformManagerTest, initTerminusTest)
35 {
36     // Add terminus
37     auto mappedTid = mockTerminusManager.mapTid(pldm::MctpInfo(10, "", "", 1));
38     auto tid = mappedTid.value();
39     termini[tid] = std::make_shared<pldm::platform_mc::Terminus>(
40         tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM);
41     auto terminus = termini[tid];
42 
43     /* Set supported command by terminus */
44     auto size = PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8);
45     std::vector<uint8_t> pldmCmds(size);
46     uint8_t type = PLDM_PLATFORM;
47     uint8_t cmd = PLDM_GET_PDR;
48     auto idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
49     pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
50     cmd = PLDM_GET_PDR_REPOSITORY_INFO;
51     idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
52     pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
53     termini[tid]->setSupportedCommands(pldmCmds);
54 
55     // queue getPDRRepositoryInfo response
56     const size_t getPDRRepositoryInfoLen =
57         PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES;
58     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen>
59         getPDRRepositoryInfoResp{
60             0x0, 0x02, 0x50, PLDM_SUCCESS,
61             0x0,                                     // repositoryState
62             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, 0x0,
63             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, // updateTime
64             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, 0x0,
65             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, // OEMUpdateTime
66             1,   0x0,  0x0,  0x0,                    // recordCount
67             0x0, 0x1,  0x0,  0x0,                    // repositorySize
68             59,  0x0,  0x0,  0x0,                    // largestRecordSize
69             0x0 // dataTransferHandleTimeout
70         };
71     auto rc = mockTerminusManager.enqueueResponse(
72         (pldm_msg*)getPDRRepositoryInfoResp.data(),
73         sizeof(getPDRRepositoryInfoResp));
74     EXPECT_EQ(rc, PLDM_SUCCESS);
75 
76     // queue getPDR responses
77     const size_t getPdrRespLen = 81;
78     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{
79         0x0, 0x02, 0x51, PLDM_SUCCESS, 0x0, 0x0, 0x0, 0x0, // nextRecordHandle
80         0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle
81         0x5,                // transferFlag
82         69, 0x0,            // responseCount
83         // numeric Sensor PDR
84         0x1, 0x0, 0x0,
85         0x0,                     // record handle
86         0x1,                     // PDRHeaderVersion
87         PLDM_NUMERIC_SENSOR_PDR, // PDRType
88         0x0,
89         0x0,                     // recordChangeNumber
90         PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
91             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH +
92             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
93         0,                             // dataLength
94         0,
95         0,                             // PLDMTerminusHandle
96         0x1,
97         0x0,                           // sensorID=1
98         120,
99         0,                             // entityType=Power Supply(120)
100         1,
101         0,                             // entityInstanceNumber
102         0x1,
103         0x0,                           // containerID=1
104         PLDM_NO_INIT,                  // sensorInit
105         false,                         // sensorAuxiliaryNamesPDR
106         PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
107         1,                             // unitModifier = 1
108         0,                             // rateUnit
109         0,                             // baseOEMUnitHandle
110         0,                             // auxUnit
111         0,                             // auxUnitModifier
112         0,                             // auxRateUnit
113         0,                             // rel
114         0,                             // auxOEMUnitHandle
115         true,                          // isLinear
116         PLDM_SENSOR_DATA_SIZE_UINT8,   // sensorDataSize
117         0, 0, 0xc0,
118         0x3f,                          // resolution=1.5
119         0, 0, 0x80,
120         0x3f,                          // offset=1.0
121         0,
122         0,                             // accuracy
123         0,                             // plusTolerance
124         0,                             // minusTolerance
125         2,                             // hysteresis
126         0,                             // supportedThresholds
127         0,                             // thresholdAndHysteresisVolatility
128         0, 0, 0x80,
129         0x3f,                          // stateTransistionInterval=1.0
130         0, 0, 0x80,
131         0x3f,                          // updateInverval=1.0
132         255,                           // maxReadable
133         0,                             // minReadable
134         PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
135         0,                             // rangeFieldsupport
136         0,                             // nominalValue
137         0,                             // normalMax
138         0,                             // normalMin
139         0,                             // warningHigh
140         0,                             // warningLow
141         0,                             // criticalHigh
142         0,                             // criticalLow
143         0,                             // fatalHigh
144         0                              // fatalLow
145     };
146     rc = mockTerminusManager.enqueueResponse((pldm_msg*)getPdrResp.data(),
147                                              sizeof(getPdrResp));
148     EXPECT_EQ(rc, PLDM_SUCCESS);
149 
150     stdexec::sync_wait(platformManager.initTerminus());
151     EXPECT_EQ(true, terminus->initialized);
152     EXPECT_EQ(1, terminus->pdrs.size());
153 }
154 
155 TEST_F(PlatformManagerTest, initTerminusDontSupportGetPDRTest)
156 {
157     // Add terminus
158     auto mappedTid = mockTerminusManager.mapTid(pldm::MctpInfo(10, "", "", 1));
159     auto tid = mappedTid.value();
160     termini[tid] = std::make_shared<pldm::platform_mc::Terminus>(
161         tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM);
162     auto terminus = termini[tid];
163 
164     /* Set supported command by terminus */
165     auto size = PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8);
166     std::vector<uint8_t> pldmCmds(size);
167     uint8_t type = PLDM_PLATFORM;
168     uint8_t cmd = PLDM_GET_PDR_REPOSITORY_INFO;
169     auto idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
170     pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
171     termini[tid]->setSupportedCommands(pldmCmds);
172 
173     // queue getPDRRepositoryInfo response
174     const size_t getPDRRepositoryInfoLen =
175         PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES;
176     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen>
177         getPDRRepositoryInfoResp{
178             0x0, 0x02, 0x50, PLDM_SUCCESS,
179             0x0,                                     // repositoryState
180             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, 0x0,
181             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, // updateTime
182             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, 0x0,
183             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, // OEMUpdateTime
184             1,   0x0,  0x0,  0x0,                    // recordCount
185             0x0, 0x1,  0x0,  0x0,                    // repositorySize
186             59,  0x0,  0x0,  0x0,                    // largestRecordSize
187             0x0 // dataTransferHandleTimeout
188         };
189     auto rc = mockTerminusManager.enqueueResponse(
190         (pldm_msg*)getPDRRepositoryInfoResp.data(),
191         sizeof(getPDRRepositoryInfoResp));
192     EXPECT_EQ(rc, PLDM_SUCCESS);
193 
194     // queue getPDR responses
195     const size_t getPdrRespLen = 81;
196     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{
197         0x0, 0x02, 0x51, PLDM_SUCCESS, 0x0, 0x0, 0x0, 0x0, // nextRecordHandle
198         0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle
199         0x5,                // transferFlag
200         69, 0x0,            // responseCount
201         // numeric Sensor PDR
202         0x1, 0x0, 0x0,
203         0x0,                     // record handle
204         0x1,                     // PDRHeaderVersion
205         PLDM_NUMERIC_SENSOR_PDR, // PDRType
206         0x0,
207         0x0,                     // recordChangeNumber
208         PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
209             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH +
210             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
211         0,                             // dataLength
212         0,
213         0,                             // PLDMTerminusHandle
214         0x1,
215         0x0,                           // sensorID=1
216         120,
217         0,                             // entityType=Power Supply(120)
218         1,
219         0,                             // entityInstanceNumber
220         0x1,
221         0x0,                           // containerID=1
222         PLDM_NO_INIT,                  // sensorInit
223         false,                         // sensorAuxiliaryNamesPDR
224         PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
225         1,                             // unitModifier = 1
226         0,                             // rateUnit
227         0,                             // baseOEMUnitHandle
228         0,                             // auxUnit
229         0,                             // auxUnitModifier
230         0,                             // auxRateUnit
231         0,                             // rel
232         0,                             // auxOEMUnitHandle
233         true,                          // isLinear
234         PLDM_SENSOR_DATA_SIZE_UINT8,   // sensorDataSize
235         0, 0, 0xc0,
236         0x3f,                          // resolution=1.5
237         0, 0, 0x80,
238         0x3f,                          // offset=1.0
239         0,
240         0,                             // accuracy
241         0,                             // plusTolerance
242         0,                             // minusTolerance
243         2,                             // hysteresis
244         0,                             // supportedThresholds
245         0,                             // thresholdAndHysteresisVolatility
246         0, 0, 0x80,
247         0x3f,                          // stateTransistionInterval=1.0
248         0, 0, 0x80,
249         0x3f,                          // updateInverval=1.0
250         255,                           // maxReadable
251         0,                             // minReadable
252         PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
253         0,                             // rangeFieldsupport
254         0,                             // nominalValue
255         0,                             // normalMax
256         0,                             // normalMin
257         0,                             // warningHigh
258         0,                             // warningLow
259         0,                             // criticalHigh
260         0,                             // criticalLow
261         0,                             // fatalHigh
262         0                              // fatalLow
263     };
264     rc = mockTerminusManager.enqueueResponse((pldm_msg*)getPdrResp.data(),
265                                              sizeof(getPdrResp));
266     EXPECT_EQ(rc, PLDM_SUCCESS);
267 
268     stdexec::sync_wait(platformManager.initTerminus());
269     EXPECT_EQ(true, terminus->initialized);
270     EXPECT_EQ(0, terminus->pdrs.size());
271 }
272 
273 TEST_F(PlatformManagerTest, negativeInitTerminusTest1)
274 {
275     // terminus doesn't Type2 support
276     auto mappedTid = mockTerminusManager.mapTid(pldm::MctpInfo(10, "", "", 1));
277     auto tid = mappedTid.value();
278     termini[tid] =
279         std::make_shared<pldm::platform_mc::Terminus>(tid, 1 << PLDM_BASE);
280     auto terminus = termini[tid];
281 
282     stdexec::sync_wait(platformManager.initTerminus());
283     EXPECT_EQ(true, terminus->initialized);
284     EXPECT_EQ(0, terminus->pdrs.size());
285 }
286 
287 TEST_F(PlatformManagerTest, negativeInitTerminusTest2)
288 {
289     // terminus responses error
290     auto mappedTid = mockTerminusManager.mapTid(pldm::MctpInfo(10, "", "", 1));
291     auto tid = mappedTid.value();
292     termini[tid] = std::make_shared<pldm::platform_mc::Terminus>(
293         tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM);
294     auto terminus = termini[tid];
295 
296     // queue getPDRRepositoryInfo response cc=PLDM_ERROR
297     const size_t getPDRRepositoryInfoLen = 1;
298     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen>
299         getPDRRepositoryInfoResp{0x0, 0x02, 0x50, PLDM_ERROR};
300     auto rc = mockTerminusManager.enqueueResponse(
301         (pldm_msg*)getPDRRepositoryInfoResp.data(),
302         sizeof(getPDRRepositoryInfoResp));
303     EXPECT_EQ(rc, PLDM_SUCCESS);
304 
305     // queue getPDR responses cc=PLDM_ERROR
306     const size_t getPdrRespLen = 1;
307     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{
308         0x0, 0x02, 0x51, PLDM_ERROR};
309     rc = mockTerminusManager.enqueueResponse((pldm_msg*)getPdrResp.data(),
310                                              sizeof(getPdrResp));
311     EXPECT_EQ(rc, PLDM_SUCCESS);
312 
313     stdexec::sync_wait(platformManager.initTerminus());
314     EXPECT_EQ(true, terminus->initialized);
315     EXPECT_EQ(0, terminus->pdrs.size());
316 }
317