blob: 6183d770281aab7b496f2e3023d9d5ddc7e9f43c [file] [log] [blame]
Patrick Venture95269db2018-08-31 09:19:17 -07001#include <systemd/sd-bus.h>
2
William A. Kennington III874e82e2018-06-22 19:23:54 -07003#include <sdbusplus/exception.hpp>
4#include <sdbusplus/test/sdbus_mock.hpp>
Patrick Williams127b8ab2020-05-21 15:24:19 -05005
6#include <cstdlib>
William A. Kennington III874e82e2018-06-22 19:23:54 -07007#include <stdexcept>
8#include <string>
William A. Kennington III874e82e2018-06-22 19:23:54 -07009#include <utility>
10
Patrick Venture95269db2018-08-31 09:19:17 -070011#include <gtest/gtest.h>
12
Gunnar Mills31a4b132018-08-14 11:59:13 -050013// Needed for constructor error testing
William A. Kennington III874e82e2018-06-22 19:23:54 -070014extern sdbusplus::SdBusImpl sdbus_impl;
15
16namespace
17{
18
19using sdbusplus::exception::SdBusError;
William A. Kennington III874e82e2018-06-22 19:23:54 -070020using testing::_;
Patrick Venture0b5d1e02018-08-31 09:12:15 -070021using testing::Return;
William A. Kennington III874e82e2018-06-22 19:23:54 -070022
William A. Kennington III874e82e2018-06-22 19:23:54 -070023TEST(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 Kobylak33335b32018-09-21 11:50:42 -050038 SdBusError& errNew = err;
39 EXPECT_EQ(errorVal, errNew.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -070040 EXPECT_EQ(std::string{error.name}, sdbusErr.name());
41 EXPECT_EQ(std::string{error.message}, sdbusErr.description());
William A. Kennington III874e82e2018-06-22 19:23:54 -070042 std::exception& stdErr = sdbusErr;
43 EXPECT_EQ(prefix + ": " + error.name + ": " + error.message, stdErr.what());
44
45 sd_bus_error_free(&error);
46}
47
48TEST(SdBusError, EnomemErrno)
49{
50 // Make sure no exception is thrown on construction
51 SdBusError err(ENOMEM, "EnomemErrno");
52}
53
54TEST(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
67TEST(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 Kobylak33335b32018-09-21 11:50:42 -050086 EXPECT_EQ(errorVal, err.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -070087 EXPECT_EQ(name, err.name());
88 EXPECT_EQ(message, err.description());
89 EXPECT_EQ(what, err.what());
William A. Kennington III874e82e2018-06-22 19:23:54 -070090
91 // Move our SdBusError to a new one
92 SdBusError errNew(std::move(err));
93
Patrick Williams4991d3b2020-05-21 07:33:24 -050094 // We are purposefully calling functions on a moved-from object,
95 // so we need to suppress the clang warnings.
96#ifndef __clang_analyzer__
William A. Kennington III874e82e2018-06-22 19:23:54 -070097 // Ensure the old object was cleaned up
Adriana Kobylak33335b32018-09-21 11:50:42 -050098 EXPECT_EQ(0, err.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -070099 EXPECT_EQ(nullptr, err.name());
100 EXPECT_EQ(nullptr, err.description());
Patrick Williams4991d3b2020-05-21 07:33:24 -0500101#endif
William A. Kennington III874e82e2018-06-22 19:23:54 -0700102
103 // Ensure our new object has the same data but moved
Adriana Kobylak33335b32018-09-21 11:50:42 -0500104 EXPECT_EQ(errorVal, errNew.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700105 EXPECT_EQ(name, errNew.name());
106 EXPECT_EQ(message, errNew.description());
107 EXPECT_EQ(what, errNew.what());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700108
109 // Move our SdBusError using the operator=()
110 errFinal = std::move(errNew);
111
Patrick Williams4991d3b2020-05-21 07:33:24 -0500112 // We are purposefully calling functions on a moved-from object,
113 // so we need to suppress the clang warnings.
114#ifndef __clang_analyzer__
William A. Kennington III874e82e2018-06-22 19:23:54 -0700115 // Ensure the old object was cleaned up
Adriana Kobylak33335b32018-09-21 11:50:42 -0500116 EXPECT_EQ(0, errNew.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700117 EXPECT_EQ(nullptr, errNew.name());
118 EXPECT_EQ(nullptr, errNew.description());
Patrick Williams4991d3b2020-05-21 07:33:24 -0500119#endif
William A. Kennington III874e82e2018-06-22 19:23:54 -0700120 }
121
122 // Ensure our new object has the same data but moved
Adriana Kobylak33335b32018-09-21 11:50:42 -0500123 EXPECT_EQ(errorVal, errFinal.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700124 EXPECT_EQ(name, errFinal.name());
125 EXPECT_EQ(message, errFinal.description());
126 EXPECT_EQ(what, errFinal.what());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700127
128 sd_bus_error_free(&error);
129}
130
131TEST(SdBusError, BasicError)
132{
133 const std::string name = "org.freedesktop.DBus.Error.Failed";
134 const std::string description = "TestCase";
135 const std::string prefix = "BasicError";
136
137 sd_bus_error error = SD_BUS_ERROR_NULL;
138 sd_bus_error_set(&error, name.c_str(), description.c_str());
139 EXPECT_TRUE(sd_bus_error_is_set(&error));
140 const char* nameBeforeMove = error.name;
Adriana Kobylak33335b32018-09-21 11:50:42 -0500141 const int errorVal = sd_bus_error_get_errno(&error);
William A. Kennington III874e82e2018-06-22 19:23:54 -0700142 SdBusError err(&error, prefix.c_str());
143
144 // We expect a move not copy
145 EXPECT_EQ(nameBeforeMove, err.name());
146
147 // The SdBusError should have moved our error so it should be freeable
148 EXPECT_FALSE(sd_bus_error_is_set(&error));
149 sd_bus_error_free(&error);
150 sd_bus_error_free(&error);
151
Adriana Kobylak33335b32018-09-21 11:50:42 -0500152 EXPECT_EQ(errorVal, err.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700153 EXPECT_EQ(name, err.name());
154 EXPECT_EQ(description, err.description());
155 EXPECT_EQ(prefix + ": " + name + ": " + description, err.what());
Vernon Maueryfac43a62018-08-01 12:29:23 -0700156}
157
158TEST(SdBusError, CatchBaseClassExceptions)
159{
160 /* test each class in the chain:
161 * std::exception
162 * -> sdbusplus::exception::exception
163 * -> sdbusplus::exception::internal_exception
164 * -> sdbusplus::exception::SdBusError
165 */
166 EXPECT_THROW({ throw SdBusError(-EINVAL, "SdBusError"); }, SdBusError);
167 EXPECT_THROW({ throw SdBusError(-EINVAL, "internal_exception"); },
168 sdbusplus::exception::internal_exception);
169 EXPECT_THROW({ throw SdBusError(-EINVAL, "exception"); },
170 sdbusplus::exception::exception);
171 EXPECT_THROW({ throw SdBusError(-EINVAL, "std::exception"); },
172 std::exception);
William A. Kennington III874e82e2018-06-22 19:23:54 -0700173}
174
175} // namespace