| Patrick Venture | 95269db | 2018-08-31 09:19:17 -0700 | [diff] [blame] | 1 | #include <systemd/sd-bus.h> | 
|  | 2 |  | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 3 | #include <sdbusplus/exception.hpp> | 
|  | 4 | #include <sdbusplus/test/sdbus_mock.hpp> | 
| Patrick Williams | 127b8ab | 2020-05-21 15:24:19 -0500 | [diff] [blame^] | 5 |  | 
|  | 6 | #include <cstdlib> | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 7 | #include <stdexcept> | 
|  | 8 | #include <string> | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 9 | #include <utility> | 
|  | 10 |  | 
| Patrick Venture | 95269db | 2018-08-31 09:19:17 -0700 | [diff] [blame] | 11 | #include <gtest/gtest.h> | 
|  | 12 |  | 
| Gunnar Mills | 31a4b13 | 2018-08-14 11:59:13 -0500 | [diff] [blame] | 13 | // Needed for constructor error testing | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 14 | extern sdbusplus::SdBusImpl sdbus_impl; | 
|  | 15 |  | 
|  | 16 | namespace | 
|  | 17 | { | 
|  | 18 |  | 
|  | 19 | using sdbusplus::exception::SdBusError; | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 20 | using testing::_; | 
| Patrick Venture | 0b5d1e0 | 2018-08-31 09:12:15 -0700 | [diff] [blame] | 21 | using testing::Return; | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 22 |  | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 23 | TEST(SdBusError, BasicErrno) | 
|  | 24 | { | 
|  | 25 | const int errorVal = EBUSY; | 
|  | 26 | const std::string prefix = "BasicErrno"; | 
|  | 27 |  | 
|  | 28 | // Build the reference sd_bus_error | 
|  | 29 | sd_bus_error error = SD_BUS_ERROR_NULL; | 
|  | 30 | EXPECT_EQ(-errorVal, sd_bus_error_set_errno(&error, errorVal)); | 
|  | 31 | EXPECT_TRUE(sd_bus_error_is_set(&error)); | 
|  | 32 |  | 
|  | 33 | // Build the SdBusError | 
|  | 34 | SdBusError err(errorVal, prefix.c_str()); | 
|  | 35 |  | 
|  | 36 | // Make sure inheritance is defined correctly | 
|  | 37 | sdbusplus::exception::exception& sdbusErr = err; | 
| Adriana Kobylak | 33335b3 | 2018-09-21 11:50:42 -0500 | [diff] [blame] | 38 | SdBusError& errNew = err; | 
|  | 39 | EXPECT_EQ(errorVal, errNew.get_errno()); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 40 | EXPECT_EQ(std::string{error.name}, sdbusErr.name()); | 
|  | 41 | EXPECT_EQ(std::string{error.message}, sdbusErr.description()); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 42 | std::exception& stdErr = sdbusErr; | 
|  | 43 | EXPECT_EQ(prefix + ": " + error.name + ": " + error.message, stdErr.what()); | 
|  | 44 |  | 
|  | 45 | sd_bus_error_free(&error); | 
|  | 46 | } | 
|  | 47 |  | 
|  | 48 | TEST(SdBusError, EnomemErrno) | 
|  | 49 | { | 
|  | 50 | // Make sure no exception is thrown on construction | 
|  | 51 | SdBusError err(ENOMEM, "EnomemErrno"); | 
|  | 52 | } | 
|  | 53 |  | 
|  | 54 | TEST(SdBusError, NotSetErrno) | 
|  | 55 | { | 
|  | 56 | const int errorVal = EBUSY; | 
|  | 57 |  | 
|  | 58 | sdbusplus::SdBusMock sdbus; | 
|  | 59 | EXPECT_CALL(sdbus, sd_bus_error_set_errno(_, errorVal)) | 
|  | 60 | .Times(1) | 
|  | 61 | .WillOnce(Return(errorVal)); | 
|  | 62 | EXPECT_CALL(sdbus, sd_bus_error_is_set(_)).Times(1).WillOnce(Return(false)); | 
|  | 63 | EXPECT_THROW(SdBusError(errorVal, "NotSetErrno", &sdbus), | 
|  | 64 | std::runtime_error); | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 | TEST(SdBusError, Move) | 
|  | 68 | { | 
|  | 69 | const int errorVal = EIO; | 
|  | 70 | const std::string prefix = "Move"; | 
|  | 71 |  | 
|  | 72 | // Build the reference sd_bus_error | 
|  | 73 | sd_bus_error error = SD_BUS_ERROR_NULL; | 
|  | 74 | EXPECT_EQ(-errorVal, sd_bus_error_set_errno(&error, errorVal)); | 
|  | 75 | EXPECT_TRUE(sd_bus_error_is_set(&error)); | 
|  | 76 | const std::string name{error.name}; | 
|  | 77 | const std::string message{error.message}; | 
|  | 78 | const std::string what = prefix + ": " + error.name + ": " + error.message; | 
|  | 79 |  | 
|  | 80 | SdBusError errFinal(EBUSY, "Move2"); | 
|  | 81 | // Nest to make sure RAII works for moves | 
|  | 82 | { | 
|  | 83 | // Build our first SdBusError | 
|  | 84 | SdBusError err(errorVal, prefix.c_str()); | 
|  | 85 |  | 
| Adriana Kobylak | 33335b3 | 2018-09-21 11:50:42 -0500 | [diff] [blame] | 86 | EXPECT_EQ(errorVal, err.get_errno()); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 87 | EXPECT_EQ(name, err.name()); | 
|  | 88 | EXPECT_EQ(message, err.description()); | 
|  | 89 | EXPECT_EQ(what, err.what()); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 90 |  | 
|  | 91 | // Move our SdBusError to a new one | 
|  | 92 | SdBusError errNew(std::move(err)); | 
|  | 93 |  | 
|  | 94 | // Ensure the old object was cleaned up | 
| Adriana Kobylak | 33335b3 | 2018-09-21 11:50:42 -0500 | [diff] [blame] | 95 | EXPECT_EQ(0, err.get_errno()); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 96 | EXPECT_EQ(nullptr, err.name()); | 
|  | 97 | EXPECT_EQ(nullptr, err.description()); | 
|  | 98 | EXPECT_EQ(std::string{}, err.what()); | 
|  | 99 |  | 
|  | 100 | // Ensure our new object has the same data but moved | 
| Adriana Kobylak | 33335b3 | 2018-09-21 11:50:42 -0500 | [diff] [blame] | 101 | EXPECT_EQ(errorVal, errNew.get_errno()); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 102 | EXPECT_EQ(name, errNew.name()); | 
|  | 103 | EXPECT_EQ(message, errNew.description()); | 
|  | 104 | EXPECT_EQ(what, errNew.what()); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 105 |  | 
|  | 106 | // Move our SdBusError using the operator=() | 
|  | 107 | errFinal = std::move(errNew); | 
|  | 108 |  | 
|  | 109 | // Ensure the old object was cleaned up | 
| Adriana Kobylak | 33335b3 | 2018-09-21 11:50:42 -0500 | [diff] [blame] | 110 | EXPECT_EQ(0, errNew.get_errno()); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 111 | EXPECT_EQ(nullptr, errNew.name()); | 
|  | 112 | EXPECT_EQ(nullptr, errNew.description()); | 
|  | 113 | EXPECT_EQ(std::string{}, errNew.what()); | 
|  | 114 | } | 
|  | 115 |  | 
|  | 116 | // Ensure our new object has the same data but moved | 
| Adriana Kobylak | 33335b3 | 2018-09-21 11:50:42 -0500 | [diff] [blame] | 117 | EXPECT_EQ(errorVal, errFinal.get_errno()); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 118 | EXPECT_EQ(name, errFinal.name()); | 
|  | 119 | EXPECT_EQ(message, errFinal.description()); | 
|  | 120 | EXPECT_EQ(what, errFinal.what()); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 121 |  | 
|  | 122 | sd_bus_error_free(&error); | 
|  | 123 | } | 
|  | 124 |  | 
|  | 125 | TEST(SdBusError, BasicError) | 
|  | 126 | { | 
|  | 127 | const std::string name = "org.freedesktop.DBus.Error.Failed"; | 
|  | 128 | const std::string description = "TestCase"; | 
|  | 129 | const std::string prefix = "BasicError"; | 
|  | 130 |  | 
|  | 131 | sd_bus_error error = SD_BUS_ERROR_NULL; | 
|  | 132 | sd_bus_error_set(&error, name.c_str(), description.c_str()); | 
|  | 133 | EXPECT_TRUE(sd_bus_error_is_set(&error)); | 
|  | 134 | const char* nameBeforeMove = error.name; | 
| Adriana Kobylak | 33335b3 | 2018-09-21 11:50:42 -0500 | [diff] [blame] | 135 | const int errorVal = sd_bus_error_get_errno(&error); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 136 | SdBusError err(&error, prefix.c_str()); | 
|  | 137 |  | 
|  | 138 | // We expect a move not copy | 
|  | 139 | EXPECT_EQ(nameBeforeMove, err.name()); | 
|  | 140 |  | 
|  | 141 | // The SdBusError should have moved our error so it should be freeable | 
|  | 142 | EXPECT_FALSE(sd_bus_error_is_set(&error)); | 
|  | 143 | sd_bus_error_free(&error); | 
|  | 144 | sd_bus_error_free(&error); | 
|  | 145 |  | 
| Adriana Kobylak | 33335b3 | 2018-09-21 11:50:42 -0500 | [diff] [blame] | 146 | EXPECT_EQ(errorVal, err.get_errno()); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 147 | EXPECT_EQ(name, err.name()); | 
|  | 148 | EXPECT_EQ(description, err.description()); | 
|  | 149 | EXPECT_EQ(prefix + ": " + name + ": " + description, err.what()); | 
| Vernon Mauery | fac43a6 | 2018-08-01 12:29:23 -0700 | [diff] [blame] | 150 | } | 
|  | 151 |  | 
|  | 152 | TEST(SdBusError, CatchBaseClassExceptions) | 
|  | 153 | { | 
|  | 154 | /* test each class in the chain: | 
|  | 155 | * std::exception | 
|  | 156 | *   -> sdbusplus::exception::exception | 
|  | 157 | *     -> sdbusplus::exception::internal_exception | 
|  | 158 | *       -> sdbusplus::exception::SdBusError | 
|  | 159 | */ | 
|  | 160 | EXPECT_THROW({ throw SdBusError(-EINVAL, "SdBusError"); }, SdBusError); | 
|  | 161 | EXPECT_THROW({ throw SdBusError(-EINVAL, "internal_exception"); }, | 
|  | 162 | sdbusplus::exception::internal_exception); | 
|  | 163 | EXPECT_THROW({ throw SdBusError(-EINVAL, "exception"); }, | 
|  | 164 | sdbusplus::exception::exception); | 
|  | 165 | EXPECT_THROW({ throw SdBusError(-EINVAL, "std::exception"); }, | 
|  | 166 | std::exception); | 
| William A. Kennington III | 874e82e | 2018-06-22 19:23:54 -0700 | [diff] [blame] | 167 | } | 
|  | 168 |  | 
|  | 169 | } // namespace |