Add unit test for full FRU decode
To start refactoring this, it is helpful if we have a representative
unit test that decodes a full FRU.
To simplify this, the internal interfaces have been updated to support
passing values by std::span<const uint8_t> instead of by reference to
std::vector.
Tested: Unit tests pass
Change-Id: If8a618969b99d3d8a32bc7203aa2f57d0f999bdf
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/src/fru_utils.cpp b/src/fru_utils.cpp
index 3ce9ef4..b5c3152 100644
--- a/src/fru_utils.cpp
+++ b/src/fru_utils.cpp
@@ -100,8 +100,8 @@
* iterator is no longer usable.
*/
std::pair<DecodeState, std::string> decodeFRUData(
- std::vector<uint8_t>::const_iterator& iter,
- const std::vector<uint8_t>::const_iterator& end, bool isLangEng)
+ std::span<const uint8_t>::const_iterator& iter,
+ std::span<const uint8_t>::const_iterator& end, bool isLangEng)
{
std::string value;
unsigned int i = 0;
@@ -224,7 +224,7 @@
* len: Length of current area space and it is a multiple of 8 bytes
* as per specification
*/
-bool verifyOffset(const std::vector<uint8_t>& fruBytes, fruAreas currentArea,
+bool verifyOffset(std::span<const uint8_t> fruBytes, fruAreas currentArea,
uint8_t len)
{
unsigned int fruBytesSize = fruBytes.size();
@@ -290,7 +290,7 @@
}
static void parseMultirecordUUID(
- const std::vector<uint8_t>& device,
+ std::span<const uint8_t> device,
boost::container::flat_map<std::string, std::string>& result)
{
constexpr size_t uuidDataLen = 16;
@@ -304,8 +304,12 @@
*/
const std::array<uint8_t, uuidDataLen> uuidCharOrder = {
3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15};
- uint32_t areaOffset =
- device.at(getHeaderAreaFieldOffset(fruAreas::fruAreaMultirecord));
+ size_t offset = getHeaderAreaFieldOffset(fruAreas::fruAreaMultirecord);
+ if (offset >= device.size())
+ {
+ throw std::runtime_error("Multirecord UUID offset is out of range");
+ }
+ uint32_t areaOffset = device[offset];
if (areaOffset == 0)
{
@@ -313,7 +317,7 @@
}
areaOffset *= fruBlockSize;
- std::vector<uint8_t>::const_iterator fruBytesIter =
+ std::span<const uint8_t>::const_iterator fruBytesIter =
device.begin() + areaOffset;
/* Verify area offset */
@@ -370,7 +374,7 @@
}
resCodes formatIPMIFRU(
- const std::vector<uint8_t>& fruBytes,
+ std::span<const uint8_t> fruBytes,
boost::container::flat_map<std::string, std::string>& result)
{
resCodes ret = resCodes::resOK;
@@ -394,7 +398,7 @@
continue;
}
offset *= fruBlockSize;
- std::vector<uint8_t>::const_iterator fruBytesIter =
+ std::span<const uint8_t>::const_iterator fruBytesIter =
fruBytes.begin() + offset;
if (fruBytesIter + fruBlockSize >= fruBytes.end())
{
@@ -418,7 +422,7 @@
}
size_t fruAreaSize = *fruBytesIter * fruBlockSize;
- std::vector<uint8_t>::const_iterator fruBytesIterEndArea =
+ std::span<const uint8_t>::const_iterator fruBytesIterEndArea =
fruBytes.begin() + offset + fruAreaSize - 1;
++fruBytesIter;
@@ -579,15 +583,15 @@
}
// Calculate new checksum for fru info area
-uint8_t calculateChecksum(std::vector<uint8_t>::const_iterator iter,
- std::vector<uint8_t>::const_iterator end)
+uint8_t calculateChecksum(std::span<const uint8_t>::const_iterator iter,
+ std::span<const uint8_t>::const_iterator end)
{
constexpr int checksumMod = 256;
uint8_t sum = std::accumulate(iter, end, static_cast<uint8_t>(0));
return (checksumMod - sum) % checksumMod;
}
-uint8_t calculateChecksum(std::vector<uint8_t>& fruAreaData)
+uint8_t calculateChecksum(std::span<const uint8_t> fruAreaData)
{
return calculateChecksum(fruAreaData.begin(), fruAreaData.end());
}
diff --git a/src/fru_utils.hpp b/src/fru_utils.hpp
index dcd9752..b427c25 100644
--- a/src/fru_utils.hpp
+++ b/src/fru_utils.hpp
@@ -114,25 +114,25 @@
char bcdPlusToChar(uint8_t val);
-bool verifyOffset(const std::vector<uint8_t>& fruBytes, fruAreas currentArea,
+bool verifyOffset(std::span<const uint8_t> fruBytes, fruAreas currentArea,
uint8_t len);
std::pair<DecodeState, std::string> decodeFRUData(
- std::vector<uint8_t>::const_iterator& iter,
- const std::vector<uint8_t>::const_iterator& end, bool isLangEng);
+ std::span<const uint8_t>::const_iterator& iter,
+ std::span<const uint8_t>::const_iterator& end, bool isLangEng);
bool checkLangEng(uint8_t lang);
resCodes formatIPMIFRU(
- const std::vector<uint8_t>& fruBytes,
+ std::span<const uint8_t> fruBytes,
boost::container::flat_map<std::string, std::string>& result);
std::vector<uint8_t>& getFRUInfo(const uint16_t& bus, const uint8_t& address);
-uint8_t calculateChecksum(std::vector<uint8_t>::const_iterator iter,
- std::vector<uint8_t>::const_iterator end);
+uint8_t calculateChecksum(std::span<const uint8_t>::const_iterator iter,
+ std::span<const uint8_t>::const_iterator end);
-uint8_t calculateChecksum(std::vector<uint8_t>& fruAreaData);
+uint8_t calculateChecksum(std::span<const uint8_t> fruAreaData);
unsigned int updateFRUAreaLenAndChecksum(
std::vector<uint8_t>& fruData, size_t fruAreaStart,