1 #include "libpldm/base.h" 2 #include "libpldm/entity.h" 3 #include "libpldm/platform.h" 4 5 #include "common/instance_id.hpp" 6 #include "common/types.hpp" 7 #include "mock_event_manager.hpp" 8 #include "mock_terminus_manager.hpp" 9 #include "platform-mc/platform_manager.hpp" 10 #include "platform-mc/terminus_manager.hpp" 11 #include "test/test_instance_id.hpp" 12 13 #include <gtest/gtest.h> 14 15 using ::testing::_; 16 using ::testing::Return; 17 18 class EventManagerTest : public testing::Test 19 { 20 protected: 21 EventManagerTest() : 22 bus(pldm::utils::DBusHandler::getBus()), 23 event(sdeventplus::Event::get_default()), instanceIdDb(), 24 reqHandler(pldmTransport, event, instanceIdDb, false, 25 std::chrono::seconds(1), 2, std::chrono::milliseconds(100)), 26 terminusManager(event, reqHandler, instanceIdDb, termini, nullptr), 27 eventManager(terminusManager, termini), 28 platformManager(terminusManager, termini) 29 {} 30 31 PldmTransport* pldmTransport = nullptr; 32 sdbusplus::bus_t& bus; 33 sdeventplus::Event event; 34 TestInstanceIdDb instanceIdDb; 35 pldm::requester::Handler<pldm::requester::Request> reqHandler; 36 pldm::platform_mc::MockTerminusManager terminusManager; 37 pldm::platform_mc::MockEventManager eventManager; 38 pldm::platform_mc::PlatformManager platformManager; 39 pldm::platform_mc::TerminiMapper termini{}; 40 }; 41 42 TEST_F(EventManagerTest, processNumericSensorEventTest) 43 { 44 #define SENSOR_READING 50 45 #define WARNING_HIGH 45 46 pldm_tid_t tid = 1; 47 termini[tid] = std::make_shared<pldm::platform_mc::Terminus>( 48 tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM); 49 std::vector<uint8_t> pdr1{ 50 0x1, 51 0x0, 52 0x0, 53 0x0, // record handle 54 0x1, // PDRHeaderVersion 55 PLDM_NUMERIC_SENSOR_PDR, // PDRType 56 0x0, 57 0x0, // recordChangeNumber 58 PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH, 59 0, // dataLength 60 0, 61 0, // PLDMTerminusHandle 62 0x1, 63 0x0, // sensorID=1 64 PLDM_ENTITY_POWER_SUPPLY, 65 0, // entityType=Power Supply(120) 66 1, 67 0, // entityInstanceNumber 68 1, 69 0, // containerID=1 70 PLDM_NO_INIT, // sensorInit 71 false, // sensorAuxiliaryNamesPDR 72 PLDM_SENSOR_UNIT_DEGRESS_C, // baseUint(2)=degrees C 73 0, // unitModifier = 0 74 0, // rateUnit 75 0, // baseOEMUnitHandle 76 0, // auxUnit 77 0, // auxUnitModifier 78 0, // auxRateUnit 79 0, // rel 80 0, // auxOEMUnitHandle 81 true, // isLinear 82 PLDM_SENSOR_DATA_SIZE_UINT8, // sensorDataSize 83 0, 84 0, 85 0x80, 86 0x3f, // resolution=1.0 87 0, 88 0, 89 0, 90 0, // offset=0 91 0, 92 0, // accuracy 93 0, // plusTolerance 94 0, // minusTolerance 95 2, // hysteresis = 2 96 0x1b, // supportedThresholds 97 0, // thresholdAndHysteresisVolatility 98 0, 99 0, 100 0x80, 101 0x3f, // stateTransistionInterval=1.0 102 0, 103 0, 104 0x80, 105 0x3f, // updateInverval=1.0 106 255, // maxReadable 107 0, // minReadable 108 PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat 109 0x18, // rangeFieldsupport 110 0, // nominalValue 111 0, // normalMax 112 0, // normalMin 113 WARNING_HIGH, // warningHigh 114 20, // warningLow 115 60, // criticalHigh 116 10, // criticalLow 117 0, // fatalHigh 118 0 // fatalLow 119 }; 120 121 std::vector<uint8_t> pdr2{ 122 0x1, 0x0, 0x0, 123 0x0, // record handle 124 0x1, // PDRHeaderVersion 125 PLDM_ENTITY_AUXILIARY_NAMES_PDR, // PDRType 126 0x1, 127 0x0, // recordChangeNumber 128 0x11, 129 0, // dataLength 130 /* Entity Auxiliary Names PDR Data*/ 131 3, 132 0x80, // entityType system software 133 0x1, 134 0x0, // Entity instance number =1 135 0, 136 0, // Overal system 137 0, // shared Name Count one name only 138 01, // nameStringCount 139 0x65, 0x6e, 0x00, 140 0x00, // Language Tag "en" 141 0x53, 0x00, 0x30, 0x00, 142 0x00 // Entity Name "S0" 143 }; 144 145 // add dummy numeric sensor 146 termini[tid]->pdrs.emplace_back(pdr1); 147 termini[tid]->pdrs.emplace_back(pdr2); 148 termini[tid]->parseTerminusPDRs(); 149 EXPECT_EQ(1, termini[tid]->numericSensors.size()); 150 151 uint8_t platformEventStatus = 0; 152 153 std::vector<uint8_t> eventData{ 154 0x1, 155 0x0, // sensor id 156 PLDM_NUMERIC_SENSOR_STATE, 157 PLDM_SENSOR_UPPERWARNING, 158 PLDM_SENSOR_NORMAL, 159 PLDM_SENSOR_DATA_SIZE_UINT8, 160 SENSOR_READING}; 161 auto rc = eventManager.handlePlatformEvent( 162 tid, 0x00, PLDM_SENSOR_EVENT, eventData.data(), eventData.size()); 163 EXPECT_EQ(PLDM_SUCCESS, rc); 164 EXPECT_EQ(PLDM_EVENT_NO_LOGGING, platformEventStatus); 165 } 166 167 TEST_F(EventManagerTest, SetEventReceiverTest) 168 { 169 // Add terminus 170 auto mappedTid = terminusManager.mapTid(pldm::MctpInfo(10, "", "", 1)); 171 auto tid = mappedTid.value(); 172 termini[tid] = std::make_shared<pldm::platform_mc::Terminus>( 173 tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM); 174 auto terminus = termini[tid]; 175 176 /* Set supported command by terminus */ 177 auto size = PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8); 178 std::vector<uint8_t> pldmCmds(size); 179 uint8_t type = PLDM_PLATFORM; 180 uint8_t cmd = PLDM_GET_PDR_REPOSITORY_INFO; 181 auto idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8); 182 pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8)); 183 cmd = PLDM_GET_PDR; 184 idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8); 185 pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8)); 186 cmd = PLDM_EVENT_MESSAGE_SUPPORTED; 187 idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8); 188 pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8)); 189 cmd = PLDM_EVENT_MESSAGE_BUFFER_SIZE; 190 idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8); 191 pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8)); 192 cmd = PLDM_SET_EVENT_RECEIVER; 193 idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8); 194 pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8)); 195 termini[tid]->setSupportedCommands(pldmCmds); 196 197 EXPECT_EQ(true, termini[tid]->doesSupportCommand(PLDM_PLATFORM, 198 PLDM_SET_EVENT_RECEIVER)); 199 EXPECT_EQ(true, termini[tid]->doesSupportCommand( 200 PLDM_PLATFORM, PLDM_EVENT_MESSAGE_BUFFER_SIZE)); 201 EXPECT_EQ(true, termini[tid]->doesSupportCommand( 202 PLDM_PLATFORM, PLDM_EVENT_MESSAGE_SUPPORTED)); 203 EXPECT_EQ(true, 204 termini[tid]->doesSupportCommand(PLDM_PLATFORM, PLDM_GET_PDR)); 205 EXPECT_EQ(true, termini[tid]->doesSupportCommand( 206 PLDM_PLATFORM, PLDM_GET_PDR_REPOSITORY_INFO)); 207 208 // queue getPDRRepositoryInfo response 209 const size_t getPDRRepositoryInfoLen = 210 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES; 211 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen> 212 getPDRRepositoryInfoResp{ 213 0x0, 0x02, 0x50, PLDM_SUCCESS, 214 0x0, // repositoryState 215 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 216 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // updateTime 217 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 218 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // OEMUpdateTime 219 2, 0x0, 0x0, 0x0, // recordCount 220 0x0, 0x1, 0x0, 0x0, // repositorySize 221 59, 0x0, 0x0, 0x0, // largestRecordSize 222 0x0 // dataTransferHandleTimeout 223 }; 224 auto rc = terminusManager.enqueueResponse( 225 reinterpret_cast<pldm_msg*>(getPDRRepositoryInfoResp.data()), 226 sizeof(getPDRRepositoryInfoResp)); 227 EXPECT_EQ(rc, PLDM_SUCCESS); 228 229 // queue getPDR responses 230 const size_t getPdrRespLen = 81; 231 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{ 232 0x0, 0x02, 0x51, PLDM_SUCCESS, 0x1, 0x0, 0x0, 0x0, // nextRecordHandle 233 0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle 234 0x5, // transferFlag 235 69, 0x0, // responseCount 236 // numeric Sensor PDR 237 0x0, 0x0, 0x0, 238 0x0, // record handle 239 0x1, // PDRHeaderVersion 240 PLDM_NUMERIC_SENSOR_PDR, // PDRType 241 0x0, 242 0x0, // recordChangeNumber 243 PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH + 244 PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH + 245 PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH, 246 0, // dataLength 247 0, 248 0, // PLDMTerminusHandle 249 0x1, 250 0x0, // sensorID=1 251 120, 252 0, // entityType=Power Supply(120) 253 1, 254 0, // entityInstanceNumber 255 0x1, 256 0x0, // containerID=1 257 PLDM_NO_INIT, // sensorInit 258 false, // sensorAuxiliaryNamesPDR 259 PLDM_SENSOR_UNIT_DEGRESS_C, // baseUint(2)=degrees C 260 1, // unitModifier = 1 261 0, // rateUnit 262 0, // baseOEMUnitHandle 263 0, // auxUnit 264 0, // auxUnitModifier 265 0, // auxRateUnit 266 0, // rel 267 0, // auxOEMUnitHandle 268 true, // isLinear 269 PLDM_SENSOR_DATA_SIZE_UINT8, // sensorDataSize 270 0, 0, 0xc0, 271 0x3f, // resolution=1.5 272 0, 0, 0x80, 273 0x3f, // offset=1.0 274 0, 275 0, // accuracy 276 0, // plusTolerance 277 0, // minusTolerance 278 2, // hysteresis 279 0, // supportedThresholds 280 0, // thresholdAndHysteresisVolatility 281 0, 0, 0x80, 282 0x3f, // stateTransistionInterval=1.0 283 0, 0, 0x80, 284 0x3f, // updateInverval=1.0 285 255, // maxReadable 286 0, // minReadable 287 PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat 288 0, // rangeFieldsupport 289 0, // nominalValue 290 0, // normalMax 291 0, // normalMin 292 0, // warningHigh 293 0, // warningLow 294 0, // criticalHigh 295 0, // criticalLow 296 0, // fatalHigh 297 0 // fatalLow 298 }; 299 rc = terminusManager.enqueueResponse( 300 reinterpret_cast<pldm_msg*>(getPdrResp.data()), sizeof(getPdrResp)); 301 EXPECT_EQ(rc, PLDM_SUCCESS); 302 303 const size_t getPdrAuxNameRespLen = 39; 304 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrAuxNameRespLen> 305 getPdrAuxNameResp{ 306 0x0, 0x02, 0x51, PLDM_SUCCESS, 0x0, 0x0, 0x0, 307 0x0, // nextRecordHandle 308 0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle 309 0x5, // transferFlag 310 0x1b, 0x0, // responseCount 311 // Common PDR Header 312 0x1, 0x0, 0x0, 313 0x0, // record handle 314 0x1, // PDRHeaderVersion 315 PLDM_ENTITY_AUXILIARY_NAMES_PDR, // PDRType 316 0x1, 317 0x0, // recordChangeNumber 318 0x11, 319 0, // dataLength 320 /* Entity Auxiliary Names PDR Data*/ 321 3, 322 0x80, // entityType system software 323 0x1, 324 0x0, // Entity instance number =1 325 0, 326 0, // Overal system 327 0, // shared Name Count one name only 328 01, // nameStringCount 329 0x65, 0x6e, 0x00, 330 0x00, // Language Tag "en" 331 0x53, 0x00, 0x30, 0x00, 332 0x00 // Entity Name "S0" 333 }; 334 rc = terminusManager.enqueueResponse( 335 reinterpret_cast<pldm_msg*>(getPdrAuxNameResp.data()), 336 sizeof(getPdrAuxNameResp)); 337 EXPECT_EQ(rc, PLDM_SUCCESS); 338 339 // queue eventMessageBufferSize response(bufferSize=32) 340 const size_t eventMessageBufferSizeRespLen = 3; 341 std::array<uint8_t, sizeof(pldm_msg_hdr) + eventMessageBufferSizeRespLen> 342 eventMessageBufferSizeResp{0x0, 0x02, 0x0d, PLDM_SUCCESS, 32, 0}; 343 rc = terminusManager.enqueueResponse( 344 reinterpret_cast<pldm_msg*>(eventMessageBufferSizeResp.data()), 345 sizeof(eventMessageBufferSizeResp)); 346 EXPECT_EQ(rc, PLDM_SUCCESS); 347 348 // queue eventMessageSupported response 349 const size_t eventMessageSupportedLen = 7; 350 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES; 351 std::array<uint8_t, sizeof(pldm_msg_hdr) + eventMessageSupportedLen> 352 eventMessageSupportedResp{0x0, 0x02, 0x0c, PLDM_SUCCESS, 353 0x0, // synchronyConfiguration 354 0x06, // synchronyConfigurationSupported 355 3, // numberEventClassReturned 356 0x0, 0x5, 0xfa}; 357 rc = terminusManager.enqueueResponse( 358 reinterpret_cast<pldm_msg*>(eventMessageSupportedResp.data()), 359 sizeof(eventMessageSupportedResp)); 360 EXPECT_EQ(rc, PLDM_SUCCESS); 361 362 // queue SetEventReceiver response 363 const size_t SetEventReceiverLen = 1; 364 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES; 365 std::array<uint8_t, sizeof(pldm_msg_hdr) + SetEventReceiverLen> 366 SetEventReceiverResp{0x0, 0x02, 0x04, PLDM_SUCCESS}; 367 rc = terminusManager.enqueueResponse( 368 reinterpret_cast<pldm_msg*>(SetEventReceiverResp.data()), 369 sizeof(SetEventReceiverResp)); 370 EXPECT_EQ(rc, PLDM_SUCCESS); 371 372 // should finish immediately 373 stdexec::sync_wait(platformManager.initTerminus()); 374 EXPECT_EQ(true, terminus->initialized); 375 EXPECT_EQ(32, terminus->maxBufferSize); 376 EXPECT_EQ(0x06, terminus->synchronyConfigurationSupported.byte); 377 EXPECT_EQ(2, terminus->pdrs.size()); 378 EXPECT_EQ(1, terminus->numericSensors.size()); 379 } 380 381 TEST_F(EventManagerTest, updateAvailableState) 382 { 383 pldm_tid_t tid = 1; 384 eventManager.updateAvailableState(tid, true); 385 EXPECT_EQ(true, eventManager.getAvailableState(tid)); 386 eventManager.updateAvailableState(tid, false); 387 EXPECT_EQ(false, eventManager.getAvailableState(tid)); 388 eventManager.updateAvailableState(2, false); 389 EXPECT_EQ(false, eventManager.getAvailableState(tid)); 390 } 391