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