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