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