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