| Matt Spinler | 97f7abc | 2019-11-06 09:40:23 -0600 | [diff] [blame] | 1 | /** | 
 | 2 |  * Copyright © 2019 IBM Corporation | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *     http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
| Matt Spinler | 6c9662c | 2019-10-09 11:27:20 -0500 | [diff] [blame] | 16 | #include "extensions/openpower-pels/callout.hpp" | 
 | 17 | #include "pel_utils.hpp" | 
 | 18 |  | 
 | 19 | #include <gtest/gtest.h> | 
 | 20 |  | 
 | 21 | using namespace openpower::pels; | 
 | 22 | using namespace openpower::pels::src; | 
 | 23 |  | 
 | 24 | // Unflatten the callout section with all three substructures | 
 | 25 | TEST(CalloutTest, TestUnflattenAllSubstructures) | 
 | 26 | { | 
 | 27 |     // The base data. | 
 | 28 |     std::vector<uint8_t> data{ | 
 | 29 |         0xFF, 0x2F, 'H', 8, // size, flags, priority, LC length | 
 | 30 |         'U',  '1',  '2', '-', 'P', '1', 0x00, 0x00 // LC | 
 | 31 |     }; | 
 | 32 |  | 
 | 33 |     auto fruIdentity = srcDataFactory(TestSRCType::fruIdentityStructure); | 
 | 34 |     auto pceIdentity = srcDataFactory(TestSRCType::pceIdentityStructure); | 
 | 35 |     auto mrus = srcDataFactory(TestSRCType::mruStructure); | 
 | 36 |  | 
 | 37 |     // Add all 3 substructures | 
 | 38 |     data.insert(data.end(), fruIdentity.begin(), fruIdentity.end()); | 
 | 39 |     data.insert(data.end(), pceIdentity.begin(), pceIdentity.end()); | 
 | 40 |     data.insert(data.end(), mrus.begin(), mrus.end()); | 
 | 41 |  | 
 | 42 |     // The final size | 
 | 43 |     data[0] = data.size(); | 
 | 44 |  | 
 | 45 |     Stream stream{data}; | 
 | 46 |     Callout callout{stream}; | 
 | 47 |  | 
 | 48 |     EXPECT_EQ(callout.flattenedSize(), data.size()); | 
 | 49 |     EXPECT_EQ(callout.priority(), 'H'); | 
 | 50 |     EXPECT_EQ(callout.locationCode(), "U12-P1"); | 
 | 51 |  | 
 | 52 |     // Spot check the 3 substructures | 
 | 53 |     EXPECT_TRUE(callout.fruIdentity()); | 
 | 54 |     EXPECT_EQ(callout.fruIdentity()->getSN(), "123456789ABC"); | 
 | 55 |  | 
 | 56 |     EXPECT_TRUE(callout.pceIdentity()); | 
 | 57 |     EXPECT_EQ(callout.pceIdentity()->enclosureName(), "PCENAME12"); | 
 | 58 |  | 
 | 59 |     EXPECT_TRUE(callout.mru()); | 
 | 60 |     EXPECT_EQ(callout.mru()->mrus().size(), 4); | 
 | 61 |     EXPECT_EQ(callout.mru()->mrus().at(3).id, 0x04040404); | 
 | 62 |  | 
 | 63 |     // Now flatten | 
 | 64 |     std::vector<uint8_t> newData; | 
 | 65 |     Stream newStream{newData}; | 
 | 66 |  | 
 | 67 |     callout.flatten(newStream); | 
 | 68 |     EXPECT_EQ(data, newData); | 
 | 69 | } | 
 | 70 |  | 
 | 71 | TEST(CalloutTest, TestUnflattenOneSubstructure) | 
 | 72 | { | 
 | 73 |     std::vector<uint8_t> data{ | 
 | 74 |         0xFF, 0x28, 'H', 0x08, // size, flags, priority, LC length | 
 | 75 |         'U',  '1',  '2', '-',  'P', '1', 0x00, 0x00 // LC | 
 | 76 |     }; | 
 | 77 |  | 
 | 78 |     auto fruIdentity = srcDataFactory(TestSRCType::fruIdentityStructure); | 
 | 79 |  | 
 | 80 |     data.insert(data.end(), fruIdentity.begin(), fruIdentity.end()); | 
 | 81 |  | 
 | 82 |     // The final size | 
 | 83 |     data[0] = data.size(); | 
 | 84 |  | 
 | 85 |     Stream stream{data}; | 
 | 86 |     Callout callout{stream}; | 
 | 87 |  | 
 | 88 |     EXPECT_EQ(callout.flattenedSize(), data.size()); | 
 | 89 |  | 
 | 90 |     // Spot check the substructure | 
 | 91 |     EXPECT_TRUE(callout.fruIdentity()); | 
 | 92 |     EXPECT_EQ(callout.fruIdentity()->getSN(), "123456789ABC"); | 
 | 93 |  | 
 | 94 |     // Not present | 
 | 95 |     EXPECT_FALSE(callout.pceIdentity()); | 
 | 96 |     EXPECT_FALSE(callout.mru()); | 
 | 97 |  | 
 | 98 |     // Now flatten | 
 | 99 |     std::vector<uint8_t> newData; | 
 | 100 |     Stream newStream{newData}; | 
 | 101 |  | 
 | 102 |     callout.flatten(newStream); | 
 | 103 |     EXPECT_EQ(data, newData); | 
 | 104 | } | 
 | 105 |  | 
 | 106 | TEST(CalloutTest, TestUnflattenTwoSubstructures) | 
 | 107 | { | 
 | 108 |     std::vector<uint8_t> data{ | 
 | 109 |         0xFF, 0x2B, 'H', 0x08, // size, flags, priority, LC length | 
 | 110 |         'U',  '1',  '2', '-',  'P', '1', 0x00, 0x00 // LC | 
 | 111 |     }; | 
 | 112 |  | 
 | 113 |     auto fruIdentity = srcDataFactory(TestSRCType::fruIdentityStructure); | 
 | 114 |     auto pceIdentity = srcDataFactory(TestSRCType::pceIdentityStructure); | 
 | 115 |  | 
 | 116 |     data.insert(data.end(), fruIdentity.begin(), fruIdentity.end()); | 
 | 117 |     data.insert(data.end(), pceIdentity.begin(), pceIdentity.end()); | 
 | 118 |  | 
 | 119 |     // The final size | 
 | 120 |     data[0] = data.size(); | 
 | 121 |  | 
 | 122 |     Stream stream{data}; | 
 | 123 |     Callout callout{stream}; | 
 | 124 |  | 
 | 125 |     EXPECT_EQ(callout.flattenedSize(), data.size()); | 
 | 126 |  | 
 | 127 |     // Spot check the 2 substructures | 
 | 128 |     EXPECT_TRUE(callout.fruIdentity()); | 
 | 129 |     EXPECT_EQ(callout.fruIdentity()->getSN(), "123456789ABC"); | 
 | 130 |  | 
 | 131 |     EXPECT_TRUE(callout.pceIdentity()); | 
 | 132 |     EXPECT_EQ(callout.pceIdentity()->enclosureName(), "PCENAME12"); | 
 | 133 |  | 
 | 134 |     // Not present | 
 | 135 |     EXPECT_FALSE(callout.mru()); | 
 | 136 |  | 
 | 137 |     // Now flatten | 
 | 138 |     std::vector<uint8_t> newData; | 
 | 139 |     Stream newStream{newData}; | 
 | 140 |  | 
 | 141 |     callout.flatten(newStream); | 
 | 142 |     EXPECT_EQ(data, newData); | 
 | 143 | } | 
 | 144 |  | 
 | 145 | TEST(CalloutTest, TestNoLocationCode) | 
 | 146 | { | 
 | 147 |     std::vector<uint8_t> data{ | 
 | 148 |         0xFF, 0x2B, 'H', 0x00 // size, flags, priority, LC length | 
 | 149 |     }; | 
 | 150 |  | 
 | 151 |     auto fruIdentity = srcDataFactory(TestSRCType::fruIdentityStructure); | 
 | 152 |     data.insert(data.end(), fruIdentity.begin(), fruIdentity.end()); | 
 | 153 |  | 
 | 154 |     // The final size | 
 | 155 |     data[0] = data.size(); | 
 | 156 |  | 
 | 157 |     Stream stream{data}; | 
 | 158 |     Callout callout{stream}; | 
 | 159 |  | 
 | 160 |     EXPECT_TRUE(callout.locationCode().empty()); | 
 | 161 | } | 
| Matt Spinler | 0a5d10c | 2020-03-13 12:54:02 -0500 | [diff] [blame] | 162 |  | 
 | 163 | // Create a callout object by passing in the hardware fields to add | 
 | 164 | TEST(CalloutTest, TestHardwareCallout) | 
 | 165 | { | 
 | 166 |     constexpr size_t fruIdentitySize = 28; | 
 | 167 |  | 
 | 168 |     { | 
 | 169 |         Callout callout{CalloutPriority::high, "U99-42.5-P1-C2-E1", "1234567", | 
 | 170 |                         "ABCD", "123456789ABC"}; | 
 | 171 |  | 
 | 172 |         // size/flags/pri/locsize fields + | 
 | 173 |         // rounded up location code length + | 
 | 174 |         // FRUIdentity size | 
 | 175 |         size_t size = 4 + 20 + fruIdentitySize; | 
 | 176 |  | 
 | 177 |         EXPECT_EQ(callout.flags(), | 
 | 178 |                   Callout::calloutType | Callout::fruIdentIncluded); | 
 | 179 |  | 
 | 180 |         EXPECT_EQ(callout.flattenedSize(), size); | 
 | 181 |         EXPECT_EQ(callout.priority(), 'H'); | 
 | 182 |         EXPECT_EQ(callout.locationCode(), "U99-42.5-P1-C2-E1"); | 
 | 183 |         EXPECT_EQ(callout.locationCodeSize(), 20); | 
 | 184 |  | 
 | 185 |         auto& fru = callout.fruIdentity(); | 
 | 186 |         EXPECT_EQ(fru->getPN().value(), "1234567"); | 
 | 187 |         EXPECT_EQ(fru->getCCIN().value(), "ABCD"); | 
 | 188 |         EXPECT_EQ(fru->getSN().value(), "123456789ABC"); | 
 | 189 |     } | 
 | 190 |  | 
 | 191 |     { | 
 | 192 |         // A 3B location code, plus null = 4 | 
 | 193 |         Callout callout{CalloutPriority::high, "123", "1234567", "ABCD", | 
 | 194 |                         "123456789ABC"}; | 
 | 195 |  | 
 | 196 |         size_t size = 4 + 4 + fruIdentitySize; | 
 | 197 |         EXPECT_EQ(callout.locationCodeSize(), 4); | 
 | 198 |         EXPECT_EQ(callout.flattenedSize(), size); | 
 | 199 |         EXPECT_EQ(callout.locationCode(), "123"); | 
 | 200 |     } | 
 | 201 |  | 
 | 202 |     { | 
 | 203 |         // A 4B location code, plus null = 5, then pad to 8 | 
 | 204 |         Callout callout{CalloutPriority::high, "1234", "1234567", "ABCD", | 
 | 205 |                         "123456789ABC"}; | 
 | 206 |  | 
 | 207 |         size_t size = 4 + 8 + fruIdentitySize; | 
 | 208 |         EXPECT_EQ(callout.locationCodeSize(), 8); | 
 | 209 |         EXPECT_EQ(callout.flattenedSize(), size); | 
 | 210 |         EXPECT_EQ(callout.locationCode(), "1234"); | 
 | 211 |     } | 
 | 212 |  | 
 | 213 |     { | 
 | 214 |         // A truncated location code (80 is max size, including null) | 
 | 215 |         std::string locCode(81, 'L'); | 
 | 216 |         Callout callout{CalloutPriority::high, locCode, "1234567", "ABCD", | 
 | 217 |                         "123456789ABC"}; | 
 | 218 |  | 
 | 219 |         size_t size = 4 + 80 + fruIdentitySize; | 
 | 220 |         EXPECT_EQ(callout.locationCodeSize(), 80); | 
 | 221 |         EXPECT_EQ(callout.flattenedSize(), size); | 
 | 222 |  | 
 | 223 |         // take off 1 to get to 80, and another for the null | 
 | 224 |         locCode = locCode.substr(0, locCode.size() - 2); | 
 | 225 |         EXPECT_EQ(callout.locationCode(), locCode); | 
 | 226 |     } | 
 | 227 |  | 
 | 228 |     { | 
 | 229 |         // A truncated location code by 1 because of the null | 
 | 230 |         std::string locCode(80, 'L'); | 
 | 231 |         Callout callout{CalloutPriority::high, locCode, "1234567", "ABCD", | 
 | 232 |                         "123456789ABC"}; | 
 | 233 |  | 
 | 234 |         size_t size = 4 + 80 + fruIdentitySize; | 
 | 235 |         EXPECT_EQ(callout.locationCodeSize(), 80); | 
 | 236 |         EXPECT_EQ(callout.flattenedSize(), size); | 
 | 237 |  | 
 | 238 |         locCode.pop_back(); | 
 | 239 |         EXPECT_EQ(callout.locationCode(), locCode); | 
 | 240 |     } | 
 | 241 |  | 
 | 242 |     { | 
 | 243 |         // Max size location code | 
 | 244 |         std::string locCode(79, 'L'); | 
 | 245 |         Callout callout{CalloutPriority::low, locCode, "1234567", "ABCD", | 
 | 246 |                         "123456789ABC"}; | 
 | 247 |  | 
 | 248 |         size_t size = 4 + 80 + fruIdentitySize; | 
 | 249 |         EXPECT_EQ(callout.locationCodeSize(), 80); | 
 | 250 |         EXPECT_EQ(callout.flattenedSize(), size); | 
 | 251 |  | 
 | 252 |         EXPECT_EQ(callout.locationCode(), locCode); | 
 | 253 |  | 
 | 254 |         // How about we flatten/unflatten this last one | 
 | 255 |         std::vector<uint8_t> data; | 
 | 256 |         Stream stream{data}; | 
 | 257 |  | 
 | 258 |         callout.flatten(stream); | 
 | 259 |  | 
 | 260 |         { | 
 | 261 |             Stream newStream{data}; | 
 | 262 |             Callout newCallout{newStream}; | 
 | 263 |  | 
 | 264 |             EXPECT_EQ(newCallout.flags(), | 
 | 265 |                       Callout::calloutType | Callout::fruIdentIncluded); | 
 | 266 |  | 
 | 267 |             EXPECT_EQ(newCallout.flattenedSize(), callout.flattenedSize()); | 
 | 268 |             EXPECT_EQ(newCallout.priority(), callout.priority()); | 
 | 269 |             EXPECT_EQ(newCallout.locationCode(), callout.locationCode()); | 
 | 270 |             EXPECT_EQ(newCallout.locationCodeSize(), | 
 | 271 |                       callout.locationCodeSize()); | 
 | 272 |  | 
 | 273 |             auto& fru = newCallout.fruIdentity(); | 
 | 274 |             EXPECT_EQ(fru->getPN().value(), "1234567"); | 
 | 275 |             EXPECT_EQ(fru->getCCIN().value(), "ABCD"); | 
 | 276 |             EXPECT_EQ(fru->getSN().value(), "123456789ABC"); | 
 | 277 |         } | 
 | 278 |     } | 
| Matt Spinler | 5ab3997 | 2020-08-13 13:02:28 -0500 | [diff] [blame] | 279 |  | 
 | 280 |     { | 
 | 281 |         // With MRUs | 
 | 282 |         std::vector<MRU::MRUCallout> mruList{{'H', 1}, {'H', 2}}; | 
 | 283 |  | 
 | 284 |         Callout callout{CalloutPriority::high, "U99-P5", "1234567", "ABCD", | 
 | 285 |                         "123456789ABC",        mruList}; | 
 | 286 |  | 
| Patrick Williams | 075c792 | 2024-08-16 15:19:49 -0400 | [diff] [blame] | 287 |         EXPECT_EQ(callout.flags(), | 
 | 288 |                   Callout::calloutType | Callout::fruIdentIncluded | | 
 | 289 |                       Callout::mruIncluded); | 
| Matt Spinler | 5ab3997 | 2020-08-13 13:02:28 -0500 | [diff] [blame] | 290 |  | 
 | 291 |         EXPECT_EQ(callout.priority(), 'H'); | 
 | 292 |         EXPECT_EQ(callout.locationCode(), "U99-P5"); | 
 | 293 |         EXPECT_EQ(callout.locationCodeSize(), 8); | 
 | 294 |  | 
 | 295 |         auto& fru = callout.fruIdentity(); | 
 | 296 |         EXPECT_EQ(fru->getPN().value(), "1234567"); | 
 | 297 |         EXPECT_EQ(fru->getCCIN().value(), "ABCD"); | 
 | 298 |         EXPECT_EQ(fru->getSN().value(), "123456789ABC"); | 
 | 299 |  | 
 | 300 |         auto& mruSection = callout.mru(); | 
 | 301 |         EXPECT_EQ(mruSection->mrus().size(), 2); | 
 | 302 |         EXPECT_EQ(mruSection->mrus().at(0).priority, 'H'); | 
 | 303 |         EXPECT_EQ(mruSection->mrus().at(0).id, 1); | 
 | 304 |         EXPECT_EQ(mruSection->mrus().at(1).priority, 'H'); | 
 | 305 |         EXPECT_EQ(mruSection->mrus().at(1).id, 2); | 
 | 306 |     } | 
| Matt Spinler | 0a5d10c | 2020-03-13 12:54:02 -0500 | [diff] [blame] | 307 | } | 
 | 308 |  | 
 | 309 | // Create a callout object by passing in the maintenance procedure to add. | 
 | 310 | TEST(CalloutTest, TestProcedureCallout) | 
 | 311 | { | 
| Matt Spinler | 479b692 | 2021-08-17 16:34:59 -0500 | [diff] [blame] | 312 |     Callout callout{CalloutPriority::medium, "bmc_code"}; | 
| Matt Spinler | 0a5d10c | 2020-03-13 12:54:02 -0500 | [diff] [blame] | 313 |  | 
 | 314 |     // size/flags/pri/locsize fields + FRUIdentity size | 
 | 315 |     // No location code. | 
 | 316 |     size_t size = 4 + 12; | 
 | 317 |  | 
 | 318 |     EXPECT_EQ(callout.flags(), | 
 | 319 |               Callout::calloutType | Callout::fruIdentIncluded); | 
 | 320 |  | 
 | 321 |     EXPECT_EQ(callout.flattenedSize(), size); | 
 | 322 |     EXPECT_EQ(callout.priority(), 'M'); | 
 | 323 |     EXPECT_EQ(callout.locationCode(), ""); | 
 | 324 |     EXPECT_EQ(callout.locationCodeSize(), 0); | 
 | 325 |  | 
 | 326 |     auto& fru = callout.fruIdentity(); | 
| Matt Spinler | ea2873d | 2021-08-18 10:35:40 -0500 | [diff] [blame] | 327 |     EXPECT_EQ(fru->getMaintProc().value(), "BMC0001"); | 
| Matt Spinler | 0a5d10c | 2020-03-13 12:54:02 -0500 | [diff] [blame] | 328 |  | 
 | 329 |     // flatten/unflatten | 
 | 330 |     std::vector<uint8_t> data; | 
 | 331 |     Stream stream{data}; | 
 | 332 |  | 
 | 333 |     callout.flatten(stream); | 
 | 334 |  | 
 | 335 |     Stream newStream{data}; | 
 | 336 |     Callout newCallout{newStream}; | 
 | 337 |  | 
 | 338 |     EXPECT_EQ(newCallout.flags(), | 
 | 339 |               Callout::calloutType | Callout::fruIdentIncluded); | 
 | 340 |  | 
 | 341 |     EXPECT_EQ(newCallout.flattenedSize(), callout.flattenedSize()); | 
 | 342 |     EXPECT_EQ(newCallout.priority(), callout.priority()); | 
 | 343 |     EXPECT_EQ(newCallout.locationCode(), callout.locationCode()); | 
 | 344 |     EXPECT_EQ(newCallout.locationCodeSize(), callout.locationCodeSize()); | 
 | 345 |  | 
 | 346 |     auto& newFRU = newCallout.fruIdentity(); | 
 | 347 |     EXPECT_EQ(newFRU->getMaintProc().value(), fru->getMaintProc().value()); | 
| Matt Spinler | 468aab5 | 2020-08-13 11:04:31 -0500 | [diff] [blame] | 348 |  | 
 | 349 |     // Use raw procedure value | 
 | 350 |  | 
| Matt Spinler | ea2873d | 2021-08-18 10:35:40 -0500 | [diff] [blame] | 351 |     Callout rawCallout{CalloutPriority::medium, "BMCXXXX", | 
| Matt Spinler | 468aab5 | 2020-08-13 11:04:31 -0500 | [diff] [blame] | 352 |                        CalloutValueType::raw}; | 
 | 353 |     auto& rawFRU = rawCallout.fruIdentity(); | 
| Matt Spinler | ea2873d | 2021-08-18 10:35:40 -0500 | [diff] [blame] | 354 |     EXPECT_EQ(rawFRU->getMaintProc().value(), "BMCXXXX"); | 
| Matt Spinler | 0a5d10c | 2020-03-13 12:54:02 -0500 | [diff] [blame] | 355 | } | 
| Matt Spinler | a86ec99 | 2020-04-09 12:42:07 -0500 | [diff] [blame] | 356 |  | 
 | 357 | // Create a callout object by passing in the symbolic FRU to add. | 
 | 358 | TEST(CalloutTest, TestSymbolicFRUCallout) | 
 | 359 | { | 
 | 360 |     // symbolic FRU with a location code | 
 | 361 |     { | 
 | 362 |         Callout callout{CalloutPriority::high, "service_docs", "P1-C3", false}; | 
 | 363 |  | 
 | 364 |         // size/flags/pri/locsize fields + plus loc + FRUIdentity size | 
 | 365 |         size_t size = 4 + 8 + 12; | 
 | 366 |  | 
 | 367 |         EXPECT_EQ(callout.flags(), | 
 | 368 |                   Callout::calloutType | Callout::fruIdentIncluded); | 
 | 369 |  | 
 | 370 |         EXPECT_EQ(callout.flattenedSize(), size); | 
 | 371 |         EXPECT_EQ(callout.priority(), 'H'); | 
 | 372 |         EXPECT_EQ(callout.locationCode(), "P1-C3"); | 
 | 373 |         EXPECT_EQ(callout.locationCodeSize(), 8); | 
 | 374 |  | 
 | 375 |         auto& fru = callout.fruIdentity(); | 
 | 376 |  | 
 | 377 |         EXPECT_EQ(fru->failingComponentType(), FRUIdentity::symbolicFRU); | 
 | 378 |         EXPECT_EQ(fru->getPN().value(), "SVCDOCS"); | 
 | 379 |     } | 
 | 380 |  | 
 | 381 |     // symbolic FRU without a location code | 
 | 382 |     { | 
 | 383 |         Callout callout{CalloutPriority::high, "service_docs", "", false}; | 
 | 384 |  | 
 | 385 |         // size/flags/pri/locsize fields + plus loc + FRUIdentity size | 
 | 386 |         size_t size = 4 + 0 + 12; | 
 | 387 |  | 
 | 388 |         EXPECT_EQ(callout.flags(), | 
 | 389 |                   Callout::calloutType | Callout::fruIdentIncluded); | 
 | 390 |  | 
 | 391 |         EXPECT_EQ(callout.flattenedSize(), size); | 
 | 392 |         EXPECT_EQ(callout.priority(), 'H'); | 
 | 393 |         EXPECT_EQ(callout.locationCode(), ""); | 
 | 394 |         EXPECT_EQ(callout.locationCodeSize(), 0); | 
 | 395 |  | 
 | 396 |         auto& fru = callout.fruIdentity(); | 
 | 397 |  | 
 | 398 |         EXPECT_EQ(fru->failingComponentType(), FRUIdentity::symbolicFRU); | 
 | 399 |         EXPECT_EQ(fru->getPN().value(), "SVCDOCS"); | 
 | 400 |     } | 
 | 401 |  | 
 | 402 |     // symbolic FRU with a trusted location code | 
 | 403 |     { | 
 | 404 |         Callout callout{CalloutPriority::high, "service_docs", "P1-C3", true}; | 
 | 405 |  | 
 | 406 |         // size/flags/pri/locsize fields + plus loc + FRUIdentity size | 
 | 407 |         size_t size = 4 + 8 + 12; | 
 | 408 |  | 
 | 409 |         EXPECT_EQ(callout.flags(), | 
 | 410 |                   Callout::calloutType | Callout::fruIdentIncluded); | 
 | 411 |  | 
 | 412 |         EXPECT_EQ(callout.flattenedSize(), size); | 
 | 413 |         EXPECT_EQ(callout.priority(), 'H'); | 
 | 414 |         EXPECT_EQ(callout.locationCode(), "P1-C3"); | 
 | 415 |         EXPECT_EQ(callout.locationCodeSize(), 8); | 
 | 416 |  | 
 | 417 |         auto& fru = callout.fruIdentity(); | 
 | 418 |         EXPECT_EQ(fru->failingComponentType(), | 
 | 419 |                   FRUIdentity::symbolicFRUTrustedLocCode); | 
 | 420 |         EXPECT_EQ(fru->getPN().value(), "SVCDOCS"); | 
 | 421 |     } | 
| Matt Spinler | 468aab5 | 2020-08-13 11:04:31 -0500 | [diff] [blame] | 422 |  | 
 | 423 |     // symbolic FRU with raw FRU value | 
 | 424 |     { | 
 | 425 |         { | 
 | 426 |             Callout callout{CalloutPriority::high, "SYMBFRU", | 
 | 427 |                             CalloutValueType::raw, "", false}; | 
 | 428 |  | 
 | 429 |             auto& fru = callout.fruIdentity(); | 
 | 430 |  | 
 | 431 |             EXPECT_EQ(fru->getPN().value(), "SYMBFRU"); | 
 | 432 |         } | 
 | 433 |     } | 
| Matt Spinler | a86ec99 | 2020-04-09 12:42:07 -0500 | [diff] [blame] | 434 | } | 
| Matt Spinler | 4efed0e | 2024-02-26 11:16:07 -0600 | [diff] [blame] | 435 |  | 
 | 436 | TEST(CalloutTest, OperatorEqualTest) | 
 | 437 | { | 
 | 438 |     { | 
 | 439 |         Callout c1{CalloutPriority::high, "A1", "1234567", "ABCD", | 
 | 440 |                    "123456789ABC"}; | 
 | 441 |         Callout c2{CalloutPriority::high, "A1", "1234567", "ABCD", | 
 | 442 |                    "123456789ABC"}; | 
 | 443 |         EXPECT_EQ(c1, c2); | 
 | 444 |     } | 
 | 445 |  | 
 | 446 |     { | 
 | 447 |         // Different location code | 
 | 448 |         Callout c1{CalloutPriority::high, "A1", "1234567", "ABCD", | 
 | 449 |                    "123456789ABC"}; | 
 | 450 |         Callout c2{CalloutPriority::high, "A2", "1234567", "ABCD", | 
 | 451 |                    "123456789ABC"}; | 
 | 452 |         EXPECT_NE(c1, c2); | 
 | 453 |     } | 
 | 454 |  | 
 | 455 |     { | 
 | 456 |         // maintenance procedure | 
 | 457 |         Callout c1{CalloutPriority::medium, "bmc_code"}; | 
 | 458 |         Callout c2{CalloutPriority::medium, "bmc_code"}; | 
 | 459 |         EXPECT_EQ(c1, c2); | 
 | 460 |     } | 
 | 461 |  | 
 | 462 |     { | 
 | 463 |         // different maintenance procedures | 
 | 464 |         Callout c1{CalloutPriority::medium, "bmc_code"}; | 
 | 465 |         Callout c2{CalloutPriority::medium, "sbe_code"}; | 
 | 466 |         EXPECT_NE(c1, c2); | 
 | 467 |     } | 
 | 468 |  | 
 | 469 |     { | 
 | 470 |         // symbolic FRU | 
 | 471 |         Callout c1{CalloutPriority::high, "service_docs", "", false}; | 
 | 472 |         Callout c2{CalloutPriority::high, "service_docs", "", false}; | 
 | 473 |         EXPECT_EQ(c1, c2); | 
 | 474 |     } | 
 | 475 |  | 
 | 476 |     { | 
 | 477 |         // different symbolic FRUs | 
 | 478 |         Callout c1{CalloutPriority::high, "service_docs", "", false}; | 
 | 479 |         Callout c2{CalloutPriority::high, "air_mover", "", false}; | 
 | 480 |         EXPECT_NE(c1, c2); | 
 | 481 |     } | 
 | 482 |  | 
 | 483 |     { | 
 | 484 |         // HW callout vs symbolic FRU | 
 | 485 |         Callout c1{CalloutPriority::high, "A1", "1234567", "ABCD", | 
 | 486 |                    "123456789ABC"}; | 
 | 487 |         Callout c2{CalloutPriority::high, "service_docs", "", false}; | 
 | 488 |         EXPECT_NE(c1, c2); | 
 | 489 |     } | 
 | 490 |  | 
 | 491 |     { | 
 | 492 |         // HW callout vs maintenance procedure | 
 | 493 |         Callout c1{CalloutPriority::high, "A1", "1234567", "ABCD", | 
 | 494 |                    "123456789ABC"}; | 
 | 495 |         Callout c2{CalloutPriority::medium, "bmc_code"}; | 
 | 496 |         EXPECT_NE(c1, c2); | 
 | 497 |     } | 
 | 498 |  | 
 | 499 |     { | 
 | 500 |         // symbolic FRU vs maintenance procedure | 
 | 501 |         Callout c1{CalloutPriority::high, "service_docs", "", false}; | 
 | 502 |         Callout c2{CalloutPriority::medium, "bmc_code"}; | 
 | 503 |         EXPECT_NE(c1, c2); | 
 | 504 |     } | 
 | 505 |  | 
 | 506 |     { | 
 | 507 |         // HW callout vs symbolic FRU is still considered equal if | 
 | 508 |         // the location code is the same | 
 | 509 |         Callout c1{CalloutPriority::high, "A1", "1234567", "ABCD", | 
 | 510 |                    "123456789ABC"}; | 
 | 511 |         Callout c2{CalloutPriority::high, "service_docs", "A1", true}; | 
 | 512 |         EXPECT_EQ(c1, c2); | 
 | 513 |     } | 
 | 514 | } | 
 | 515 |  | 
 | 516 | TEST(CalloutTest, OperatorGreaterThanTest) | 
 | 517 | { | 
 | 518 |     { | 
 | 519 |         Callout c1{CalloutPriority::high, "bmc_code"}; | 
 | 520 |         Callout c2{CalloutPriority::medium, "bmc_code"}; | 
 | 521 |         EXPECT_TRUE(c1 > c2); | 
 | 522 |     } | 
 | 523 |     { | 
 | 524 |         Callout c1{CalloutPriority::high, "bmc_code"}; | 
 | 525 |         Callout c2{CalloutPriority::low, "bmc_code"}; | 
 | 526 |         EXPECT_TRUE(c1 > c2); | 
 | 527 |     } | 
 | 528 |     { | 
 | 529 |         Callout c1{CalloutPriority::medium, "bmc_code"}; | 
 | 530 |         Callout c2{CalloutPriority::low, "bmc_code"}; | 
 | 531 |         EXPECT_TRUE(c1 > c2); | 
 | 532 |     } | 
 | 533 |     { | 
 | 534 |         Callout c1{CalloutPriority::mediumGroupA, "bmc_code"}; | 
 | 535 |         Callout c2{CalloutPriority::low, "bmc_code"}; | 
 | 536 |         EXPECT_TRUE(c1 > c2); | 
 | 537 |     } | 
 | 538 |     { | 
 | 539 |         Callout c1{CalloutPriority::medium, "bmc_code"}; | 
 | 540 |         Callout c2{CalloutPriority::high, "bmc_code"}; | 
 | 541 |         EXPECT_FALSE(c1 > c2); | 
 | 542 |     } | 
 | 543 |     { | 
 | 544 |         Callout c1{CalloutPriority::high, "bmc_code"}; | 
 | 545 |         Callout c2{CalloutPriority::high, "bmc_code"}; | 
 | 546 |         EXPECT_FALSE(c1 > c2); | 
 | 547 |     } | 
 | 548 |     { | 
 | 549 |         Callout c1{CalloutPriority::low, "bmc_code"}; | 
 | 550 |         Callout c2{CalloutPriority::high, "bmc_code"}; | 
 | 551 |         EXPECT_FALSE(c1 > c2); | 
 | 552 |     } | 
 | 553 |     { | 
 | 554 |         // Treat the different mediums the same | 
 | 555 |         Callout c1{CalloutPriority::medium, "bmc_code"}; | 
 | 556 |         Callout c2{CalloutPriority::mediumGroupA, "bmc_code"}; | 
 | 557 |         EXPECT_FALSE(c1 > c2); | 
 | 558 |     } | 
 | 559 | } |