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 // After destruction, the object will be removed 87 EXPECT_CALL(sdbusMock, sd_bus_emit_object_removed(_, StrEq(objPath))) 88 .Times(1); 89 EXPECT_CALL(sdbusMock, 90 sd_bus_emit_interfaces_removed_strv(_, StrEq(objPath), _)) 91 .Times(0); 92 } 93 94 TEST_F(Object, ObjectAdded) 95 { 96 // Simulate the typical usage of a service 97 sdbusplus::server::manager_t objManager(bus, objPath); 98 bus.request_name(busName); 99 100 EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(_, StrEq(objPath))) 101 .Times(1); 102 EXPECT_CALL(sdbusMock, 103 sd_bus_emit_interfaces_added_strv(_, StrEq(objPath), _)) 104 .Times(0); 105 106 // Note: this is the wrong usage! 107 // With the below code, the interface is added as expected, but after 108 // destruction of TestInherit, the whole object will be removed from DBus. 109 // Refer to InterfaceAddedOnly case for the correct usage. 110 auto test = std::make_unique<TestInherit>(bus, objPath); 111 112 EXPECT_CALL(sdbusMock, sd_bus_emit_object_removed(_, StrEq(objPath))) 113 .Times(1); 114 EXPECT_CALL(sdbusMock, 115 sd_bus_emit_interfaces_removed_strv(_, StrEq(objPath), _)) 116 .Times(0); 117 } 118 119 TEST_F(Object, DoubleHasDefaultValues) 120 { 121 // Simulate the typical usage of a service 122 sdbusplus::server::manager_t objManager(bus, objPath); 123 bus.request_name(busName); 124 125 EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(_, StrEq(objPath))) 126 .Times(1); 127 EXPECT_CALL(sdbusMock, 128 sd_bus_emit_interfaces_added_strv(_, StrEq(objPath), _)) 129 .Times(0); 130 131 auto test = std::make_unique<TestInherit>(bus, objPath); 132 EXPECT_TRUE(std::isnan(test->doubleAsNAN())); 133 EXPECT_TRUE(std::isinf(test->doubleAsInf()) && 134 !std::signbit(test->doubleAsInf())); 135 EXPECT_TRUE(std::isinf(test->doubleAsNegInf()) && 136 std::signbit(test->doubleAsNegInf())); 137 EXPECT_EQ(std::numeric_limits<double>::epsilon(), test->doubleAsEpsilon()); 138 } 139