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