fix logic error for unpack vector of tuple

Unpacking a vector of tuples is failing if the correct number of bytes
does not match an integral number of bytes needed to fully unpack all
the tuples.

Unpacking a tuple should return an error if it does not fully unpack all
the items. This will signal the vector unpack to bail and return however
many items it has unpacked to that point.

A vector unpack should always return success because no matter how many
items it has unpacked, it is fine, because a vector can have any number
of items.

Tested: Unit tests updated to check for proper unpacking of vectors and
        tuples (and optionals) as well as new unit tests added for more
        targetted testing.

Change-Id: I4b45198f8bc4a49913beb923d10079983179402a
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/test/message/unpack.cpp b/test/message/unpack.cpp
index 611a5fe..7d69218 100644
--- a/test/message/unpack.cpp
+++ b/test/message/unpack.cpp
@@ -660,8 +660,8 @@
                               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 vector unpacks successfully
+    ASSERT_EQ(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
@@ -686,6 +686,51 @@
     ASSERT_EQ(v, k);
 }
 
+TEST(Vectors, VectorEmptyOk)
+{
+    // an empty input vector to show that unpacking elements is okay
+    std::vector<uint8_t> i{};
+    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{};
+    // check that the unpacked vector is empty as expected
+    ASSERT_EQ(v, k);
+}
+
+TEST(Vectors, VectorOfTuplesOk)
+{
+    // 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<std::tuple<uint8_t, 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<std::tuple<uint8_t, uint8_t>> k = {{0x02, 0x00}, {0x86, 0x04}};
+    // check that the bytes were correctly unpacked (in byte order)
+    ASSERT_EQ(v, k);
+}
+
+TEST(Vectors, VectorOfTuplesInsufficientBytes)
+{
+    // a vector of bytes will be unpacked verbatim, low-order element first
+    std::vector<uint8_t> i = {0x02, 0x00, 0x86, 0x04, 0xb4};
+    ipmi::message::Payload p(std::forward<std::vector<uint8_t>>(i));
+    std::vector<std::tuple<uint8_t, 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());
+    std::vector<std::tuple<uint8_t, 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) {}
@@ -716,7 +761,7 @@
     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}};
+    std::optional<std::tuple<uint8_t, uint32_t>> k;
     // check that the bytes were correctly unpacked (in byte order)
     ASSERT_EQ(v, k);
 }