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