Home | History | Annotate | Download | only in dbus
      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