1 #include "common/instance_id.hpp" 2 #include "mock_terminus_manager.hpp" 3 #include "platform-mc/platform_manager.hpp" 4 #include "test/test_instance_id.hpp" 5 6 #include <sdeventplus/event.hpp> 7 8 #include <bitset> 9 10 #include <gtest/gtest.h> 11 12 class PlatformManagerTest : public testing::Test 13 { 14 protected: 15 PlatformManagerTest() : 16 bus(pldm::utils::DBusHandler::getBus()), 17 event(sdeventplus::Event::get_default()), instanceIdDb(), 18 reqHandler(pldmTransport, event, instanceIdDb, false, 19 std::chrono::seconds(1), 2, std::chrono::milliseconds(100)), 20 mockTerminusManager(event, reqHandler, instanceIdDb, termini, nullptr), 21 platformManager(mockTerminusManager, termini) 22 {} 23 24 PldmTransport* pldmTransport = nullptr; 25 sdbusplus::bus_t& bus; 26 sdeventplus::Event event; 27 TestInstanceIdDb instanceIdDb; 28 pldm::requester::Handler<pldm::requester::Request> reqHandler; 29 pldm::platform_mc::MockTerminusManager mockTerminusManager; 30 pldm::platform_mc::PlatformManager platformManager; 31 std::map<pldm_tid_t, std::shared_ptr<pldm::platform_mc::Terminus>> termini; 32 }; 33 34 TEST_F(PlatformManagerTest, initTerminusTest) 35 { 36 // Add terminus 37 auto mappedTid = mockTerminusManager.mapTid(pldm::MctpInfo(10, "", "", 1)); 38 auto tid = mappedTid.value(); 39 termini[tid] = std::make_shared<pldm::platform_mc::Terminus>( 40 tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM); 41 auto terminus = termini[tid]; 42 43 /* Set supported command by terminus */ 44 auto size = PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8); 45 std::vector<uint8_t> pldmCmds(size); 46 uint8_t type = PLDM_PLATFORM; 47 uint8_t cmd = PLDM_GET_PDR; 48 auto idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8); 49 pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8)); 50 cmd = PLDM_GET_PDR_REPOSITORY_INFO; 51 idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8); 52 pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8)); 53 termini[tid]->setSupportedCommands(pldmCmds); 54 55 // queue getPDRRepositoryInfo response 56 const size_t getPDRRepositoryInfoLen = 57 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES; 58 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen> 59 getPDRRepositoryInfoResp{ 60 0x0, 0x02, 0x50, PLDM_SUCCESS, 61 0x0, // repositoryState 62 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 63 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // updateTime 64 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 65 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // OEMUpdateTime 66 1, 0x0, 0x0, 0x0, // recordCount 67 0x0, 0x1, 0x0, 0x0, // repositorySize 68 59, 0x0, 0x0, 0x0, // largestRecordSize 69 0x0 // dataTransferHandleTimeout 70 }; 71 auto rc = mockTerminusManager.enqueueResponse( 72 reinterpret_cast<pldm_msg*>(getPDRRepositoryInfoResp.data()), 73 sizeof(getPDRRepositoryInfoResp)); 74 EXPECT_EQ(rc, PLDM_SUCCESS); 75 76 // queue getPDR responses 77 const size_t getPdrRespLen = 81; 78 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{ 79 0x0, 0x02, 0x51, PLDM_SUCCESS, 0x0, 0x0, 0x0, 0x0, // nextRecordHandle 80 0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle 81 0x5, // transferFlag 82 69, 0x0, // responseCount 83 // numeric Sensor PDR 84 0x1, 0x0, 0x0, 85 0x0, // record handle 86 0x1, // PDRHeaderVersion 87 PLDM_NUMERIC_SENSOR_PDR, // PDRType 88 0x0, 89 0x0, // recordChangeNumber 90 PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH + 91 PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH + 92 PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH, 93 0, // dataLength 94 0, 95 0, // PLDMTerminusHandle 96 0x1, 97 0x0, // sensorID=1 98 120, 99 0, // entityType=Power Supply(120) 100 1, 101 0, // entityInstanceNumber 102 0x1, 103 0x0, // containerID=1 104 PLDM_NO_INIT, // sensorInit 105 false, // sensorAuxiliaryNamesPDR 106 PLDM_SENSOR_UNIT_DEGRESS_C, // baseUint(2)=degrees C 107 1, // unitModifier = 1 108 0, // rateUnit 109 0, // baseOEMUnitHandle 110 0, // auxUnit 111 0, // auxUnitModifier 112 0, // auxRateUnit 113 0, // rel 114 0, // auxOEMUnitHandle 115 true, // isLinear 116 PLDM_SENSOR_DATA_SIZE_UINT8, // sensorDataSize 117 0, 0, 0xc0, 118 0x3f, // resolution=1.5 119 0, 0, 0x80, 120 0x3f, // offset=1.0 121 0, 122 0, // accuracy 123 0, // plusTolerance 124 0, // minusTolerance 125 2, // hysteresis 126 0, // supportedThresholds 127 0, // thresholdAndHysteresisVolatility 128 0, 0, 0x80, 129 0x3f, // stateTransistionInterval=1.0 130 0, 0, 0x80, 131 0x3f, // updateInverval=1.0 132 255, // maxReadable 133 0, // minReadable 134 PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat 135 0, // rangeFieldsupport 136 0, // nominalValue 137 0, // normalMax 138 0, // normalMin 139 0, // warningHigh 140 0, // warningLow 141 0, // criticalHigh 142 0, // criticalLow 143 0, // fatalHigh 144 0 // fatalLow 145 }; 146 rc = mockTerminusManager.enqueueResponse( 147 reinterpret_cast<pldm_msg*>(getPdrResp.data()), sizeof(getPdrResp)); 148 EXPECT_EQ(rc, PLDM_SUCCESS); 149 150 stdexec::sync_wait(platformManager.initTerminus()); 151 EXPECT_EQ(true, terminus->initialized); 152 EXPECT_EQ(1, terminus->pdrs.size()); 153 } 154 155 TEST_F(PlatformManagerTest, parseTerminusNameTest) 156 { 157 // Add terminus 158 auto mappedTid = mockTerminusManager.mapTid(pldm::MctpInfo(10, "", "", 1)); 159 auto tid = mappedTid.value(); 160 termini[tid] = std::make_shared<pldm::platform_mc::Terminus>( 161 tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM); 162 auto terminus = termini[tid]; 163 164 /* Set supported command by terminus */ 165 auto size = PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8); 166 std::vector<uint8_t> pldmCmds(size); 167 uint8_t type = PLDM_PLATFORM; 168 uint8_t cmd = PLDM_GET_PDR; 169 auto idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8); 170 pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8)); 171 cmd = PLDM_GET_PDR_REPOSITORY_INFO; 172 idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8); 173 pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8)); 174 termini[tid]->setSupportedCommands(pldmCmds); 175 176 // queue getPDRRepositoryInfo response 177 const size_t getPDRRepositoryInfoLen = 178 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES; 179 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen> 180 getPDRRepositoryInfoResp{ 181 0x0, 0x02, 0x50, PLDM_SUCCESS, 182 0x0, // repositoryState 183 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 184 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // updateTime 185 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 186 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // OEMUpdateTime 187 2, 0x0, 0x0, 0x0, // recordCount 188 0x0, 0x1, 0x0, 0x0, // repositorySize 189 59, 0x0, 0x0, 0x0, // largestRecordSize 190 0x0 // dataTransferHandleTimeout 191 }; 192 auto rc = mockTerminusManager.enqueueResponse( 193 reinterpret_cast<pldm_msg*>(getPDRRepositoryInfoResp.data()), 194 sizeof(getPDRRepositoryInfoResp)); 195 EXPECT_EQ(rc, PLDM_SUCCESS); 196 197 // queue getPDR responses 198 const size_t getPdrRespLen = 81; 199 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{ 200 0x0, 0x02, 0x51, PLDM_SUCCESS, 0x1, 0x0, 0x0, 0x0, // nextRecordHandle 201 0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle 202 0x5, // transferFlag 203 69, 0x0, // responseCount 204 // numeric Sensor PDR 205 0x0, 0x0, 0x0, 206 0x0, // record handle 207 0x1, // PDRHeaderVersion 208 PLDM_NUMERIC_SENSOR_PDR, // PDRType 209 0x0, 210 0x0, // recordChangeNumber 211 PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH + 212 PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH + 213 PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH, 214 0, // dataLength 215 0, 216 0, // PLDMTerminusHandle 217 0x1, 218 0x0, // sensorID=1 219 120, 220 0, // entityType=Power Supply(120) 221 1, 222 0, // entityInstanceNumber 223 0x1, 224 0x0, // containerID=1 225 PLDM_NO_INIT, // sensorInit 226 false, // sensorAuxiliaryNamesPDR 227 PLDM_SENSOR_UNIT_DEGRESS_C, // baseUint(2)=degrees C 228 1, // unitModifier = 1 229 0, // rateUnit 230 0, // baseOEMUnitHandle 231 0, // auxUnit 232 0, // auxUnitModifier 233 0, // auxRateUnit 234 0, // rel 235 0, // auxOEMUnitHandle 236 true, // isLinear 237 PLDM_SENSOR_DATA_SIZE_UINT8, // sensorDataSize 238 0, 0, 0xc0, 239 0x3f, // resolution=1.5 240 0, 0, 0x80, 241 0x3f, // offset=1.0 242 0, 243 0, // accuracy 244 0, // plusTolerance 245 0, // minusTolerance 246 2, // hysteresis 247 0, // supportedThresholds 248 0, // thresholdAndHysteresisVolatility 249 0, 0, 0x80, 250 0x3f, // stateTransistionInterval=1.0 251 0, 0, 0x80, 252 0x3f, // updateInverval=1.0 253 255, // maxReadable 254 0, // minReadable 255 PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat 256 0, // rangeFieldsupport 257 0, // nominalValue 258 0, // normalMax 259 0, // normalMin 260 0, // warningHigh 261 0, // warningLow 262 0, // criticalHigh 263 0, // criticalLow 264 0, // fatalHigh 265 0 // fatalLow 266 }; 267 rc = mockTerminusManager.enqueueResponse( 268 reinterpret_cast<pldm_msg*>(getPdrResp.data()), sizeof(getPdrResp)); 269 EXPECT_EQ(rc, PLDM_SUCCESS); 270 271 const size_t getPdrAuxNameRespLen = 39; 272 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrAuxNameRespLen> 273 getPdrAuxNameResp{ 274 0x0, 0x02, 0x51, PLDM_SUCCESS, 0x0, 0x0, 0x0, 275 0x0, // nextRecordHandle 276 0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle 277 0x5, // transferFlag 278 0x1b, 0x0, // responseCount 279 // Common PDR Header 280 0x1, 0x0, 0x0, 281 0x0, // record handle 282 0x1, // PDRHeaderVersion 283 PLDM_ENTITY_AUXILIARY_NAMES_PDR, // PDRType 284 0x1, 285 0x0, // recordChangeNumber 286 0x11, 287 0, // dataLength 288 /* Entity Auxiliary Names PDR Data*/ 289 3, 290 0x80, // entityType system software 291 0x1, 292 0x0, // Entity instance number =1 293 0, 294 0, // Overal system 295 0, // shared Name Count one name only 296 01, // nameStringCount 297 0x65, 0x6e, 0x00, 298 0x00, // Language Tag "en" 299 0x53, 0x00, 0x30, 0x00, 300 0x00 // Entity Name "S0" 301 }; 302 rc = mockTerminusManager.enqueueResponse( 303 reinterpret_cast<pldm_msg*>(getPdrAuxNameResp.data()), 304 sizeof(getPdrAuxNameResp)); 305 EXPECT_EQ(rc, PLDM_SUCCESS); 306 307 stdexec::sync_wait(platformManager.initTerminus()); 308 EXPECT_EQ(true, terminus->initialized); 309 EXPECT_EQ(2, terminus->pdrs.size()); 310 EXPECT_EQ("S0", terminus->getTerminusName()); 311 } 312 313 TEST_F(PlatformManagerTest, initTerminusDontSupportGetPDRTest) 314 { 315 // Add terminus 316 auto mappedTid = mockTerminusManager.mapTid(pldm::MctpInfo(10, "", "", 1)); 317 auto tid = mappedTid.value(); 318 termini[tid] = std::make_shared<pldm::platform_mc::Terminus>( 319 tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM); 320 auto terminus = termini[tid]; 321 322 /* Set supported command by terminus */ 323 auto size = PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8); 324 std::vector<uint8_t> pldmCmds(size); 325 uint8_t type = PLDM_PLATFORM; 326 uint8_t cmd = PLDM_GET_PDR_REPOSITORY_INFO; 327 auto idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8); 328 pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8)); 329 termini[tid]->setSupportedCommands(pldmCmds); 330 331 // queue getPDRRepositoryInfo response 332 const size_t getPDRRepositoryInfoLen = 333 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES; 334 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen> 335 getPDRRepositoryInfoResp{ 336 0x0, 0x02, 0x50, PLDM_SUCCESS, 337 0x0, // repositoryState 338 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 339 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // updateTime 340 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 341 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // OEMUpdateTime 342 1, 0x0, 0x0, 0x0, // recordCount 343 0x0, 0x1, 0x0, 0x0, // repositorySize 344 59, 0x0, 0x0, 0x0, // largestRecordSize 345 0x0 // dataTransferHandleTimeout 346 }; 347 auto rc = mockTerminusManager.enqueueResponse( 348 reinterpret_cast<pldm_msg*>(getPDRRepositoryInfoResp.data()), 349 sizeof(getPDRRepositoryInfoResp)); 350 EXPECT_EQ(rc, PLDM_SUCCESS); 351 352 // queue getPDR responses 353 const size_t getPdrRespLen = 81; 354 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{ 355 0x0, 0x02, 0x51, PLDM_SUCCESS, 0x0, 0x0, 0x0, 0x0, // nextRecordHandle 356 0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle 357 0x5, // transferFlag 358 69, 0x0, // responseCount 359 // numeric Sensor PDR 360 0x1, 0x0, 0x0, 361 0x0, // record handle 362 0x1, // PDRHeaderVersion 363 PLDM_NUMERIC_SENSOR_PDR, // PDRType 364 0x0, 365 0x0, // recordChangeNumber 366 PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH + 367 PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH + 368 PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH, 369 0, // dataLength 370 0, 371 0, // PLDMTerminusHandle 372 0x1, 373 0x0, // sensorID=1 374 120, 375 0, // entityType=Power Supply(120) 376 1, 377 0, // entityInstanceNumber 378 0x1, 379 0x0, // containerID=1 380 PLDM_NO_INIT, // sensorInit 381 false, // sensorAuxiliaryNamesPDR 382 PLDM_SENSOR_UNIT_DEGRESS_C, // baseUint(2)=degrees C 383 1, // unitModifier = 1 384 0, // rateUnit 385 0, // baseOEMUnitHandle 386 0, // auxUnit 387 0, // auxUnitModifier 388 0, // auxRateUnit 389 0, // rel 390 0, // auxOEMUnitHandle 391 true, // isLinear 392 PLDM_SENSOR_DATA_SIZE_UINT8, // sensorDataSize 393 0, 0, 0xc0, 394 0x3f, // resolution=1.5 395 0, 0, 0x80, 396 0x3f, // offset=1.0 397 0, 398 0, // accuracy 399 0, // plusTolerance 400 0, // minusTolerance 401 2, // hysteresis 402 0, // supportedThresholds 403 0, // thresholdAndHysteresisVolatility 404 0, 0, 0x80, 405 0x3f, // stateTransistionInterval=1.0 406 0, 0, 0x80, 407 0x3f, // updateInverval=1.0 408 255, // maxReadable 409 0, // minReadable 410 PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat 411 0, // rangeFieldsupport 412 0, // nominalValue 413 0, // normalMax 414 0, // normalMin 415 0, // warningHigh 416 0, // warningLow 417 0, // criticalHigh 418 0, // criticalLow 419 0, // fatalHigh 420 0 // fatalLow 421 }; 422 rc = mockTerminusManager.enqueueResponse( 423 reinterpret_cast<pldm_msg*>(getPdrResp.data()), sizeof(getPdrResp)); 424 EXPECT_EQ(rc, PLDM_SUCCESS); 425 426 stdexec::sync_wait(platformManager.initTerminus()); 427 EXPECT_EQ(true, terminus->initialized); 428 EXPECT_EQ(0, terminus->pdrs.size()); 429 } 430 431 TEST_F(PlatformManagerTest, negativeInitTerminusTest1) 432 { 433 // terminus doesn't Type2 support 434 auto mappedTid = mockTerminusManager.mapTid(pldm::MctpInfo(10, "", "", 1)); 435 auto tid = mappedTid.value(); 436 termini[tid] = 437 std::make_shared<pldm::platform_mc::Terminus>(tid, 1 << PLDM_BASE); 438 auto terminus = termini[tid]; 439 440 stdexec::sync_wait(platformManager.initTerminus()); 441 EXPECT_EQ(true, terminus->initialized); 442 EXPECT_EQ(0, terminus->pdrs.size()); 443 } 444 445 TEST_F(PlatformManagerTest, negativeInitTerminusTest2) 446 { 447 // terminus responses error 448 auto mappedTid = mockTerminusManager.mapTid(pldm::MctpInfo(10, "", "", 1)); 449 auto tid = mappedTid.value(); 450 termini[tid] = std::make_shared<pldm::platform_mc::Terminus>( 451 tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM); 452 auto terminus = termini[tid]; 453 454 // queue getPDRRepositoryInfo response cc=PLDM_ERROR 455 const size_t getPDRRepositoryInfoLen = 1; 456 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen> 457 getPDRRepositoryInfoResp{0x0, 0x02, 0x50, PLDM_ERROR}; 458 auto rc = mockTerminusManager.enqueueResponse( 459 reinterpret_cast<pldm_msg*>(getPDRRepositoryInfoResp.data()), 460 sizeof(getPDRRepositoryInfoResp)); 461 EXPECT_EQ(rc, PLDM_SUCCESS); 462 463 // queue getPDR responses cc=PLDM_ERROR 464 const size_t getPdrRespLen = 1; 465 std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{ 466 0x0, 0x02, 0x51, PLDM_ERROR}; 467 rc = mockTerminusManager.enqueueResponse( 468 reinterpret_cast<pldm_msg*>(getPdrResp.data()), sizeof(getPdrResp)); 469 EXPECT_EQ(rc, PLDM_SUCCESS); 470 471 stdexec::sync_wait(platformManager.initTerminus()); 472 EXPECT_EQ(true, terminus->initialized); 473 EXPECT_EQ(0, terminus->pdrs.size()); 474 } 475