1 #include "../interface_ops.hpp" 2 3 #include <sdbusplus/test/sdbus_mock.hpp> 4 5 #include <gtest/gtest.h> 6 7 using namespace phosphor::inventory::manager; 8 using namespace testing; 9 using namespace std::string_literals; 10 11 struct MockInterface; 12 struct DummyInterfaceWithProperties; 13 14 MockInterface* g_currentMock = nullptr; 15 16 using FakeVariantType = int; 17 using InterfaceVariant = std::map<std::string, FakeVariantType>; 18 19 struct MockInterface 20 { 21 MockInterface() 22 { 23 g_currentMock = this; 24 } 25 ~MockInterface() 26 { 27 g_currentMock = nullptr; 28 } 29 MockInterface(const MockInterface&) = delete; 30 MockInterface& operator=(const MockInterface&) = delete; 31 // Not supporting move semantics simply because they aren't needed. 32 MockInterface(MockInterface&&) = delete; 33 MockInterface& operator=(MockInterface&&) = delete; 34 35 // We'll be getting calls proxyed through other objects. 36 MOCK_METHOD3(constructWithProperties, 37 void(const char*, const InterfaceVariant& i, bool)); 38 MOCK_METHOD1(constructWithoutProperties, void(const char*)); 39 MOCK_METHOD3(setPropertyByName, void(std::string, FakeVariantType, bool)); 40 41 MOCK_METHOD2(serializeTwoArgs, 42 void(const std::string&, const std::string&)); 43 MOCK_METHOD3(serializeThreeArgs, 44 void(const std::string&, const std::string&, 45 const DummyInterfaceWithProperties&)); 46 47 MOCK_METHOD0(deserializeNoop, void()); 48 MOCK_METHOD3(deserializeThreeArgs, 49 void(const std::string&, const std::string&, 50 DummyInterfaceWithProperties&)); 51 }; 52 53 struct DummyInterfaceWithoutProperties 54 { 55 DummyInterfaceWithoutProperties(sdbusplus::bus::bus&, const char* name) 56 { 57 g_currentMock->constructWithoutProperties(name); 58 } 59 }; 60 61 struct DummyInterfaceWithProperties 62 { 63 using PropertiesVariant = FakeVariantType; 64 65 DummyInterfaceWithProperties(sdbusplus::bus::bus&, const char* name, 66 const InterfaceVariant& i, bool skipSignal) 67 { 68 g_currentMock->constructWithProperties(name, i, skipSignal); 69 } 70 71 void setPropertyByName(std::string name, PropertiesVariant val, 72 bool skipSignal) 73 { 74 g_currentMock->setPropertyByName(name, val, skipSignal); 75 } 76 }; 77 78 struct SerialForwarder 79 { 80 static void serialize(const std::string& path, const std::string& iface) 81 { 82 g_currentMock->serializeTwoArgs(path, iface); 83 } 84 85 static void serialize(const std::string& path, const std::string& iface, 86 const DummyInterfaceWithProperties& obj) 87 { 88 g_currentMock->serializeThreeArgs(path, iface, obj); 89 } 90 91 static void deserialize(const std::string& /* path */, 92 const std::string& /* iface */) 93 { 94 g_currentMock->deserializeNoop(); 95 } 96 97 static void deserialize(const std::string& path, const std::string& iface, 98 DummyInterfaceWithProperties& obj) 99 { 100 g_currentMock->deserializeThreeArgs(path, iface, obj); 101 } 102 }; 103 104 TEST(InterfaceOpsTest, TestHasPropertiesNoProperties) 105 { 106 EXPECT_FALSE(HasProperties<DummyInterfaceWithoutProperties>::value); 107 } 108 109 TEST(InterfaceOpsTest, TestHasPropertiesHasProperties) 110 { 111 EXPECT_TRUE(HasProperties<DummyInterfaceWithProperties>::value); 112 } 113 114 TEST(InterfaceOpsTest, TestMakePropertylessInterfaceWithoutArguments) 115 { 116 MockInterface mock; 117 Interface i; 118 sdbusplus::SdBusMock interface; 119 120 EXPECT_CALL(mock, constructWithoutProperties("foo")).Times(1); 121 EXPECT_CALL(mock, constructWithProperties(_, _, _)).Times(0); 122 123 auto b = sdbusplus::get_mocked_new(&interface); 124 auto r = 125 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 126 127 EXPECT_NO_THROW( 128 std::any_cast<std::shared_ptr<DummyInterfaceWithoutProperties>>(r)); 129 } 130 131 TEST(InterfaceOpsTest, TestMakePropertylessInterfaceWithOneArgument) 132 { 133 MockInterface mock; 134 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 135 sdbusplus::SdBusMock interface; 136 137 EXPECT_CALL(mock, constructWithoutProperties("foo")).Times(1); 138 EXPECT_CALL(mock, constructWithProperties(_, _, _)).Times(0); 139 140 auto b = sdbusplus::get_mocked_new(&interface); 141 auto r = 142 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 143 144 EXPECT_NO_THROW( 145 std::any_cast<std::shared_ptr<DummyInterfaceWithoutProperties>>(r)); 146 } 147 148 TEST(InterfaceOpsTest, TestMakeInterfaceWithWithoutArguments) 149 { 150 MockInterface mock; 151 Interface i; 152 sdbusplus::SdBusMock interface; 153 154 EXPECT_CALL(mock, constructWithoutProperties(_)).Times(0); 155 EXPECT_CALL(mock, constructWithProperties("bar", _, _)).Times(1); 156 157 auto b = sdbusplus::get_mocked_new(&interface); 158 auto r = 159 MakeInterface<DummyInterfaceWithProperties>::op(b, "bar", i, false); 160 161 EXPECT_NO_THROW( 162 std::any_cast<std::shared_ptr<DummyInterfaceWithProperties>>(r)); 163 } 164 165 TEST(InterfaceOpsTest, TestMakeInterfaceWithOneArgument) 166 { 167 MockInterface mock; 168 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 169 sdbusplus::SdBusMock interface; 170 171 EXPECT_CALL(mock, constructWithoutProperties(_)).Times(0); 172 EXPECT_CALL(mock, constructWithProperties("foo", _, _)).Times(1); 173 174 auto b = sdbusplus::get_mocked_new(&interface); 175 auto r = 176 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 177 178 EXPECT_NO_THROW( 179 std::any_cast<std::shared_ptr<DummyInterfaceWithProperties>>(r)); 180 } 181 182 TEST(InterfaceOpsTest, TestAssignPropertylessInterfaceWithoutArguments) 183 { 184 MockInterface mock; 185 Interface i; 186 sdbusplus::SdBusMock interface; 187 188 EXPECT_CALL(mock, setPropertyByName(_, _, _)).Times(0); 189 190 auto b = sdbusplus::get_mocked_new(&interface); 191 auto r = 192 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 193 194 AssignInterface<DummyInterfaceWithoutProperties>::op(i, r, false); 195 } 196 197 TEST(InterfaceOpsTest, TestAssignPropertylessInterfaceWithOneArgument) 198 { 199 MockInterface mock; 200 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 201 sdbusplus::SdBusMock interface; 202 203 EXPECT_CALL(mock, setPropertyByName(_, _, _)).Times(0); 204 205 auto b = sdbusplus::get_mocked_new(&interface); 206 auto r = 207 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 208 209 AssignInterface<DummyInterfaceWithoutProperties>::op(i, r, false); 210 } 211 212 TEST(InterfaceOpsTest, TestAssignInterfaceWithoutArguments) 213 { 214 MockInterface mock; 215 Interface i; 216 sdbusplus::SdBusMock interface; 217 218 EXPECT_CALL(mock, setPropertyByName(_, _, _)).Times(0); 219 220 auto b = sdbusplus::get_mocked_new(&interface); 221 auto r = 222 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 223 224 AssignInterface<DummyInterfaceWithProperties>::op(i, r, false); 225 } 226 227 TEST(InterfaceOpsTest, TestAssignInterfaceWithOneArgument) 228 { 229 MockInterface mock; 230 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 231 sdbusplus::SdBusMock interface; 232 233 EXPECT_CALL(mock, setPropertyByName("foo"s, 1ll, _)).Times(1); 234 235 auto b = sdbusplus::get_mocked_new(&interface); 236 auto r = 237 MakeInterface<DummyInterfaceWithProperties>::op(b, "bar", i, false); 238 239 AssignInterface<DummyInterfaceWithProperties>::op(i, r, false); 240 } 241 242 TEST(InterfaceOpsTest, TestSerializePropertylessInterfaceWithoutArguments) 243 { 244 MockInterface mock; 245 Interface i; 246 sdbusplus::SdBusMock interface; 247 248 auto b = sdbusplus::get_mocked_new(&interface); 249 auto r = 250 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 251 252 EXPECT_CALL(mock, serializeTwoArgs("/foo"s, "bar"s)).Times(1); 253 254 SerializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op( 255 "/foo"s, "bar"s, r); 256 } 257 258 TEST(InterfaceOpsTest, TestSerializePropertylessInterfaceWithOneArgument) 259 { 260 MockInterface mock; 261 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 262 sdbusplus::SdBusMock interface; 263 264 auto b = sdbusplus::get_mocked_new(&interface); 265 auto r = 266 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 267 268 EXPECT_CALL(mock, serializeTwoArgs("/foo"s, "bar"s)).Times(1); 269 270 SerializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op( 271 "/foo"s, "bar"s, r); 272 } 273 274 TEST(InterfaceOpsTest, TestSerializeInterfaceWithNoArguments) 275 { 276 MockInterface mock; 277 Interface i; 278 sdbusplus::SdBusMock interface; 279 280 auto b = sdbusplus::get_mocked_new(&interface); 281 auto r = 282 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 283 284 EXPECT_CALL(mock, serializeThreeArgs("/foo"s, "bar"s, _)).Times(1); 285 286 SerializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op( 287 "/foo"s, "bar"s, r); 288 } 289 290 TEST(InterfaceOpsTest, TestSerializeInterfaceWithOneArgument) 291 { 292 MockInterface mock; 293 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 294 sdbusplus::SdBusMock interface; 295 296 auto b = sdbusplus::get_mocked_new(&interface); 297 auto r = 298 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 299 300 EXPECT_CALL(mock, serializeThreeArgs("/foo"s, "bar"s, _)).Times(1); 301 302 SerializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op( 303 "/foo"s, "bar"s, r); 304 } 305 306 TEST(InterfaceOpsTest, TestDeserializePropertylessInterfaceWithoutArguments) 307 { 308 MockInterface mock; 309 Interface i; 310 sdbusplus::SdBusMock interface; 311 312 auto b = sdbusplus::get_mocked_new(&interface); 313 auto r = 314 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 315 316 EXPECT_CALL(mock, deserializeNoop()).Times(1); 317 318 DeserializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op( 319 "/foo"s, "bar"s, r); 320 } 321 322 TEST(InterfaceOpsTest, TestDeserializePropertylessInterfaceWithOneArgument) 323 { 324 MockInterface mock; 325 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 326 sdbusplus::SdBusMock interface; 327 328 auto b = sdbusplus::get_mocked_new(&interface); 329 auto r = 330 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 331 332 EXPECT_CALL(mock, deserializeNoop()).Times(1); 333 334 DeserializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op( 335 "/foo"s, "bar"s, r); 336 } 337 338 TEST(InterfaceOpsTest, TestDeserializeInterfaceWithNoArguments) 339 { 340 MockInterface mock; 341 Interface i; 342 sdbusplus::SdBusMock interface; 343 344 auto b = sdbusplus::get_mocked_new(&interface); 345 auto r = 346 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 347 348 EXPECT_CALL(mock, deserializeThreeArgs("/foo"s, "bar"s, _)).Times(1); 349 350 DeserializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op( 351 "/foo"s, "bar"s, r); 352 } 353 354 TEST(InterfaceOpsTest, TestDeserializeInterfaceWithOneArgument) 355 { 356 MockInterface mock; 357 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 358 sdbusplus::SdBusMock interface; 359 360 auto b = sdbusplus::get_mocked_new(&interface); 361 auto r = 362 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 363 364 EXPECT_CALL(mock, deserializeThreeArgs("/foo"s, "bar"s, _)).Times(1); 365 366 DeserializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op( 367 "/foo"s, "bar"s, r); 368 } 369