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