test/message/read: Test that our error handling cases work
This improves our test coverage of sd_bus_message read functionality to
100%.
Tested:
Ran through the usual unit test scripts including valgrind and code
coverage.
Change-Id: Ifa849d05364349e27e39c6dda5e4cab4efa35476
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/message/read.cpp b/test/message/read.cpp
index 89f6af0..168865a 100644
--- a/test/message/read.cpp
+++ b/test/message/read.cpp
@@ -1,6 +1,8 @@
+#include <cerrno>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <map>
+#include <sdbusplus/exception.hpp>
#include <sdbusplus/message.hpp>
#include <sdbusplus/test/sdbus_mock.hpp>
#include <set>
@@ -42,6 +44,12 @@
nullptr, nullptr, nullptr, nullptr);
}
+ void expect_basic_error(char type, int ret)
+ {
+ EXPECT_CALL(mock, sd_bus_message_read_basic(nullptr, type, testing::_))
+ .WillOnce(Return(ret));
+ }
+
template <typename T> void expect_basic(char type, T val)
{
EXPECT_CALL(mock, sd_bus_message_read_basic(nullptr, type, testing::_))
@@ -61,23 +69,23 @@
.WillOnce(Return(ret));
}
- void expect_skip(const char *contents)
+ void expect_skip(const char *contents, int ret = 0)
{
EXPECT_CALL(mock, sd_bus_message_skip(nullptr, StrEq(contents)))
- .WillOnce(Return(0));
+ .WillOnce(Return(ret));
}
- void expect_enter_container(char type, const char *contents)
+ void expect_enter_container(char type, const char *contents, int ret = 0)
{
EXPECT_CALL(mock, sd_bus_message_enter_container(nullptr, type,
StrEq(contents)))
- .WillOnce(Return(0));
+ .WillOnce(Return(ret));
}
- void expect_exit_container()
+ void expect_exit_container(int ret = 0)
{
EXPECT_CALL(mock, sd_bus_message_exit_container(nullptr))
- .WillOnce(Return(0));
+ .WillOnce(Return(ret));
}
};
@@ -171,6 +179,34 @@
EXPECT_EQ(d, ret_d);
}
+TEST_F(ReadTest, BasicError)
+{
+ expect_basic_error(SD_BUS_TYPE_INT32, -EINVAL);
+ int ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, BasicStringError)
+{
+ expect_basic_error(SD_BUS_TYPE_STRING, -EINVAL);
+ std::string ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, BasicStringWrapperError)
+{
+ expect_basic_error(SD_BUS_TYPE_SIGNATURE, -EINVAL);
+ sdbusplus::message::signature ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, BasicBoolError)
+{
+ expect_basic_error(SD_BUS_TYPE_BOOLEAN, -EINVAL);
+ bool ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
TEST_F(ReadTest, Vector)
{
const std::vector<int> vi{1, 2, 3, 4};
@@ -192,6 +228,48 @@
EXPECT_EQ(vi, ret_vi);
}
+TEST_F(ReadTest, VectorEnterError)
+{
+ {
+ testing::InSequence seq;
+ expect_enter_container(SD_BUS_TYPE_ARRAY, "i", -EINVAL);
+ }
+
+ std::vector<int> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, VectorIterError)
+{
+ {
+ testing::InSequence seq;
+ expect_enter_container(SD_BUS_TYPE_ARRAY, "i");
+ expect_at_end(false, 0);
+ expect_basic<int>(SD_BUS_TYPE_INT32, 1);
+ expect_at_end(false, -EINVAL);
+ }
+
+ std::vector<int> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, VectorExitError)
+{
+ {
+ testing::InSequence seq;
+ expect_enter_container(SD_BUS_TYPE_ARRAY, "i");
+ expect_at_end(false, 0);
+ expect_basic<int>(SD_BUS_TYPE_INT32, 1);
+ expect_at_end(false, 0);
+ expect_basic<int>(SD_BUS_TYPE_INT32, 2);
+ expect_at_end(false, 1);
+ expect_exit_container(-EINVAL);
+ }
+
+ std::vector<int> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
TEST_F(ReadTest, Set)
{
const std::set<std::string> ss{"one", "two", "eight"};
@@ -242,6 +320,81 @@
EXPECT_EQ(mis, ret_mis);
}
+TEST_F(ReadTest, MapEnterError)
+{
+ {
+ testing::InSequence seq;
+ expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}", -EINVAL);
+ }
+
+ std::map<std::string, int> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, MapEntryEnterError)
+{
+ {
+ testing::InSequence seq;
+ expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
+ expect_at_end(false, 0);
+ expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si", -EINVAL);
+ }
+
+ std::map<std::string, int> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, MapEntryExitError)
+{
+ {
+ testing::InSequence seq;
+ expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
+ expect_at_end(false, 0);
+ expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
+ expect_basic<const char *>(SD_BUS_TYPE_STRING, "ab");
+ expect_basic<int>(SD_BUS_TYPE_INT32, 1);
+ expect_exit_container(-EINVAL);
+ }
+
+ std::map<std::string, int> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, MapIterError)
+{
+ {
+ testing::InSequence seq;
+ expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
+ expect_at_end(false, 0);
+ expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
+ expect_basic<const char *>(SD_BUS_TYPE_STRING, "ab");
+ expect_basic<int>(SD_BUS_TYPE_INT32, 1);
+ expect_exit_container();
+ expect_at_end(false, -EINVAL);
+ }
+
+ std::map<std::string, int> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, MapExitError)
+{
+ {
+ testing::InSequence seq;
+ expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
+ expect_at_end(false, 0);
+ expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
+ expect_basic<const char *>(SD_BUS_TYPE_STRING, "ab");
+ expect_basic<int>(SD_BUS_TYPE_INT32, 1);
+ expect_exit_container();
+ expect_at_end(false, 1);
+ expect_exit_container(-EINVAL);
+ }
+
+ std::map<std::string, int> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
TEST_F(ReadTest, UnorderedMap)
{
const std::unordered_map<int, std::string> mis{
@@ -290,6 +443,32 @@
EXPECT_EQ(tisb, ret_tisb);
}
+TEST_F(ReadTest, TupleEnterError)
+{
+ {
+ testing::InSequence seq;
+ expect_enter_container(SD_BUS_TYPE_STRUCT, "bis", -EINVAL);
+ }
+
+ std::tuple<bool, int, std::string> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, TupleExitError)
+{
+ {
+ testing::InSequence seq;
+ expect_enter_container(SD_BUS_TYPE_STRUCT, "bis");
+ expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
+ expect_basic<int>(SD_BUS_TYPE_INT32, 1);
+ expect_basic<const char *>(SD_BUS_TYPE_STRING, "ab");
+ expect_exit_container(-EINVAL);
+ }
+
+ std::tuple<bool, int, std::string> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
TEST_F(ReadTest, Variant)
{
const bool b1 = false;
@@ -317,6 +496,17 @@
EXPECT_EQ(v2, ret_v2);
}
+TEST_F(ReadTest, VariantVerifyError)
+{
+ {
+ testing::InSequence seq;
+ expect_verify_type(SD_BUS_TYPE_VARIANT, "i", -EINVAL);
+ }
+
+ sdbusplus::message::variant<int, bool> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
TEST_F(ReadTest, VariantSkipUnmatched)
{
{
@@ -325,10 +515,50 @@
expect_verify_type(SD_BUS_TYPE_VARIANT, "b", false);
expect_skip("v");
}
+
sdbusplus::message::variant<int, bool> ret;
new_message().read(ret);
}
+TEST_F(ReadTest, VariantSkipError)
+{
+ {
+ testing::InSequence seq;
+ expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
+ expect_verify_type(SD_BUS_TYPE_VARIANT, "b", false);
+ expect_skip("v", -EINVAL);
+ }
+
+ sdbusplus::message::variant<int, bool> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, VariantEnterError)
+{
+ {
+ testing::InSequence seq;
+ expect_verify_type(SD_BUS_TYPE_VARIANT, "i", true);
+ expect_enter_container(SD_BUS_TYPE_VARIANT, "i", -EINVAL);
+ }
+
+ sdbusplus::message::variant<int, bool> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
+TEST_F(ReadTest, VariantExitError)
+{
+ {
+ testing::InSequence seq;
+ expect_verify_type(SD_BUS_TYPE_VARIANT, "i", true);
+ expect_enter_container(SD_BUS_TYPE_VARIANT, "i");
+ expect_basic<int>(SD_BUS_TYPE_INT32, 10);
+ expect_exit_container(-EINVAL);
+ }
+
+ sdbusplus::message::variant<int, bool> ret;
+ EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
+}
+
TEST_F(ReadTest, LargeCombo)
{
const std::vector<std::set<std::string>> vas{