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