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