blob: 13cd054eea3ac4870845d5eaabf445cac2d59f10 [file] [log] [blame]
Lei YUe57c38e2019-09-20 17:38:17 +08001#include <sdbusplus/bus.hpp>
2#include <sdbusplus/server/manager.hpp>
3#include <sdbusplus/test/sdbus_mock.hpp>
William A. Kennington III293c8a22022-09-02 14:35:54 -07004#include <server/Test/server.hpp>
Lei YUe57c38e2019-09-20 17:38:17 +08005
6#include <gtest/gtest.h>
7
8using ::testing::_;
9using ::testing::StrEq;
10
Patrick Williams4a46eb52021-11-23 09:35:56 -060011struct UselessInherit
12{
13 template <typename... Args>
14 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.
22using TestInherit = sdbusplus::server::object_t<
23 UselessInherit,
24 sdbusplus::server::object_t<sdbusplus::server::server::Test>>;
Lei YUe57c38e2019-09-20 17:38:17 +080025
26class Object : public ::testing::Test
27{
28 protected:
29 sdbusplus::SdBusMock sdbusMock;
Patrick Williams0f282c42021-11-19 11:36:18 -060030 sdbusplus::bus_t bus = sdbusplus::get_mocked_new(&sdbusMock);
Lei YUe57c38e2019-09-20 17:38:17 +080031
32 static constexpr auto busName = "xyz.openbmc_project.sdbusplus.test.Object";
33 static constexpr auto objPath = "/xyz/openbmc_project/sdbusplus/test";
34};
35
36TEST_F(Object, InterfaceAddedOnly)
37{
38 // Simulate the typical usage of a service
Patrick Williamsba33c2a2021-11-19 12:08:31 -060039 sdbusplus::server::manager_t objManager(bus, objPath);
Lei YUe57c38e2019-09-20 17:38:17 +080040 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
60TEST_F(Object, DeferAddInterface)
61{
62 // Simulate the typical usage of a service
Patrick Williamsba33c2a2021-11-19 12:08:31 -060063 sdbusplus::server::manager_t objManager(bus, objPath);
Lei YUe57c38e2019-09-20 17:38:17 +080064 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
Lei YUe57c38e2019-09-20 17:38:17 +080085 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
Patrick Williamsba5460d2022-03-30 13:59:29 -050092TEST_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
Lei YUe57c38e2019-09-20 17:38:17 +0800122TEST_F(Object, ObjectAdded)
123{
124 // Simulate the typical usage of a service
Patrick Williamsba33c2a2021-11-19 12:08:31 -0600125 sdbusplus::server::manager_t objManager(bus, objPath);
Lei YUe57c38e2019-09-20 17:38:17 +0800126 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}
Patrick Williamsc67e1e82020-11-04 12:39:24 -0600146
147TEST_F(Object, DoubleHasDefaultValues)
148{
149 // Simulate the typical usage of a service
Patrick Williamsba33c2a2021-11-19 12:08:31 -0600150 sdbusplus::server::manager_t objManager(bus, objPath);
Patrick Williamsc67e1e82020-11-04 12:39:24 -0600151 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}