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> 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. 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 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 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 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 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 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