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