summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVernon Mauery <vernon.mauery@linux.intel.com>2018-12-12 09:39:22 -0800
committerVernon Mauery <vernon.mauery@linux.intel.com>2019-02-25 14:27:21 -0800
commitebe8e90639e3ce11193c9c823662b1ad8280b6f2 (patch)
tree83ca24b523d140b7899f52f9a98f4c819f3fbb1b
parente7329c71f3d22e010c38a7f738e81ab78330038e (diff)
downloadphosphor-host-ipmid-ebe8e90639e3ce11193c9c823662b1ad8280b6f2.tar.gz
phosphor-host-ipmid-ebe8e90639e3ce11193c9c823662b1ad8280b6f2.zip
ipmid: add message packing/unpacking unit tests
This adds unit tests for the various types that the message packer/unpacker handles. This includes tests for simple messages as well as complex messages. It also includes positive and negative testing to make sure that failed packing and unpacking gets reported properly. Change-Id: I9360c867cccbeba6a707dda6df6c5e29fa585c5c Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
-rw-r--r--test/Makefile.am49
-rw-r--r--test/message/pack.cpp324
-rw-r--r--test/message/payload.cpp308
-rw-r--r--test/message/unpack.cpp857
4 files changed, 1536 insertions, 2 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index 847aaad..e510230 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,4 +1,23 @@
-AM_CPPFLAGS = -I$(top_srcdir) $(CODE_COVERAGE_CPPFLAGS) $(GTEST_CFLAGS)
+COMMON_CXX = \
+ -flto \
+ -Wno-psabi \
+ $(SDBUSPLUS_CFLAGS) \
+ $(SYSTEMD_CFLAGS) \
+ $(libmapper_CFLAGS) \
+ $(SDBUSPLUS_CFLAGS) \
+ $(PHOSPHOR_LOGGING_CFLAGS) \
+ $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
+ -DBOOST_ERROR_CODE_HEADER_ONLY \
+ -DBOOST_SYSTEM_NO_DEPRECATED \
+ -DBOOST_COROUTINES_NO_DEPRECATION_WARNING \
+ -DBOOST_ASIO_DISABLE_THREADS \
+ -DBOOST_ALL_NO_LIB
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/include \
+ $(CODE_COVERAGE_CPPFLAGS) \
+ $(GTEST_CFLAGS)
AM_CFLAGS = $(CODE_COVERAGE_CFLAGS)
AM_CXXFLAGS = $(GTEST_MAIN_CFLAGS) $(GTEST_CFLAGS)
AM_LDFLAGS = $(GTEST_MAIN_LIBS) $(OESDK_TESTCASE_FLAGS)
@@ -11,7 +30,7 @@ TESTS = $(check_PROGRAMS)
sample_unittest_CPPFLAGS = -Igtest $(GTEST_CPPFLAGS) $(AM_CPPFLAGS)
sample_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(CODE_COVERAGE_CXXFLAGS) \
$(CODE_COVERAGE_CFLAGS)
-sample_unittest_LDFLAGS = -lgtest_main -lgtest $(PTHREAD_LIBS) $(OESDK_TESTCASE_FLAGS) \
+sample_unittest_LDFLAGS = -lgtest_main -lgtest -pthread $(OESDK_TESTCASE_FLAGS) \
$(CODE_COVERAGE_LDFLAGS)
sample_unittest_SOURCES = %reldir%/sample_unittest.cpp
sample_unittest_LDADD = $(top_builddir)/sample.o
@@ -22,3 +41,29 @@ check_PROGRAMS += %reldir%/sample_unittest
#check_PROGRAMS += oemrouter_unittest
#oemrouter_unittest_SOURCES = oemrouter_unittest.cpp
#oemrouter_unittest_LDADD = $(top_builddir)/oemrouter.o
+
+# Build/add message packing/unpacking unit tests
+message_unittest_CPPFLAGS = \
+ -Igtest \
+ $(GTEST_CPPFLAGS) \
+ $(AM_CPPFLAGS)
+message_unittest_CXXFLAGS = \
+ $(COMMON_CXX) \
+ $(PTHREAD_CFLAGS) \
+ $(PHOSPHOR_LOGGING_CFLAGS) \
+ $(CODE_COVERAGE_CXXFLAGS) \
+ $(CODE_COVERAGE_CFLAGS)
+message_unittest_LDFLAGS = \
+ -lgtest_main \
+ -lgtest \
+ -lsdbusplus \
+ -lsystemd \
+ -pthread \
+ $(PHOSPHOR_LOGGING_LIBS) \
+ $(OESDK_TESTCASE_FLAGS) \
+ $(CODE_COVERAGE_LDFLAGS)
+message_unittest_SOURCES = \
+ %reldir%/message/payload.cpp \
+ %reldir%/message/unpack.cpp \
+ %reldir%/message/pack.cpp
+check_PROGRAMS += %reldir%/message_unittest
diff --git a/test/message/pack.cpp b/test/message/pack.cpp
new file mode 100644
index 0000000..60459ed
--- /dev/null
+++ b/test/message/pack.cpp
@@ -0,0 +1,324 @@
+/**
+ * Copyright © 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <ipmid/api.hpp>
+#include <ipmid/message.hpp>
+
+#include <gtest/gtest.h>
+
+// TODO: Add testing of Payload response API
+
+TEST(PackBasics, Uint8)
+{
+ ipmi::message::Payload p;
+ uint8_t v = 4;
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), sizeof(v));
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0x04};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Uint16)
+{
+ ipmi::message::Payload p;
+ uint16_t v = 0x8604;
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), sizeof(v));
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0x04, 0x86};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Uint32)
+{
+ ipmi::message::Payload p;
+ uint32_t v = 0x02008604;
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), sizeof(v));
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0x04, 0x86, 0x00, 0x02};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Uint64)
+{
+ ipmi::message::Payload p;
+ uint64_t v = 0x1122334402008604ull;
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), sizeof(v));
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22, 0x11};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Uint24)
+{
+ ipmi::message::Payload p;
+ uint24_t v = 0x112358;
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), types::nrFixedBits<decltype(v)> / CHAR_BIT);
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0x58, 0x23, 0x11};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Uint3Uint5)
+{
+ // individual bytes are packed low-order-bits first
+ // v1 will occupy [2:0], v2 will occupy [7:3]
+ ipmi::message::Payload p;
+ uint3_t v1 = 0x1;
+ uint5_t v2 = 0x19;
+ p.pack(v1, v2);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), (types::nrFixedBits<decltype(v1)> +
+ types::nrFixedBits<decltype(v2)>) /
+ CHAR_BIT);
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0xc9};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Boolx8)
+{
+ // individual bytes are packed low-order-bits first
+ // [v8, v7, v6, v5, v4, v3, v2, v1]
+ ipmi::message::Payload p;
+ bool v8 = true, v7 = true, v6 = false, v5 = false;
+ bool v4 = true, v3 = false, v2 = false, v1 = true;
+ p.pack(v1, v2, v3, v4, v5, v6, v7, v8);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), sizeof(uint8_t));
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0xc9};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Bitset8)
+{
+ // individual bytes are packed low-order-bits first
+ // a bitset for 8 bits fills the full byte
+ ipmi::message::Payload p;
+ std::bitset<8> v(0xc9);
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), v.size() / CHAR_BIT);
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0xc9};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Bitset3Bitset5)
+{
+ // individual bytes are packed low-order-bits first
+ // v1 will occupy [2:0], v2 will occupy [7:3]
+ ipmi::message::Payload p;
+ std::bitset<3> v1(0x1);
+ std::bitset<5> v2(0x19);
+ p.pack(v1, v2);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), (v1.size() + v2.size()) / CHAR_BIT);
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0xc9};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Bitset32)
+{
+ // individual bytes are packed low-order-bits first
+ // v1 will occupy 4 bytes, but in LSByte first order
+ // v1[7:0] v1[15:9] v1[23:16] v1[31:24]
+ ipmi::message::Payload p;
+ std::bitset<32> v(0x02008604);
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), v.size() / CHAR_BIT);
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0x04, 0x86, 0x00, 0x02};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Array4xUint8)
+{
+ // an array of bytes will be output verbatim, low-order element first
+ ipmi::message::Payload p;
+ std::array<uint8_t, 4> v = {{0x02, 0x00, 0x86, 0x04}};
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), v.size() * sizeof(v[0]));
+ // check that the bytes were correctly packed (in byte order)
+ std::vector<uint8_t> k = {0x02, 0x00, 0x86, 0x04};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, Array4xUint32)
+{
+ // an array of multi-byte values will be output in order low-order
+ // element first, each multi-byte element in LSByte order
+ // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+ // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+ // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+ // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+ ipmi::message::Payload p;
+ std::array<uint32_t, 4> v = {
+ {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), v.size() * sizeof(v[0]));
+ // check that the bytes were correctly packed (in byte order)
+ std::vector<uint8_t> k = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+ 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, VectorUint32)
+{
+ // a vector of multi-byte values will be output in order low-order
+ // element first, each multi-byte element in LSByte order
+ // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+ // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+ // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+ // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+ ipmi::message::Payload p;
+ std::vector<uint32_t> v = {
+ {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), v.size() * sizeof(v[0]));
+ // check that the bytes were correctly packed (in byte order)
+ std::vector<uint8_t> k = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+ 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, VectorUint8)
+{
+ // a vector of bytes will be output verbatim, low-order element first
+ ipmi::message::Payload p;
+ std::vector<uint8_t> v = {0x02, 0x00, 0x86, 0x04};
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), v.size() * sizeof(v[0]));
+ // check that the bytes were correctly packed (in byte order)
+ std::vector<uint8_t> k = {0x02, 0x00, 0x86, 0x04};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackAdvanced, Uints)
+{
+ // all elements will be processed in order, with each multi-byte
+ // element being processed LSByte first
+ // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
+ // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
+ // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
+ ipmi::message::Payload p;
+ uint8_t v1 = 0x02;
+ uint16_t v2 = 0x0604;
+ uint32_t v3 = 0x44332211;
+ uint64_t v4 = 0xccbbaa9988776655ull;
+ p.pack(v1, v2, v3, v4);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), sizeof(v1) + sizeof(v2) + sizeof(v3) + sizeof(v4));
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackAdvanced, TupleInts)
+{
+ // all elements will be processed in order, with each multi-byte
+ // element being processed LSByte first
+ // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
+ // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
+ // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
+ ipmi::message::Payload p;
+ uint8_t v1 = 0x02;
+ uint16_t v2 = 0x0604;
+ uint32_t v3 = 0x44332211;
+ uint64_t v4 = 0xccbbaa9988776655ull;
+ auto v = std::make_tuple(v1, v2, v3, v4);
+ p.pack(v);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), sizeof(v1) + sizeof(v2) + sizeof(v3) + sizeof(v4));
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackAdvanced, BoolsnBitfieldsnFixedIntsOhMy)
+{
+ // each element will be added, filling the low-order bits first
+ // with multi-byte values getting added LSByte first
+ // v1 will occupy k[0][1:0]
+ // v2 will occupy k[0][2]
+ // v3[4:0] will occupy k[0][7:3], v3[6:5] will occupy k[1][1:0]
+ // v4 will occupy k[1][2]
+ // v5 will occupy k[1][7:3]
+ ipmi::message::Payload p;
+ uint2_t v1 = 2; // binary 0b10
+ bool v2 = true; // binary 0b1
+ std::bitset<7> v3(0x73); // binary 0b1110011
+ bool v4 = false; // binary 0b0
+ uint5_t v5 = 27; // binary 0b11011
+ // concat binary: 0b1101101110011110 -> 0xdb9e -> 0x9e 0xdb (LSByte first)
+ p.pack(v1, v2, v3, v4, v5);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), sizeof(uint16_t));
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0x9e, 0xdb};
+ ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackAdvanced, UnalignedBitPacking)
+{
+ // unaligned multi-byte values will be packed the same as
+ // other bits, effectively building up a large value, low-order
+ // bits first, then outputting a stream of LSByte values
+ // v1 will occupy k[0][1:0]
+ // v2[5:0] will occupy k[0][7:2], v2[7:6] will occupy k[1][1:0]
+ // v3 will occupy k[1][2]
+ // v4[4:0] will occupy k[1][7:3] v4[12:5] will occupy k[2][7:0]
+ // v4[15:13] will occupy k[3][2:0]
+ // v5 will occupy k[3][3]
+ // v6[3:0] will occupy k[3][7:0] v6[11:4] will occupy k[4][7:0]
+ // v6[19:12] will occupy k[5][7:0] v6[27:20] will occupy k[6][7:0]
+ // v6[31:28] will occupy k[7][3:0]
+ // v7 will occupy k[7][7:4]
+ ipmi::message::Payload p;
+ uint2_t v1 = 2; // binary 0b10
+ uint8_t v2 = 0xa5; // binary 0b10100101
+ bool v3 = false; // binary 0b0
+ uint16_t v4 = 0xa55a; // binary 0b1010010101011010
+ bool v5 = true; // binary 0b1
+ uint32_t v6 = 0xdbc3bd3c; // binary 0b11011011110000111011110100111100
+ uint4_t v7 = 9; // binary 0b1001
+ // concat binary:
+ // 0b1001110110111100001110111101001111001101001010101101001010010110
+ // -> 0x9dbc3bd3cd2ad296 -> 0x96 0xd2 0x2a 0xcd 0xd3 0x3b 0xbc 0x9d
+ p.pack(v1, v2, v3, v4, v5, v6, v7);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.size(), sizeof(uint64_t));
+ // check that the bytes were correctly packed (LSB first)
+ std::vector<uint8_t> k = {0x96, 0xd2, 0x2a, 0xcd, 0xd3, 0x3b, 0xbc, 0x9d};
+ ASSERT_EQ(p.raw, k);
+}
diff --git a/test/message/payload.cpp b/test/message/payload.cpp
new file mode 100644
index 0000000..9d20ff0
--- /dev/null
+++ b/test/message/payload.cpp
@@ -0,0 +1,308 @@
+/**
+ * Copyright © 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <ipmid/api.hpp>
+#include <ipmid/message.hpp>
+
+#include <gtest/gtest.h>
+
+TEST(Payload, InputSize)
+{
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ size_t input_size = i.size();
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ ASSERT_EQ(input_size, p.size());
+}
+
+TEST(Payload, OutputSize)
+{
+ ipmi::message::Payload p;
+ ASSERT_EQ(0, p.size());
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ p.pack(i);
+ ASSERT_EQ(i.size(), p.size());
+ p.pack(i);
+ p.pack(i);
+ ASSERT_EQ(3 * i.size(), p.size());
+}
+
+TEST(Payload, Resize)
+{
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ ipmi::message::Payload p;
+ p.pack(i);
+ p.resize(16);
+ ASSERT_EQ(p.size(), 16);
+}
+
+TEST(Payload, Data)
+{
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ ipmi::message::Payload p;
+ p.pack(i);
+ ASSERT_NE(nullptr, p.data());
+}
+
+TEST(PayloadResponse, Append)
+{
+ std::string s("0123456789abcdef");
+ ipmi::message::Payload p;
+ p.append(s.data(), s.data() + s.size());
+ ASSERT_EQ(s.size(), p.size());
+}
+
+TEST(PayloadResponse, AppendDrain)
+{
+ std::string s("0123456789abcdef");
+ ipmi::message::Payload p;
+ bool b = true;
+ // first pack a lone bit
+ p.pack(b);
+ p.append(s.data(), s.data() + s.size());
+ // append will 'drain' first, padding the lone bit into a full byte
+ ASSERT_EQ(s.size() + 1, p.size());
+}
+
+TEST(PayloadResponse, AppendBits)
+{
+ ipmi::message::Payload p;
+ p.appendBits(3, 0b101);
+ ASSERT_EQ(p.bitStream, 0b101);
+ p.appendBits(4, 0b1100);
+ ASSERT_EQ(p.bitStream, 0b1100101);
+ p.appendBits(1, 0b1);
+ ASSERT_EQ(p.bitStream, 0);
+ ASSERT_EQ(p.bitCount, 0);
+ // appended 8 bits, should be one byte
+ ASSERT_EQ(p.size(), 1);
+ std::vector<uint8_t> k1 = {0b11100101};
+ ASSERT_EQ(p.raw, k1);
+ p.appendBits(7, 0b1110111);
+ // appended 7 more bits, should still be one byte
+ ASSERT_EQ(p.size(), 1);
+ p.drain();
+ // drain forces padding; should be two bytes now
+ ASSERT_EQ(p.size(), 2);
+ std::vector<uint8_t> k2 = {0b11100101, 0b01110111};
+ ASSERT_EQ(p.raw, k2);
+}
+
+TEST(PayloadResponse, Drain16Bits)
+{
+ ipmi::message::Payload p;
+ p.bitStream = 0b1011010011001111;
+ p.bitCount = 16;
+ p.drain();
+ ASSERT_EQ(p.size(), 2);
+ ASSERT_EQ(p.bitCount, 0);
+ ASSERT_EQ(p.bitStream, 0);
+ std::vector<uint8_t> k1 = {0b11001111, 0b10110100};
+ ASSERT_EQ(p.raw, k1);
+}
+
+TEST(PayloadResponse, Drain15Bits)
+{
+ ipmi::message::Payload p;
+ p.bitStream = 0b101101001100111;
+ p.bitCount = 15;
+ p.drain();
+ ASSERT_EQ(p.size(), 2);
+ ASSERT_EQ(p.bitCount, 0);
+ ASSERT_EQ(p.bitStream, 0);
+ std::vector<uint8_t> k1 = {0b1100111, 0b1011010};
+ ASSERT_EQ(p.raw, k1);
+}
+
+TEST(PayloadResponse, Drain15BitsWholeBytesOnly)
+{
+ ipmi::message::Payload p;
+ p.bitStream = 0b101101001100111;
+ p.bitCount = 15;
+ p.drain(true);
+ // only the first whole byte should have been 'drained' into p.raw
+ ASSERT_EQ(p.size(), 1);
+ ASSERT_EQ(p.bitCount, 7);
+ ASSERT_EQ(p.bitStream, 0b1011010);
+ std::vector<uint8_t> k1 = {0b1100111};
+ ASSERT_EQ(p.raw, k1);
+}
+
+TEST(PayloadRequest, Pop)
+{
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ const auto& [vb, ve] = p.pop<uint8_t>(4);
+ std::vector<uint8_t> v(vb, ve);
+ std::vector<uint8_t> k = {0xbf, 0x04, 0x86, 0x00};
+ ASSERT_EQ(v, k);
+}
+
+TEST(PayloadRequest, FillBits)
+{
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ p.fillBits(5);
+ ASSERT_FALSE(p.unpackError);
+ ASSERT_EQ(p.bitStream, 0xbf);
+ ASSERT_EQ(p.bitCount, 8);
+ // should still have 5 bits available, no change
+ p.fillBits(5);
+ ASSERT_FALSE(p.unpackError);
+ ASSERT_EQ(p.bitStream, 0xbf);
+ ASSERT_EQ(p.bitCount, 8);
+ // discard 5 bits (low order)
+ p.popBits(5);
+ // should add another byte into the stream (high order)
+ p.fillBits(5);
+ ASSERT_FALSE(p.unpackError);
+ ASSERT_EQ(p.bitStream, 0x25);
+ ASSERT_EQ(p.bitCount, 11);
+}
+
+TEST(PayloadRequest, FillBitsTooManyBits)
+{
+ std::vector<uint8_t> i = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ p.fillBits(72);
+ ASSERT_TRUE(p.unpackError);
+}
+
+TEST(PayloadRequest, FillBitsNotEnoughBytes)
+{
+ std::vector<uint8_t> i = {1, 2, 3, 4};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ p.fillBits(48);
+ ASSERT_TRUE(p.unpackError);
+}
+
+TEST(PayloadRequest, PopBits)
+{
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ p.fillBits(4);
+ uint8_t v = p.popBits(4);
+ ASSERT_FALSE(p.unpackError);
+ ASSERT_EQ(p.bitStream, 0x0b);
+ ASSERT_EQ(p.bitCount, 4);
+ ASSERT_EQ(v, 0x0f);
+}
+
+TEST(PayloadRequest, PopBitsNoFillBits)
+{
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ p.popBits(4);
+ ASSERT_TRUE(p.unpackError);
+}
+
+TEST(PayloadRequest, DiscardBits)
+{
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ p.fillBits(5);
+ ASSERT_FALSE(p.unpackError);
+ ASSERT_EQ(p.bitStream, 0xbf);
+ ASSERT_EQ(p.bitCount, 8);
+ p.discardBits();
+ ASSERT_FALSE(p.unpackError);
+ ASSERT_EQ(p.bitStream, 0);
+ ASSERT_EQ(p.bitCount, 0);
+}
+
+TEST(PayloadRequest, FullyUnpacked)
+{
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint32_t v1;
+ p.unpack(v1);
+ // still one remaining byte
+ ASSERT_FALSE(p.fullyUnpacked());
+ p.fillBits(3);
+ p.popBits(3);
+ // still five remaining bits
+ ASSERT_FALSE(p.fullyUnpacked());
+ p.fillBits(5);
+ p.popBits(5);
+ // fully unpacked, should be no errors
+ ASSERT_TRUE(p.fullyUnpacked());
+ p.fillBits(4);
+ // fullyUnpacked fails because an attempt to unpack too many bytes
+ ASSERT_FALSE(p.fullyUnpacked());
+}
+
+TEST(PayloadRequest, ResetInternal)
+{
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ p.fillBits(4);
+ p.unpackError = true;
+ p.reset();
+ ASSERT_EQ(p.rawIndex, 0);
+ ASSERT_EQ(p.bitStream, 0);
+ ASSERT_EQ(p.bitCount, 0);
+ ASSERT_FALSE(p.unpackError);
+}
+
+TEST(PayloadRequest, ResetUsage)
+{
+ // Payload.reset is used to rewind the unpacking to the initial
+ // state. This is needed so that OEM commands can unpack the group
+ // number or the IANA to determine which handler needs to be called
+ std::vector<uint8_t> i = {0x04, 0x86};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint8_t v1;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v1), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ uint8_t k1 = 0x04;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v1, k1);
+ // do a reset on the payload
+ p.reset();
+ // unpack a uint16
+ uint16_t v2;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v2), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ uint16_t k2 = 0x8604;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v2, k2);
+}
+
+TEST(PayloadRequest, PartialPayload)
+{
+ std::vector<uint8_t> i = {0xbf, 0x04, 0x86, 0x00, 0x02};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint8_t v1;
+ ipmi::message::Payload localPayload;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v1, localPayload), 0);
+ // check that the payload was partially unpacked and not in error
+ ASSERT_FALSE(p.fullyUnpacked());
+ ASSERT_FALSE(p.unpackError);
+ // check that the 'extracted' payload is not fully unpacked
+ ASSERT_FALSE(localPayload.fullyUnpacked());
+ uint8_t k1 = 0xbf;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v1, k1);
+ uint32_t v2;
+ // unpack using the 'extracted' payload
+ ASSERT_EQ(localPayload.unpack(v2), 0);
+ ASSERT_TRUE(localPayload.fullyUnpacked());
+ uint32_t k2 = 0x02008604;
+ ASSERT_EQ(v2, k2);
+}
diff --git a/test/message/unpack.cpp b/test/message/unpack.cpp
new file mode 100644
index 0000000..611a5fe
--- /dev/null
+++ b/test/message/unpack.cpp
@@ -0,0 +1,857 @@
+/**
+ * Copyright © 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <ipmid/api.hpp>
+#include <ipmid/message.hpp>
+
+#include <gtest/gtest.h>
+
+TEST(Uints, Uint8)
+{
+ std::vector<uint8_t> i = {0x04};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint8_t v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ uint8_t k = 0x04;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint8TooManyBytes)
+{
+ std::vector<uint8_t> i = {0x04, 0x86};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint8_t v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ uint8_t k = 0x04;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint8InsufficientBytes)
+{
+ std::vector<uint8_t> i = {};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint8_t v = 0;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v), 0);
+ // check that the payload was not fully unpacked (comprehends unpack errors)
+ ASSERT_FALSE(p.fullyUnpacked());
+ // check that v is zero
+ ASSERT_EQ(v, 0);
+}
+
+TEST(Uints, Uint16)
+{
+ std::vector<uint8_t> i = {0x04, 0x86};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint16_t v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ uint16_t k = 0x8604;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint16TooManyBytes)
+{
+ std::vector<uint8_t> i = {0x04, 0x86, 0x00};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint16_t v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ uint16_t k = 0x8604;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint16InsufficientBytes)
+{
+ std::vector<uint8_t> i = {0x04};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint16_t v = 0;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v), 0);
+ // check that the payload was not fully unpacked (comprehends unpack errors)
+ ASSERT_FALSE(p.fullyUnpacked());
+ // check that v is zero
+ ASSERT_EQ(v, 0);
+}
+
+TEST(Uints, Uint32)
+{
+ std::vector<uint8_t> i = {0x04, 0x86, 0x00, 0x02};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint32_t v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ uint32_t k = 0x02008604;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint32TooManyBytes)
+{
+ std::vector<uint8_t> i = {0x04, 0x86, 0x00, 0x02, 0x44};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint32_t v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ uint32_t k = 0x02008604;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint32InsufficientBytes)
+{
+ std::vector<uint8_t> i = {0x04, 0x86, 0x00};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint32_t v = 0;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v), 0);
+ // check that the payload was not fully unpacked (comprehends unpack errors)
+ ASSERT_FALSE(p.fullyUnpacked());
+ // check that v is zero
+ ASSERT_EQ(v, 0);
+}
+
+TEST(Uints, Uint64)
+{
+ std::vector<uint8_t> i = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22, 0x11};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint64_t v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ uint64_t k = 0x1122334402008604ull;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint64TooManyBytes)
+{
+ std::vector<uint8_t> i = {0x04, 0x86, 0x00, 0x02, 0x44,
+ 0x33, 0x22, 0x11, 0x55};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint64_t v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ uint64_t k = 0x1122334402008604ull;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Uints, Uint64InsufficientBytes)
+{
+ std::vector<uint8_t> i = {0x04, 0x86, 0x00, 0x02, 0x44, 0x33, 0x22};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint64_t v = 0;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v), 0);
+ // check that the payload was not fully unpacked (comprehends unpack errors)
+ ASSERT_FALSE(p.fullyUnpacked());
+ // check that v is zero
+ ASSERT_EQ(v, 0);
+}
+
+TEST(Uints, Uint24)
+{
+ std::vector<uint8_t> i = {0x58, 0x23, 0x11};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint24_t v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ uint24_t k = 0x112358;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(FixedInts, Uint24TooManyBytes)
+{
+ std::vector<uint8_t> i = {0x58, 0x23, 0x11, 0x00};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint24_t v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ uint24_t k = 0x112358;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(FixedInts, Uint24InsufficientBytes)
+{
+ std::vector<uint8_t> i = {0x58, 0x23};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint24_t v = 0;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v), 0);
+ // check that the payload was not fully unpacked (comprehends unpack errors)
+ ASSERT_FALSE(p.fullyUnpacked());
+ // check that v is zero
+ ASSERT_EQ(v, 0);
+}
+
+TEST(FixedInts, Uint3Uint5)
+{
+ // individual bytes are unpacked low-order-bits first
+ // v1 will use [2:0], v2 will use [7:3]
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint3_t v1;
+ uint5_t v2;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v1, v2), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ uint3_t k1 = 0x1;
+ uint5_t k2 = 0x19;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v1, k1);
+ ASSERT_EQ(v2, k2);
+}
+
+TEST(FixedInts, Uint3Uint4TooManyBits)
+{
+ // high order bit should not get unpacked
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint3_t v1;
+ uint4_t v2;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v1, v2), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ uint3_t k1 = 0x1;
+ uint4_t k2 = 0x9;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v1, k1);
+ ASSERT_EQ(v2, k2);
+}
+
+TEST(FixedInts, Uint3Uint6InsufficientBits)
+{
+ // insufficient bits to unpack v2
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint3_t v1;
+ uint6_t v2;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v1, v2), 0);
+ // check that the payload was not fully unpacked (comprehends unpack errors)
+ ASSERT_FALSE(p.fullyUnpacked());
+ uint3_t k1 = 0x1;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v1, k1);
+ // check that v2 is zero
+ ASSERT_EQ(v2, 0);
+}
+
+TEST(Bools, Boolx8)
+{
+ // individual bytes are unpacked low-order-bits first
+ // [v8, v7, v6, v5, v4, v3, v2, v1]
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ bool v8, v7, v6, v5;
+ bool v4, v3, v2, v1;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5, v6, v7, v8), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ // check that the bytes were correctly unpacked (LSB first)
+ bool k8 = true, k7 = true, k6 = false, k5 = false;
+ bool k4 = true, k3 = false, k2 = false, k1 = true;
+ ASSERT_EQ(v1, k1);
+ ASSERT_EQ(v2, k2);
+ ASSERT_EQ(v3, k3);
+ ASSERT_EQ(v4, k4);
+ ASSERT_EQ(v5, k5);
+ ASSERT_EQ(v6, k6);
+ ASSERT_EQ(v7, k7);
+ ASSERT_EQ(v8, k8);
+}
+
+TEST(Bools, Boolx8TooManyBits)
+{
+ // high order bit should not get unpacked
+ // individual bytes are unpacked low-order-bits first
+ // [v7, v6, v5, v4, v3, v2, v1]
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ bool v7, v6, v5;
+ bool v4, v3, v2, v1;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5, v6, v7), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ // check that the bytes were correctly unpacked (LSB first)
+ bool k7 = true, k6 = false, k5 = false;
+ bool k4 = true, k3 = false, k2 = false, k1 = true;
+ ASSERT_EQ(v1, k1);
+ ASSERT_EQ(v2, k2);
+ ASSERT_EQ(v3, k3);
+ ASSERT_EQ(v4, k4);
+ ASSERT_EQ(v5, k5);
+ ASSERT_EQ(v6, k6);
+ ASSERT_EQ(v7, k7);
+}
+
+TEST(Bools, Boolx8InsufficientBits)
+{
+ // individual bytes are unpacked low-order-bits first
+ // [v8, v7, v6, v5, v4, v3, v2, v1]
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ bool v9;
+ bool v8, v7, v6, v5;
+ bool v4, v3, v2, v1;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v1, v2, v3, v4, v5, v6, v7, v8, v9), 0);
+ // check that the payload was not fully unpacked (comprehends unpack errors)
+ ASSERT_FALSE(p.fullyUnpacked());
+ // check that the bytes were correctly unpacked (LSB first)
+ bool k8 = true, k7 = true, k6 = false, k5 = false;
+ bool k4 = true, k3 = false, k2 = false, k1 = true;
+ ASSERT_EQ(v1, k1);
+ ASSERT_EQ(v2, k2);
+ ASSERT_EQ(v3, k3);
+ ASSERT_EQ(v4, k4);
+ ASSERT_EQ(v5, k5);
+ ASSERT_EQ(v6, k6);
+ ASSERT_EQ(v7, k7);
+ ASSERT_EQ(v8, k8);
+}
+
+TEST(Bitsets, Bitset8)
+{
+ // individual bytes are unpacked low-order-bits first
+ // a bitset for 8 bits fills the full byte
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::bitset<8> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ std::bitset<8> k(0xc9);
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Bitsets, Bitset7TooManyBits)
+{
+ // individual bytes are unpacked low-order-bits first
+ // a bitset for 8 bits fills the full byte
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::bitset<7> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ std::bitset<7> k(0x49);
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Bitsets, Bitset9InsufficientBits)
+{
+ // individual bytes are unpacked low-order-bits first
+ // a bitset for 8 bits fills the full byte
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::bitset<9> v;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v), 0);
+ // check that the payload was not fully unpacked (comprehends unpack errors)
+ ASSERT_FALSE(p.fullyUnpacked());
+ std::bitset<9> k(0);
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Bitsets, Bitset3Bitset5)
+{
+ // individual bytes are unpacked low-order-bits first
+ // v1 will use [2:0], v2 will use [7:3]
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::bitset<3> v1;
+ std::bitset<5> v2;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v1, v2), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ std::bitset<3> k1(0x1);
+ std::bitset<5> k2(0x19);
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v1, k1);
+ ASSERT_EQ(v2, k2);
+}
+
+TEST(Bitsets, Bitset3Bitset4TooManyBits)
+{
+ // high order bit should not get unpacked
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::bitset<3> v1;
+ std::bitset<4> v2;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v1, v2), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ std::bitset<3> k1 = 0x1;
+ std::bitset<4> k2 = 0x9;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v1, k1);
+ ASSERT_EQ(v2, k2);
+}
+
+TEST(Bitsets, Bitset3Bitset6InsufficientBits)
+{
+ // insufficient bits to unpack v2
+ std::vector<uint8_t> i = {0xc9};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::bitset<3> v1;
+ std::bitset<6> v2;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v1, v2), 0);
+ // check that the payload was not fully unpacked (comprehends unpack errors)
+ ASSERT_FALSE(p.fullyUnpacked());
+ std::bitset<3> k1 = 0x1;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v1, k1);
+ // check that v2 is zero
+ ASSERT_EQ(v2, 0);
+}
+
+TEST(Bitsets, Bitset32)
+{
+ // individual bytes are unpacked low-order-bits first
+ // v1 will use 4 bytes, but in LSByte first order
+ // v1[7:0] v1[15:9] v1[23:16] v1[31:24]
+ std::vector<uint8_t> i = {0xb4, 0x86, 0x91, 0xc2};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::bitset<32> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ std::bitset<32> k(0xc29186b4);
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Bitsets, Bitset31TooManyBits)
+{
+ // high order bit should not get unpacked
+ std::vector<uint8_t> i = {0xb4, 0x86, 0x91, 0xc2};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::bitset<31> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ std::bitset<31> k(0x429186b4);
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Bitsets, Bitset33InsufficientBits)
+{
+ // insufficient bits to unpack v2
+ std::vector<uint8_t> i = {0xb4, 0x86, 0x91, 0xc2};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::bitset<33> v;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v), 0);
+ // check that the payload was not fully unpacked (comprehends unpack errors)
+ ASSERT_FALSE(p.fullyUnpacked());
+ std::bitset<33> k(0);
+ // check that v is zero
+ ASSERT_EQ(v, 0);
+}
+
+TEST(Arrays, Array4xUint8)
+{
+ // an array of bytes will be read verbatim, low-order element first
+ std::vector<uint8_t> i = {0x02, 0x00, 0x86, 0x04};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::array<uint8_t, 4> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ std::array<uint8_t, 4> k = {{0x02, 0x00, 0x86, 0x04}};
+ // check that the bytes were correctly unpacked (in byte order)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Arrays, Array4xUint8TooManyBytes)
+{
+ // last byte should not get unpacked
+ // an array of bytes will be read verbatim, low-order element first
+ std::vector<uint8_t> i = {0x02, 0x00, 0x86, 0x04, 0x22};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::array<uint8_t, 4> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ std::array<uint8_t, 4> k = {{0x02, 0x00, 0x86, 0x04}};
+ // check that the bytes were correctly unpacked (in byte order)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Arrays, Array4xUint8InsufficientBytes)
+{
+ // last byte should not get unpacked
+ // an array of bytes will be read verbatim, low-order element first
+ std::vector<uint8_t> i = {0x02, 0x00, 0x86};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::array<uint8_t, 4> v;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ // arrays of uint8_t will be unpacked all at once
+ // so nothing will get unpacked
+ std::array<uint8_t, 4> k = {{0, 0, 0, 0}};
+ // check that the bytes were correctly unpacked (in byte order)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Arrays, Array4xUint32)
+{
+ // an array of multi-byte values will be unpacked in order low-order
+ // element first, each multi-byte element in LSByte order
+ // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+ // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+ // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+ // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+ std::vector<uint8_t> i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+ 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::array<uint32_t, 4> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ std::array<uint32_t, 4> k = {
+ {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
+ // check that the bytes were correctly unpacked (in byte order)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Arrays, Array4xUint32TooManyBytes)
+{
+ // last byte should not get unpacked
+ // an array of multi-byte values will be unpacked in order low-order
+ // element first, each multi-byte element in LSByte order
+ // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+ // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+ // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+ // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+ std::vector<uint8_t> i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66,
+ 0x44, 0x22, 0x99, 0x77, 0x55, 0x33,
+ 0x78, 0x56, 0x34, 0x12, 0xaa};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::array<uint32_t, 4> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ std::array<uint32_t, 4> k = {
+ {0x11223344, 0x22446688, 0x33557799, 0x12345678}};
+ // check that the bytes were correctly unpacked (in byte order)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Arrays, Array4xUint32InsufficientBytes)
+{
+ // last value should not get unpacked
+ // an array of multi-byte values will be unpacked in order low-order
+ // element first, each multi-byte element in LSByte order
+ // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+ // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+ // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+ // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+ std::vector<uint8_t> i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+ 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::array<uint32_t, 4> v;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ // arrays of uint32_t will be unpacked in a way that looks atomic
+ std::array<uint32_t, 4> k = {{0, 0, 0, 0}};
+ // check that the bytes were correctly unpacked (in byte order)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Vectors, VectorUint32)
+{
+ // a vector of multi-byte values will be unpacked in order low-order
+ // element first, each multi-byte element in LSByte order
+ // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+ // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+ // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+ // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+ std::vector<uint8_t> i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+ 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34, 0x12};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::vector<uint32_t> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ std::vector<uint32_t> k = {0x11223344, 0x22446688, 0x33557799, 0x12345678};
+ // check that the bytes were correctly unpacked (in byte order)
+ ASSERT_EQ(v, k);
+}
+
+// combination of TooManyBytes and InsufficientBytes because
+// vectors will attempt to unpack full <T>s until the end of the input
+TEST(Vectors, VectorUint32NonIntegralBytes)
+{
+ // last value should not get unpacked
+ // a vector of multi-byte values will be unpacked in order low-order
+ // element first, each multi-byte element in LSByte order,
+ // and will attempt to consume all bytes remaining
+ // v[0][7:0] v[0][15:9] v[0][23:16] v[0][31:24]
+ // v[1][7:0] v[1][15:9] v[1][23:16] v[1][31:24]
+ // v[2][7:0] v[2][15:9] v[2][23:16] v[2][31:24]
+ // v[3][7:0] v[3][15:9] v[3][23:16] v[3][31:24]
+ std::vector<uint8_t> i = {0x44, 0x33, 0x22, 0x11, 0x88, 0x66, 0x44, 0x22,
+ 0x99, 0x77, 0x55, 0x33, 0x78, 0x56, 0x34};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::vector<uint32_t> v;
+ // check that the number of bytes matches
+ ASSERT_NE(p.unpack(v), 0);
+ // check that the payload was not fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ // arrays of uint32_t will be unpacked one at a time, so the
+ // last entry should not get unpacked properly
+ std::vector<uint32_t> k = {0x11223344, 0x22446688, 0x33557799};
+ // check that the bytes were correctly unpacked (in byte order)
+ ASSERT_EQ(v, k);
+}
+
+TEST(Vectors, VectorUint8)
+{
+ // a vector of bytes will be unpacked verbatim, low-order element first
+ std::vector<uint8_t> i = {0x02, 0x00, 0x86, 0x04};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::vector<uint8_t> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ std::vector<uint8_t> k = {0x02, 0x00, 0x86, 0x04};
+ // check that the bytes were correctly unpacked (in byte order)
+ ASSERT_EQ(v, k);
+}
+
+// Cannot test TooManyBytes or InsufficientBytes for vector<uint8_t>
+// because it will always unpack whatever bytes are remaining
+// TEST(Vectors, VectorUint8TooManyBytes) {}
+// TEST(Vectors, VectorUint8InsufficientBytes) {}
+
+TEST(UnpackAdvanced, OptionalOk)
+{
+ // a vector of bytes will be unpacked verbatim, low-order element first
+ std::vector<uint8_t> i = {0xbe, 0x02, 0x00, 0x86, 0x04};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::optional<std::tuple<uint8_t, uint32_t>> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ std::optional<std::tuple<uint8_t, uint32_t>> k{{0xbe, 0x04860002}};
+ // check that the bytes were correctly unpacked (in byte order)
+ ASSERT_EQ(v, k);
+}
+
+TEST(UnpackAdvanced, OptionalInsufficientBytes)
+{
+ // a vector of bytes will be unpacked verbatim, low-order element first
+ std::vector<uint8_t> i = {0x02, 0x00, 0x86, 0x04};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ std::optional<std::tuple<uint8_t, uint32_t>> v;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_FALSE(p.fullyUnpacked());
+ std::optional<std::tuple<uint8_t, uint32_t>> k = {{0, 0}};
+ // check that the bytes were correctly unpacked (in byte order)
+ ASSERT_EQ(v, k);
+}
+
+TEST(UnpackAdvanced, Uints)
+{
+ // all elements will be unpacked in order, with each multi-byte
+ // element being processed LSByte first
+ // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
+ // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
+ // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
+ std::vector<uint8_t> i = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint8_t v1;
+ uint16_t v2;
+ uint32_t v3;
+ uint64_t v4;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v1, v2, v3, v4), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ uint8_t k1 = 0x02;
+ uint16_t k2 = 0x0604;
+ uint32_t k3 = 0x44332211;
+ uint64_t k4 = 0xccbbaa9988776655ull;
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v1, k1);
+ ASSERT_EQ(v2, k2);
+ ASSERT_EQ(v3, k3);
+ ASSERT_EQ(v4, k4);
+}
+
+TEST(UnpackAdvanced, TupleInts)
+{
+ // all elements will be unpacked in order, with each multi-byte
+ // element being processed LSByte first
+ // v1[7:0] v2[7:0] v2[15:8] v3[7:0] v3[15:8] v3[23:16] v3[31:24]
+ // v4[7:0] v4[15:8] v4[23:16] v4[31:24]
+ // v4[39:25] v4[47:40] v4[55:48] v4[63:56]
+ std::vector<uint8_t> i = {0x02, 0x04, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint8_t v1;
+ uint16_t v2;
+ uint32_t v3;
+ uint64_t v4;
+ auto v = std::make_tuple(v1, v2, v3, v4);
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ uint8_t k1 = 0x02;
+ uint16_t k2 = 0x0604;
+ uint32_t k3 = 0x44332211;
+ uint64_t k4 = 0xccbbaa9988776655ull;
+ auto k = std::make_tuple(k1, k2, k3, k4);
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v, k);
+}
+
+TEST(UnpackAdvanced, BoolsnBitfieldsnFixedIntsOhMy)
+{
+ // each element will be unpacked, filling the low-order bits first
+ // with multi-byte values getting unpacked LSByte first
+ // v1 will use k[0][1:0]
+ // v2 will use k[0][2]
+ // v3[4:0] will use k[0][7:3], v3[6:5] will use k[1][1:0]
+ // v4 will use k[1][2]
+ // v5 will use k[1][7:3]
+ std::vector<uint8_t> i = {0x9e, 0xdb};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint2_t v1;
+ bool v2;
+ std::bitset<7> v3;
+ bool v4;
+ uint5_t v5;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ uint2_t k1 = 2; // binary 0b10
+ bool k2 = true; // binary 0b1
+ std::bitset<7> k3(0x73); // binary 0b1110011
+ bool k4 = false; // binary 0b0
+ uint5_t k5 = 27; // binary 0b11011
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v1, k1);
+ ASSERT_EQ(v2, k2);
+ ASSERT_EQ(v3, k3);
+ ASSERT_EQ(v4, k4);
+ ASSERT_EQ(v5, k5);
+}
+
+TEST(UnpackAdvanced, UnalignedBitUnpacking)
+{
+ // unaligned multi-byte values will be unpacked the same as
+ // other bits, effectively reading from a large value, low-order
+ // bits first, then consuming the stream LSByte first
+ // v1 will use k[0][1:0]
+ // v2[5:0] will use k[0][7:2], v2[7:6] will use k[1][1:0]
+ // v3 will use k[1][2]
+ // v4[4:0] will use k[1][7:3] v4[12:5] will use k[2][7:0]
+ // v4[15:13] will use k[3][2:0]
+ // v5 will use k[3][3]
+ // v6[3:0] will use k[3][7:0] v6[11:4] will use k[4][7:0]
+ // v6[19:12] will use k[5][7:0] v6[27:20] will use k[6][7:0]
+ // v6[31:28] will use k[7][3:0]
+ // v7 will use k[7][7:4]
+ std::vector<uint8_t> i = {0x96, 0xd2, 0x2a, 0xcd, 0xd3, 0x3b, 0xbc, 0x9d};
+ ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+ uint2_t v1;
+ uint8_t v2;
+ bool v3;
+ uint16_t v4;
+ bool v5;
+ uint32_t v6;
+ uint4_t v7;
+ // check that the number of bytes matches
+ ASSERT_EQ(p.unpack(v1, v2, v3, v4, v5, v6, v7), 0);
+ // check that the payload was fully unpacked
+ ASSERT_TRUE(p.fullyUnpacked());
+ uint2_t k1 = 2; // binary 0b10
+ uint8_t k2 = 0xa5; // binary 0b10100101
+ bool k3 = false; // binary 0b0
+ uint16_t k4 = 0xa55a; // binary 0b1010010101011010
+ bool k5 = true; // binary 0b1
+ uint32_t k6 = 0xdbc3bd3c; // binary 0b11011011110000111011110100111100
+ uint4_t k7 = 9; // binary 0b1001
+ // check that the bytes were correctly unpacked (LSB first)
+ ASSERT_EQ(v1, k1);
+ ASSERT_EQ(v2, k2);
+ ASSERT_EQ(v3, k3);
+ ASSERT_EQ(v4, k4);
+ ASSERT_EQ(v5, k5);
+ ASSERT_EQ(v6, k6);
+ ASSERT_EQ(v7, k7);
+}
OpenPOWER on IntegriCloud