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, const std::string& iface) 92 { 93 g_currentMock->deserializeNoop(); 94 } 95 96 static void deserialize(const std::string& path, const std::string& iface, 97 DummyInterfaceWithProperties& obj) 98 { 99 g_currentMock->deserializeThreeArgs(path, iface, obj); 100 } 101 }; 102 103 TEST(InterfaceOpsTest, TestHasPropertiesNoProperties) 104 { 105 EXPECT_FALSE(HasProperties<DummyInterfaceWithoutProperties>::value); 106 } 107 108 TEST(InterfaceOpsTest, TestHasPropertiesHasProperties) 109 { 110 EXPECT_TRUE(HasProperties<DummyInterfaceWithProperties>::value); 111 } 112 113 TEST(InterfaceOpsTest, TestMakePropertylessInterfaceWithoutArguments) 114 { 115 MockInterface mock; 116 Interface i; 117 sdbusplus::SdBusMock interface; 118 119 EXPECT_CALL(mock, constructWithoutProperties("foo")).Times(1); 120 EXPECT_CALL(mock, constructWithProperties(_, _, _)).Times(0); 121 122 auto b = sdbusplus::get_mocked_new(&interface); 123 auto r = 124 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 125 126 EXPECT_NO_THROW( 127 std::any_cast<std::shared_ptr<DummyInterfaceWithoutProperties>>(r)); 128 } 129 130 TEST(InterfaceOpsTest, TestMakePropertylessInterfaceWithOneArgument) 131 { 132 MockInterface mock; 133 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 134 sdbusplus::SdBusMock interface; 135 136 EXPECT_CALL(mock, constructWithoutProperties("foo")).Times(1); 137 EXPECT_CALL(mock, constructWithProperties(_, _, _)).Times(0); 138 139 auto b = sdbusplus::get_mocked_new(&interface); 140 auto r = 141 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 142 143 EXPECT_NO_THROW( 144 std::any_cast<std::shared_ptr<DummyInterfaceWithoutProperties>>(r)); 145 } 146 147 TEST(InterfaceOpsTest, TestMakeInterfaceWithWithoutArguments) 148 { 149 MockInterface mock; 150 Interface i; 151 sdbusplus::SdBusMock interface; 152 153 EXPECT_CALL(mock, constructWithoutProperties(_)).Times(0); 154 EXPECT_CALL(mock, constructWithProperties("bar", _, _)).Times(1); 155 156 auto b = sdbusplus::get_mocked_new(&interface); 157 auto r = 158 MakeInterface<DummyInterfaceWithProperties>::op(b, "bar", i, false); 159 160 EXPECT_NO_THROW( 161 std::any_cast<std::shared_ptr<DummyInterfaceWithProperties>>(r)); 162 } 163 164 TEST(InterfaceOpsTest, TestMakeInterfaceWithOneArgument) 165 { 166 MockInterface mock; 167 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 168 sdbusplus::SdBusMock interface; 169 170 EXPECT_CALL(mock, constructWithoutProperties(_)).Times(0); 171 EXPECT_CALL(mock, constructWithProperties("foo", _, _)).Times(1); 172 173 auto b = sdbusplus::get_mocked_new(&interface); 174 auto r = 175 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 176 177 EXPECT_NO_THROW( 178 std::any_cast<std::shared_ptr<DummyInterfaceWithProperties>>(r)); 179 } 180 181 TEST(InterfaceOpsTest, TestAssignPropertylessInterfaceWithoutArguments) 182 { 183 MockInterface mock; 184 Interface i; 185 sdbusplus::SdBusMock interface; 186 187 EXPECT_CALL(mock, setPropertyByName(_, _, _)).Times(0); 188 189 auto b = sdbusplus::get_mocked_new(&interface); 190 auto r = 191 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 192 193 AssignInterface<DummyInterfaceWithoutProperties>::op(i, r, false); 194 } 195 196 TEST(InterfaceOpsTest, TestAssignPropertylessInterfaceWithOneArgument) 197 { 198 MockInterface mock; 199 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 200 sdbusplus::SdBusMock interface; 201 202 EXPECT_CALL(mock, setPropertyByName(_, _, _)).Times(0); 203 204 auto b = sdbusplus::get_mocked_new(&interface); 205 auto r = 206 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 207 208 AssignInterface<DummyInterfaceWithoutProperties>::op(i, r, false); 209 } 210 211 TEST(InterfaceOpsTest, TestAssignInterfaceWithoutArguments) 212 { 213 MockInterface mock; 214 Interface i; 215 sdbusplus::SdBusMock interface; 216 217 EXPECT_CALL(mock, setPropertyByName(_, _, _)).Times(0); 218 219 auto b = sdbusplus::get_mocked_new(&interface); 220 auto r = 221 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 222 223 AssignInterface<DummyInterfaceWithProperties>::op(i, r, false); 224 } 225 226 TEST(InterfaceOpsTest, TestAssignInterfaceWithOneArgument) 227 { 228 MockInterface mock; 229 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 230 sdbusplus::SdBusMock interface; 231 232 EXPECT_CALL(mock, setPropertyByName("foo"s, 1ll, _)).Times(1); 233 234 auto b = sdbusplus::get_mocked_new(&interface); 235 auto r = 236 MakeInterface<DummyInterfaceWithProperties>::op(b, "bar", i, false); 237 238 AssignInterface<DummyInterfaceWithProperties>::op(i, r, false); 239 } 240 241 TEST(InterfaceOpsTest, TestSerializePropertylessInterfaceWithoutArguments) 242 { 243 MockInterface mock; 244 Interface i; 245 sdbusplus::SdBusMock interface; 246 247 auto b = sdbusplus::get_mocked_new(&interface); 248 auto r = 249 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 250 251 EXPECT_CALL(mock, serializeTwoArgs("/foo"s, "bar"s)).Times(1); 252 253 SerializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op( 254 "/foo"s, "bar"s, r); 255 } 256 257 TEST(InterfaceOpsTest, TestSerializePropertylessInterfaceWithOneArgument) 258 { 259 MockInterface mock; 260 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 261 sdbusplus::SdBusMock interface; 262 263 auto b = sdbusplus::get_mocked_new(&interface); 264 auto r = 265 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 266 267 EXPECT_CALL(mock, serializeTwoArgs("/foo"s, "bar"s)).Times(1); 268 269 SerializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op( 270 "/foo"s, "bar"s, r); 271 } 272 273 TEST(InterfaceOpsTest, TestSerializeInterfaceWithNoArguments) 274 { 275 MockInterface mock; 276 Interface i; 277 sdbusplus::SdBusMock interface; 278 279 auto b = sdbusplus::get_mocked_new(&interface); 280 auto r = 281 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 282 283 EXPECT_CALL(mock, serializeThreeArgs("/foo"s, "bar"s, _)).Times(1); 284 285 SerializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op( 286 "/foo"s, "bar"s, r); 287 } 288 289 TEST(InterfaceOpsTest, TestSerializeInterfaceWithOneArgument) 290 { 291 MockInterface mock; 292 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 293 sdbusplus::SdBusMock interface; 294 295 auto b = sdbusplus::get_mocked_new(&interface); 296 auto r = 297 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 298 299 EXPECT_CALL(mock, serializeThreeArgs("/foo"s, "bar"s, _)).Times(1); 300 301 SerializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op( 302 "/foo"s, "bar"s, r); 303 } 304 305 TEST(InterfaceOpsTest, TestDeserializePropertylessInterfaceWithoutArguments) 306 { 307 MockInterface mock; 308 Interface i; 309 sdbusplus::SdBusMock interface; 310 311 auto b = sdbusplus::get_mocked_new(&interface); 312 auto r = 313 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 314 315 EXPECT_CALL(mock, deserializeNoop()).Times(1); 316 317 DeserializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op( 318 "/foo"s, "bar"s, r); 319 } 320 321 TEST(InterfaceOpsTest, TestDeserializePropertylessInterfaceWithOneArgument) 322 { 323 MockInterface mock; 324 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 325 sdbusplus::SdBusMock interface; 326 327 auto b = sdbusplus::get_mocked_new(&interface); 328 auto r = 329 MakeInterface<DummyInterfaceWithoutProperties>::op(b, "foo", i, false); 330 331 EXPECT_CALL(mock, deserializeNoop()).Times(1); 332 333 DeserializeInterface<DummyInterfaceWithoutProperties, SerialForwarder>::op( 334 "/foo"s, "bar"s, r); 335 } 336 337 TEST(InterfaceOpsTest, TestDeserializeInterfaceWithNoArguments) 338 { 339 MockInterface mock; 340 Interface i; 341 sdbusplus::SdBusMock interface; 342 343 auto b = sdbusplus::get_mocked_new(&interface); 344 auto r = 345 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 346 347 EXPECT_CALL(mock, deserializeThreeArgs("/foo"s, "bar"s, _)).Times(1); 348 349 DeserializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op( 350 "/foo"s, "bar"s, r); 351 } 352 353 TEST(InterfaceOpsTest, TestDeserializeInterfaceWithOneArgument) 354 { 355 MockInterface mock; 356 Interface i{{"foo"s, static_cast<int64_t>(1ll)}}; 357 sdbusplus::SdBusMock interface; 358 359 auto b = sdbusplus::get_mocked_new(&interface); 360 auto r = 361 MakeInterface<DummyInterfaceWithProperties>::op(b, "foo", i, false); 362 363 EXPECT_CALL(mock, deserializeThreeArgs("/foo"s, "bar"s, _)).Times(1); 364 365 DeserializeInterface<DummyInterfaceWithProperties, SerialForwarder>::op( 366 "/foo"s, "bar"s, r); 367 } 368