1 // Copyright 2014 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <brillo/dbus/data_serialization.h> 6 7 #include <limits> 8 9 #include <base/files/scoped_file.h> 10 #include <brillo/variant_dictionary.h> 11 #include <gtest/gtest.h> 12 13 #include "brillo/dbus/test.pb.h" 14 15 using base::ScopedFD; 16 using dbus::Message; 17 using dbus::MessageReader; 18 using dbus::MessageWriter; 19 using dbus::ObjectPath; 20 using dbus::Response; 21 22 namespace brillo { 23 namespace dbus_utils { 24 25 TEST(DBusUtils, Supported_BasicTypes) { 26 EXPECT_TRUE(IsTypeSupported<bool>::value); 27 EXPECT_TRUE(IsTypeSupported<uint8_t>::value); 28 EXPECT_TRUE(IsTypeSupported<int16_t>::value); 29 EXPECT_TRUE(IsTypeSupported<uint16_t>::value); 30 EXPECT_TRUE(IsTypeSupported<int32_t>::value); 31 EXPECT_TRUE(IsTypeSupported<uint32_t>::value); 32 EXPECT_TRUE(IsTypeSupported<int64_t>::value); 33 EXPECT_TRUE(IsTypeSupported<uint64_t>::value); 34 EXPECT_TRUE(IsTypeSupported<double>::value); 35 EXPECT_TRUE(IsTypeSupported<std::string>::value); 36 EXPECT_TRUE(IsTypeSupported<ObjectPath>::value); 37 EXPECT_TRUE(IsTypeSupported<ScopedFD>::value); 38 EXPECT_TRUE(IsTypeSupported<Any>::value); 39 EXPECT_TRUE(IsTypeSupported<google::protobuf::MessageLite>::value); 40 EXPECT_TRUE(IsTypeSupported<dbus_utils_test::TestMessage>::value); 41 } 42 43 TEST(DBusUtils, Unsupported_BasicTypes) { 44 EXPECT_FALSE(IsTypeSupported<char>::value); 45 EXPECT_FALSE(IsTypeSupported<float>::value); 46 } 47 48 TEST(DBusUtils, Supported_ComplexTypes) { 49 EXPECT_TRUE(IsTypeSupported<std::vector<bool>>::value); 50 EXPECT_TRUE(IsTypeSupported<std::vector<uint8_t>>::value); 51 EXPECT_TRUE((IsTypeSupported<std::pair<int16_t, double>>::value)); 52 EXPECT_TRUE( 53 (IsTypeSupported<std::map<uint16_t, std::vector<int64_t>>>::value)); 54 EXPECT_TRUE((IsTypeSupported<std::tuple<bool, double, int32_t>>::value)); 55 EXPECT_TRUE( 56 IsTypeSupported<std::vector<dbus_utils_test::TestMessage>>::value); 57 } 58 59 TEST(DBusUtils, Unsupported_ComplexTypes) { 60 EXPECT_FALSE(IsTypeSupported<std::vector<char>>::value); 61 EXPECT_FALSE((IsTypeSupported<std::pair<int16_t, float>>::value)); 62 EXPECT_FALSE((IsTypeSupported<std::pair<char, int32_t>>::value)); 63 EXPECT_FALSE((IsTypeSupported<std::map<int16_t, float>>::value)); 64 EXPECT_FALSE((IsTypeSupported<std::map<char, int32_t>>::value)); 65 EXPECT_FALSE((IsTypeSupported<std::tuple<bool, char, int32_t>>::value)); 66 } 67 68 TEST(DBusUtils, Supported_TypeSet) { 69 EXPECT_TRUE((IsTypeSupported<int32_t, double, std::string>::value)); 70 EXPECT_TRUE((IsTypeSupported<bool, std::vector<int32_t>, uint8_t>::value)); 71 } 72 73 TEST(DBusUtils, Unupported_TypeSet) { 74 EXPECT_FALSE((IsTypeSupported<int32_t, double, std::string, char>::value)); 75 EXPECT_FALSE( 76 (IsTypeSupported<bool, std::pair<std::vector<float>, uint8_t>>::value)); 77 EXPECT_FALSE((IsTypeSupported<char, double, std::string, int16_t>::value)); 78 EXPECT_FALSE((IsTypeSupported<char, std::vector<float>, float>::value)); 79 } 80 81 TEST(DBusUtils, Signatures_BasicTypes) { 82 EXPECT_EQ("b", GetDBusSignature<bool>()); 83 EXPECT_EQ("y", GetDBusSignature<uint8_t>()); 84 EXPECT_EQ("n", GetDBusSignature<int16_t>()); 85 EXPECT_EQ("q", GetDBusSignature<uint16_t>()); 86 EXPECT_EQ("i", GetDBusSignature<int32_t>()); 87 EXPECT_EQ("u", GetDBusSignature<uint32_t>()); 88 EXPECT_EQ("x", GetDBusSignature<int64_t>()); 89 EXPECT_EQ("t", GetDBusSignature<uint64_t>()); 90 EXPECT_EQ("d", GetDBusSignature<double>()); 91 EXPECT_EQ("s", GetDBusSignature<std::string>()); 92 EXPECT_EQ("o", GetDBusSignature<ObjectPath>()); 93 EXPECT_EQ("h", GetDBusSignature<ScopedFD>()); 94 EXPECT_EQ("v", GetDBusSignature<Any>()); 95 } 96 97 TEST(DBusUtils, Signatures_Arrays) { 98 EXPECT_EQ("ab", GetDBusSignature<std::vector<bool>>()); 99 EXPECT_EQ("ay", GetDBusSignature<std::vector<uint8_t>>()); 100 EXPECT_EQ("an", GetDBusSignature<std::vector<int16_t>>()); 101 EXPECT_EQ("aq", GetDBusSignature<std::vector<uint16_t>>()); 102 EXPECT_EQ("ai", GetDBusSignature<std::vector<int32_t>>()); 103 EXPECT_EQ("au", GetDBusSignature<std::vector<uint32_t>>()); 104 EXPECT_EQ("ax", GetDBusSignature<std::vector<int64_t>>()); 105 EXPECT_EQ("at", GetDBusSignature<std::vector<uint64_t>>()); 106 EXPECT_EQ("ad", GetDBusSignature<std::vector<double>>()); 107 EXPECT_EQ("as", GetDBusSignature<std::vector<std::string>>()); 108 EXPECT_EQ("ao", GetDBusSignature<std::vector<ObjectPath>>()); 109 EXPECT_EQ("ah", GetDBusSignature<std::vector<ScopedFD>>()); 110 EXPECT_EQ("av", GetDBusSignature<std::vector<Any>>()); 111 EXPECT_EQ("a(is)", 112 (GetDBusSignature<std::vector<std::pair<int, std::string>>>())); 113 EXPECT_EQ("aad", GetDBusSignature<std::vector<std::vector<double>>>()); 114 } 115 116 TEST(DBusUtils, Signatures_Maps) { 117 EXPECT_EQ("a{sb}", (GetDBusSignature<std::map<std::string, bool>>())); 118 EXPECT_EQ("a{ss}", (GetDBusSignature<std::map<std::string, std::string>>())); 119 EXPECT_EQ("a{sv}", (GetDBusSignature<std::map<std::string, Any>>())); 120 EXPECT_EQ("a{id}", (GetDBusSignature<std::map<int, double>>())); 121 EXPECT_EQ( 122 "a{ia{ss}}", 123 (GetDBusSignature<std::map<int, std::map<std::string, std::string>>>())); 124 } 125 126 TEST(DBusUtils, Signatures_Pairs) { 127 EXPECT_EQ("(sb)", (GetDBusSignature<std::pair<std::string, bool>>())); 128 EXPECT_EQ("(sv)", (GetDBusSignature<std::pair<std::string, Any>>())); 129 EXPECT_EQ("(id)", (GetDBusSignature<std::pair<int, double>>())); 130 } 131 132 TEST(DBusUtils, Signatures_Tuples) { 133 EXPECT_EQ("(i)", (GetDBusSignature<std::tuple<int>>())); 134 EXPECT_EQ("(sv)", (GetDBusSignature<std::tuple<std::string, Any>>())); 135 EXPECT_EQ("(id(si))", 136 (GetDBusSignature< 137 std::tuple<int, double, std::tuple<std::string, int>>>())); 138 } 139 140 TEST(DBusUtils, Signatures_Protobufs) { 141 EXPECT_EQ("ay", (GetDBusSignature<google::protobuf::MessageLite>())); 142 EXPECT_EQ("ay", (GetDBusSignature<dbus_utils_test::TestMessage>())); 143 } 144 145 // Test that a byte can be properly written and read. We only have this 146 // test for byte, as repeating this for other basic types is too redundant. 147 TEST(DBusUtils, AppendAndPopByte) { 148 std::unique_ptr<Response> message = Response::CreateEmpty(); 149 MessageWriter writer(message.get()); 150 AppendValueToWriter(&writer, uint8_t{123}); 151 EXPECT_EQ("y", message->GetSignature()); 152 153 MessageReader reader(message.get()); 154 EXPECT_TRUE(reader.HasMoreData()); // Should have data to read. 155 EXPECT_EQ(Message::BYTE, reader.GetDataType()); 156 157 bool bool_value = false; 158 // Should fail as the type is not bool here. 159 EXPECT_FALSE(PopValueFromReader(&reader, &bool_value)); 160 161 uint8_t byte_value = 0; 162 EXPECT_TRUE(PopValueFromReader(&reader, &byte_value)); 163 EXPECT_EQ(123, byte_value); // Should match with the input. 164 EXPECT_FALSE(reader.HasMoreData()); // Should not have more data to read. 165 166 // Try to get another byte. Should fail. 167 EXPECT_FALSE(PopValueFromReader(&reader, &byte_value)); 168 } 169 170 // Check all basic types can be properly written and read. 171 TEST(DBusUtils, AppendAndPopBasicDataTypes) { 172 std::unique_ptr<Response> message = Response::CreateEmpty(); 173 MessageWriter writer(message.get()); 174 175 // Append 0, true, 2, 3, 4, 5, 6, 7, 8.0, "string", "/object/path". 176 AppendValueToWriter(&writer, uint8_t{0}); 177 AppendValueToWriter(&writer, bool{true}); 178 AppendValueToWriter(&writer, int16_t{2}); 179 AppendValueToWriter(&writer, uint16_t{3}); 180 AppendValueToWriter(&writer, int32_t{4}); 181 AppendValueToWriter(&writer, uint32_t{5}); 182 AppendValueToWriter(&writer, int64_t{6}); 183 AppendValueToWriter(&writer, uint64_t{7}); 184 AppendValueToWriter(&writer, double{8.0}); 185 AppendValueToWriter(&writer, std::string{"string"}); 186 AppendValueToWriter(&writer, ObjectPath{"/object/path"}); 187 188 EXPECT_EQ("ybnqiuxtdso", message->GetSignature()); 189 190 uint8_t byte_value = 0; 191 bool bool_value = false; 192 int16_t int16_value = 0; 193 uint16_t uint16_value = 0; 194 int32_t int32_value = 0; 195 uint32_t uint32_value = 0; 196 int64_t int64_value = 0; 197 uint64_t uint64_value = 0; 198 double double_value = 0; 199 std::string string_value; 200 ObjectPath object_path_value; 201 202 MessageReader reader(message.get()); 203 EXPECT_TRUE(reader.HasMoreData()); 204 EXPECT_TRUE(PopValueFromReader(&reader, &byte_value)); 205 EXPECT_TRUE(PopValueFromReader(&reader, &bool_value)); 206 EXPECT_TRUE(PopValueFromReader(&reader, &int16_value)); 207 EXPECT_TRUE(PopValueFromReader(&reader, &uint16_value)); 208 EXPECT_TRUE(PopValueFromReader(&reader, &int32_value)); 209 EXPECT_TRUE(PopValueFromReader(&reader, &uint32_value)); 210 EXPECT_TRUE(PopValueFromReader(&reader, &int64_value)); 211 EXPECT_TRUE(PopValueFromReader(&reader, &uint64_value)); 212 EXPECT_TRUE(PopValueFromReader(&reader, &double_value)); 213 EXPECT_TRUE(PopValueFromReader(&reader, &string_value)); 214 EXPECT_TRUE(PopValueFromReader(&reader, &object_path_value)); 215 EXPECT_FALSE(reader.HasMoreData()); 216 217 // 0, true, 2, 3, 4, 5, 6, 7, 8, "string", "/object/path" should be returned. 218 EXPECT_EQ(0, byte_value); 219 EXPECT_TRUE(bool_value); 220 EXPECT_EQ(2, int16_value); 221 EXPECT_EQ(3U, uint16_value); 222 EXPECT_EQ(4, int32_value); 223 EXPECT_EQ(5U, uint32_value); 224 EXPECT_EQ(6, int64_value); 225 EXPECT_EQ(7U, uint64_value); 226 EXPECT_DOUBLE_EQ(8.0, double_value); 227 EXPECT_EQ("string", string_value); 228 EXPECT_EQ(ObjectPath{"/object/path"}, object_path_value); 229 } 230 231 // Check all basic types can be properly written and read. 232 TEST(DBusUtils, AppendAndPopFileDescriptor) { 233 if (!dbus::IsDBusTypeUnixFdSupported()) { 234 LOG(WARNING) << "FD passing is not supported"; 235 return; 236 } 237 238 std::unique_ptr<Response> message = Response::CreateEmpty(); 239 MessageWriter writer(message.get()); 240 241 // Append stdout. 242 ScopedFD temp(1); 243 // Descriptor should not be valid until checked. 244 EXPECT_FALSE(temp.is_valid()); 245 // NB: thread IO requirements not relevant for unit tests. 246 temp.CheckValidity(); 247 EXPECT_TRUE(temp.is_valid()); 248 AppendValueToWriter(&writer, temp); 249 250 EXPECT_EQ("h", message->GetSignature()); 251 252 ScopedFD fd_value; 253 254 MessageReader reader(message.get()); 255 EXPECT_TRUE(reader.HasMoreData()); 256 EXPECT_TRUE(PopValueFromReader(&reader, &fd_value)); 257 EXPECT_FALSE(reader.HasMoreData()); 258 // Descriptor is automatically checked for validity as part of 259 // PopValueFromReader() call. 260 EXPECT_TRUE(fd_value.is_valid()); 261 } 262 263 // Check all variant types can be properly written and read. 264 TEST(DBusUtils, AppendAndPopVariantDataTypes) { 265 std::unique_ptr<Response> message = Response::CreateEmpty(); 266 MessageWriter writer(message.get()); 267 268 // Append 10, false, 12, 13, 14, 15, 16, 17, 18.5, "data", "/obj/path". 269 AppendValueToWriterAsVariant(&writer, uint8_t{10}); 270 AppendValueToWriterAsVariant(&writer, bool{false}); 271 AppendValueToWriterAsVariant(&writer, int16_t{12}); 272 AppendValueToWriterAsVariant(&writer, uint16_t{13}); 273 AppendValueToWriterAsVariant(&writer, int32_t{14}); 274 AppendValueToWriterAsVariant(&writer, uint32_t{15}); 275 AppendValueToWriterAsVariant(&writer, int64_t{16}); 276 AppendValueToWriterAsVariant(&writer, uint64_t{17}); 277 AppendValueToWriterAsVariant(&writer, double{18.5}); 278 AppendValueToWriterAsVariant(&writer, std::string{"data"}); 279 AppendValueToWriterAsVariant(&writer, ObjectPath{"/obj/path"}); 280 AppendValueToWriterAsVariant(&writer, Any{17}); 281 AppendValueToWriterAsVariant(&writer, 282 Any{std::vector<std::vector<int>>{{6, 7}}}); 283 284 EXPECT_EQ("vvvvvvvvvvvvv", message->GetSignature()); 285 286 uint8_t byte_value = 0; 287 bool bool_value = true; 288 int16_t int16_value = 0; 289 uint16_t uint16_value = 0; 290 int32_t int32_value = 0; 291 uint32_t uint32_value = 0; 292 int64_t int64_value = 0; 293 uint64_t uint64_value = 0; 294 double double_value = 0; 295 std::string string_value; 296 ObjectPath object_path_value; 297 Any any_value; 298 Any any_vector_vector; 299 300 MessageReader reader(message.get()); 301 EXPECT_TRUE(reader.HasMoreData()); 302 EXPECT_TRUE(PopVariantValueFromReader(&reader, &byte_value)); 303 EXPECT_TRUE(PopVariantValueFromReader(&reader, &bool_value)); 304 EXPECT_TRUE(PopVariantValueFromReader(&reader, &int16_value)); 305 EXPECT_TRUE(PopVariantValueFromReader(&reader, &uint16_value)); 306 EXPECT_TRUE(PopVariantValueFromReader(&reader, &int32_value)); 307 EXPECT_TRUE(PopVariantValueFromReader(&reader, &uint32_value)); 308 EXPECT_TRUE(PopVariantValueFromReader(&reader, &int64_value)); 309 EXPECT_TRUE(PopVariantValueFromReader(&reader, &uint64_value)); 310 EXPECT_TRUE(PopVariantValueFromReader(&reader, &double_value)); 311 EXPECT_TRUE(PopVariantValueFromReader(&reader, &string_value)); 312 EXPECT_TRUE(PopVariantValueFromReader(&reader, &object_path_value)); 313 EXPECT_TRUE(PopVariantValueFromReader(&reader, &any_value)); 314 // Not implemented. 315 EXPECT_FALSE(PopVariantValueFromReader(&reader, &any_vector_vector)); 316 EXPECT_FALSE(reader.HasMoreData()); 317 318 EXPECT_EQ(10, byte_value); 319 EXPECT_FALSE(bool_value); 320 EXPECT_EQ(12, int16_value); 321 EXPECT_EQ(13U, uint16_value); 322 EXPECT_EQ(14, int32_value); 323 EXPECT_EQ(15U, uint32_value); 324 EXPECT_EQ(16, int64_value); 325 EXPECT_EQ(17U, uint64_value); 326 EXPECT_DOUBLE_EQ(18.5, double_value); 327 EXPECT_EQ("data", string_value); 328 EXPECT_EQ(ObjectPath{"/obj/path"}, object_path_value); 329 EXPECT_EQ(17, any_value.Get<int>()); 330 EXPECT_TRUE(any_vector_vector.IsEmpty()); 331 } 332 333 TEST(DBusUtils, AppendAndPopBasicAny) { 334 std::unique_ptr<Response> message = Response::CreateEmpty(); 335 MessageWriter writer(message.get()); 336 337 // Append 10, true, 12, 13, 14, 15, 16, 17, 18.5, "data", "/obj/path". 338 AppendValueToWriter(&writer, Any(uint8_t{10})); 339 AppendValueToWriter(&writer, Any(bool{true})); 340 AppendValueToWriter(&writer, Any(int16_t{12})); 341 AppendValueToWriter(&writer, Any(uint16_t{13})); 342 AppendValueToWriter(&writer, Any(int32_t{14})); 343 AppendValueToWriter(&writer, Any(uint32_t{15})); 344 AppendValueToWriter(&writer, Any(int64_t{16})); 345 AppendValueToWriter(&writer, Any(uint64_t{17})); 346 AppendValueToWriter(&writer, Any(double{18.5})); 347 AppendValueToWriter(&writer, Any(std::string{"data"})); 348 AppendValueToWriter(&writer, Any(ObjectPath{"/obj/path"})); 349 EXPECT_EQ("vvvvvvvvvvv", message->GetSignature()); 350 351 Any byte_value; 352 Any bool_value; 353 Any int16_value; 354 Any uint16_value; 355 Any int32_value; 356 Any uint32_value; 357 Any int64_value; 358 Any uint64_value; 359 Any double_value; 360 Any string_value; 361 Any object_path_value; 362 363 MessageReader reader(message.get()); 364 EXPECT_TRUE(reader.HasMoreData()); 365 EXPECT_TRUE(PopValueFromReader(&reader, &byte_value)); 366 EXPECT_TRUE(PopValueFromReader(&reader, &bool_value)); 367 EXPECT_TRUE(PopValueFromReader(&reader, &int16_value)); 368 EXPECT_TRUE(PopValueFromReader(&reader, &uint16_value)); 369 EXPECT_TRUE(PopValueFromReader(&reader, &int32_value)); 370 EXPECT_TRUE(PopValueFromReader(&reader, &uint32_value)); 371 EXPECT_TRUE(PopValueFromReader(&reader, &int64_value)); 372 EXPECT_TRUE(PopValueFromReader(&reader, &uint64_value)); 373 EXPECT_TRUE(PopValueFromReader(&reader, &double_value)); 374 EXPECT_TRUE(PopValueFromReader(&reader, &string_value)); 375 EXPECT_TRUE(PopValueFromReader(&reader, &object_path_value)); 376 EXPECT_FALSE(reader.HasMoreData()); 377 378 // Must be: 10, true, 12, 13, 14, 15, 16, 17, 18.5, "data", "/obj/path". 379 EXPECT_EQ(10, byte_value.Get<uint8_t>()); 380 EXPECT_TRUE(bool_value.Get<bool>()); 381 EXPECT_EQ(12, int16_value.Get<int16_t>()); 382 EXPECT_EQ(13U, uint16_value.Get<uint16_t>()); 383 EXPECT_EQ(14, int32_value.Get<int32_t>()); 384 EXPECT_EQ(15U, uint32_value.Get<uint32_t>()); 385 EXPECT_EQ(16, int64_value.Get<int64_t>()); 386 EXPECT_EQ(17U, uint64_value.Get<uint64_t>()); 387 EXPECT_DOUBLE_EQ(18.5, double_value.Get<double>()); 388 EXPECT_EQ("data", string_value.Get<std::string>()); 389 EXPECT_EQ(ObjectPath{"/obj/path"}, object_path_value.Get<ObjectPath>()); 390 } 391 392 TEST(DBusUtils, ArrayOfBytes) { 393 std::unique_ptr<Response> message = Response::CreateEmpty(); 394 MessageWriter writer(message.get()); 395 std::vector<uint8_t> bytes{1, 2, 3}; 396 AppendValueToWriter(&writer, bytes); 397 398 EXPECT_EQ("ay", message->GetSignature()); 399 400 MessageReader reader(message.get()); 401 std::vector<uint8_t> bytes_out; 402 EXPECT_TRUE(PopValueFromReader(&reader, &bytes_out)); 403 EXPECT_FALSE(reader.HasMoreData()); 404 EXPECT_EQ(bytes, bytes_out); 405 } 406 407 TEST(DBusUtils, ArrayOfBytes_Empty) { 408 std::unique_ptr<Response> message = Response::CreateEmpty(); 409 MessageWriter writer(message.get()); 410 std::vector<uint8_t> bytes; 411 AppendValueToWriter(&writer, bytes); 412 413 EXPECT_EQ("ay", message->GetSignature()); 414 415 MessageReader reader(message.get()); 416 std::vector<uint8_t> bytes_out; 417 EXPECT_TRUE(PopValueFromReader(&reader, &bytes_out)); 418 EXPECT_FALSE(reader.HasMoreData()); 419 EXPECT_EQ(bytes, bytes_out); 420 } 421 422 TEST(DBusUtils, ArrayOfStrings) { 423 std::unique_ptr<Response> message = Response::CreateEmpty(); 424 MessageWriter writer(message.get()); 425 std::vector<std::string> strings{"foo", "bar", "baz"}; 426 AppendValueToWriter(&writer, strings); 427 428 EXPECT_EQ("as", message->GetSignature()); 429 430 MessageReader reader(message.get()); 431 std::vector<std::string> strings_out; 432 EXPECT_TRUE(PopValueFromReader(&reader, &strings_out)); 433 EXPECT_FALSE(reader.HasMoreData()); 434 EXPECT_EQ(strings, strings_out); 435 } 436 437 TEST(DBusUtils, ArrayOfInt64) { 438 std::unique_ptr<Response> message = Response::CreateEmpty(); 439 MessageWriter writer(message.get()); 440 std::vector<int64_t> values{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 441 std::numeric_limits<int64_t>::min(), 442 std::numeric_limits<int64_t>::max()}; 443 AppendValueToWriter(&writer, values); 444 445 EXPECT_EQ("ax", message->GetSignature()); 446 447 MessageReader reader(message.get()); 448 std::vector<int64_t> values_out; 449 EXPECT_TRUE(PopValueFromReader(&reader, &values_out)); 450 EXPECT_FALSE(reader.HasMoreData()); 451 EXPECT_EQ(values, values_out); 452 } 453 454 TEST(DBusUtils, ArrayOfObjectPaths) { 455 std::unique_ptr<Response> message = Response::CreateEmpty(); 456 MessageWriter writer(message.get()); 457 std::vector<ObjectPath> object_paths{ 458 ObjectPath("/object/path/1"), 459 ObjectPath("/object/path/2"), 460 ObjectPath("/object/path/3"), 461 }; 462 AppendValueToWriter(&writer, object_paths); 463 464 EXPECT_EQ("ao", message->GetSignature()); 465 466 MessageReader reader(message.get()); 467 std::vector<ObjectPath> object_paths_out; 468 EXPECT_TRUE(PopValueFromReader(&reader, &object_paths_out)); 469 EXPECT_FALSE(reader.HasMoreData()); 470 EXPECT_EQ(object_paths, object_paths_out); 471 } 472 473 TEST(DBusUtils, ArraysAsVariant) { 474 std::unique_ptr<Response> message = Response::CreateEmpty(); 475 MessageWriter writer(message.get()); 476 std::vector<int> int_array{1, 2, 3}; 477 std::vector<std::string> str_array{"foo", "bar", "baz"}; 478 std::vector<double> dbl_array_empty{}; 479 std::map<std::string, std::string> dict_ss{{"k1", "v1"}, {"k2", "v2"}}; 480 VariantDictionary dict_sv{{"k1", 1}, {"k2", "v2"}}; 481 AppendValueToWriterAsVariant(&writer, int_array); 482 AppendValueToWriterAsVariant(&writer, str_array); 483 AppendValueToWriterAsVariant(&writer, dbl_array_empty); 484 AppendValueToWriterAsVariant(&writer, dict_ss); 485 AppendValueToWriterAsVariant(&writer, dict_sv); 486 487 EXPECT_EQ("vvvvv", message->GetSignature()); 488 489 Any int_array_out; 490 Any str_array_out; 491 Any dbl_array_out; 492 Any dict_ss_out; 493 Any dict_sv_out; 494 495 MessageReader reader(message.get()); 496 EXPECT_TRUE(PopValueFromReader(&reader, &int_array_out)); 497 EXPECT_TRUE(PopValueFromReader(&reader, &str_array_out)); 498 EXPECT_TRUE(PopValueFromReader(&reader, &dbl_array_out)); 499 EXPECT_TRUE(PopValueFromReader(&reader, &dict_ss_out)); 500 EXPECT_TRUE(PopValueFromReader(&reader, &dict_sv_out)); 501 EXPECT_FALSE(reader.HasMoreData()); 502 503 EXPECT_EQ(int_array, int_array_out.Get<std::vector<int>>()); 504 EXPECT_EQ(str_array, str_array_out.Get<std::vector<std::string>>()); 505 EXPECT_EQ(dbl_array_empty, dbl_array_out.Get<std::vector<double>>()); 506 EXPECT_EQ(dict_ss, (dict_ss_out.Get<std::map<std::string, std::string>>())); 507 EXPECT_EQ(dict_sv["k1"].Get<int>(), 508 dict_sv_out.Get<VariantDictionary>().at("k1").Get<int>()); 509 EXPECT_EQ(dict_sv["k2"].Get<const char*>(), 510 dict_sv_out.Get<VariantDictionary>().at("k2").Get<std::string>()); 511 } 512 513 TEST(DBusUtils, VariantDictionary) { 514 std::unique_ptr<Response> message = Response::CreateEmpty(); 515 MessageWriter writer(message.get()); 516 VariantDictionary values{ 517 {"key1", uint8_t{10}}, 518 {"key2", bool{true}}, 519 {"key3", int16_t{12}}, 520 {"key4", uint16_t{13}}, 521 {"key5", int32_t{14}}, 522 {"key6", uint32_t{15}}, 523 {"key7", int64_t{16}}, 524 {"key8", uint64_t{17}}, 525 {"key9", double{18.5}}, 526 {"keyA", std::string{"data"}}, 527 {"keyB", ObjectPath{"/obj/path"}}, 528 }; 529 AppendValueToWriter(&writer, values); 530 531 EXPECT_EQ("a{sv}", message->GetSignature()); 532 533 MessageReader reader(message.get()); 534 VariantDictionary values_out; 535 EXPECT_TRUE(PopValueFromReader(&reader, &values_out)); 536 EXPECT_FALSE(reader.HasMoreData()); 537 EXPECT_EQ(values.size(), values_out.size()); 538 EXPECT_EQ(values["key1"].Get<uint8_t>(), values_out["key1"].Get<uint8_t>()); 539 EXPECT_EQ(values["key2"].Get<bool>(), values_out["key2"].Get<bool>()); 540 EXPECT_EQ(values["key3"].Get<int16_t>(), values_out["key3"].Get<int16_t>()); 541 EXPECT_EQ(values["key4"].Get<uint16_t>(), values_out["key4"].Get<uint16_t>()); 542 EXPECT_EQ(values["key5"].Get<int32_t>(), values_out["key5"].Get<int32_t>()); 543 EXPECT_EQ(values["key6"].Get<uint32_t>(), values_out["key6"].Get<uint32_t>()); 544 EXPECT_EQ(values["key7"].Get<int64_t>(), values_out["key7"].Get<int64_t>()); 545 EXPECT_EQ(values["key8"].Get<uint64_t>(), values_out["key8"].Get<uint64_t>()); 546 EXPECT_EQ(values["key9"].Get<double>(), values_out["key9"].Get<double>()); 547 EXPECT_EQ(values["keyA"].Get<std::string>(), 548 values_out["keyA"].Get<std::string>()); 549 EXPECT_EQ(values["keyB"].Get<ObjectPath>(), 550 values_out["keyB"].Get<ObjectPath>()); 551 } 552 553 TEST(DBusUtils, StringToStringMap) { 554 std::unique_ptr<Response> message = Response::CreateEmpty(); 555 MessageWriter writer(message.get()); 556 std::map<std::string, std::string> values{ 557 {"key1", "value1"}, 558 {"key2", "value2"}, 559 {"key3", "value3"}, 560 {"key4", "value4"}, 561 {"key5", "value5"}, 562 }; 563 AppendValueToWriter(&writer, values); 564 565 EXPECT_EQ("a{ss}", message->GetSignature()); 566 567 MessageReader reader(message.get()); 568 std::map<std::string, std::string> values_out; 569 EXPECT_TRUE(PopValueFromReader(&reader, &values_out)); 570 EXPECT_FALSE(reader.HasMoreData()); 571 EXPECT_EQ(values, values_out); 572 } 573 574 TEST(DBusUtils, Pair) { 575 std::unique_ptr<Response> message = Response::CreateEmpty(); 576 MessageWriter writer(message.get()); 577 std::pair<std::string, int> struct1{"value2", 3}; 578 AppendValueToWriter(&writer, struct1); 579 std::pair<int, std::pair<int, int>> struct2{1, {2, 3}}; 580 AppendValueToWriter(&writer, struct2); 581 582 EXPECT_EQ("(si)(i(ii))", message->GetSignature()); 583 584 std::pair<std::string, int> struct1_out; 585 std::pair<int, std::pair<int, int>> struct2_out; 586 587 MessageReader reader(message.get()); 588 EXPECT_TRUE(PopValueFromReader(&reader, &struct1_out)); 589 EXPECT_TRUE(PopValueFromReader(&reader, &struct2_out)); 590 EXPECT_FALSE(reader.HasMoreData()); 591 EXPECT_EQ(struct1, struct1_out); 592 EXPECT_EQ(struct2, struct2_out); 593 } 594 595 TEST(DBusUtils, Tuple) { 596 std::unique_ptr<Response> message = Response::CreateEmpty(); 597 MessageWriter writer(message.get()); 598 std::tuple<std::string, int> struct1{"value2", 3}; 599 AppendValueToWriter(&writer, struct1); 600 std::tuple<int, std::string, std::vector<std::pair<int, int>>> struct2{ 601 1, "a", {{2, 3}} 602 }; 603 AppendValueToWriter(&writer, struct2); 604 605 EXPECT_EQ("(si)(isa(ii))", message->GetSignature()); 606 607 std::tuple<std::string, int> struct1_out; 608 std::tuple<int, std::string, std::vector<std::pair<int, int>>> struct2_out; 609 610 MessageReader reader(message.get()); 611 EXPECT_TRUE(PopValueFromReader(&reader, &struct1_out)); 612 EXPECT_TRUE(PopValueFromReader(&reader, &struct2_out)); 613 EXPECT_FALSE(reader.HasMoreData()); 614 EXPECT_EQ(struct1, struct1_out); 615 EXPECT_EQ(struct2, struct2_out); 616 } 617 618 TEST(DBusUtils, ReinterpretVariant) { 619 std::unique_ptr<Response> message = Response::CreateEmpty(); 620 MessageWriter writer(message.get()); 621 std::vector<std::string> str_array{"foo", "bar", "baz"}; 622 std::map<std::string, std::string> dict_ss{{"k1", "v1"}, {"k2", "v2"}}; 623 VariantDictionary dict_sv{{"k1", "v1"}, {"k2", "v2"}}; 624 AppendValueToWriterAsVariant(&writer, 123); 625 AppendValueToWriterAsVariant(&writer, str_array); 626 AppendValueToWriterAsVariant(&writer, 1.7); 627 AppendValueToWriterAsVariant(&writer, dict_ss); 628 AppendValueToWriter(&writer, dict_sv); 629 630 EXPECT_EQ("vvvva{sv}", message->GetSignature()); 631 632 int int_out = 0; 633 std::vector<std::string> str_array_out; 634 double dbl_out = 0.0; 635 std::map<std::string, std::string> dict_ss_out; 636 std::map<std::string, std::string> dict_ss_out2; 637 638 MessageReader reader(message.get()); 639 EXPECT_TRUE(PopValueFromReader(&reader, &int_out)); 640 EXPECT_TRUE(PopValueFromReader(&reader, &str_array_out)); 641 EXPECT_TRUE(PopValueFromReader(&reader, &dbl_out)); 642 EXPECT_TRUE(PopValueFromReader(&reader, &dict_ss_out)); 643 EXPECT_TRUE(PopValueFromReader(&reader, 644 &dict_ss_out2)); // Read "a{sv}" as "a{ss}". 645 EXPECT_FALSE(reader.HasMoreData()); 646 647 EXPECT_EQ(123, int_out); 648 EXPECT_EQ(str_array, str_array_out); 649 EXPECT_DOUBLE_EQ(1.7, dbl_out); 650 EXPECT_EQ(dict_ss, dict_ss_out); 651 EXPECT_EQ(dict_ss, dict_ss_out2); 652 } 653 654 // Test handling of custom data types. 655 struct Person { 656 std::string first_name; 657 std::string last_name; 658 int age; 659 // Provide == operator so we can easily compare arrays of Person. 660 bool operator==(const Person& rhs) const { 661 return first_name == rhs.first_name && last_name == rhs.last_name && 662 age == rhs.age; 663 } 664 }; 665 666 // Overload AppendValueToWriter() for "Person" structure. 667 void AppendValueToWriter(dbus::MessageWriter* writer, const Person& value) { 668 dbus::MessageWriter struct_writer(nullptr); 669 writer->OpenStruct(&struct_writer); 670 AppendValueToWriter(&struct_writer, value.first_name); 671 AppendValueToWriter(&struct_writer, value.last_name); 672 AppendValueToWriter(&struct_writer, value.age); 673 writer->CloseContainer(&struct_writer); 674 } 675 676 // Overload PopValueFromReader() for "Person" structure. 677 bool PopValueFromReader(dbus::MessageReader* reader, Person* value) { 678 dbus::MessageReader variant_reader(nullptr); 679 dbus::MessageReader struct_reader(nullptr); 680 if (!details::DescendIntoVariantIfPresent(&reader, &variant_reader) || 681 !reader->PopStruct(&struct_reader)) 682 return false; 683 return PopValueFromReader(&struct_reader, &value->first_name) && 684 PopValueFromReader(&struct_reader, &value->last_name) && 685 PopValueFromReader(&struct_reader, &value->age); 686 } 687 688 // Specialize DBusType<T> for "Person" structure. 689 template<> 690 struct DBusType<Person> { 691 inline static std::string GetSignature() { 692 return GetStructDBusSignature<std::string, std::string, int>(); 693 } 694 inline static void Write(dbus::MessageWriter* writer, const Person& value) { 695 AppendValueToWriter(writer, value); 696 } 697 inline static bool Read(dbus::MessageReader* reader, Person* value) { 698 return PopValueFromReader(reader, value); 699 } 700 }; 701 702 TEST(DBusUtils, CustomStruct) { 703 std::unique_ptr<Response> message = Response::CreateEmpty(); 704 MessageWriter writer(message.get()); 705 std::vector<Person> people{{"John", "Doe", 32}, {"Jane", "Smith", 48}}; 706 AppendValueToWriter(&writer, people); 707 AppendValueToWriterAsVariant(&writer, people); 708 AppendValueToWriterAsVariant(&writer, people); 709 710 EXPECT_EQ("a(ssi)vv", message->GetSignature()); 711 712 std::vector<Person> people_out1; 713 std::vector<Person> people_out2; 714 std::vector<Person> people_out3; 715 716 MessageReader reader(message.get()); 717 EXPECT_TRUE(PopValueFromReader(&reader, &people_out1)); 718 EXPECT_TRUE(PopValueFromReader(&reader, &people_out2)); 719 EXPECT_TRUE(PopVariantValueFromReader(&reader, &people_out3)); 720 EXPECT_FALSE(reader.HasMoreData()); 721 722 EXPECT_EQ(people, people_out1); 723 EXPECT_EQ(people, people_out2); 724 EXPECT_EQ(people, people_out3); 725 } 726 727 TEST(DBusUtils, CustomStructInComplexTypes) { 728 std::unique_ptr<Response> message = Response::CreateEmpty(); 729 MessageWriter writer(message.get()); 730 std::vector<Person> people{{"John", "Doe", 32}, {"Jane", "Smith", 48}}; 731 std::vector<std::map<int, Person>> data{ 732 { 733 {1, Person{"John", "Doe", 32}}, 734 {2, Person{"Jane", "Smith", 48}}, 735 } 736 }; 737 AppendValueToWriter(&writer, data); 738 739 EXPECT_EQ("aa{i(ssi)}", message->GetSignature()); 740 741 std::vector<std::map<int, Person>> data_out; 742 743 MessageReader reader(message.get()); 744 EXPECT_TRUE(PopValueFromReader(&reader, &data_out)); 745 EXPECT_FALSE(reader.HasMoreData()); 746 747 EXPECT_EQ(data, data_out); 748 } 749 750 TEST(DBusUtils, EmptyVariant) { 751 std::unique_ptr<Response> message = Response::CreateEmpty(); 752 MessageWriter writer(message.get()); 753 EXPECT_DEATH(AppendValueToWriter(&writer, Any{}), 754 "Must not be called on an empty Any"); 755 } 756 757 TEST(DBusUtils, IncompatibleVariant) { 758 std::unique_ptr<Response> message = Response::CreateEmpty(); 759 MessageWriter writer(message.get()); 760 EXPECT_DEATH(AppendValueToWriter(&writer, Any{2.2f}), 761 "Type 'float' is not supported by D-Bus"); 762 } 763 764 TEST(DBusUtils, Protobuf) { 765 std::unique_ptr<Response> message = Response::CreateEmpty(); 766 MessageWriter writer(message.get()); 767 768 dbus_utils_test::TestMessage test_message; 769 test_message.set_foo(123); 770 test_message.set_bar("abcd"); 771 772 AppendValueToWriter(&writer, test_message); 773 774 EXPECT_EQ("ay", message->GetSignature()); 775 776 dbus_utils_test::TestMessage test_message_out; 777 778 MessageReader reader(message.get()); 779 EXPECT_TRUE(PopValueFromReader(&reader, &test_message_out)); 780 EXPECT_FALSE(reader.HasMoreData()); 781 782 EXPECT_EQ(123, test_message_out.foo()); 783 EXPECT_EQ("abcd", test_message_out.bar()); 784 } 785 786 } // namespace dbus_utils 787 } // namespace brillo 788