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