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