blob: 72715678ab28f2012ed61d2a179d6004f1cb8174 [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;
Sampa Misra032bd502019-03-06 05:03:22 -060022
23TEST(epochToBCDTime, testTime)
24{
25 struct tm time
26 {
27 };
28 time.tm_year = 119;
29 time.tm_mon = 3;
30 time.tm_mday = 13;
31 time.tm_hour = 5;
32 time.tm_min = 18;
33 time.tm_sec = 13;
34 time.tm_isdst = -1;
35
36 time_t epochTime = mktime(&time);
37 uint8_t seconds = 0;
38 uint8_t minutes = 0;
39 uint8_t hours = 0;
40 uint8_t day = 0;
41 uint8_t month = 0;
42 uint16_t year = 0;
43
44 epochToBCDTime(epochTime, seconds, minutes, hours, day, month, year);
45
46 ASSERT_EQ(0x13, seconds);
47 ASSERT_EQ(0x18, minutes);
48 ASSERT_EQ(0x5, hours);
49 ASSERT_EQ(0x13, day);
50 ASSERT_EQ(0x4, month);
51 ASSERT_EQ(0x2019, year);
52}
Tom Joseph52552ef2019-06-20 09:50:15 +053053
54TEST(GetBIOSStrings, allScenarios)
55{
56 using namespace bios_parser;
57 // All the BIOS Strings in the BIOS JSON config files.
John Wangecb7d572019-10-17 13:38:53 +080058 Strings vec{"HMCManagedState",
59 "On",
60 "Off",
61 "FWBootSide",
62 "Perm",
63 "Temp",
64 "InbandCodeUpdate",
65 "Allowed",
66 "NotAllowed",
67 "CodeUpdatePolicy",
68 "Concurrent",
69 "Disruptive",
70 "VDD_AVSBUS_RAIL",
71 "SBE_IMAGE_MINIMUM_VALID_ECS",
72 "INTEGER_INVALID_CASE",
73 "str_example1",
74 "str_example2",
75 "str_example3"};
Tom Joseph52552ef2019-06-20 09:50:15 +053076
77 Strings nullVec{};
78
79 // Invalid directory
John Wange96e7e52019-10-05 17:47:30 +080080 bios_parser::setupConfig("./bios_json_invalid");
81 auto strings = bios_parser::getStrings();
Tom Joseph52552ef2019-06-20 09:50:15 +053082 ASSERT_EQ(strings == nullVec, true);
83
John Wange96e7e52019-10-05 17:47:30 +080084 bios_parser::setupConfig("./bios_jsons");
85 strings = bios_parser::getStrings();
Carol Wang612f35b2019-08-26 17:14:26 +080086 std::sort(strings.begin(), strings.end());
87 std::sort(vec.begin(), vec.end());
Tom Joseph52552ef2019-06-20 09:50:15 +053088 ASSERT_EQ(strings == vec, true);
89}
90
Carol Wang69d3e7f2019-09-04 16:43:15 +080091TEST(getAttrValue, enumScenarios)
Tom Joseph52552ef2019-06-20 09:50:15 +053092{
John Wangecb7d572019-10-17 13:38:53 +080093 using namespace bios_parser::bios_enum;
Tom Joseph52552ef2019-06-20 09:50:15 +053094 // All the BIOS Strings in the BIOS JSON config files.
95 AttrValuesMap valueMap{
96 {"HMCManagedState", {false, {"On", "Off"}, {"On"}}},
97 {"FWBootSide", {false, {"Perm", "Temp"}, {"Perm"}}},
98 {"InbandCodeUpdate", {false, {"Allowed", "NotAllowed"}, {"Allowed"}}},
99 {"CodeUpdatePolicy",
John Wange96e7e52019-10-05 17:47:30 +0800100 {true, {"Concurrent", "Disruptive"}, {"Concurrent"}}}};
Sampa Misrab37be312019-07-03 02:26:41 -0500101
Carol Wang69d3e7f2019-09-04 16:43:15 +0800102 auto values = bios_parser::bios_enum::getValues();
Tom Joseph52552ef2019-06-20 09:50:15 +0530103 ASSERT_EQ(valueMap == values, true);
104
Carol Wang69d3e7f2019-09-04 16:43:15 +0800105 bios_parser::bios_enum::CurrentValues cv{"Concurrent"};
106 auto value = bios_parser::bios_enum::getAttrValue("CodeUpdatePolicy");
Tom Joseph52552ef2019-06-20 09:50:15 +0530107 ASSERT_EQ(value == cv, true);
108
109 // Invalid attribute name
Carol Wang69d3e7f2019-09-04 16:43:15 +0800110 ASSERT_THROW(bios_parser::bios_enum::getAttrValue("CodeUpdatePolic"),
111 std::out_of_range);
112}
113
114TEST(getAttrValue, stringScenarios)
115{
116 // All the BIOS Strings in the BIOS JSON config files.
117 bios_parser::bios_string::AttrValuesMap valueMap{
118 {"str_example1", {false, 1, 1, 100, 3, "abc"}},
119 {"str_example2", {false, 2, 0, 100, 0, ""}},
120 {"str_example3", {true, 0, 1, 100, 2, "ef"}}};
121
Carol Wang69d3e7f2019-09-04 16:43:15 +0800122 auto values = bios_parser::bios_string::getValues();
123 ASSERT_EQ(valueMap == values, true);
124
125 // Test the attribute without dbus
126 std::string cv = "ef";
127 auto value = bios_parser::bios_string::getAttrValue("str_example3");
128 EXPECT_EQ(value, cv);
129
130 // Invalid attribute name
131 ASSERT_THROW(bios_parser::bios_string::getAttrValue("str_example"),
132 std::out_of_range);
Tom Joseph52552ef2019-06-20 09:50:15 +0530133}
Sampa Misrab37be312019-07-03 02:26:41 -0500134
John Wangecb7d572019-10-17 13:38:53 +0800135TEST(getAttrValue, integerScenarios)
136{
137 using namespace bios_parser::bios_integer;
138 AttrValuesMap valueMap{
139 {"VDD_AVSBUS_RAIL", {false, 0, 15, 1, 0}},
140 {"SBE_IMAGE_MINIMUM_VALID_ECS", {true, 1, 15, 1, 2}}};
141
142 auto values = getValues();
143 EXPECT_EQ(valueMap, values);
144 auto value = getAttrValue("SBE_IMAGE_MINIMUM_VALID_ECS");
145 EXPECT_EQ(value, 2);
146
147 EXPECT_THROW(getAttrValue("VDM"), std::out_of_range);
148}
149
John Wang02700402019-10-06 16:34:29 +0800150TEST(traverseBIOSTable, attrTableScenarios)
151{
152 std::vector<uint8_t> enumEntry{
153 0, 0, /* attr handle */
154 0, /* attr type */
155 1, 0, /* attr name handle */
156 2, /* number of possible value */
157 2, 0, /* possible value handle */
158 3, 0, /* possible value handle */
159 1, /* number of default value */
160 0 /* defaut value string handle index */
161 };
162 std::vector<uint8_t> stringEntry{
163 4, 0, /* attr handle */
164 1, /* attr type */
165 12, 0, /* attr name handle */
166 1, /* string type */
167 1, 0, /* minimum length of the string in bytes */
168 100, 0, /* maximum length of the string in bytes */
169 3, 0, /* length of default string in length */
170 'a', 'b', 'c' /* default string */
171 };
172 std::vector<uint8_t> table;
173 table.insert(table.end(), enumEntry.begin(), enumEntry.end());
174 table.insert(table.end(), stringEntry.begin(), stringEntry.end());
175 auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
176
177 table.insert(table.end(), padSize, 0);
178 table.insert(table.end(), sizeof(uint32_t) /*checksum*/, 0);
179
180 pldm::responder::traverseBIOSAttrTable(
181 table, [&](const struct pldm_bios_attr_table_entry* entry) {
182 int rc;
183 switch (entry->attr_type)
184 {
185 case 0:
186 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
187 EXPECT_EQ(rc, 0);
188 break;
189 case 1:
190 rc = std::memcmp(entry, stringEntry.data(),
191 stringEntry.size());
192 EXPECT_EQ(rc, 0);
193 break;
194 default:
195 break;
196 }
197 });
198}
199
Sampa Misrab37be312019-07-03 02:26:41 -0500200namespace fs = std::filesystem;
201class TestAllBIOSTables : public ::testing::Test
202{
203 public:
204 static void SetUpTestCase() // will execute once at the begining of all
205 // TestAllBIOSTables objects
206 {
207 char tmpdir[] = "/tmp/allBiosTables.XXXXXX";
208 biosPath = fs::path(mkdtemp(tmpdir));
209 }
210
211 static void TearDownTestCase() // will be executed once at th eend of all
212 // TestAllBIOSTables objects
213 {
214 fs::remove_all(biosPath);
215 }
216
217 static fs::path biosPath;
218};
219
220fs::path TestAllBIOSTables::biosPath;
221
222TEST_F(TestAllBIOSTables, GetBIOSTableTestBadRequest)
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 = 0xFF;
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
239 struct pldm_get_bios_table_resp* resp =
240 reinterpret_cast<struct pldm_get_bios_table_resp*>(
241 responsePtr->payload);
242
243 ASSERT_EQ(PLDM_INVALID_BIOS_TABLE_TYPE, resp->completion_code);
244}
245
246TEST_F(TestAllBIOSTables, buildBIOSTablesTestBadRequest)
247{
248 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
249 requestPayload{};
250 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
251 struct pldm_get_bios_table_req* req =
252 (struct pldm_get_bios_table_req*)request->payload;
253 req->transfer_handle = 9;
254 req->transfer_op_flag = PLDM_GET_FIRSTPART;
255 req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
256
257 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
258
259 auto response = internal::buildBIOSTables(request, requestPayloadLength,
260 "./bios_jsons", biosPath.c_str());
261 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
262 struct pldm_get_bios_table_resp* resp =
263 reinterpret_cast<struct pldm_get_bios_table_resp*>(
264 responsePtr->payload);
265 ASSERT_EQ(PLDM_BIOS_TABLE_UNAVAILABLE, resp->completion_code);
266
267 req->table_type = PLDM_BIOS_ATTR_TABLE;
268 response = internal::buildBIOSTables(request, requestPayloadLength,
269 "./bios_jsons", biosPath.c_str());
270 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
271 resp = reinterpret_cast<struct pldm_get_bios_table_resp*>(
272 responsePtr->payload);
273 ASSERT_EQ(PLDM_BIOS_TABLE_UNAVAILABLE, resp->completion_code);
274}
275
276TEST_F(TestAllBIOSTables, GetBIOSStringTableTestGoodRequest)
277{
278 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
279 requestPayload{};
280 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
281 struct pldm_get_bios_table_req* req =
282 (struct pldm_get_bios_table_req*)request->payload;
283 req->transfer_handle = 9;
284 req->transfer_op_flag = PLDM_GET_FIRSTPART;
285 req->table_type = PLDM_BIOS_STRING_TABLE;
286
John Wange96e7e52019-10-05 17:47:30 +0800287 Strings biosStrings = getStrings();
Sampa Misrab37be312019-07-03 02:26:41 -0500288 std::sort(biosStrings.begin(), biosStrings.end());
289 biosStrings.erase(std::unique(biosStrings.begin(), biosStrings.end()),
290 biosStrings.end());
291
292 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
293 uint8_t times = 0;
294 while (times < 2)
295 { // first time fresh table second time existing table
296 auto response = internal::buildBIOSTables(
297 request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
298 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
299
300 struct pldm_get_bios_table_resp* resp =
301 reinterpret_cast<struct pldm_get_bios_table_resp*>(
302 responsePtr->payload);
303
304 ASSERT_EQ(0, resp->completion_code);
305 ASSERT_EQ(0, resp->next_transfer_handle);
306 ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
307
308 uint16_t strLen = 0;
309 uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
310
311 for (auto elem : biosStrings)
312 {
313 struct pldm_bios_string_table_entry* ptr =
314 reinterpret_cast<struct pldm_bios_string_table_entry*>(
315 tableData);
316 strLen = ptr->string_length;
317 ASSERT_EQ(strLen, elem.size());
318 ASSERT_EQ(0, memcmp(elem.c_str(), ptr->name, strLen));
319 tableData += (sizeof(pldm_bios_string_table_entry) - 1) + strLen;
320
321 } // end for
322 times++;
323 }
324}
325
326TEST_F(TestAllBIOSTables, getBIOSAttributeTableTestGoodRequest)
327{
328 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
329 requestPayload{};
330 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
331 struct pldm_get_bios_table_req* req =
332 (struct pldm_get_bios_table_req*)request->payload;
333 req->transfer_handle = 9;
334 req->transfer_op_flag = PLDM_GET_FIRSTPART;
335 req->table_type = PLDM_BIOS_ATTR_TABLE;
336
337 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
338
339 uint8_t times = 0;
340 while (times < 2)
341 { // first time fresh table second time existing table
342 auto response = internal::buildBIOSTables(
343 request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
344 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
345
346 struct pldm_get_bios_table_resp* resp =
347 reinterpret_cast<struct pldm_get_bios_table_resp*>(
348 responsePtr->payload);
349
350 ASSERT_EQ(0, resp->completion_code);
351 ASSERT_EQ(0, resp->next_transfer_handle);
352 ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
353
354 uint32_t attrTableLen =
355 response.size() - sizeof(pldm_msg_hdr) -
356 (sizeof(resp->completion_code) +
357 sizeof(resp->next_transfer_handle) + sizeof(resp->transfer_flag));
358 uint32_t traversed = 0;
359 uint16_t attrHdl = 0;
360 uint16_t stringHdl = 0;
361 uint8_t attrType = 0;
362 uint8_t numPosVals = 0;
363 uint8_t numDefVals = 0;
364 uint8_t defIndex = 0;
365
366 uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
367 while (1)
368 {
369 struct pldm_bios_attr_table_entry* ptr =
370 reinterpret_cast<struct pldm_bios_attr_table_entry*>(tableData);
371 attrHdl = ptr->attr_handle;
372 attrType = ptr->attr_type;
373 EXPECT_EQ(0, attrHdl);
John Wange96e7e52019-10-05 17:47:30 +0800374 EXPECT_EQ(PLDM_BIOS_ENUMERATION_READ_ONLY, attrType);
Sampa Misrab37be312019-07-03 02:26:41 -0500375 stringHdl = ptr->string_handle;
376 EXPECT_EQ(stringHdl, 1);
377 tableData += sizeof(attrHdl) + sizeof(attrType) + sizeof(stringHdl);
378 numPosVals = *tableData;
379 EXPECT_EQ(numPosVals, 2);
380 traversed += sizeof(attrHdl) + sizeof(attrType) + sizeof(stringHdl);
381 traversed += sizeof(numPosVals);
382 PossibleValuesByHandle possiVals;
383 tableData++;
384 uint16_t* temp = reinterpret_cast<uint16_t*>(tableData);
385 uint32_t i = 0;
386 while (i < numPosVals)
387 {
388 uint16_t val = *temp;
389 possiVals.push_back(val);
390 temp++;
391 i++;
392 }
393 EXPECT_EQ(possiVals.size(), 2);
394 tableData += numPosVals * sizeof(stringHdl);
395 traversed += numPosVals * sizeof(stringHdl);
396 numDefVals = *tableData;
397 EXPECT_EQ(numDefVals, 1);
398 tableData += numDefVals * sizeof(defIndex);
399 traversed += numDefVals + sizeof(numDefVals);
400
401 break; // test for first row only
402
403 if ((attrTableLen - traversed) < 8)
404 {
405 // reached pad
406 break;
407 }
408
409 } // end while
410 times++;
411 }
412
413} // end TEST
414
415TEST_F(TestAllBIOSTables, getBIOSAttributeValueTableTestGoodRequest)
416{
417 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
418 requestPayload{};
419 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
420 struct pldm_get_bios_table_req* req =
421 (struct pldm_get_bios_table_req*)request->payload;
422 req->transfer_handle = 9;
423 req->transfer_op_flag = PLDM_GET_FIRSTPART;
424 req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
425
426 std::string attrName("CodeUpdatePolicy");
John Wangecb7d572019-10-17 13:38:53 +0800427 bios_enum::CurrentValues currVals = bios_enum::getAttrValue(attrName);
Sampa Misrab37be312019-07-03 02:26:41 -0500428
429 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
430
431 uint8_t times = 0;
432 while (times < 2)
433 { // first time frest table second time existing table
434 auto response = internal::buildBIOSTables(
435 request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
436 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
437
438 struct pldm_get_bios_table_resp* resp =
439 reinterpret_cast<struct pldm_get_bios_table_resp*>(
440 responsePtr->payload);
441
442 ASSERT_EQ(0, resp->completion_code);
443 ASSERT_EQ(0, resp->next_transfer_handle);
444 ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
445
446 uint32_t attrValTableLen =
447 response.size() - sizeof(pldm_msg_hdr) -
448 (sizeof(resp->completion_code) +
449 sizeof(resp->next_transfer_handle) + sizeof(resp->transfer_flag));
450 uint32_t traversed = 0;
451 uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
452
453 uint16_t attrHdl;
454 uint8_t attrType;
455 uint8_t numCurrVals;
456 uint8_t currValStrIndex;
457
458 while (1)
459 {
460 struct pldm_bios_attr_val_table_entry* ptr =
461 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
462 tableData);
463 attrHdl = ptr->attr_handle;
464 attrType = ptr->attr_type;
465 EXPECT_EQ(0, attrHdl);
John Wange96e7e52019-10-05 17:47:30 +0800466 EXPECT_EQ(PLDM_BIOS_ENUMERATION_READ_ONLY, attrType);
Sampa Misrab37be312019-07-03 02:26:41 -0500467 tableData += sizeof(attrHdl) + sizeof(attrType);
468 traversed += sizeof(attrHdl) + sizeof(attrType);
469 numCurrVals = *tableData;
470 EXPECT_EQ(1, numCurrVals);
471 tableData += sizeof(numCurrVals);
472 traversed += sizeof(numCurrVals);
473 currValStrIndex = *tableData;
474 EXPECT_EQ(0, currValStrIndex);
475 tableData += numCurrVals;
476 traversed += numCurrVals;
477 break; // testing for first row
478 if ((attrValTableLen - traversed) < 8)
479 {
480 break;
481 }
482 }
483 times++;
484 }
485
486} // end TEST
Carol Wang69d3e7f2019-09-04 16:43:15 +0800487
488class TestSingleTypeBIOSTable : public ::testing::Test
489{
490 public:
491 void SetUp() override
492 { // will be executed before each individual test defined
493 // in TestSingleTypeBIOSTable
494 char tmpdir[] = "/tmp/singleTypeBIOSTable.XXXXXX";
495 destBiosPath = fs::path(mkdtemp(tmpdir));
496 }
497
498 void TearDown() override
499 { // will be executed after each individual test
500 // defined in TestSingleTypeBIOSTable
501 fs::remove_all(destBiosPath);
502 }
503
504 void CopySingleJsonFile(std::string file)
505 {
506 fs::path srcDir("./bios_jsons");
507 fs::path srcBiosPath = srcDir / file;
508 std::filesystem::copy(srcBiosPath, destBiosPath);
509 }
510
511 fs::path destBiosPath;
512};
513
514TEST_F(TestSingleTypeBIOSTable, getBIOSAttributeValueTableBasedOnStringTypeTest)
515{
516 // Copy string json file to the destination
517 TestSingleTypeBIOSTable::CopySingleJsonFile(bios_parser::bIOSStrJson);
518 auto fpath = TestSingleTypeBIOSTable::destBiosPath.c_str();
519
520 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
521 requestPayload{};
522 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
523 struct pldm_get_bios_table_req* req =
524 (struct pldm_get_bios_table_req*)request->payload;
525
526 // Get string table with string json file only
527 req->transfer_handle = 9;
528 req->transfer_op_flag = PLDM_GET_FIRSTPART;
529 req->table_type = PLDM_BIOS_STRING_TABLE;
530
531 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
532 auto str_response =
533 internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
534
535 // Get attribute table with string json file only
536 req->transfer_handle = 9;
537 req->transfer_op_flag = PLDM_GET_FIRSTPART;
538 req->table_type = PLDM_BIOS_ATTR_TABLE;
539
540 auto attr_response =
541 internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
542
543 // Get attribute value table with string type
544 req->transfer_handle = 9;
545 req->transfer_op_flag = PLDM_GET_FIRSTPART;
546 req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
547
548 // Test attribute str_example3 here, which has no dbus
549 for (uint8_t times = 0; times < 2; times++)
550 { // first time first table second time existing table
551 auto response = internal::buildBIOSTables(request, requestPayloadLength,
552 fpath, fpath);
553 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
554
555 struct pldm_get_bios_table_resp* resp =
556 reinterpret_cast<struct pldm_get_bios_table_resp*>(
557 responsePtr->payload);
558
559 ASSERT_EQ(0, resp->completion_code);
560 ASSERT_EQ(0, resp->next_transfer_handle);
561 ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
562
563 uint32_t attrValTableLen =
564 response.size() - sizeof(pldm_msg_hdr) -
565 (sizeof(struct pldm_get_bios_table_resp) - 1);
566 uint32_t traversed = 0;
567 uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
568
569 while (true)
570 {
571 struct pldm_bios_attr_val_table_entry* ptr =
572 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
573 tableData);
574 uint16_t attrHdl = ptr->attr_handle;
575 uint8_t attrType = ptr->attr_type;
576 EXPECT_EQ(PLDM_BIOS_STRING_READ_ONLY, attrType);
577 tableData += sizeof(attrHdl) + sizeof(attrType);
578 traversed += sizeof(attrHdl) + sizeof(attrType);
579 auto sizeDefaultStr = *(reinterpret_cast<uint16_t*>(tableData));
580 EXPECT_EQ(2, sizeDefaultStr);
581 tableData += sizeof(uint16_t);
582 traversed += sizeof(uint16_t);
583 EXPECT_EQ('e', *tableData);
584 EXPECT_EQ('f', *(tableData + 1));
585 tableData += sizeDefaultStr;
586 traversed += sizeDefaultStr;
587 break; // testing for first row
588 if ((attrValTableLen - traversed) < 8)
589 {
590 break;
591 }
592 }
593 }
594
595} // end TEST
John Wangdbbc9ff2019-10-25 13:53:46 +0800596
597TEST_F(TestSingleTypeBIOSTable,
598 getBIOSAttributeValueTableBasedOnIntegerTypeTest)
599{
600 // Copy integer json file to the destination
601 TestSingleTypeBIOSTable::CopySingleJsonFile(bios_parser::bIOSIntegerJson);
602 auto fpath = TestSingleTypeBIOSTable::destBiosPath.c_str();
603
604 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
605 requestPayload{};
606 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
607 struct pldm_get_bios_table_req* req =
608 (struct pldm_get_bios_table_req*)request->payload;
609
610 // Get string table with integer json file only
611 req->transfer_handle = 9;
612 req->transfer_op_flag = PLDM_GET_FIRSTPART;
613 req->table_type = PLDM_BIOS_STRING_TABLE;
614
615 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
616 internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
617
618 // Get attribute table with integer json file only
619 req->transfer_handle = 9;
620 req->transfer_op_flag = PLDM_GET_FIRSTPART;
621 req->table_type = PLDM_BIOS_ATTR_TABLE;
622
623 auto attr_response =
624 internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
625
626 // Get attribute value table with integer type
627 req->transfer_handle = 9;
628 req->transfer_op_flag = PLDM_GET_FIRSTPART;
629 req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
630
631 // Test attribute SBE_IMAGE_MINIMUM_VALID_ECS here, which has no dbus
632 for (uint8_t times = 0; times < 2; times++)
633 { // first time first table second time existing table
634 auto response = internal::buildBIOSTables(request, requestPayloadLength,
635 fpath, fpath);
636 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
637
638 struct pldm_get_bios_table_resp* resp =
639 reinterpret_cast<struct pldm_get_bios_table_resp*>(
640 responsePtr->payload);
641
642 EXPECT_EQ(0, resp->completion_code);
643 EXPECT_EQ(0, resp->next_transfer_handle);
644 EXPECT_EQ(PLDM_START_AND_END, resp->transfer_flag);
645 uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
646 auto ptr =
647 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(tableData);
648 uint16_t attrHdl = ptr->attr_handle;
649 uint8_t attrType = ptr->attr_type;
650 EXPECT_EQ(PLDM_BIOS_INTEGER_READ_ONLY, attrType);
651 tableData += sizeof(attrHdl) + sizeof(attrType);
652 auto cv = *(reinterpret_cast<uint64_t*>(tableData));
653 EXPECT_EQ(2, cv);
654 }
655}