Darin Petkov | e4b2702 | 2012-05-16 13:28:50 +0200 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
Darin Petkov | e0a312e | 2011-07-20 13:45:28 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Darin Petkov | e0a312e | 2011-07-20 13:45:28 -0700 | [diff] [blame] | 5 | #include "shill/dbus_properties.h" |
| 6 | |
Ben Chan | 0a3a3a5 | 2013-07-10 11:34:07 -0700 | [diff] [blame] | 7 | #include <limits> |
| 8 | |
| 9 | #include <gtest/gtest.h> |
| 10 | |
Arman Uguray | 631c7e4 | 2013-07-30 16:41:12 -0700 | [diff] [blame] | 11 | using std::map; |
Ben Chan | 0a3a3a5 | 2013-07-10 11:34:07 -0700 | [diff] [blame] | 12 | using std::numeric_limits; |
Darin Petkov | e0a312e | 2011-07-20 13:45:28 -0700 | [diff] [blame] | 13 | using std::string; |
Jason Glasgow | 9c09e36 | 2012-04-18 15:16:29 -0400 | [diff] [blame] | 14 | using std::vector; |
Darin Petkov | e0a312e | 2011-07-20 13:45:28 -0700 | [diff] [blame] | 15 | using testing::Test; |
| 16 | |
| 17 | namespace shill { |
| 18 | |
Ben Chan | 0a3a3a5 | 2013-07-10 11:34:07 -0700 | [diff] [blame] | 19 | class DBusPropertiesTest : public Test {}; |
Darin Petkov | e4b2702 | 2012-05-16 13:28:50 +0200 | [diff] [blame] | 20 | |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 21 | TEST_F(DBusPropertiesTest, ConvertPathsToRpcIdentifiers) { |
| 22 | static const char kOldTestPath[] = "/org/chromium/Something/Old"; |
| 23 | static const char kTestPath0[] = "/org/chromium/Something"; |
| 24 | static const char kTestPath1[] = "/org/chromium/Else"; |
| 25 | |
| 26 | RpcIdentifiers ids(1, kOldTestPath); |
| 27 | vector<DBus::Path> paths; |
| 28 | paths.push_back(kTestPath0); |
| 29 | paths.push_back(kTestPath1); |
| 30 | DBusProperties::ConvertPathsToRpcIdentifiers(paths, &ids); |
| 31 | ASSERT_EQ(2, ids.size()); |
| 32 | EXPECT_EQ(kTestPath0, ids[0]); |
| 33 | EXPECT_EQ(kTestPath1, ids[1]); |
| 34 | } |
| 35 | |
Darin Petkov | 25665aa | 2012-05-21 14:08:12 +0200 | [diff] [blame] | 36 | TEST_F(DBusPropertiesTest, ConvertKeyValueStoreToMap) { |
| 37 | static const char kStringKey[] = "StringKey"; |
| 38 | static const char kStringValue[] = "StringValue"; |
Arman Uguray | 631c7e4 | 2013-07-30 16:41:12 -0700 | [diff] [blame] | 39 | static const char kStringmapKey[] = "StringmapKey"; |
| 40 | const map<string, string> kStringmapValue = { { "key", "value" } }; |
Ben Chan | 0a3a3a5 | 2013-07-10 11:34:07 -0700 | [diff] [blame] | 41 | static const char kStringsKey[] = "StringsKey"; |
| 42 | const vector<string> kStringsValue = {"StringsValue1", "StringsValue2"}; |
Darin Petkov | 25665aa | 2012-05-21 14:08:12 +0200 | [diff] [blame] | 43 | static const char kBoolKey[] = "BoolKey"; |
| 44 | const bool kBoolValue = true; |
| 45 | static const char kInt32Key[] = "Int32Key"; |
| 46 | const int32 kInt32Value = 123; |
| 47 | static const char kUint32Key[] = "Uint32Key"; |
| 48 | const uint32 kUint32Value = 654; |
| 49 | KeyValueStore store; |
| 50 | store.SetString(kStringKey, kStringValue); |
Arman Uguray | 631c7e4 | 2013-07-30 16:41:12 -0700 | [diff] [blame] | 51 | store.SetStringmap(kStringmapKey, kStringmapValue); |
Ben Chan | 0a3a3a5 | 2013-07-10 11:34:07 -0700 | [diff] [blame] | 52 | store.SetStrings(kStringsKey, kStringsValue); |
Darin Petkov | 25665aa | 2012-05-21 14:08:12 +0200 | [diff] [blame] | 53 | store.SetBool(kBoolKey, kBoolValue); |
| 54 | store.SetInt(kInt32Key, kInt32Value); |
| 55 | store.SetUint(kUint32Key, kUint32Value); |
| 56 | DBusPropertiesMap props; |
| 57 | props["RandomKey"].writer().append_string("RandomValue"); |
| 58 | DBusProperties::ConvertKeyValueStoreToMap(store, &props); |
Arman Uguray | 631c7e4 | 2013-07-30 16:41:12 -0700 | [diff] [blame] | 59 | EXPECT_EQ(6, props.size()); |
Darin Petkov | 25665aa | 2012-05-21 14:08:12 +0200 | [diff] [blame] | 60 | string string_value; |
| 61 | EXPECT_TRUE(DBusProperties::GetString(props, kStringKey, &string_value)); |
| 62 | EXPECT_EQ(kStringValue, string_value); |
Arman Uguray | 631c7e4 | 2013-07-30 16:41:12 -0700 | [diff] [blame] | 63 | map<string, string> stringmap_value; |
| 64 | EXPECT_TRUE( |
| 65 | DBusProperties::GetStringmap(props, kStringmapKey, &stringmap_value)); |
| 66 | EXPECT_EQ(kStringmapValue, stringmap_value); |
Ben Chan | 0a3a3a5 | 2013-07-10 11:34:07 -0700 | [diff] [blame] | 67 | vector<string> strings_value; |
| 68 | EXPECT_TRUE(DBusProperties::GetStrings(props, kStringsKey, &strings_value)); |
| 69 | EXPECT_EQ(kStringsValue, strings_value); |
Darin Petkov | 25665aa | 2012-05-21 14:08:12 +0200 | [diff] [blame] | 70 | bool bool_value = !kBoolValue; |
| 71 | EXPECT_TRUE(DBusProperties::GetBool(props, kBoolKey, &bool_value)); |
| 72 | EXPECT_EQ(kBoolValue, bool_value); |
| 73 | int32 int32_value = ~kInt32Value; |
| 74 | EXPECT_TRUE(DBusProperties::GetInt32(props, kInt32Key, &int32_value)); |
| 75 | EXPECT_EQ(kInt32Value, int32_value); |
| 76 | uint32 uint32_value = ~kUint32Value; |
| 77 | EXPECT_TRUE(DBusProperties::GetUint32(props, kUint32Key, &uint32_value)); |
| 78 | EXPECT_EQ(kUint32Value, uint32_value); |
| 79 | } |
| 80 | |
Ben Chan | 0a3a3a5 | 2013-07-10 11:34:07 -0700 | [diff] [blame] | 81 | template <typename T> class DBusPropertiesGetterTest : public Test {}; |
| 82 | |
| 83 | template <typename DerivedT, typename ValueT, typename DBusT = ValueT> |
| 84 | struct TestTraits { |
| 85 | typedef ValueT ValueType; |
| 86 | typedef DBusT DBusType; |
| 87 | typedef bool (*GetterType)(const DBusPropertiesMap &properties, |
| 88 | const string &key, |
| 89 | ValueType *value); |
| 90 | |
| 91 | static DBusType GetTestValue() { return DerivedT::GetNewValue(); } |
| 92 | |
| 93 | static void CheckValueEqual(const ValueType &expected, |
| 94 | const ValueType &actual) { |
| 95 | EXPECT_EQ(expected, actual); |
| 96 | } |
| 97 | }; |
| 98 | |
| 99 | struct BoolTestTraits : public TestTraits<BoolTestTraits, bool> { |
| 100 | static bool GetOldValue() { return false; } |
| 101 | static bool GetNewValue() { return true; } |
| 102 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetBool; |
| 103 | }; |
| 104 | |
| 105 | template <typename DerivedT, typename ValueT> |
| 106 | struct IntTestTraits : public TestTraits<DerivedT, ValueT> { |
| 107 | static ValueT GetOldValue() { return numeric_limits<ValueT>::min(); } |
| 108 | static ValueT GetNewValue() { return numeric_limits<ValueT>::max(); } |
| 109 | }; |
| 110 | |
| 111 | struct Int16TestTraits : public IntTestTraits<Int16TestTraits, int16> { |
| 112 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetInt16; |
| 113 | }; |
| 114 | |
| 115 | struct Int32TestTraits : public IntTestTraits<Int32TestTraits, int32> { |
| 116 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetInt32; |
| 117 | }; |
| 118 | |
| 119 | struct Int64TestTraits : public IntTestTraits<Int64TestTraits, int64> { |
| 120 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetInt64; |
| 121 | }; |
| 122 | |
| 123 | struct Uint8TestTraits : public IntTestTraits<Uint8TestTraits, uint8> { |
| 124 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetUint8; |
| 125 | }; |
| 126 | |
| 127 | struct Uint16TestTraits : public IntTestTraits<Uint16TestTraits, uint16> { |
| 128 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetUint16; |
| 129 | }; |
| 130 | |
| 131 | struct Uint32TestTraits : public IntTestTraits<Uint32TestTraits, uint32> { |
| 132 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetUint32; |
| 133 | }; |
| 134 | |
| 135 | struct Uint64TestTraits : public IntTestTraits<Uint64TestTraits, uint64> { |
| 136 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetUint64; |
| 137 | }; |
| 138 | |
| 139 | struct DoubleTestTraits : public TestTraits<DoubleTestTraits, double> { |
| 140 | static double GetOldValue() { return -1.1; } |
| 141 | static double GetNewValue() { return 3.14; } |
| 142 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetDouble; |
| 143 | }; |
| 144 | |
| 145 | struct StringTestTraits : public TestTraits<StringTestTraits, string> { |
| 146 | static string GetOldValue() { return "old"; } |
| 147 | static string GetNewValue() { return "new"; } |
| 148 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetString; |
| 149 | }; |
| 150 | |
Arman Uguray | 631c7e4 | 2013-07-30 16:41:12 -0700 | [diff] [blame] | 151 | struct StringmapTestTraits |
| 152 | : public TestTraits<StringmapTestTraits, map<string, string>> { |
| 153 | static map<string, string> GetOldValue() { |
| 154 | return { { "oldKey", "oldValue" } }; |
| 155 | } |
| 156 | static map<string, string> GetNewValue() { |
| 157 | return { { "newKey", "newValue" } }; |
| 158 | } |
| 159 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetStringmap; |
| 160 | }; |
| 161 | |
Ben Chan | 0a3a3a5 | 2013-07-10 11:34:07 -0700 | [diff] [blame] | 162 | struct StringsTestTraits |
| 163 | : public TestTraits<StringsTestTraits, vector<string>> { |
| 164 | static vector<string> GetOldValue() { return {"1", "2", "3"}; } |
| 165 | static vector<string> GetNewValue() { return {"a", "b"}; } |
| 166 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetStrings; |
| 167 | }; |
| 168 | |
| 169 | struct ObjectPathTestTraits |
| 170 | : public TestTraits<ObjectPathTestTraits, DBus::Path> { |
| 171 | static DBus::Path GetOldValue() { return "/old/path"; } |
| 172 | static DBus::Path GetNewValue() { return "/new/path"; } |
| 173 | static constexpr GetterType kMethodUnderTest = &DBusProperties::GetObjectPath; |
| 174 | }; |
| 175 | |
| 176 | struct RpcIdentifiersTestTraits : public TestTraits<RpcIdentifiersTestTraits, |
| 177 | RpcIdentifiers, |
| 178 | vector<DBus::Path>> { |
| 179 | static RpcIdentifiers GetOldValue() { return {"/device/1", "/service/2"}; } |
| 180 | static RpcIdentifiers GetNewValue() { return {"/obj/3", "/obj/4", "/obj/5"}; } |
| 181 | static vector<DBus::Path> GetTestValue() { |
| 182 | return {"/obj/3", "/obj/4", "/obj/5"}; |
| 183 | } |
| 184 | static constexpr GetterType kMethodUnderTest = |
| 185 | &DBusProperties::GetRpcIdentifiers; |
| 186 | }; |
| 187 | |
| 188 | struct DBusPropertiesMapTestTraits |
| 189 | : public TestTraits<DBusPropertiesMapTestTraits, DBusPropertiesMap> { |
| 190 | static DBusPropertiesMap GetOldValue() { |
| 191 | DBusPropertiesMap value; |
| 192 | value["OldKey"].writer().append_bool(false); |
| 193 | return value; |
| 194 | } |
| 195 | |
| 196 | static DBusPropertiesMap GetNewValue() { |
| 197 | DBusPropertiesMap value; |
| 198 | value["BoolKey"].writer().append_bool(true); |
| 199 | value["Int16Key"].writer().append_int16(numeric_limits<int16>::max()); |
| 200 | value["Int32Key"].writer().append_int32(numeric_limits<int32>::max()); |
| 201 | value["Int64Key"].writer().append_int64(numeric_limits<int64>::max()); |
| 202 | value["Uint8Key"].writer().append_byte(numeric_limits<uint8>::max()); |
| 203 | value["Uint16Key"].writer().append_uint16(numeric_limits<uint16>::max()); |
| 204 | value["Uint32Key"].writer().append_uint32(numeric_limits<uint32>::max()); |
| 205 | value["Uint64Key"].writer().append_uint64(numeric_limits<uint64>::max()); |
| 206 | value["DoubleKey"].writer().append_double(3.14); |
| 207 | value["StringKey"].writer().append_string("new"); |
| 208 | return value; |
| 209 | } |
| 210 | |
| 211 | template <typename T> |
| 212 | static void CheckDBusVariantEqual(const string &key, |
| 213 | const DBus::Variant &expected, |
| 214 | const DBus::Variant &actual) { |
| 215 | T expected_value = expected.operator T(); |
| 216 | T actual_value = actual.operator T(); |
| 217 | EXPECT_EQ(expected_value, actual_value) << "Value mismatch - key: " << key; |
| 218 | } |
| 219 | |
| 220 | static void CheckValueEqual(const DBusPropertiesMap &expected, |
| 221 | const DBusPropertiesMap &actual) { |
| 222 | ASSERT_EQ(expected.size(), actual.size()) << "Map size mismatch"; |
| 223 | |
| 224 | for (const auto &key_value_pair : expected) { |
| 225 | const string &key = key_value_pair.first; |
| 226 | |
| 227 | const auto &actual_it = actual.find(key); |
| 228 | ASSERT_TRUE(actual_it != actual.end()) << "Key '" << key << "' not found"; |
| 229 | |
| 230 | const DBus::Variant &actual_value = actual_it->second; |
| 231 | const DBus::Variant &expected_value = key_value_pair.second; |
| 232 | |
| 233 | string actual_signature = actual_value.signature(); |
| 234 | string expected_signature = expected_value.signature(); |
| 235 | ASSERT_EQ(expected_signature, actual_signature) |
| 236 | << "Value type mismatch - key: " << key; |
| 237 | |
| 238 | if (expected_signature == DBus::type<bool>::sig()) { |
| 239 | CheckDBusVariantEqual<bool>(key, expected_value, actual_value); |
| 240 | } else if (expected_signature == DBus::type<int16>::sig()) { |
| 241 | CheckDBusVariantEqual<int16>(key, expected_value, actual_value); |
| 242 | } else if (expected_signature == DBus::type<int32>::sig()) { |
| 243 | CheckDBusVariantEqual<int32>(key, expected_value, actual_value); |
| 244 | } else if (expected_signature == DBus::type<int64>::sig()) { |
| 245 | CheckDBusVariantEqual<int64>(key, expected_value, actual_value); |
| 246 | } else if (expected_signature == DBus::type<uint8>::sig()) { |
| 247 | CheckDBusVariantEqual<uint8>(key, expected_value, actual_value); |
| 248 | } else if (expected_signature == DBus::type<uint16>::sig()) { |
| 249 | CheckDBusVariantEqual<uint16>(key, expected_value, actual_value); |
| 250 | } else if (expected_signature == DBus::type<uint32>::sig()) { |
| 251 | CheckDBusVariantEqual<uint32>(key, expected_value, actual_value); |
| 252 | } else if (expected_signature == DBus::type<uint64>::sig()) { |
| 253 | CheckDBusVariantEqual<uint64>(key, expected_value, actual_value); |
| 254 | } else if (expected_signature == DBus::type<double>::sig()) { |
| 255 | CheckDBusVariantEqual<double>(key, expected_value, actual_value); |
| 256 | } else if (expected_signature == DBus::type<string>::sig()) { |
| 257 | CheckDBusVariantEqual<string>(key, expected_value, actual_value); |
| 258 | } else if (expected_signature == DBus::type<DBus::Path>::sig()) { |
| 259 | CheckDBusVariantEqual<DBus::Path>(key, expected_value, actual_value); |
| 260 | } else { |
| 261 | // TODO(benchan): Comparison of other types is not yet implemented. |
| 262 | FAIL() << "Value type '" << expected_signature << "' not implemented."; |
| 263 | } |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | static constexpr GetterType kMethodUnderTest = |
| 268 | &DBusProperties::GetDBusPropertiesMap; |
| 269 | }; |
| 270 | |
| 271 | typedef testing::Types<BoolTestTraits, |
| 272 | Int16TestTraits, |
| 273 | Int32TestTraits, |
| 274 | Int64TestTraits, |
| 275 | Uint8TestTraits, |
| 276 | Uint16TestTraits, |
| 277 | Uint32TestTraits, |
| 278 | Uint64TestTraits, |
| 279 | DoubleTestTraits, |
| 280 | StringTestTraits, |
Arman Uguray | 631c7e4 | 2013-07-30 16:41:12 -0700 | [diff] [blame] | 281 | StringmapTestTraits, |
Ben Chan | 0a3a3a5 | 2013-07-10 11:34:07 -0700 | [diff] [blame] | 282 | StringsTestTraits, |
| 283 | ObjectPathTestTraits, |
| 284 | RpcIdentifiersTestTraits, |
| 285 | DBusPropertiesMapTestTraits> DBusPropertyValueTypes; |
| 286 | TYPED_TEST_CASE(DBusPropertiesGetterTest, DBusPropertyValueTypes); |
| 287 | |
| 288 | TYPED_TEST(DBusPropertiesGetterTest, GetValue) { |
| 289 | static const char kTestProperty[] = "TestProperty"; |
| 290 | const typename TypeParam::ValueType kOldValue = TypeParam::GetOldValue(); |
| 291 | const typename TypeParam::ValueType kNewValue = TypeParam::GetNewValue(); |
| 292 | const typename TypeParam::DBusType kTestValue = TypeParam::GetTestValue(); |
| 293 | typename TypeParam::ValueType value = kOldValue; |
| 294 | DBusPropertiesMap properties; |
| 295 | |
| 296 | // Property key is not found. |value| should remain the initial value. |
| 297 | EXPECT_FALSE(TypeParam::kMethodUnderTest(properties, kTestProperty, &value)); |
| 298 | TypeParam::CheckValueEqual(kOldValue, value); |
| 299 | |
| 300 | // Property value type mismatch. |value| should remain the initial value. |
| 301 | properties[kTestProperty].writer().append_fd(1); |
| 302 | EXPECT_FALSE(TypeParam::kMethodUnderTest(properties, kTestProperty, &value)); |
| 303 | TypeParam::CheckValueEqual(kOldValue, value); |
| 304 | |
| 305 | // Property key is found. |value| should be set to the test value. |
| 306 | properties.clear(); |
| 307 | DBus::MessageIter writer = properties[kTestProperty].writer(); |
| 308 | writer << kTestValue; |
| 309 | EXPECT_TRUE(TypeParam::kMethodUnderTest(properties, kTestProperty, &value)); |
| 310 | TypeParam::CheckValueEqual(kNewValue, value); |
| 311 | } |
| 312 | |
Darin Petkov | e0a312e | 2011-07-20 13:45:28 -0700 | [diff] [blame] | 313 | } // namespace shill |