blob: 1df46ccd7c234c9ce4e0f7ce1f4f0cda263d7cf3 [file] [log] [blame]
Sampa Misra032bd502019-03-06 05:03:22 -06001#include "libpldmresponder/bios.hpp"
Tom Joseph52552ef2019-06-20 09:50:15 +05302#include "libpldmresponder/bios_parser.hpp"
Sampa Misrab37be312019-07-03 02:26:41 -05003#include "libpldmresponder/bios_table.hpp"
Sampa Misra032bd502019-03-06 05:03:22 -06004
5#include <string.h>
6
7#include <array>
John Wang02700402019-10-06 16:34:29 +08008#include <cstring>
Sampa Misra032bd502019-03-06 05:03:22 -06009#include <ctime>
Sampa Misrab37be312019-07-03 02:26:41 -050010#include <filesystem>
Sampa Misra032bd502019-03-06 05:03:22 -060011
12#include "libpldm/base.h"
13#include "libpldm/bios.h"
14
15#include <gtest/gtest.h>
16
Sampa Misrab37be312019-07-03 02:26:41 -050017using namespace pldm;
Sampa Misra032bd502019-03-06 05:03:22 -060018using namespace pldm::responder;
Sampa Misrab37be312019-07-03 02:26:41 -050019using namespace pldm::responder::bios;
Sampa Misra032bd502019-03-06 05:03:22 -060020using namespace pldm::responder::utils;
Sampa Misrab37be312019-07-03 02:26:41 -050021using namespace bios_parser;
22using namespace bios_parser::bios_enum;
Sampa Misra032bd502019-03-06 05:03:22 -060023
24TEST(epochToBCDTime, testTime)
25{
26 struct tm time
27 {
28 };
29 time.tm_year = 119;
30 time.tm_mon = 3;
31 time.tm_mday = 13;
32 time.tm_hour = 5;
33 time.tm_min = 18;
34 time.tm_sec = 13;
35 time.tm_isdst = -1;
36
37 time_t epochTime = mktime(&time);
38 uint8_t seconds = 0;
39 uint8_t minutes = 0;
40 uint8_t hours = 0;
41 uint8_t day = 0;
42 uint8_t month = 0;
43 uint16_t year = 0;
44
45 epochToBCDTime(epochTime, seconds, minutes, hours, day, month, year);
46
47 ASSERT_EQ(0x13, seconds);
48 ASSERT_EQ(0x18, minutes);
49 ASSERT_EQ(0x5, hours);
50 ASSERT_EQ(0x13, day);
51 ASSERT_EQ(0x4, month);
52 ASSERT_EQ(0x2019, year);
53}
Tom Joseph52552ef2019-06-20 09:50:15 +053054
55TEST(GetBIOSStrings, allScenarios)
56{
57 using namespace bios_parser;
58 // All the BIOS Strings in the BIOS JSON config files.
Carol Wang612f35b2019-08-26 17:14:26 +080059 Strings vec{"HMCManagedState", "On", "Off",
60 "FWBootSide", "Perm", "Temp",
61 "InbandCodeUpdate", "Allowed", "NotAllowed",
62 "CodeUpdatePolicy", "Concurrent", "Disruptive",
63 "str_example1", "str_example2", "str_example3"};
Tom Joseph52552ef2019-06-20 09:50:15 +053064
65 Strings nullVec{};
66
67 // Invalid directory
68 auto strings = bios_parser::getStrings("./bios_json");
69 ASSERT_EQ(strings == nullVec, true);
70
71 strings = bios_parser::getStrings("./bios_jsons");
Carol Wang612f35b2019-08-26 17:14:26 +080072 std::sort(strings.begin(), strings.end());
73 std::sort(vec.begin(), vec.end());
Tom Joseph52552ef2019-06-20 09:50:15 +053074 ASSERT_EQ(strings == vec, true);
75}
76
Carol Wang69d3e7f2019-09-04 16:43:15 +080077TEST(getAttrValue, enumScenarios)
Tom Joseph52552ef2019-06-20 09:50:15 +053078{
Tom Joseph52552ef2019-06-20 09:50:15 +053079 // All the BIOS Strings in the BIOS JSON config files.
80 AttrValuesMap valueMap{
81 {"HMCManagedState", {false, {"On", "Off"}, {"On"}}},
82 {"FWBootSide", {false, {"Perm", "Temp"}, {"Perm"}}},
83 {"InbandCodeUpdate", {false, {"Allowed", "NotAllowed"}, {"Allowed"}}},
84 {"CodeUpdatePolicy",
85 {false, {"Concurrent", "Disruptive"}, {"Concurrent"}}}};
86
Carol Wang69d3e7f2019-09-04 16:43:15 +080087 auto rc = bios_parser::bios_enum::setupValueLookup("./bios_jsons");
Sampa Misrab37be312019-07-03 02:26:41 -050088 ASSERT_EQ(rc, 0);
89
Carol Wang69d3e7f2019-09-04 16:43:15 +080090 auto values = bios_parser::bios_enum::getValues();
Tom Joseph52552ef2019-06-20 09:50:15 +053091 ASSERT_EQ(valueMap == values, true);
92
Carol Wang69d3e7f2019-09-04 16:43:15 +080093 bios_parser::bios_enum::CurrentValues cv{"Concurrent"};
94 auto value = bios_parser::bios_enum::getAttrValue("CodeUpdatePolicy");
Tom Joseph52552ef2019-06-20 09:50:15 +053095 ASSERT_EQ(value == cv, true);
96
97 // Invalid attribute name
Carol Wang69d3e7f2019-09-04 16:43:15 +080098 ASSERT_THROW(bios_parser::bios_enum::getAttrValue("CodeUpdatePolic"),
99 std::out_of_range);
100}
101
102TEST(getAttrValue, stringScenarios)
103{
104 // All the BIOS Strings in the BIOS JSON config files.
105 bios_parser::bios_string::AttrValuesMap valueMap{
106 {"str_example1", {false, 1, 1, 100, 3, "abc"}},
107 {"str_example2", {false, 2, 0, 100, 0, ""}},
108 {"str_example3", {true, 0, 1, 100, 2, "ef"}}};
109
110 auto rc = bios_parser::bios_string::setupValueLookup("./bios_jsons");
111 EXPECT_EQ(rc, 0);
112
113 auto values = bios_parser::bios_string::getValues();
114 ASSERT_EQ(valueMap == values, true);
115
116 // Test the attribute without dbus
117 std::string cv = "ef";
118 auto value = bios_parser::bios_string::getAttrValue("str_example3");
119 EXPECT_EQ(value, cv);
120
121 // Invalid attribute name
122 ASSERT_THROW(bios_parser::bios_string::getAttrValue("str_example"),
123 std::out_of_range);
Tom Joseph52552ef2019-06-20 09:50:15 +0530124}
Sampa Misrab37be312019-07-03 02:26:41 -0500125
John Wang02700402019-10-06 16:34:29 +0800126TEST(traverseBIOSTable, attrTableScenarios)
127{
128 std::vector<uint8_t> enumEntry{
129 0, 0, /* attr handle */
130 0, /* attr type */
131 1, 0, /* attr name handle */
132 2, /* number of possible value */
133 2, 0, /* possible value handle */
134 3, 0, /* possible value handle */
135 1, /* number of default value */
136 0 /* defaut value string handle index */
137 };
138 std::vector<uint8_t> stringEntry{
139 4, 0, /* attr handle */
140 1, /* attr type */
141 12, 0, /* attr name handle */
142 1, /* string type */
143 1, 0, /* minimum length of the string in bytes */
144 100, 0, /* maximum length of the string in bytes */
145 3, 0, /* length of default string in length */
146 'a', 'b', 'c' /* default string */
147 };
148 std::vector<uint8_t> table;
149 table.insert(table.end(), enumEntry.begin(), enumEntry.end());
150 table.insert(table.end(), stringEntry.begin(), stringEntry.end());
151 auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
152
153 table.insert(table.end(), padSize, 0);
154 table.insert(table.end(), sizeof(uint32_t) /*checksum*/, 0);
155
156 pldm::responder::traverseBIOSAttrTable(
157 table, [&](const struct pldm_bios_attr_table_entry* entry) {
158 int rc;
159 switch (entry->attr_type)
160 {
161 case 0:
162 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
163 EXPECT_EQ(rc, 0);
164 break;
165 case 1:
166 rc = std::memcmp(entry, stringEntry.data(),
167 stringEntry.size());
168 EXPECT_EQ(rc, 0);
169 break;
170 default:
171 break;
172 }
173 });
174}
175
Sampa Misrab37be312019-07-03 02:26:41 -0500176namespace fs = std::filesystem;
177class TestAllBIOSTables : public ::testing::Test
178{
179 public:
180 static void SetUpTestCase() // will execute once at the begining of all
181 // TestAllBIOSTables objects
182 {
183 char tmpdir[] = "/tmp/allBiosTables.XXXXXX";
184 biosPath = fs::path(mkdtemp(tmpdir));
185 }
186
187 static void TearDownTestCase() // will be executed once at th eend of all
188 // TestAllBIOSTables objects
189 {
190 fs::remove_all(biosPath);
191 }
192
193 static fs::path biosPath;
194};
195
196fs::path TestAllBIOSTables::biosPath;
197
198TEST_F(TestAllBIOSTables, GetBIOSTableTestBadRequest)
199{
200 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
201 requestPayload{};
202 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
203 struct pldm_get_bios_table_req* req =
204 (struct pldm_get_bios_table_req*)request->payload;
205 req->transfer_handle = 9;
206 req->transfer_op_flag = PLDM_GET_FIRSTPART;
207 req->table_type = 0xFF;
208
209 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
210
211 auto response = internal::buildBIOSTables(request, requestPayloadLength,
212 "./bios_jsons", biosPath.c_str());
213 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
214
215 struct pldm_get_bios_table_resp* resp =
216 reinterpret_cast<struct pldm_get_bios_table_resp*>(
217 responsePtr->payload);
218
219 ASSERT_EQ(PLDM_INVALID_BIOS_TABLE_TYPE, resp->completion_code);
220}
221
222TEST_F(TestAllBIOSTables, buildBIOSTablesTestBadRequest)
223{
224 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
225 requestPayload{};
226 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
227 struct pldm_get_bios_table_req* req =
228 (struct pldm_get_bios_table_req*)request->payload;
229 req->transfer_handle = 9;
230 req->transfer_op_flag = PLDM_GET_FIRSTPART;
231 req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
232
233 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
234
235 auto response = internal::buildBIOSTables(request, requestPayloadLength,
236 "./bios_jsons", biosPath.c_str());
237 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
238 struct pldm_get_bios_table_resp* resp =
239 reinterpret_cast<struct pldm_get_bios_table_resp*>(
240 responsePtr->payload);
241 ASSERT_EQ(PLDM_BIOS_TABLE_UNAVAILABLE, resp->completion_code);
242
243 req->table_type = PLDM_BIOS_ATTR_TABLE;
244 response = internal::buildBIOSTables(request, requestPayloadLength,
245 "./bios_jsons", biosPath.c_str());
246 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
247 resp = reinterpret_cast<struct pldm_get_bios_table_resp*>(
248 responsePtr->payload);
249 ASSERT_EQ(PLDM_BIOS_TABLE_UNAVAILABLE, resp->completion_code);
250}
251
252TEST_F(TestAllBIOSTables, GetBIOSStringTableTestGoodRequest)
253{
254 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
255 requestPayload{};
256 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
257 struct pldm_get_bios_table_req* req =
258 (struct pldm_get_bios_table_req*)request->payload;
259 req->transfer_handle = 9;
260 req->transfer_op_flag = PLDM_GET_FIRSTPART;
261 req->table_type = PLDM_BIOS_STRING_TABLE;
262
263 Strings biosStrings = getStrings("./bios_jsons");
264 std::sort(biosStrings.begin(), biosStrings.end());
265 biosStrings.erase(std::unique(biosStrings.begin(), biosStrings.end()),
266 biosStrings.end());
267
268 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
269 uint8_t times = 0;
270 while (times < 2)
271 { // first time fresh table second time existing table
272 auto response = internal::buildBIOSTables(
273 request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
274 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
275
276 struct pldm_get_bios_table_resp* resp =
277 reinterpret_cast<struct pldm_get_bios_table_resp*>(
278 responsePtr->payload);
279
280 ASSERT_EQ(0, resp->completion_code);
281 ASSERT_EQ(0, resp->next_transfer_handle);
282 ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
283
284 uint16_t strLen = 0;
285 uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
286
287 for (auto elem : biosStrings)
288 {
289 struct pldm_bios_string_table_entry* ptr =
290 reinterpret_cast<struct pldm_bios_string_table_entry*>(
291 tableData);
292 strLen = ptr->string_length;
293 ASSERT_EQ(strLen, elem.size());
294 ASSERT_EQ(0, memcmp(elem.c_str(), ptr->name, strLen));
295 tableData += (sizeof(pldm_bios_string_table_entry) - 1) + strLen;
296
297 } // end for
298 times++;
299 }
300}
301
302TEST_F(TestAllBIOSTables, getBIOSAttributeTableTestGoodRequest)
303{
304 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
305 requestPayload{};
306 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
307 struct pldm_get_bios_table_req* req =
308 (struct pldm_get_bios_table_req*)request->payload;
309 req->transfer_handle = 9;
310 req->transfer_op_flag = PLDM_GET_FIRSTPART;
311 req->table_type = PLDM_BIOS_ATTR_TABLE;
312
313 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
314
315 uint8_t times = 0;
316 while (times < 2)
317 { // first time fresh table second time existing table
318 auto response = internal::buildBIOSTables(
319 request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
320 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
321
322 struct pldm_get_bios_table_resp* resp =
323 reinterpret_cast<struct pldm_get_bios_table_resp*>(
324 responsePtr->payload);
325
326 ASSERT_EQ(0, resp->completion_code);
327 ASSERT_EQ(0, resp->next_transfer_handle);
328 ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
329
330 uint32_t attrTableLen =
331 response.size() - sizeof(pldm_msg_hdr) -
332 (sizeof(resp->completion_code) +
333 sizeof(resp->next_transfer_handle) + sizeof(resp->transfer_flag));
334 uint32_t traversed = 0;
335 uint16_t attrHdl = 0;
336 uint16_t stringHdl = 0;
337 uint8_t attrType = 0;
338 uint8_t numPosVals = 0;
339 uint8_t numDefVals = 0;
340 uint8_t defIndex = 0;
341
342 uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
343 while (1)
344 {
345 struct pldm_bios_attr_table_entry* ptr =
346 reinterpret_cast<struct pldm_bios_attr_table_entry*>(tableData);
347 attrHdl = ptr->attr_handle;
348 attrType = ptr->attr_type;
349 EXPECT_EQ(0, attrHdl);
350 EXPECT_EQ(PLDM_BIOS_ENUMERATION, attrType);
351 stringHdl = ptr->string_handle;
352 EXPECT_EQ(stringHdl, 1);
353 tableData += sizeof(attrHdl) + sizeof(attrType) + sizeof(stringHdl);
354 numPosVals = *tableData;
355 EXPECT_EQ(numPosVals, 2);
356 traversed += sizeof(attrHdl) + sizeof(attrType) + sizeof(stringHdl);
357 traversed += sizeof(numPosVals);
358 PossibleValuesByHandle possiVals;
359 tableData++;
360 uint16_t* temp = reinterpret_cast<uint16_t*>(tableData);
361 uint32_t i = 0;
362 while (i < numPosVals)
363 {
364 uint16_t val = *temp;
365 possiVals.push_back(val);
366 temp++;
367 i++;
368 }
369 EXPECT_EQ(possiVals.size(), 2);
370 tableData += numPosVals * sizeof(stringHdl);
371 traversed += numPosVals * sizeof(stringHdl);
372 numDefVals = *tableData;
373 EXPECT_EQ(numDefVals, 1);
374 tableData += numDefVals * sizeof(defIndex);
375 traversed += numDefVals + sizeof(numDefVals);
376
377 break; // test for first row only
378
379 if ((attrTableLen - traversed) < 8)
380 {
381 // reached pad
382 break;
383 }
384
385 } // end while
386 times++;
387 }
388
389} // end TEST
390
391TEST_F(TestAllBIOSTables, getBIOSAttributeValueTableTestGoodRequest)
392{
393 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
394 requestPayload{};
395 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
396 struct pldm_get_bios_table_req* req =
397 (struct pldm_get_bios_table_req*)request->payload;
398 req->transfer_handle = 9;
399 req->transfer_op_flag = PLDM_GET_FIRSTPART;
400 req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
401
402 std::string attrName("CodeUpdatePolicy");
403 CurrentValues currVals = getAttrValue(attrName);
404
405 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
406
407 uint8_t times = 0;
408 while (times < 2)
409 { // first time frest table second time existing table
410 auto response = internal::buildBIOSTables(
411 request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
412 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
413
414 struct pldm_get_bios_table_resp* resp =
415 reinterpret_cast<struct pldm_get_bios_table_resp*>(
416 responsePtr->payload);
417
418 ASSERT_EQ(0, resp->completion_code);
419 ASSERT_EQ(0, resp->next_transfer_handle);
420 ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
421
422 uint32_t attrValTableLen =
423 response.size() - sizeof(pldm_msg_hdr) -
424 (sizeof(resp->completion_code) +
425 sizeof(resp->next_transfer_handle) + sizeof(resp->transfer_flag));
426 uint32_t traversed = 0;
427 uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
428
429 uint16_t attrHdl;
430 uint8_t attrType;
431 uint8_t numCurrVals;
432 uint8_t currValStrIndex;
433
434 while (1)
435 {
436 struct pldm_bios_attr_val_table_entry* ptr =
437 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
438 tableData);
439 attrHdl = ptr->attr_handle;
440 attrType = ptr->attr_type;
441 EXPECT_EQ(0, attrHdl);
442 EXPECT_EQ(PLDM_BIOS_ENUMERATION, attrType);
443 tableData += sizeof(attrHdl) + sizeof(attrType);
444 traversed += sizeof(attrHdl) + sizeof(attrType);
445 numCurrVals = *tableData;
446 EXPECT_EQ(1, numCurrVals);
447 tableData += sizeof(numCurrVals);
448 traversed += sizeof(numCurrVals);
449 currValStrIndex = *tableData;
450 EXPECT_EQ(0, currValStrIndex);
451 tableData += numCurrVals;
452 traversed += numCurrVals;
453 break; // testing for first row
454 if ((attrValTableLen - traversed) < 8)
455 {
456 break;
457 }
458 }
459 times++;
460 }
461
462} // end TEST
Carol Wang69d3e7f2019-09-04 16:43:15 +0800463
464class TestSingleTypeBIOSTable : public ::testing::Test
465{
466 public:
467 void SetUp() override
468 { // will be executed before each individual test defined
469 // in TestSingleTypeBIOSTable
470 char tmpdir[] = "/tmp/singleTypeBIOSTable.XXXXXX";
471 destBiosPath = fs::path(mkdtemp(tmpdir));
472 }
473
474 void TearDown() override
475 { // will be executed after each individual test
476 // defined in TestSingleTypeBIOSTable
477 fs::remove_all(destBiosPath);
478 }
479
480 void CopySingleJsonFile(std::string file)
481 {
482 fs::path srcDir("./bios_jsons");
483 fs::path srcBiosPath = srcDir / file;
484 std::filesystem::copy(srcBiosPath, destBiosPath);
485 }
486
487 fs::path destBiosPath;
488};
489
490TEST_F(TestSingleTypeBIOSTable, getBIOSAttributeValueTableBasedOnStringTypeTest)
491{
492 // Copy string json file to the destination
493 TestSingleTypeBIOSTable::CopySingleJsonFile(bios_parser::bIOSStrJson);
494 auto fpath = TestSingleTypeBIOSTable::destBiosPath.c_str();
495
496 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
497 requestPayload{};
498 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
499 struct pldm_get_bios_table_req* req =
500 (struct pldm_get_bios_table_req*)request->payload;
501
502 // Get string table with string json file only
503 req->transfer_handle = 9;
504 req->transfer_op_flag = PLDM_GET_FIRSTPART;
505 req->table_type = PLDM_BIOS_STRING_TABLE;
506
507 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
508 auto str_response =
509 internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
510
511 // Get attribute table with string json file only
512 req->transfer_handle = 9;
513 req->transfer_op_flag = PLDM_GET_FIRSTPART;
514 req->table_type = PLDM_BIOS_ATTR_TABLE;
515
516 auto attr_response =
517 internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
518
519 // Get attribute value table with string type
520 req->transfer_handle = 9;
521 req->transfer_op_flag = PLDM_GET_FIRSTPART;
522 req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
523
524 // Test attribute str_example3 here, which has no dbus
525 for (uint8_t times = 0; times < 2; times++)
526 { // first time first table second time existing table
527 auto response = internal::buildBIOSTables(request, requestPayloadLength,
528 fpath, fpath);
529 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
530
531 struct pldm_get_bios_table_resp* resp =
532 reinterpret_cast<struct pldm_get_bios_table_resp*>(
533 responsePtr->payload);
534
535 ASSERT_EQ(0, resp->completion_code);
536 ASSERT_EQ(0, resp->next_transfer_handle);
537 ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
538
539 uint32_t attrValTableLen =
540 response.size() - sizeof(pldm_msg_hdr) -
541 (sizeof(struct pldm_get_bios_table_resp) - 1);
542 uint32_t traversed = 0;
543 uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
544
545 while (true)
546 {
547 struct pldm_bios_attr_val_table_entry* ptr =
548 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
549 tableData);
550 uint16_t attrHdl = ptr->attr_handle;
551 uint8_t attrType = ptr->attr_type;
552 EXPECT_EQ(PLDM_BIOS_STRING_READ_ONLY, attrType);
553 tableData += sizeof(attrHdl) + sizeof(attrType);
554 traversed += sizeof(attrHdl) + sizeof(attrType);
555 auto sizeDefaultStr = *(reinterpret_cast<uint16_t*>(tableData));
556 EXPECT_EQ(2, sizeDefaultStr);
557 tableData += sizeof(uint16_t);
558 traversed += sizeof(uint16_t);
559 EXPECT_EQ('e', *tableData);
560 EXPECT_EQ('f', *(tableData + 1));
561 tableData += sizeDefaultStr;
562 traversed += sizeDefaultStr;
563 break; // testing for first row
564 if ((attrValTableLen - traversed) < 8)
565 {
566 break;
567 }
568 }
569 }
570
571} // end TEST