xref: /openbmc/pldm/platform-mc/test/event_manager_test.cpp (revision 378e3f7dda6886dff4ffe9f771af74eb8cf5f281)
1 #include "common/instance_id.hpp"
2 #include "common/types.hpp"
3 #include "mock_event_manager.hpp"
4 #include "mock_terminus_manager.hpp"
5 #include "platform-mc/platform_manager.hpp"
6 #include "platform-mc/terminus_manager.hpp"
7 #include "test/test_instance_id.hpp"
8 #include "utils_test.hpp"
9 
10 #include <libpldm/base.h>
11 #include <libpldm/entity.h>
12 #include <libpldm/platform.h>
13 
14 #include <gtest/gtest.h>
15 
16 using ::testing::_;
17 using ::testing::Return;
18 
19 class EventManagerTest : public testing::Test
20 {
21   protected:
EventManagerTest()22     EventManagerTest() :
23         bus(pldm::utils::DBusHandler::getBus()),
24         event(sdeventplus::Event::get_default()), instanceIdDb(),
25         reqHandler(pldmTransport, event, instanceIdDb, false,
26                    std::chrono::seconds(1), 2, std::chrono::milliseconds(100)),
27         terminusManager(event, reqHandler, instanceIdDb, termini, nullptr),
28         eventManager(terminusManager, termini),
29         platformManager(terminusManager, termini, nullptr)
30     {}
31 
32     PldmTransport* pldmTransport = nullptr;
33     sdbusplus::bus_t& bus;
34     sdeventplus::Event event;
35     TestInstanceIdDb instanceIdDb;
36     pldm::requester::Handler<pldm::requester::Request> reqHandler;
37     pldm::platform_mc::MockTerminusManager terminusManager;
38     pldm::platform_mc::MockEventManager eventManager;
39     pldm::platform_mc::PlatformManager platformManager;
40     pldm::platform_mc::TerminiMapper termini{};
41 };
42 
TEST_F(EventManagerTest,processNumericSensorEventTest)43 TEST_F(EventManagerTest, processNumericSensorEventTest)
44 {
45 #define SENSOR_READING 50
46 #define WARNING_HIGH 45
47     pldm_tid_t tid = 1;
48     termini[tid] = std::make_shared<pldm::platform_mc::Terminus>(
49         tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM, event);
50     std::vector<uint8_t> pdr1{
51         0x1,
52         0x0,
53         0x0,
54         0x0,                         // record handle
55         0x1,                         // PDRHeaderVersion
56         PLDM_NUMERIC_SENSOR_PDR,     // PDRType
57         0x0,
58         0x0,                         // recordChangeNumber
59         PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
60         0,                           // dataLength
61         0,
62         0,                           // PLDMTerminusHandle
63         0x1,
64         0x0,                         // sensorID=1
65         PLDM_ENTITY_POWER_SUPPLY,
66         0,                           // entityType=Power Supply(120)
67         1,
68         0,                           // entityInstanceNumber
69         1,
70         0,                           // containerID=1
71         PLDM_NO_INIT,                // sensorInit
72         false,                       // sensorAuxiliaryNamesPDR
73         PLDM_SENSOR_UNIT_DEGRESS_C,  // baseUint(2)=degrees C
74         0,                           // unitModifier = 0
75         0,                           // rateUnit
76         0,                           // baseOEMUnitHandle
77         0,                           // auxUnit
78         0,                           // auxUnitModifier
79         0,                           // auxRateUnit
80         0,                           // rel
81         0,                           // auxOEMUnitHandle
82         true,                        // isLinear
83         PLDM_SENSOR_DATA_SIZE_UINT8, // sensorDataSize
84         0,
85         0,
86         0x80,
87         0x3f, // resolution=1.0
88         0,
89         0,
90         0,
91         0,    // offset=0
92         0,
93         0,    // accuracy
94         0,    // plusTolerance
95         0,    // minusTolerance
96         2,    // hysteresis = 2
97         0x1b, // supportedThresholds
98         0,    // thresholdAndHysteresisVolatility
99         0,
100         0,
101         0x80,
102         0x3f, // stateTransistionInterval=1.0
103         0,
104         0,
105         0x80,
106         0x3f,                          // updateInverval=1.0
107         255,                           // maxReadable
108         0,                             // minReadable
109         PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
110         0x18,                          // rangeFieldsupport
111         0,                             // nominalValue
112         0,                             // normalMax
113         0,                             // normalMin
114         WARNING_HIGH,                  // warningHigh
115         20,                            // warningLow
116         60,                            // criticalHigh
117         10,                            // criticalLow
118         0,                             // fatalHigh
119         0                              // fatalLow
120     };
121 
122     std::vector<uint8_t> pdr2{
123         0x1, 0x0, 0x0,
124         0x0,                             // record handle
125         0x1,                             // PDRHeaderVersion
126         PLDM_ENTITY_AUXILIARY_NAMES_PDR, // PDRType
127         0x1,
128         0x0,                             // recordChangeNumber
129         0x11,
130         0,                               // dataLength
131         /* Entity Auxiliary Names PDR Data*/
132         3,
133         0x80, // entityType system software
134         0x1,
135         0x0,  // Entity instance number =1
136         0,
137         0,    // Overal system
138         0,    // shared Name Count one name only
139         01,   // nameStringCount
140         0x65, 0x6e, 0x00,
141         0x00, // Language Tag "en"
142         0x53, 0x00, 0x30, 0x00,
143         0x00  // Entity Name "S0"
144     };
145 
146     // add dummy numeric sensor
147     termini[tid]->pdrs.emplace_back(pdr1);
148     termini[tid]->pdrs.emplace_back(pdr2);
149     termini[tid]->parseTerminusPDRs();
150     // Run event loop for a few seconds to let sensor creation
151     // defer tasks be run. May increase time when sensor num is large
152     utils::runEventLoopForSeconds(event, 1);
153     EXPECT_EQ(1, termini[tid]->numericSensors.size());
154 
155     uint8_t platformEventStatus = 0;
156 
157     std::vector<uint8_t> eventData{
158         0x1,
159         0x0, // sensor id
160         PLDM_NUMERIC_SENSOR_STATE,
161         PLDM_SENSOR_UPPERWARNING,
162         PLDM_SENSOR_NORMAL,
163         PLDM_SENSOR_DATA_SIZE_UINT8,
164         SENSOR_READING};
165     auto rc = eventManager.handlePlatformEvent(
166         tid, 0x00, PLDM_SENSOR_EVENT, eventData.data(), eventData.size());
167     EXPECT_EQ(PLDM_SUCCESS, rc);
168     EXPECT_EQ(PLDM_EVENT_NO_LOGGING, platformEventStatus);
169 }
170 
TEST_F(EventManagerTest,SetEventReceiverTest)171 TEST_F(EventManagerTest, SetEventReceiverTest)
172 {
173     // Add terminus
174     auto mappedTid =
175         terminusManager.mapTid(pldm::MctpInfo(10, "", "", 1, std::nullopt));
176     auto tid = mappedTid.value();
177     termini[tid] = std::make_shared<pldm::platform_mc::Terminus>(
178         tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM, event);
179     auto terminus = termini[tid];
180 
181     /* Set supported command by terminus */
182     auto size = PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8);
183     std::vector<uint8_t> pldmCmds(size);
184     uint8_t type = PLDM_PLATFORM;
185     uint8_t cmd = PLDM_GET_PDR_REPOSITORY_INFO;
186     auto idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
187     pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
188     cmd = PLDM_GET_PDR;
189     idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
190     pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
191     cmd = PLDM_EVENT_MESSAGE_SUPPORTED;
192     idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
193     pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
194     cmd = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
195     idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
196     pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
197     cmd = PLDM_SET_EVENT_RECEIVER;
198     idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
199     pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
200     termini[tid]->setSupportedCommands(pldmCmds);
201 
202     EXPECT_EQ(true, termini[tid]->doesSupportCommand(PLDM_PLATFORM,
203                                                      PLDM_SET_EVENT_RECEIVER));
204     EXPECT_EQ(true, termini[tid]->doesSupportCommand(
205                         PLDM_PLATFORM, PLDM_EVENT_MESSAGE_BUFFER_SIZE));
206     EXPECT_EQ(true, termini[tid]->doesSupportCommand(
207                         PLDM_PLATFORM, PLDM_EVENT_MESSAGE_SUPPORTED));
208     EXPECT_EQ(true,
209               termini[tid]->doesSupportCommand(PLDM_PLATFORM, PLDM_GET_PDR));
210     EXPECT_EQ(true, termini[tid]->doesSupportCommand(
211                         PLDM_PLATFORM, PLDM_GET_PDR_REPOSITORY_INFO));
212 
213     // queue getPDRRepositoryInfo response
214     const size_t getPDRRepositoryInfoLen =
215         PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES;
216     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen>
217         getPDRRepositoryInfoResp{
218             0x0, 0x02, 0x50, PLDM_SUCCESS,
219             0x0,                                     // repositoryState
220             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, 0x0,
221             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, // updateTime
222             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, 0x0,
223             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, // OEMUpdateTime
224             2,   0x0,  0x0,  0x0,                    // recordCount
225             0x0, 0x1,  0x0,  0x0,                    // repositorySize
226             59,  0x0,  0x0,  0x0,                    // largestRecordSize
227             0x0 // dataTransferHandleTimeout
228         };
229     auto rc = terminusManager.enqueueResponse(
230         new (getPDRRepositoryInfoResp.data()) pldm_msg,
231         sizeof(getPDRRepositoryInfoResp));
232     EXPECT_EQ(rc, PLDM_SUCCESS);
233 
234     // queue getPDR responses
235     const size_t getPdrRespLen = 81;
236     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{
237         0x0, 0x02, 0x51, PLDM_SUCCESS, 0x1, 0x0, 0x0, 0x0, // nextRecordHandle
238         0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle
239         0x5,                // transferFlag
240         69, 0x0,            // responseCount
241         // numeric Sensor PDR
242         0x0, 0x0, 0x0,
243         0x0,                     // record handle
244         0x1,                     // PDRHeaderVersion
245         PLDM_NUMERIC_SENSOR_PDR, // PDRType
246         0x0,
247         0x0,                     // recordChangeNumber
248         PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
249             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH +
250             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
251         0,                             // dataLength
252         0,
253         0,                             // PLDMTerminusHandle
254         0x1,
255         0x0,                           // sensorID=1
256         120,
257         0,                             // entityType=Power Supply(120)
258         1,
259         0,                             // entityInstanceNumber
260         0x1,
261         0x0,                           // containerID=1
262         PLDM_NO_INIT,                  // sensorInit
263         false,                         // sensorAuxiliaryNamesPDR
264         PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
265         1,                             // unitModifier = 1
266         0,                             // rateUnit
267         0,                             // baseOEMUnitHandle
268         0,                             // auxUnit
269         0,                             // auxUnitModifier
270         0,                             // auxRateUnit
271         0,                             // rel
272         0,                             // auxOEMUnitHandle
273         true,                          // isLinear
274         PLDM_SENSOR_DATA_SIZE_UINT8,   // sensorDataSize
275         0, 0, 0xc0,
276         0x3f,                          // resolution=1.5
277         0, 0, 0x80,
278         0x3f,                          // offset=1.0
279         0,
280         0,                             // accuracy
281         0,                             // plusTolerance
282         0,                             // minusTolerance
283         2,                             // hysteresis
284         0,                             // supportedThresholds
285         0,                             // thresholdAndHysteresisVolatility
286         0, 0, 0x80,
287         0x3f,                          // stateTransistionInterval=1.0
288         0, 0, 0x80,
289         0x3f,                          // updateInverval=1.0
290         255,                           // maxReadable
291         0,                             // minReadable
292         PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
293         0,                             // rangeFieldsupport
294         0,                             // nominalValue
295         0,                             // normalMax
296         0,                             // normalMin
297         0,                             // warningHigh
298         0,                             // warningLow
299         0,                             // criticalHigh
300         0,                             // criticalLow
301         0,                             // fatalHigh
302         0                              // fatalLow
303     };
304     rc = terminusManager.enqueueResponse(new (getPdrResp.data()) pldm_msg,
305                                          sizeof(getPdrResp));
306     EXPECT_EQ(rc, PLDM_SUCCESS);
307 
308     const size_t getPdrAuxNameRespLen = 39;
309     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrAuxNameRespLen>
310         getPdrAuxNameResp{
311             0x0, 0x02, 0x51, PLDM_SUCCESS, 0x0, 0x0, 0x0,
312             0x0,                // nextRecordHandle
313             0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle
314             0x5,                // transferFlag
315             0x1b, 0x0,          // responseCount
316             // Common PDR Header
317             0x1, 0x0, 0x0,
318             0x0,                             // record handle
319             0x1,                             // PDRHeaderVersion
320             PLDM_ENTITY_AUXILIARY_NAMES_PDR, // PDRType
321             0x1,
322             0x0,                             // recordChangeNumber
323             0x11,
324             0,                               // dataLength
325             /* Entity Auxiliary Names PDR Data*/
326             3,
327             0x80, // entityType system software
328             0x1,
329             0x0,  // Entity instance number =1
330             0,
331             0,    // Overal system
332             0,    // shared Name Count one name only
333             01,   // nameStringCount
334             0x65, 0x6e, 0x00,
335             0x00, // Language Tag "en"
336             0x53, 0x00, 0x30, 0x00,
337             0x00  // Entity Name "S0"
338         };
339     rc = terminusManager.enqueueResponse(
340         new (getPdrAuxNameResp.data()) pldm_msg, sizeof(getPdrAuxNameResp));
341     EXPECT_EQ(rc, PLDM_SUCCESS);
342 
343     // queue eventMessageBufferSize response(bufferSize=32)
344     const size_t eventMessageBufferSizeRespLen = 3;
345     std::array<uint8_t, sizeof(pldm_msg_hdr) + eventMessageBufferSizeRespLen>
346         eventMessageBufferSizeResp{0x0, 0x02, 0x0d, PLDM_SUCCESS, 32, 0};
347     rc = terminusManager.enqueueResponse(
348         new (eventMessageBufferSizeResp.data()) pldm_msg,
349         sizeof(eventMessageBufferSizeResp));
350     EXPECT_EQ(rc, PLDM_SUCCESS);
351 
352     // queue eventMessageSupported response
353     const size_t eventMessageSupportedLen = 7;
354     PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES;
355     std::array<uint8_t, sizeof(pldm_msg_hdr) + eventMessageSupportedLen>
356         eventMessageSupportedResp{0x0,  0x02, 0x0c, PLDM_SUCCESS,
357                                   0x0,  // synchronyConfiguration
358                                   0x06, // synchronyConfigurationSupported
359                                   3,    // numberEventClassReturned
360                                   0x0,  0x5,  0xfa};
361     rc = terminusManager.enqueueResponse(
362         new (eventMessageSupportedResp.data()) pldm_msg,
363         sizeof(eventMessageSupportedResp));
364     EXPECT_EQ(rc, PLDM_SUCCESS);
365 
366     terminusManager.updateMctpEndpointAvailability(
367         pldm::MctpInfo(10, "", "", 1, std::nullopt), true);
368 
369     // queue SetEventReceiver response
370     const size_t SetEventReceiverLen = 1;
371     PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES;
372     std::array<uint8_t, sizeof(pldm_msg_hdr) + SetEventReceiverLen>
373         SetEventReceiverResp{0x0, 0x02, 0x04, PLDM_SUCCESS};
374     rc = terminusManager.enqueueResponse(
375         new (SetEventReceiverResp.data()) pldm_msg,
376         sizeof(SetEventReceiverResp));
377     EXPECT_EQ(rc, PLDM_SUCCESS);
378 
379     // should finish immediately
380     stdexec::sync_wait(platformManager.initTerminus());
381     // Run event loop for a few seconds to let sensor creation
382     // defer tasks be run. May increase time when sensor num is large
383     utils::runEventLoopForSeconds(event, 1);
384     EXPECT_EQ(true, terminus->initialized);
385     EXPECT_EQ(32, terminus->maxBufferSize);
386     EXPECT_EQ(0x06, terminus->synchronyConfigurationSupported.byte);
387     EXPECT_EQ(2, terminus->pdrs.size());
388     EXPECT_EQ(1, terminus->numericSensors.size());
389 }
390 
TEST_F(EventManagerTest,updateAvailableState)391 TEST_F(EventManagerTest, updateAvailableState)
392 {
393     pldm_tid_t tid = 1;
394     eventManager.updateAvailableState(tid, true);
395     EXPECT_EQ(true, eventManager.getAvailableState(tid));
396     eventManager.updateAvailableState(tid, false);
397     EXPECT_EQ(false, eventManager.getAvailableState(tid));
398     eventManager.updateAvailableState(2, false);
399     EXPECT_EQ(false, eventManager.getAvailableState(tid));
400 }
401 
TEST_F(EventManagerTest,pollForPlatformEventTaskMultipartTransferTest)402 TEST_F(EventManagerTest, pollForPlatformEventTaskMultipartTransferTest)
403 {
404     // Add terminus
405     auto mappedTid =
406         terminusManager.mapTid(pldm::MctpInfo(10, "", "", 1, std::nullopt));
407     auto tid = mappedTid.value();
408     termini[tid] = std::make_shared<pldm::platform_mc::Terminus>(
409         tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM, event);
410     auto terminus = termini[tid];
411 
412     // queue pollForPlatformEventMessage first part response
413     const size_t pollForPlatformEventMessage1Len = 22;
414     std::array<uint8_t, sizeof(pldm_msg_hdr) + pollForPlatformEventMessage1Len>
415         pollForPlatformEventMessage1Resp{
416             0x0,
417             0x02,
418             0x0d,
419             PLDM_SUCCESS,
420             tid, // TID
421             0x1,
422             0x0, // eventID
423             0x1,
424             0x0,
425             0x0,
426             0x0,                          // nextDataTransferHandle
427             PLDM_PLATFORM_TRANSFER_START, // transferFlag = start
428             PLDM_CPER_EVENT,              // eventClass
429             8,
430             0,
431             0,
432             0,    // eventDataSize
433             0x01, // CPER event formatVersion= 0x01
434             1,    // formatType = single CPER section(0x01)
435             10,
436             0,    // eventDataLength = 10
437             1,
438             2,
439             3,
440             4 // eventData first part
441         };
442     auto rc = terminusManager.enqueueResponse(
443         new (pollForPlatformEventMessage1Resp.data()) pldm_msg,
444         sizeof(pollForPlatformEventMessage1Resp));
445     EXPECT_EQ(rc, PLDM_SUCCESS);
446 
447     // queue pollForPlatformEventMessage last part response
448     const size_t pollForPlatformEventMessage2Len = 24;
449     std::array<uint8_t, sizeof(pldm_msg_hdr) + pollForPlatformEventMessage2Len>
450         pollForPlatformEventMessage2Resp{
451             0x0,
452             0x02,
453             0x0d,
454             PLDM_SUCCESS,
455             tid, // TID
456             0x1,
457             0x0, // eventID
458             0x2,
459             0x0,
460             0x0,
461             0x0,                        // nextDataTransferHandle
462             PLDM_PLATFORM_TRANSFER_END, // transferFlag = end
463             PLDM_CPER_EVENT,            // eventClass
464             6,
465             0,
466             0,
467             0, // eventDataSize
468             5,
469             6,
470             7,
471             8,
472             9,
473             0, // eventData last part
474             0x46,
475             0x7f,
476             0x6a,
477             0x5d // crc32
478         };
479     rc = terminusManager.enqueueResponse(
480         new (pollForPlatformEventMessage2Resp.data()) pldm_msg,
481         sizeof(pollForPlatformEventMessage2Resp));
482     EXPECT_EQ(rc, PLDM_SUCCESS);
483 
484     // queue pollForPlatformEventMessage Ack response
485     const size_t pollForPlatformEventMessage3Len = 4;
486     std::array<uint8_t, sizeof(pldm_msg_hdr) + pollForPlatformEventMessage3Len>
487         pollForPlatformEventMessage3Resp{
488             0x0, 0x02, 0x0d, PLDM_SUCCESS,
489             tid,     // TID
490             0x0, 0x0 // eventID
491         };
492     rc = terminusManager.enqueueResponse(
493         new (pollForPlatformEventMessage3Resp.data()) pldm_msg,
494         sizeof(pollForPlatformEventMessage3Resp));
495     EXPECT_EQ(rc, PLDM_SUCCESS);
496 
497     terminusManager.updateMctpEndpointAvailability(
498         pldm::MctpInfo(10, "", "", 1, std::nullopt), true);
499 
500     EXPECT_CALL(eventManager, processCperEvent(_, _, _, _))
501         .Times(1)
502         .WillRepeatedly(Return(1));
503 
504     // start task to poll event from terminus
505     // should finish immediately
506     stdexec::sync_wait(eventManager.pollForPlatformEventTask(tid, 0x0000));
507 }
508 
TEST(EventManagerNumericEventTest,HandleNormalToUpperWarning)509 TEST(EventManagerNumericEventTest, HandleNormalToUpperWarning)
510 {
511     using namespace pldm::platform_mc;
512     unsigned int callCount = 0;
513     auto handle =
514         [&callCount](pldm::utils::Level level, pldm::utils::Direction direction,
515                      double rawValue, bool newAlarm, bool assert) {
516             callCount++;
517             EXPECT_EQ(rawValue, 10.0);
518             EXPECT_TRUE(newAlarm);
519             EXPECT_TRUE(assert);
520             EXPECT_EQ(level, pldm::utils::Level::WARNING);
521             EXPECT_EQ(direction, pldm::utils::Direction::HIGH);
522             EXPECT_EQ(callCount, 1);
523             return PLDM_SUCCESS;
524         };
525     int rc = triggerNumericSensorThresholdEvent(handle, PLDM_SENSOR_NORMAL,
526                                                 PLDM_SENSOR_UPPERWARNING, 10.0);
527     ASSERT_EQ(rc, PLDM_SUCCESS);
528 }
529 
TEST(EventManagerNumericEventTest,HandleUpperWarningToNormal)530 TEST(EventManagerNumericEventTest, HandleUpperWarningToNormal)
531 {
532     using namespace pldm::platform_mc;
533     unsigned int callCount = 0;
534     auto handle =
535         [&callCount](pldm::utils::Level level, pldm::utils::Direction direction,
536                      double rawValue, bool newAlarm, bool assert) {
537             callCount++;
538             EXPECT_EQ(rawValue, 4.0);
539             EXPECT_FALSE(newAlarm);
540             EXPECT_FALSE(assert);
541             EXPECT_EQ(level, pldm::utils::Level::WARNING);
542             EXPECT_EQ(direction, pldm::utils::Direction::HIGH);
543             EXPECT_EQ(callCount, 1);
544             return PLDM_SUCCESS;
545         };
546     int rc = triggerNumericSensorThresholdEvent(
547         handle, PLDM_SENSOR_UPPERWARNING, PLDM_SENSOR_NORMAL, 4.0);
548     ASSERT_EQ(rc, PLDM_SUCCESS);
549 }
550 
TEST(EventManagerNumericEventTest,HandleNormalToUpperCritical)551 TEST(EventManagerNumericEventTest, HandleNormalToUpperCritical)
552 {
553     using namespace pldm::platform_mc;
554     unsigned int callCount = 0;
555     auto handle =
556         [&callCount](pldm::utils::Level level, pldm::utils::Direction direction,
557                      double rawValue, bool newAlarm, bool assert) {
558             callCount++;
559             EXPECT_EQ(rawValue, 10.0);
560             EXPECT_TRUE(newAlarm);
561             EXPECT_TRUE(assert);
562             if (callCount == 1)
563             {
564                 EXPECT_EQ(level, pldm::utils::Level::WARNING);
565             }
566             else
567             {
568                 EXPECT_EQ(level, pldm::utils::Level::CRITICAL);
569             }
570             EXPECT_EQ(direction, pldm::utils::Direction::HIGH);
571             EXPECT_LE(callCount, 2);
572             return PLDM_SUCCESS;
573         };
574     int rc = triggerNumericSensorThresholdEvent(
575         handle, PLDM_SENSOR_NORMAL, PLDM_SENSOR_UPPERCRITICAL, 10.0);
576     ASSERT_EQ(rc, PLDM_SUCCESS);
577 }
578 
TEST(EventManagerNumericEventTest,HandleUpperCriticalToNormal)579 TEST(EventManagerNumericEventTest, HandleUpperCriticalToNormal)
580 {
581     using namespace pldm::platform_mc;
582     unsigned int callCount = 0;
583     auto handle =
584         [&callCount](pldm::utils::Level level, pldm::utils::Direction direction,
585                      double rawValue, bool newAlarm, bool assert) {
586             callCount++;
587             EXPECT_EQ(rawValue, 10.0);
588             if (callCount == 1)
589             {
590                 // First deasserts critical
591                 EXPECT_EQ(level, pldm::utils::Level::CRITICAL);
592                 EXPECT_FALSE(newAlarm);
593                 EXPECT_FALSE(assert);
594             }
595             else if (callCount == 2)
596             {
597                 // second  asserts warning just before deasserting it.
598                 EXPECT_TRUE(newAlarm);
599                 EXPECT_TRUE(assert);
600                 EXPECT_EQ(level, pldm::utils::Level::WARNING);
601             }
602             else
603             {
604                 // Third and final time we deassert warning.
605                 EXPECT_FALSE(newAlarm);
606                 EXPECT_FALSE(assert);
607                 EXPECT_EQ(level, pldm::utils::Level::WARNING);
608             }
609             EXPECT_EQ(direction, pldm::utils::Direction::HIGH);
610             EXPECT_LE(callCount, 3);
611             return PLDM_SUCCESS;
612         };
613     int rc = triggerNumericSensorThresholdEvent(
614         handle, PLDM_SENSOR_UPPERCRITICAL, PLDM_SENSOR_NORMAL, 10.0);
615     ASSERT_EQ(rc, PLDM_SUCCESS);
616 }
617 
TEST(EventManagerNumericEventTest,HandleNormalToLowerWarning)618 TEST(EventManagerNumericEventTest, HandleNormalToLowerWarning)
619 {
620     using namespace pldm::platform_mc;
621     unsigned int callCount = 0;
622     auto handle =
623         [&callCount](pldm::utils::Level level, pldm::utils::Direction direction,
624                      double rawValue, bool newAlarm, bool assert) {
625             callCount++;
626             EXPECT_EQ(rawValue, 10.0);
627             EXPECT_TRUE(newAlarm);
628             EXPECT_TRUE(assert);
629             EXPECT_EQ(level, pldm::utils::Level::WARNING);
630             EXPECT_EQ(direction, pldm::utils::Direction::LOW);
631             EXPECT_EQ(callCount, 1);
632             return PLDM_SUCCESS;
633         };
634     int rc = triggerNumericSensorThresholdEvent(handle, PLDM_SENSOR_NORMAL,
635                                                 PLDM_SENSOR_LOWERWARNING, 10.0);
636     ASSERT_EQ(rc, PLDM_SUCCESS);
637 }
638 
TEST(EventManagerNumericEventTest,HandleLowerWarningToNormal)639 TEST(EventManagerNumericEventTest, HandleLowerWarningToNormal)
640 {
641     using namespace pldm::platform_mc;
642     unsigned int callCount = 0;
643     auto handle =
644         [&callCount](pldm::utils::Level level, pldm::utils::Direction direction,
645                      double rawValue, bool newAlarm, bool assert) {
646             callCount++;
647             EXPECT_EQ(rawValue, 4.0);
648             EXPECT_FALSE(newAlarm);
649             EXPECT_FALSE(assert);
650             EXPECT_EQ(level, pldm::utils::Level::WARNING);
651             EXPECT_EQ(direction, pldm::utils::Direction::LOW);
652             EXPECT_EQ(callCount, 1);
653             return PLDM_SUCCESS;
654         };
655     int rc = triggerNumericSensorThresholdEvent(
656         handle, PLDM_SENSOR_LOWERWARNING, PLDM_SENSOR_NORMAL, 4.0);
657     ASSERT_EQ(rc, PLDM_SUCCESS);
658 }
659 
TEST(EventManagerNumericEventTest,HandleNormalToLowerCritical)660 TEST(EventManagerNumericEventTest, HandleNormalToLowerCritical)
661 {
662     using namespace pldm::platform_mc;
663     unsigned int callCount = 0;
664     auto handle =
665         [&callCount](pldm::utils::Level level, pldm::utils::Direction direction,
666                      double rawValue, bool newAlarm, bool assert) {
667             callCount++;
668             EXPECT_EQ(rawValue, 10.0);
669             EXPECT_TRUE(newAlarm);
670             EXPECT_TRUE(assert);
671             if (callCount == 1)
672             {
673                 EXPECT_EQ(level, pldm::utils::Level::WARNING);
674             }
675             else
676             {
677                 EXPECT_EQ(level, pldm::utils::Level::CRITICAL);
678             }
679             EXPECT_EQ(direction, pldm::utils::Direction::LOW);
680             EXPECT_LE(callCount, 2);
681             return PLDM_SUCCESS;
682         };
683     int rc = triggerNumericSensorThresholdEvent(
684         handle, PLDM_SENSOR_NORMAL, PLDM_SENSOR_LOWERCRITICAL, 10.0);
685     ASSERT_EQ(rc, PLDM_SUCCESS);
686 }
687 
TEST(EventManagerNumericEventTest,HandleLowerCriticalToNormal)688 TEST(EventManagerNumericEventTest, HandleLowerCriticalToNormal)
689 {
690     using namespace pldm::platform_mc;
691     unsigned int callCount = 0;
692     auto handle =
693         [&callCount](pldm::utils::Level level, pldm::utils::Direction direction,
694                      double rawValue, bool newAlarm, bool assert) {
695             callCount++;
696             EXPECT_EQ(rawValue, 10.0);
697             if (callCount == 1)
698             {
699                 // First deasserts critical
700                 EXPECT_EQ(level, pldm::utils::Level::CRITICAL);
701                 EXPECT_FALSE(newAlarm);
702                 EXPECT_FALSE(assert);
703             }
704             else if (callCount == 2)
705             {
706                 // second  asserts warning just before deasserting it.
707                 EXPECT_TRUE(newAlarm);
708                 EXPECT_TRUE(assert);
709                 EXPECT_EQ(level, pldm::utils::Level::WARNING);
710             }
711             else
712             {
713                 // Third and final time we deassert warning.
714                 EXPECT_FALSE(newAlarm);
715                 EXPECT_FALSE(assert);
716                 EXPECT_EQ(level, pldm::utils::Level::WARNING);
717             }
718             EXPECT_EQ(direction, pldm::utils::Direction::LOW);
719             EXPECT_LE(callCount, 3);
720             return PLDM_SUCCESS;
721         };
722     int rc = triggerNumericSensorThresholdEvent(
723         handle, PLDM_SENSOR_LOWERCRITICAL, PLDM_SENSOR_NORMAL, 10.0);
724     ASSERT_EQ(rc, PLDM_SUCCESS);
725 }
726 
TEST(EventManagerNumericEventTest,HandleLowerCriticalToUpperCritical)727 TEST(EventManagerNumericEventTest, HandleLowerCriticalToUpperCritical)
728 {
729     using namespace pldm::platform_mc;
730     unsigned int callCount = 0;
731     auto handle =
732         [&callCount](pldm::utils::Level level, pldm::utils::Direction direction,
733                      double rawValue, bool newAlarm, bool assert) {
734             callCount++;
735             EXPECT_EQ(rawValue, 10.0);
736             if (callCount == 1)
737             {
738                 // First deasserts critical
739                 EXPECT_EQ(level, pldm::utils::Level::CRITICAL);
740                 EXPECT_FALSE(newAlarm);
741                 EXPECT_FALSE(assert);
742                 EXPECT_EQ(direction, pldm::utils::Direction::LOW);
743             }
744             else if (callCount == 2)
745             {
746                 // second  asserts low-warning just before deasserting it.
747                 EXPECT_TRUE(newAlarm);
748                 EXPECT_TRUE(assert);
749                 EXPECT_EQ(level, pldm::utils::Level::WARNING);
750                 EXPECT_EQ(direction, pldm::utils::Direction::LOW);
751             }
752             else if (callCount == 3)
753             {
754                 // third deasserts low-warning
755                 EXPECT_FALSE(newAlarm);
756                 EXPECT_FALSE(assert);
757                 EXPECT_EQ(level, pldm::utils::Level::WARNING);
758                 EXPECT_EQ(direction, pldm::utils::Direction::LOW);
759             }
760             else if (callCount == 4)
761             {
762                 // forth asserts upper warning
763                 EXPECT_TRUE(newAlarm);
764                 EXPECT_TRUE(assert);
765                 EXPECT_EQ(level, pldm::utils::Level::WARNING);
766                 EXPECT_EQ(direction, pldm::utils::Direction::HIGH);
767             }
768             else
769             {
770                 // fifth, asserts upper critical
771                 EXPECT_TRUE(newAlarm);
772                 EXPECT_TRUE(assert);
773                 EXPECT_EQ(level, pldm::utils::Level::CRITICAL);
774                 EXPECT_EQ(direction, pldm::utils::Direction::HIGH);
775             }
776             EXPECT_LE(callCount, 5);
777             return PLDM_SUCCESS;
778         };
779     int rc = triggerNumericSensorThresholdEvent(
780         handle, PLDM_SENSOR_LOWERCRITICAL, PLDM_SENSOR_UPPERCRITICAL, 10.0);
781     ASSERT_EQ(callCount, 5);
782     ASSERT_EQ(rc, PLDM_SUCCESS);
783 }
784