1 #include "common/test/mocked_utils.hpp"
2 #include "common/utils.hpp"
3 #include "libpldmresponder/event_parser.hpp"
4 #include "libpldmresponder/pdr.hpp"
5 #include "libpldmresponder/pdr_utils.hpp"
6 #include "libpldmresponder/platform.hpp"
7 #include "libpldmresponder/platform_numeric_effecter.hpp"
8 #include "libpldmresponder/platform_state_effecter.hpp"
9 #include "libpldmresponder/platform_state_sensor.hpp"
10 
11 #include <sdbusplus/test/sdbus_mock.hpp>
12 #include <sdeventplus/event.hpp>
13 
14 #include <iostream>
15 
16 using namespace pldm::utils;
17 using namespace pldm::responder;
18 using namespace pldm::responder::platform;
19 using namespace pldm::responder::pdr;
20 using namespace pldm::responder::pdr_utils;
21 
22 using ::testing::_;
23 using ::testing::Return;
24 using ::testing::StrEq;
25 
26 TEST(getPDR, testGoodPath)
27 {
28     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
29         requestPayload{};
30     auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
31     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
32 
33     struct pldm_get_pdr_req* request =
34         reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
35     request->request_count = 100;
36 
37     MockdBusHandler mockedUtils;
38     EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
39         .Times(5)
40         .WillRepeatedly(Return("foo.bar"));
41 
42     auto pdrRepo = pldm_pdr_init();
43     auto event = sdeventplus::Event::get_default();
44     Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo,
45                     nullptr, nullptr, nullptr, nullptr, event);
46     Repo repo(pdrRepo);
47     ASSERT_EQ(repo.empty(), false);
48     auto response = handler.getPDR(req, requestPayloadLength);
49     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
50 
51     struct pldm_get_pdr_resp* resp =
52         reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload);
53     ASSERT_EQ(PLDM_SUCCESS, resp->completion_code);
54     ASSERT_EQ(2, resp->next_record_handle);
55     ASSERT_EQ(true, resp->response_count != 0);
56 
57     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(resp->record_data);
58     ASSERT_EQ(hdr->record_handle, 1);
59     ASSERT_EQ(hdr->version, 1);
60 
61     pldm_pdr_destroy(pdrRepo);
62 }
63 
64 TEST(getPDR, testShortRead)
65 {
66     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
67         requestPayload{};
68     auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
69     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
70 
71     struct pldm_get_pdr_req* request =
72         reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
73     request->request_count = 1;
74 
75     MockdBusHandler mockedUtils;
76     EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
77         .Times(5)
78         .WillRepeatedly(Return("foo.bar"));
79 
80     auto pdrRepo = pldm_pdr_init();
81     auto event = sdeventplus::Event::get_default();
82     Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo,
83                     nullptr, nullptr, nullptr, nullptr, event);
84     Repo repo(pdrRepo);
85     ASSERT_EQ(repo.empty(), false);
86     auto response = handler.getPDR(req, requestPayloadLength);
87     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
88     struct pldm_get_pdr_resp* resp =
89         reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload);
90     ASSERT_EQ(PLDM_SUCCESS, resp->completion_code);
91     ASSERT_EQ(1, resp->response_count);
92     pldm_pdr_destroy(pdrRepo);
93 }
94 
95 TEST(getPDR, testBadRecordHandle)
96 {
97     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
98         requestPayload{};
99     auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
100     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
101 
102     struct pldm_get_pdr_req* request =
103         reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
104     request->record_handle = 100000;
105     request->request_count = 1;
106 
107     MockdBusHandler mockedUtils;
108     EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
109         .Times(5)
110         .WillRepeatedly(Return("foo.bar"));
111 
112     auto pdrRepo = pldm_pdr_init();
113     auto event = sdeventplus::Event::get_default();
114     Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo,
115                     nullptr, nullptr, nullptr, nullptr, event);
116     Repo repo(pdrRepo);
117     ASSERT_EQ(repo.empty(), false);
118     auto response = handler.getPDR(req, requestPayloadLength);
119     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
120 
121     ASSERT_EQ(responsePtr->payload[0], PLDM_PLATFORM_INVALID_RECORD_HANDLE);
122 
123     pldm_pdr_destroy(pdrRepo);
124 }
125 
126 TEST(getPDR, testNoNextRecord)
127 {
128     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
129         requestPayload{};
130     auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
131     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
132 
133     struct pldm_get_pdr_req* request =
134         reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
135     request->record_handle = 1;
136 
137     MockdBusHandler mockedUtils;
138     EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
139         .Times(5)
140         .WillRepeatedly(Return("foo.bar"));
141 
142     auto pdrRepo = pldm_pdr_init();
143     auto event = sdeventplus::Event::get_default();
144     Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo,
145                     nullptr, nullptr, nullptr, nullptr, event);
146     Repo repo(pdrRepo);
147     ASSERT_EQ(repo.empty(), false);
148     auto response = handler.getPDR(req, requestPayloadLength);
149     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
150     struct pldm_get_pdr_resp* resp =
151         reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload);
152     ASSERT_EQ(PLDM_SUCCESS, resp->completion_code);
153     ASSERT_EQ(2, resp->next_record_handle);
154 
155     pldm_pdr_destroy(pdrRepo);
156 }
157 
158 TEST(getPDR, testFindPDR)
159 {
160     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
161         requestPayload{};
162     auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
163     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
164 
165     struct pldm_get_pdr_req* request =
166         reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
167     request->request_count = 100;
168 
169     MockdBusHandler mockedUtils;
170     EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
171         .Times(5)
172         .WillRepeatedly(Return("foo.bar"));
173 
174     auto pdrRepo = pldm_pdr_init();
175     auto event = sdeventplus::Event::get_default();
176     Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", pdrRepo,
177                     nullptr, nullptr, nullptr, nullptr, event);
178     Repo repo(pdrRepo);
179     ASSERT_EQ(repo.empty(), false);
180     auto response = handler.getPDR(req, requestPayloadLength);
181 
182     // Let's try to find a PDR of type stateEffecter (= 11) and entity type =
183     // 100
184     bool found = false;
185     uint32_t handle = 0; // start asking for PDRs from recordHandle 0
186     while (!found)
187     {
188         request->record_handle = handle;
189         auto response = handler.getPDR(req, requestPayloadLength);
190         auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
191         struct pldm_get_pdr_resp* resp =
192             reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload);
193         ASSERT_EQ(PLDM_SUCCESS, resp->completion_code);
194 
195         handle = resp->next_record_handle; // point to the next pdr in case
196                                            // current is not what we want
197 
198         pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(resp->record_data);
199         std::cerr << "PDR next record handle " << handle << "\n";
200         std::cerr << "PDR type " << hdr->type << "\n";
201         if (hdr->type == PLDM_STATE_EFFECTER_PDR)
202         {
203             pldm_state_effecter_pdr* pdr =
204                 reinterpret_cast<pldm_state_effecter_pdr*>(resp->record_data);
205             std::cerr << "PDR entity type " << pdr->entity_type << "\n";
206             if (pdr->entity_type == 100)
207             {
208                 found = true;
209                 // Rest of the PDR can be accessed as need be
210                 break;
211             }
212         }
213         if (!resp->next_record_handle) // no more records
214         {
215             break;
216         }
217     }
218     ASSERT_EQ(found, true);
219 
220     pldm_pdr_destroy(pdrRepo);
221 }
222 
223 TEST(setStateEffecterStatesHandler, testGoodRequest)
224 {
225     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
226         requestPayload{};
227     auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
228     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
229 
230     MockdBusHandler mockedUtils;
231     EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
232         .Times(5)
233         .WillRepeatedly(Return("foo.bar"));
234 
235     auto inPDRRepo = pldm_pdr_init();
236     auto outPDRRepo = pldm_pdr_init();
237     Repo outRepo(outPDRRepo);
238     auto event = sdeventplus::Event::get_default();
239     Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
240                     nullptr, nullptr, nullptr, nullptr, event);
241     handler.getPDR(req, requestPayloadLength);
242     Repo inRepo(inPDRRepo);
243     getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR);
244     pdr_utils::PdrEntry e;
245     auto record1 = pdr::getRecordByHandle(outRepo, 2, e);
246     ASSERT_NE(record1, nullptr);
247     pldm_state_effecter_pdr* pdr =
248         reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
249     EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
250 
251     std::vector<set_effecter_state_field> stateField;
252     stateField.push_back({PLDM_REQUEST_SET, 1});
253     stateField.push_back({PLDM_REQUEST_SET, 1});
254     std::string value = "xyz.openbmc_project.Foo.Bar.V1";
255     PropertyValue propertyValue = value;
256 
257     DBusMapping dbusMapping{"/foo/bar", "xyz.openbmc_project.Foo.Bar",
258                             "propertyName", "string"};
259 
260     EXPECT_CALL(mockedUtils, setDbusProperty(dbusMapping, propertyValue))
261         .Times(2);
262     auto rc = platform_state_effecter::setStateEffecterStatesHandler<
263         MockdBusHandler, Handler>(mockedUtils, handler, 0x1, stateField);
264     ASSERT_EQ(rc, 0);
265 
266     pldm_pdr_destroy(inPDRRepo);
267     pldm_pdr_destroy(outPDRRepo);
268 }
269 
270 TEST(setStateEffecterStatesHandler, testBadRequest)
271 {
272     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
273         requestPayload{};
274     auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
275     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
276 
277     MockdBusHandler mockedUtils;
278     EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
279         .Times(5)
280         .WillRepeatedly(Return("foo.bar"));
281 
282     auto inPDRRepo = pldm_pdr_init();
283     auto outPDRRepo = pldm_pdr_init();
284     Repo outRepo(outPDRRepo);
285     auto event = sdeventplus::Event::get_default();
286     Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
287                     nullptr, nullptr, nullptr, nullptr, event);
288     handler.getPDR(req, requestPayloadLength);
289     Repo inRepo(inPDRRepo);
290     getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR);
291     pdr_utils::PdrEntry e;
292     auto record1 = pdr::getRecordByHandle(outRepo, 2, e);
293     ASSERT_NE(record1, nullptr);
294     pldm_state_effecter_pdr* pdr =
295         reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
296     EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
297 
298     std::vector<set_effecter_state_field> stateField;
299     stateField.push_back({PLDM_REQUEST_SET, 3});
300     stateField.push_back({PLDM_REQUEST_SET, 4});
301 
302     auto rc = platform_state_effecter::setStateEffecterStatesHandler<
303         MockdBusHandler, Handler>(mockedUtils, handler, 0x1, stateField);
304     ASSERT_EQ(rc, PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE);
305 
306     rc = platform_state_effecter::setStateEffecterStatesHandler<MockdBusHandler,
307                                                                 Handler>(
308         mockedUtils, handler, 0x9, stateField);
309     ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_EFFECTER_ID);
310 
311     stateField.push_back({PLDM_REQUEST_SET, 4});
312     rc = platform_state_effecter::setStateEffecterStatesHandler<MockdBusHandler,
313                                                                 Handler>(
314         mockedUtils, handler, 0x1, stateField);
315     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
316 
317     pldm_pdr_destroy(inPDRRepo);
318     pldm_pdr_destroy(outPDRRepo);
319 }
320 
321 TEST(setNumericEffecterValueHandler, testGoodRequest)
322 {
323     MockdBusHandler mockedUtils;
324     EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
325         .Times(5)
326         .WillRepeatedly(Return("foo.bar"));
327 
328     auto inPDRRepo = pldm_pdr_init();
329     auto numericEffecterPdrRepo = pldm_pdr_init();
330     Repo numericEffecterPDRs(numericEffecterPdrRepo);
331     auto event = sdeventplus::Event::get_default();
332     Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
333                     nullptr, nullptr, nullptr, nullptr, event);
334     Repo inRepo(inPDRRepo);
335     getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR);
336 
337     pdr_utils::PdrEntry e;
338     auto record4 = pdr::getRecordByHandle(numericEffecterPDRs, 4, e);
339     ASSERT_NE(record4, nullptr);
340 
341     pldm_numeric_effecter_value_pdr* pdr =
342         reinterpret_cast<pldm_numeric_effecter_value_pdr*>(e.data);
343     EXPECT_EQ(pdr->hdr.type, PLDM_NUMERIC_EFFECTER_PDR);
344 
345     uint16_t effecterId = 3;
346     uint32_t effecterValue = 2100000000; // 2036-07-18 21:20:00
347     PropertyValue propertyValue = static_cast<uint32_t>(effecterValue);
348 
349     DBusMapping dbusMapping{"/foo/bar", "xyz.openbmc_project.Foo.Bar",
350                             "propertyName", "uint64_t"};
351     EXPECT_CALL(mockedUtils, setDbusProperty(dbusMapping, propertyValue))
352         .Times(1);
353 
354     auto rc = platform_numeric_effecter::setNumericEffecterValueHandler<
355         MockdBusHandler, Handler>(
356         mockedUtils, handler, effecterId, PLDM_EFFECTER_DATA_SIZE_UINT32,
357         reinterpret_cast<uint8_t*>(&effecterValue), 4);
358     ASSERT_EQ(rc, 0);
359 
360     pldm_pdr_destroy(inPDRRepo);
361     pldm_pdr_destroy(numericEffecterPdrRepo);
362 }
363 
364 TEST(setNumericEffecterValueHandler, testBadRequest)
365 {
366     MockdBusHandler mockedUtils;
367     EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
368         .Times(5)
369         .WillRepeatedly(Return("foo.bar"));
370 
371     auto inPDRRepo = pldm_pdr_init();
372     auto numericEffecterPdrRepo = pldm_pdr_init();
373     Repo numericEffecterPDRs(numericEffecterPdrRepo);
374     auto event = sdeventplus::Event::get_default();
375     Handler handler(&mockedUtils, "./pdr_jsons/state_effecter/good", inPDRRepo,
376                     nullptr, nullptr, nullptr, nullptr, event);
377     Repo inRepo(inPDRRepo);
378     getRepoByType(inRepo, numericEffecterPDRs, PLDM_NUMERIC_EFFECTER_PDR);
379 
380     pdr_utils::PdrEntry e;
381     auto record4 = pdr::getRecordByHandle(numericEffecterPDRs, 4, e);
382     ASSERT_NE(record4, nullptr);
383 
384     pldm_numeric_effecter_value_pdr* pdr =
385         reinterpret_cast<pldm_numeric_effecter_value_pdr*>(e.data);
386     EXPECT_EQ(pdr->hdr.type, PLDM_NUMERIC_EFFECTER_PDR);
387 
388     uint16_t effecterId = 3;
389     uint64_t effecterValue = 9876543210;
390     auto rc = platform_numeric_effecter::setNumericEffecterValueHandler<
391         MockdBusHandler, Handler>(
392         mockedUtils, handler, effecterId, PLDM_EFFECTER_DATA_SIZE_SINT32,
393         reinterpret_cast<uint8_t*>(&effecterValue), 3);
394     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
395 
396     pldm_pdr_destroy(inPDRRepo);
397     pldm_pdr_destroy(numericEffecterPdrRepo);
398 }
399 
400 TEST(parseStateSensor, allScenarios)
401 {
402     // Sample state sensor with SensorID - 1, EntityType - Processor Module(67)
403     // State Set ID - Operational Running Status(11), Supported States - 3,4
404     std::vector<uint8_t> sample1PDR{0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
405                                     0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00,
406                                     0x43, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
407                                     0x00, 0x01, 0x0b, 0x00, 0x01, 0x18};
408 
409     const auto& [terminusHandle1, sensorID1, sensorInfo1] =
410         parseStateSensorPDR(sample1PDR);
411     const auto& [containerID1, entityType1, entityInstance1] =
412         std::get<0>(sensorInfo1);
413     const auto& states1 = std::get<1>(sensorInfo1);
414     CompositeSensorStates statesCmp1{{3u, 4u}};
415 
416     ASSERT_EQ(le16toh(terminusHandle1), 0u);
417     ASSERT_EQ(le16toh(sensorID1), 1u);
418     ASSERT_EQ(le16toh(containerID1), 0u);
419     ASSERT_EQ(le16toh(entityType1), 67u);
420     ASSERT_EQ(le16toh(entityInstance1), 1u);
421     ASSERT_EQ(states1, statesCmp1);
422 
423     // Sample state sensor with SensorID - 2, EntityType - System Firmware(31)
424     // State Set ID - Availability(2), Supported States - 3,4,9,10,11,13
425     std::vector<uint8_t> sample2PDR{0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
426                                     0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00,
427                                     0x1F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
428                                     0x00, 0x01, 0x02, 0x00, 0x02, 0x18, 0x2E};
429 
430     const auto& [terminusHandle2, sensorID2, sensorInfo2] =
431         parseStateSensorPDR(sample2PDR);
432     const auto& [containerID2, entityType2, entityInstance2] =
433         std::get<0>(sensorInfo2);
434     const auto& states2 = std::get<1>(sensorInfo2);
435     CompositeSensorStates statesCmp2{{3u, 4u, 9u, 10u, 11u, 13u}};
436 
437     ASSERT_EQ(le16toh(terminusHandle2), 0u);
438     ASSERT_EQ(le16toh(sensorID2), 2u);
439     ASSERT_EQ(le16toh(containerID2), 0u);
440     ASSERT_EQ(le16toh(entityType2), 31u);
441     ASSERT_EQ(le16toh(entityInstance2), 1u);
442     ASSERT_EQ(states2, statesCmp2);
443 
444     // Sample state sensor with SensorID - 3, EntityType - Virtual Machine
445     // Manager(33), Composite State Sensor -2 , State Set ID - Link State(33),
446     // Supported States - 1,2, State Set ID - Configuration State(15),
447     // Supported States - 1,2,3,4
448     std::vector<uint8_t> sample3PDR{
449         0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x17, 0x00, 0x00,
450         0x00, 0x03, 0x00, 0x21, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
451         0x02, 0x21, 0x00, 0x01, 0x06, 0x0F, 0x00, 0x01, 0x1E};
452 
453     const auto& [terminusHandle3, sensorID3, sensorInfo3] =
454         parseStateSensorPDR(sample3PDR);
455     const auto& [containerID3, entityType3, entityInstance3] =
456         std::get<0>(sensorInfo3);
457     const auto& states3 = std::get<1>(sensorInfo3);
458     CompositeSensorStates statesCmp3{{1u, 2u}, {1u, 2u, 3u, 4u}};
459 
460     ASSERT_EQ(le16toh(terminusHandle3), 0u);
461     ASSERT_EQ(le16toh(sensorID3), 3u);
462     ASSERT_EQ(le16toh(containerID3), 1u);
463     ASSERT_EQ(le16toh(entityType3), 33u);
464     ASSERT_EQ(le16toh(entityInstance3), 2u);
465     ASSERT_EQ(states3, statesCmp3);
466 }
467 
468 TEST(StateSensorHandler, allScenarios)
469 {
470     using namespace pldm::responder::events;
471 
472     StateSensorHandler handler{"./event_jsons/good"};
473     constexpr uint8_t eventState0 = 0;
474     constexpr uint8_t eventState1 = 1;
475     constexpr uint8_t eventState2 = 2;
476     constexpr uint8_t eventState3 = 3;
477 
478     // Event Entry 1
479     {
480         StateSensorEntry entry{1, 64, 1, 0};
481         const auto& [dbusMapping, eventStateMap] = handler.getEventInfo(entry);
482         DBusMapping mapping{"/xyz/abc/def",
483                             "xyz.openbmc_project.example1.value", "value1",
484                             "string"};
485         ASSERT_EQ(mapping == dbusMapping, true);
486 
487         const auto& propValue0 = eventStateMap.at(eventState0);
488         const auto& propValue1 = eventStateMap.at(eventState1);
489         const auto& propValue2 = eventStateMap.at(eventState2);
490         PropertyValue value0{std::in_place_type<std::string>,
491                              "xyz.openbmc_project.State.Normal"};
492         PropertyValue value1{std::in_place_type<std::string>,
493                              "xyz.openbmc_project.State.Critical"};
494         PropertyValue value2{std::in_place_type<std::string>,
495                              "xyz.openbmc_project.State.Fatal"};
496         ASSERT_EQ(value0 == propValue0, true);
497         ASSERT_EQ(value1 == propValue1, true);
498         ASSERT_EQ(value2 == propValue2, true);
499     }
500 
501     // Event Entry 2
502     {
503         StateSensorEntry entry{1, 64, 1, 1};
504         const auto& [dbusMapping, eventStateMap] = handler.getEventInfo(entry);
505         DBusMapping mapping{"/xyz/abc/def",
506                             "xyz.openbmc_project.example2.value", "value2",
507                             "uint8_t"};
508         ASSERT_EQ(mapping == dbusMapping, true);
509 
510         const auto& propValue0 = eventStateMap.at(eventState2);
511         const auto& propValue1 = eventStateMap.at(eventState3);
512         PropertyValue value0{std::in_place_type<uint8_t>, 9};
513         PropertyValue value1{std::in_place_type<uint8_t>, 10};
514         ASSERT_EQ(value0 == propValue0, true);
515         ASSERT_EQ(value1 == propValue1, true);
516     }
517 
518     // Event Entry 3
519     {
520         StateSensorEntry entry{2, 67, 2, 0};
521         const auto& [dbusMapping, eventStateMap] = handler.getEventInfo(entry);
522         DBusMapping mapping{"/xyz/abc/ghi",
523                             "xyz.openbmc_project.example3.value", "value3",
524                             "bool"};
525         ASSERT_EQ(mapping == dbusMapping, true);
526 
527         const auto& propValue0 = eventStateMap.at(eventState0);
528         const auto& propValue1 = eventStateMap.at(eventState1);
529         PropertyValue value0{std::in_place_type<bool>, false};
530         PropertyValue value1{std::in_place_type<bool>, true};
531         ASSERT_EQ(value0 == propValue0, true);
532         ASSERT_EQ(value1 == propValue1, true);
533     }
534 
535     // Invalid Entry
536     {
537         StateSensorEntry entry{0, 0, 0, 0};
538         ASSERT_THROW(handler.getEventInfo(entry), std::out_of_range);
539     }
540 }
541 
542 TEST(TerminusLocatorPDR, BMCTerminusLocatorPDR)
543 {
544     auto inPDRRepo = pldm_pdr_init();
545     auto outPDRRepo = pldm_pdr_init();
546     Repo outRepo(outPDRRepo);
547     MockdBusHandler mockedUtils;
548     auto event = sdeventplus::Event::get_default();
549     Handler handler(&mockedUtils, "", inPDRRepo, nullptr, nullptr, nullptr,
550                     nullptr, event);
551     Repo inRepo(inPDRRepo);
552     getRepoByType(inRepo, outRepo, PLDM_TERMINUS_LOCATOR_PDR);
553 
554     // 1 BMC terminus locator PDR in the PDR repository
555     ASSERT_EQ(outRepo.getRecordCount(), 1);
556 
557     pdr_utils::PdrEntry entry;
558     auto record = pdr::getRecordByHandle(outRepo, 1, entry);
559     ASSERT_NE(record, nullptr);
560 
561     auto pdr = reinterpret_cast<const pldm_terminus_locator_pdr*>(entry.data);
562     EXPECT_EQ(pdr->hdr.record_handle, 1);
563     EXPECT_EQ(pdr->hdr.version, 1);
564     EXPECT_EQ(pdr->hdr.type, PLDM_TERMINUS_LOCATOR_PDR);
565     EXPECT_EQ(pdr->hdr.record_change_num, 0);
566     EXPECT_EQ(pdr->hdr.length,
567               sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr));
568     EXPECT_EQ(pdr->terminus_handle, BmcPldmTerminusHandle);
569     EXPECT_EQ(pdr->validity, PLDM_TL_PDR_VALID);
570     EXPECT_EQ(pdr->tid, BmcTerminusId);
571     EXPECT_EQ(pdr->container_id, 0);
572     EXPECT_EQ(pdr->terminus_locator_type, PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID);
573     EXPECT_EQ(pdr->terminus_locator_value_size,
574               sizeof(pldm_terminus_locator_type_mctp_eid));
575     auto locatorValue =
576         reinterpret_cast<const pldm_terminus_locator_type_mctp_eid*>(
577             pdr->terminus_locator_value);
578     EXPECT_EQ(locatorValue->eid, BmcMctpEid);
579     pldm_pdr_destroy(inPDRRepo);
580     pldm_pdr_destroy(outPDRRepo);
581 }
582 
583 TEST(getStateSensorReadingsHandler, testGoodRequest)
584 {
585     MockdBusHandler mockedUtils;
586     EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
587         .Times(1)
588         .WillRepeatedly(Return("foo.bar"));
589 
590     auto inPDRRepo = pldm_pdr_init();
591     auto outPDRRepo = pldm_pdr_init();
592     Repo outRepo(outPDRRepo);
593     auto event = sdeventplus::Event::get_default();
594     Handler handler(&mockedUtils, "./pdr_jsons/state_sensor/good", inPDRRepo,
595                     nullptr, nullptr, nullptr, nullptr, event);
596     Repo inRepo(inPDRRepo);
597     getRepoByType(inRepo, outRepo, PLDM_STATE_SENSOR_PDR);
598     pdr_utils::PdrEntry e;
599     auto record = pdr::getRecordByHandle(outRepo, 2, e);
600     ASSERT_NE(record, nullptr);
601     pldm_state_sensor_pdr* pdr =
602         reinterpret_cast<pldm_state_sensor_pdr*>(e.data);
603     EXPECT_EQ(pdr->hdr.type, PLDM_STATE_SENSOR_PDR);
604 
605     std::vector<get_sensor_state_field> stateField;
606     uint8_t compSensorCnt{};
607     uint8_t sensorRearmCnt = 1;
608 
609     MockdBusHandler handlerObj;
610     EXPECT_CALL(handlerObj,
611                 getDbusPropertyVariant(StrEq("/foo/bar"), StrEq("propertyName"),
612                                        StrEq("xyz.openbmc_project.Foo.Bar")))
613         .WillOnce(Return(
614             PropertyValue(std::string("xyz.openbmc_project.Foo.Bar.V0"))));
615 
616     auto rc = platform_state_sensor::getStateSensorReadingsHandler<
617         MockdBusHandler, Handler>(handlerObj, handler, 0x1, sensorRearmCnt,
618                                   compSensorCnt, stateField);
619     ASSERT_EQ(rc, 0);
620     ASSERT_EQ(compSensorCnt, 1);
621     ASSERT_EQ(stateField[0].sensor_op_state, PLDM_SENSOR_UNAVAILABLE);
622     ASSERT_EQ(stateField[0].present_state, PLDM_SENSOR_NORMAL);
623     ASSERT_EQ(stateField[0].previous_state, PLDM_SENSOR_UNKNOWN);
624     ASSERT_EQ(stateField[0].event_state, PLDM_SENSOR_UNKNOWN);
625 
626     pldm_pdr_destroy(inPDRRepo);
627     pldm_pdr_destroy(outPDRRepo);
628 }
629 
630 TEST(getStateSensorReadingsHandler, testBadRequest)
631 {
632     MockdBusHandler mockedUtils;
633     EXPECT_CALL(mockedUtils, getService(StrEq("/foo/bar"), _))
634         .Times(1)
635         .WillRepeatedly(Return("foo.bar"));
636 
637     auto inPDRRepo = pldm_pdr_init();
638     auto outPDRRepo = pldm_pdr_init();
639     Repo outRepo(outPDRRepo);
640     auto event = sdeventplus::Event::get_default();
641     Handler handler(&mockedUtils, "./pdr_jsons/state_sensor/good", inPDRRepo,
642                     nullptr, nullptr, nullptr, nullptr, event);
643     Repo inRepo(inPDRRepo);
644     getRepoByType(inRepo, outRepo, PLDM_STATE_SENSOR_PDR);
645     pdr_utils::PdrEntry e;
646     auto record = pdr::getRecordByHandle(outRepo, 2, e);
647     ASSERT_NE(record, nullptr);
648     pldm_state_sensor_pdr* pdr =
649         reinterpret_cast<pldm_state_sensor_pdr*>(e.data);
650     EXPECT_EQ(pdr->hdr.type, PLDM_STATE_SENSOR_PDR);
651 
652     std::vector<get_sensor_state_field> stateField;
653     uint8_t compSensorCnt{};
654     uint8_t sensorRearmCnt = 3;
655 
656     MockdBusHandler handlerObj;
657     auto rc = platform_state_sensor::getStateSensorReadingsHandler<
658         MockdBusHandler, Handler>(handlerObj, handler, 0x1, sensorRearmCnt,
659                                   compSensorCnt, stateField);
660     ASSERT_EQ(rc, PLDM_PLATFORM_REARM_UNAVAILABLE_IN_PRESENT_STATE);
661 
662     pldm_pdr_destroy(inPDRRepo);
663     pldm_pdr_destroy(outPDRRepo);
664 }
665