blob: afb7ad014f86ab6c273e793fc1eedf7ca27d46ca [file] [log] [blame]
Lei YUe57c38e2019-09-20 17:38:17 +08001#include "Test/server.hpp"
2
3#include <sdbusplus/bus.hpp>
4#include <sdbusplus/server/manager.hpp>
5#include <sdbusplus/test/sdbus_mock.hpp>
6
7#include <gtest/gtest.h>
8
9using ::testing::_;
10using ::testing::StrEq;
11
Patrick Williams4a46eb52021-11-23 09:35:56 -060012struct UselessInherit
13{
14 template <typename... Args>
15 explicit UselessInherit(Args&&...)
16 {}
17};
18
19// It isn't a particularly good idea to inherit from object_t twice, but some
20// clients seem to do it. Do it here to ensure that code compiles (avoiding
21// diamond-inheritance problems) and that emit happens correctly when it is
22// done.
23using TestInherit = sdbusplus::server::object_t<
24 UselessInherit,
25 sdbusplus::server::object_t<sdbusplus::server::server::Test>>;
Lei YUe57c38e2019-09-20 17:38:17 +080026
27class Object : public ::testing::Test
28{
29 protected:
30 sdbusplus::SdBusMock sdbusMock;
Patrick Williams0f282c42021-11-19 11:36:18 -060031 sdbusplus::bus_t bus = sdbusplus::get_mocked_new(&sdbusMock);
Lei YUe57c38e2019-09-20 17:38:17 +080032
33 static constexpr auto busName = "xyz.openbmc_project.sdbusplus.test.Object";
34 static constexpr auto objPath = "/xyz/openbmc_project/sdbusplus/test";
35};
36
37TEST_F(Object, InterfaceAddedOnly)
38{
39 // Simulate the typical usage of a service
Patrick Williamsba33c2a2021-11-19 12:08:31 -060040 sdbusplus::server::manager_t objManager(bus, objPath);
Lei YUe57c38e2019-09-20 17:38:17 +080041 bus.request_name(busName);
42
43 EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(_, StrEq(objPath)))
44 .Times(0);
45 EXPECT_CALL(sdbusMock,
46 sd_bus_emit_interfaces_added_strv(_, StrEq(objPath), _))
47 .Times(1);
48
49 // This only add interface to the existing object
50 auto test = std::make_unique<TestInherit>(
51 bus, objPath, TestInherit::action::emit_interface_added);
52
53 // After destruction, the interface shall be removed
54 EXPECT_CALL(sdbusMock, sd_bus_emit_object_removed(_, StrEq(objPath)))
55 .Times(0);
56 EXPECT_CALL(sdbusMock,
57 sd_bus_emit_interfaces_removed_strv(_, StrEq(objPath), _))
58 .Times(1);
59}
60
61TEST_F(Object, DeferAddInterface)
62{
63 // Simulate the typical usage of a service
Patrick Williamsba33c2a2021-11-19 12:08:31 -060064 sdbusplus::server::manager_t objManager(bus, objPath);
Lei YUe57c38e2019-09-20 17:38:17 +080065 bus.request_name(busName);
66
67 EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(_, StrEq(objPath)))
68 .Times(0);
69 EXPECT_CALL(sdbusMock,
70 sd_bus_emit_interfaces_added_strv(_, StrEq(objPath), _))
71 .Times(0);
72
73 // It defers emit_object_added()
74 auto test = std::make_unique<TestInherit>(bus, objPath,
75 TestInherit::action::defer_emit);
76
77 EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(_, StrEq(objPath)))
78 .Times(1);
79 EXPECT_CALL(sdbusMock,
80 sd_bus_emit_interfaces_added_strv(_, StrEq(objPath), _))
81 .Times(0);
82
83 // Now invoke emit_object_added()
84 test->emit_object_added();
85
Lei YUe57c38e2019-09-20 17:38:17 +080086 EXPECT_CALL(sdbusMock, sd_bus_emit_object_removed(_, StrEq(objPath)))
87 .Times(1);
88 EXPECT_CALL(sdbusMock,
89 sd_bus_emit_interfaces_removed_strv(_, StrEq(objPath), _))
90 .Times(0);
91}
92
Patrick Williamsba5460d2022-03-30 13:59:29 -050093TEST_F(Object, NeverAddInterface)
94{
95 // Simulate the typical usage of a service
96 sdbusplus::server::manager_t objManager(bus, objPath);
97 bus.request_name(busName);
98
99 EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(_, StrEq(objPath)))
100 .Times(0);
101 EXPECT_CALL(sdbusMock,
102 sd_bus_emit_interfaces_added_strv(_, StrEq(objPath), _))
103 .Times(0);
104
105 // It defers emit_object_added()
106 auto test = std::make_unique<TestInherit>(
107 bus, objPath, TestInherit::action::emit_no_signals);
108
109 EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(_, StrEq(objPath)))
110 .Times(0);
111 EXPECT_CALL(sdbusMock,
112 sd_bus_emit_interfaces_added_strv(_, StrEq(objPath), _))
113 .Times(0);
114
115 // After destruction, the object will be removed
116 EXPECT_CALL(sdbusMock, sd_bus_emit_object_removed(_, StrEq(objPath)))
117 .Times(0);
118 EXPECT_CALL(sdbusMock,
119 sd_bus_emit_interfaces_removed_strv(_, StrEq(objPath), _))
120 .Times(0);
121}
122
Lei YUe57c38e2019-09-20 17:38:17 +0800123TEST_F(Object, ObjectAdded)
124{
125 // Simulate the typical usage of a service
Patrick Williamsba33c2a2021-11-19 12:08:31 -0600126 sdbusplus::server::manager_t objManager(bus, objPath);
Lei YUe57c38e2019-09-20 17:38:17 +0800127 bus.request_name(busName);
128
129 EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(_, StrEq(objPath)))
130 .Times(1);
131 EXPECT_CALL(sdbusMock,
132 sd_bus_emit_interfaces_added_strv(_, StrEq(objPath), _))
133 .Times(0);
134
135 // Note: this is the wrong usage!
136 // With the below code, the interface is added as expected, but after
137 // destruction of TestInherit, the whole object will be removed from DBus.
138 // Refer to InterfaceAddedOnly case for the correct usage.
139 auto test = std::make_unique<TestInherit>(bus, objPath);
140
141 EXPECT_CALL(sdbusMock, sd_bus_emit_object_removed(_, StrEq(objPath)))
142 .Times(1);
143 EXPECT_CALL(sdbusMock,
144 sd_bus_emit_interfaces_removed_strv(_, StrEq(objPath), _))
145 .Times(0);
146}
Patrick Williamsc67e1e82020-11-04 12:39:24 -0600147
148TEST_F(Object, DoubleHasDefaultValues)
149{
150 // Simulate the typical usage of a service
Patrick Williamsba33c2a2021-11-19 12:08:31 -0600151 sdbusplus::server::manager_t objManager(bus, objPath);
Patrick Williamsc67e1e82020-11-04 12:39:24 -0600152 bus.request_name(busName);
153
154 EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(_, StrEq(objPath)))
155 .Times(1);
156 EXPECT_CALL(sdbusMock,
157 sd_bus_emit_interfaces_added_strv(_, StrEq(objPath), _))
158 .Times(0);
159
160 auto test = std::make_unique<TestInherit>(bus, objPath);
161 EXPECT_TRUE(std::isnan(test->doubleAsNAN()));
162 EXPECT_TRUE(std::isinf(test->doubleAsInf()) &&
163 !std::signbit(test->doubleAsInf()));
164 EXPECT_TRUE(std::isinf(test->doubleAsNegInf()) &&
165 std::signbit(test->doubleAsNegInf()));
166 EXPECT_EQ(std::numeric_limits<double>::epsilon(), test->doubleAsEpsilon());
167}