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