1 #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 9 using ::testing::_; 10 using ::testing::StrEq; 11 12 struct 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. 23 using TestInherit = sdbusplus::server::object_t< 24 UselessInherit, 25 sdbusplus::server::object_t<sdbusplus::server::server::Test>>; 26 27 class Object : public ::testing::Test 28 { 29 protected: 30 sdbusplus::SdBusMock sdbusMock; 31 sdbusplus::bus_t bus = sdbusplus::get_mocked_new(&sdbusMock); 32 33 static constexpr auto busName = "xyz.openbmc_project.sdbusplus.test.Object"; 34 static constexpr auto objPath = "/xyz/openbmc_project/sdbusplus/test"; 35 }; 36 37 TEST_F(Object, InterfaceAddedOnly) 38 { 39 // Simulate the typical usage of a service 40 sdbusplus::server::manager_t objManager(bus, objPath); 41 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 61 TEST_F(Object, DeferAddInterface) 62 { 63 // Simulate the typical usage of a service 64 sdbusplus::server::manager_t objManager(bus, objPath); 65 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 86 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 93 TEST_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 123 TEST_F(Object, ObjectAdded) 124 { 125 // Simulate the typical usage of a service 126 sdbusplus::server::manager_t objManager(bus, objPath); 127 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 } 147 148 TEST_F(Object, DoubleHasDefaultValues) 149 { 150 // Simulate the typical usage of a service 151 sdbusplus::server::manager_t objManager(bus, objPath); 152 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 } 168