blob: fde0a85cd47abf24c431efde2b3f3dcda72de503 [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 <cstdlib>
William A. Kennington III874e82e2018-06-22 19:23:54 -07004#include <sdbusplus/exception.hpp>
5#include <sdbusplus/test/sdbus_mock.hpp>
6#include <stdexcept>
7#include <string>
William A. Kennington III874e82e2018-06-22 19:23:54 -07008#include <utility>
9
Patrick Venture95269db2018-08-31 09:19:17 -070010#include <gtest/gtest.h>
11
Gunnar Mills31a4b132018-08-14 11:59:13 -050012// Needed for constructor error testing
William A. Kennington III874e82e2018-06-22 19:23:54 -070013extern sdbusplus::SdBusImpl sdbus_impl;
14
15namespace
16{
17
18using sdbusplus::exception::SdBusError;
William A. Kennington III874e82e2018-06-22 19:23:54 -070019using testing::_;
Patrick Venture0b5d1e02018-08-31 09:12:15 -070020using testing::Return;
William A. Kennington III874e82e2018-06-22 19:23:54 -070021
William A. Kennington III874e82e2018-06-22 19:23:54 -070022TEST(SdBusError, BasicErrno)
23{
24 const int errorVal = EBUSY;
25 const std::string prefix = "BasicErrno";
26
27 // Build the reference sd_bus_error
28 sd_bus_error error = SD_BUS_ERROR_NULL;
29 EXPECT_EQ(-errorVal, sd_bus_error_set_errno(&error, errorVal));
30 EXPECT_TRUE(sd_bus_error_is_set(&error));
31
32 // Build the SdBusError
33 SdBusError err(errorVal, prefix.c_str());
34
35 // Make sure inheritance is defined correctly
36 sdbusplus::exception::exception& sdbusErr = err;
Adriana Kobylak33335b32018-09-21 11:50:42 -050037 SdBusError& errNew = err;
38 EXPECT_EQ(errorVal, errNew.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -070039 EXPECT_EQ(std::string{error.name}, sdbusErr.name());
40 EXPECT_EQ(std::string{error.message}, sdbusErr.description());
William A. Kennington III874e82e2018-06-22 19:23:54 -070041 std::exception& stdErr = sdbusErr;
42 EXPECT_EQ(prefix + ": " + error.name + ": " + error.message, stdErr.what());
43
44 sd_bus_error_free(&error);
45}
46
47TEST(SdBusError, EnomemErrno)
48{
49 // Make sure no exception is thrown on construction
50 SdBusError err(ENOMEM, "EnomemErrno");
51}
52
53TEST(SdBusError, NotSetErrno)
54{
55 const int errorVal = EBUSY;
56
57 sdbusplus::SdBusMock sdbus;
58 EXPECT_CALL(sdbus, sd_bus_error_set_errno(_, errorVal))
59 .Times(1)
60 .WillOnce(Return(errorVal));
61 EXPECT_CALL(sdbus, sd_bus_error_is_set(_)).Times(1).WillOnce(Return(false));
62 EXPECT_THROW(SdBusError(errorVal, "NotSetErrno", &sdbus),
63 std::runtime_error);
64}
65
66TEST(SdBusError, Move)
67{
68 const int errorVal = EIO;
69 const std::string prefix = "Move";
70
71 // Build the reference sd_bus_error
72 sd_bus_error error = SD_BUS_ERROR_NULL;
73 EXPECT_EQ(-errorVal, sd_bus_error_set_errno(&error, errorVal));
74 EXPECT_TRUE(sd_bus_error_is_set(&error));
75 const std::string name{error.name};
76 const std::string message{error.message};
77 const std::string what = prefix + ": " + error.name + ": " + error.message;
78
79 SdBusError errFinal(EBUSY, "Move2");
80 // Nest to make sure RAII works for moves
81 {
82 // Build our first SdBusError
83 SdBusError err(errorVal, prefix.c_str());
84
Adriana Kobylak33335b32018-09-21 11:50:42 -050085 EXPECT_EQ(errorVal, err.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -070086 EXPECT_EQ(name, err.name());
87 EXPECT_EQ(message, err.description());
88 EXPECT_EQ(what, err.what());
William A. Kennington III874e82e2018-06-22 19:23:54 -070089
90 // Move our SdBusError to a new one
91 SdBusError errNew(std::move(err));
92
93 // Ensure the old object was cleaned up
Adriana Kobylak33335b32018-09-21 11:50:42 -050094 EXPECT_EQ(0, err.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -070095 EXPECT_EQ(nullptr, err.name());
96 EXPECT_EQ(nullptr, err.description());
97 EXPECT_EQ(std::string{}, err.what());
98
99 // Ensure our new object has the same data but moved
Adriana Kobylak33335b32018-09-21 11:50:42 -0500100 EXPECT_EQ(errorVal, errNew.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700101 EXPECT_EQ(name, errNew.name());
102 EXPECT_EQ(message, errNew.description());
103 EXPECT_EQ(what, errNew.what());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700104
105 // Move our SdBusError using the operator=()
106 errFinal = std::move(errNew);
107
108 // Ensure the old object was cleaned up
Adriana Kobylak33335b32018-09-21 11:50:42 -0500109 EXPECT_EQ(0, errNew.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700110 EXPECT_EQ(nullptr, errNew.name());
111 EXPECT_EQ(nullptr, errNew.description());
112 EXPECT_EQ(std::string{}, errNew.what());
113 }
114
115 // Ensure our new object has the same data but moved
Adriana Kobylak33335b32018-09-21 11:50:42 -0500116 EXPECT_EQ(errorVal, errFinal.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700117 EXPECT_EQ(name, errFinal.name());
118 EXPECT_EQ(message, errFinal.description());
119 EXPECT_EQ(what, errFinal.what());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700120
121 sd_bus_error_free(&error);
122}
123
124TEST(SdBusError, BasicError)
125{
126 const std::string name = "org.freedesktop.DBus.Error.Failed";
127 const std::string description = "TestCase";
128 const std::string prefix = "BasicError";
129
130 sd_bus_error error = SD_BUS_ERROR_NULL;
131 sd_bus_error_set(&error, name.c_str(), description.c_str());
132 EXPECT_TRUE(sd_bus_error_is_set(&error));
133 const char* nameBeforeMove = error.name;
Adriana Kobylak33335b32018-09-21 11:50:42 -0500134 const int errorVal = sd_bus_error_get_errno(&error);
William A. Kennington III874e82e2018-06-22 19:23:54 -0700135 SdBusError err(&error, prefix.c_str());
136
137 // We expect a move not copy
138 EXPECT_EQ(nameBeforeMove, err.name());
139
140 // The SdBusError should have moved our error so it should be freeable
141 EXPECT_FALSE(sd_bus_error_is_set(&error));
142 sd_bus_error_free(&error);
143 sd_bus_error_free(&error);
144
Adriana Kobylak33335b32018-09-21 11:50:42 -0500145 EXPECT_EQ(errorVal, err.get_errno());
William A. Kennington III874e82e2018-06-22 19:23:54 -0700146 EXPECT_EQ(name, err.name());
147 EXPECT_EQ(description, err.description());
148 EXPECT_EQ(prefix + ": " + name + ": " + description, err.what());
Vernon Maueryfac43a62018-08-01 12:29:23 -0700149}
150
151TEST(SdBusError, CatchBaseClassExceptions)
152{
153 /* test each class in the chain:
154 * std::exception
155 * -> sdbusplus::exception::exception
156 * -> sdbusplus::exception::internal_exception
157 * -> sdbusplus::exception::SdBusError
158 */
159 EXPECT_THROW({ throw SdBusError(-EINVAL, "SdBusError"); }, SdBusError);
160 EXPECT_THROW({ throw SdBusError(-EINVAL, "internal_exception"); },
161 sdbusplus::exception::internal_exception);
162 EXPECT_THROW({ throw SdBusError(-EINVAL, "exception"); },
163 sdbusplus::exception::exception);
164 EXPECT_THROW({ throw SdBusError(-EINVAL, "std::exception"); },
165 std::exception);
William A. Kennington III874e82e2018-06-22 19:23:54 -0700166}
167
168} // namespace