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/dbus_param_reader.h>
6 
7 #include <memory>
8 #include <string>
9 
10 #include <brillo/variant_dictionary.h>
11 #include <gtest/gtest.h>
12 
13 using dbus::MessageReader;
14 using dbus::MessageWriter;
15 using dbus::Response;
16 
17 namespace brillo {
18 namespace dbus_utils {
19 
TEST(DBusParamReader,NoArgs)20 TEST(DBusParamReader, NoArgs) {
21   std::unique_ptr<Response> message = Response::CreateEmpty();
22   MessageReader reader(message.get());
23   bool called = false;
24   auto callback = [&called]() { called = true; };
25   EXPECT_TRUE(DBusParamReader<false>::Invoke(callback, &reader, nullptr));
26   EXPECT_TRUE(called);
27 }
28 
TEST(DBusParamReader,OneArg)29 TEST(DBusParamReader, OneArg) {
30   std::unique_ptr<Response> message = Response::CreateEmpty();
31   MessageWriter writer(message.get());
32   AppendValueToWriter(&writer, 123);
33   MessageReader reader(message.get());
34   bool called = false;
35   auto callback = [&called](int param1) {
36     EXPECT_EQ(123, param1);
37     called = true;
38   };
39   EXPECT_TRUE(
40       (DBusParamReader<false, int>::Invoke(callback, &reader, nullptr)));
41   EXPECT_TRUE(called);
42 }
43 
TEST(DBusParamReader,ManyArgs)44 TEST(DBusParamReader, ManyArgs) {
45   std::unique_ptr<Response> message = Response::CreateEmpty();
46   MessageWriter writer(message.get());
47   AppendValueToWriter(&writer, true);
48   AppendValueToWriter(&writer, 1972);
49   AppendValueToWriter(&writer,
50                       VariantDictionary{{"key", std::string{"value"}}});
51   MessageReader reader(message.get());
52   bool called = false;
53   auto callback = [&called](bool p1, int p2, const VariantDictionary& p3) {
54     EXPECT_TRUE(p1);
55     EXPECT_EQ(1972, p2);
56     EXPECT_EQ(1, p3.size());
57     EXPECT_EQ("value", p3.find("key")->second.Get<std::string>());
58     called = true;
59   };
60   EXPECT_TRUE((DBusParamReader<false, bool, int, VariantDictionary>::Invoke(
61       callback, &reader, nullptr)));
62   EXPECT_TRUE(called);
63 }
64 
TEST(DBusParamReader,TooManyArgs)65 TEST(DBusParamReader, TooManyArgs) {
66   std::unique_ptr<Response> message = Response::CreateEmpty();
67   MessageWriter writer(message.get());
68   AppendValueToWriter(&writer, true);
69   AppendValueToWriter(&writer, 1972);
70   AppendValueToWriter(&writer,
71                       VariantDictionary{{"key", std::string{"value"}}});
72   MessageReader reader(message.get());
73   bool called = false;
74   auto callback = [&called](bool param1, int param2) {
75     EXPECT_TRUE(param1);
76     EXPECT_EQ(1972, param2);
77     called = true;
78   };
79   ErrorPtr error;
80   EXPECT_FALSE(
81       (DBusParamReader<false, bool, int>::Invoke(callback, &reader, &error)));
82   EXPECT_FALSE(called);
83   EXPECT_EQ(errors::dbus::kDomain, error->GetDomain());
84   EXPECT_EQ(DBUS_ERROR_INVALID_ARGS, error->GetCode());
85   EXPECT_EQ("Too many parameters in a method call", error->GetMessage());
86 }
87 
TEST(DBusParamReader,TooFewArgs)88 TEST(DBusParamReader, TooFewArgs) {
89   std::unique_ptr<Response> message = Response::CreateEmpty();
90   MessageWriter writer(message.get());
91   AppendValueToWriter(&writer, true);
92   MessageReader reader(message.get());
93   bool called = false;
94   auto callback = [&called](bool param1, int param2) {
95     EXPECT_TRUE(param1);
96     EXPECT_EQ(1972, param2);
97     called = true;
98   };
99   ErrorPtr error;
100   EXPECT_FALSE(
101       (DBusParamReader<false, bool, int>::Invoke(callback, &reader, &error)));
102   EXPECT_FALSE(called);
103   EXPECT_EQ(errors::dbus::kDomain, error->GetDomain());
104   EXPECT_EQ(DBUS_ERROR_INVALID_ARGS, error->GetCode());
105   EXPECT_EQ("Too few parameters in a method call", error->GetMessage());
106 }
107 
TEST(DBusParamReader,TypeMismatch)108 TEST(DBusParamReader, TypeMismatch) {
109   std::unique_ptr<Response> message = Response::CreateEmpty();
110   MessageWriter writer(message.get());
111   AppendValueToWriter(&writer, true);
112   AppendValueToWriter(&writer, 1972);
113   MessageReader reader(message.get());
114   bool called = false;
115   auto callback = [&called](bool param1, double param2) {
116     EXPECT_TRUE(param1);
117     EXPECT_DOUBLE_EQ(1972.0, param2);
118     called = true;
119   };
120   ErrorPtr error;
121   EXPECT_FALSE((
122       DBusParamReader<false, bool, double>::Invoke(callback, &reader, &error)));
123   EXPECT_FALSE(called);
124   EXPECT_EQ(errors::dbus::kDomain, error->GetDomain());
125   EXPECT_EQ(DBUS_ERROR_INVALID_ARGS, error->GetCode());
126   EXPECT_EQ("Method parameter type mismatch", error->GetMessage());
127 }
128 
TEST(DBusParamReader,NoArgs_With_OUT)129 TEST(DBusParamReader, NoArgs_With_OUT) {
130   std::unique_ptr<Response> message = Response::CreateEmpty();
131   MessageReader reader(message.get());
132   bool called = false;
133   auto callback = [&called](int* param1) {
134     EXPECT_EQ(0, *param1);
135     called = true;
136   };
137   EXPECT_TRUE(
138       (DBusParamReader<true, int*>::Invoke(callback, &reader, nullptr)));
139   EXPECT_TRUE(called);
140 }
141 
TEST(DBusParamReader,OneArg_Before_OUT)142 TEST(DBusParamReader, OneArg_Before_OUT) {
143   std::unique_ptr<Response> message = Response::CreateEmpty();
144   MessageWriter writer(message.get());
145   AppendValueToWriter(&writer, 123);
146   MessageReader reader(message.get());
147   bool called = false;
148   auto callback = [&called](int param1, double* param2) {
149     EXPECT_EQ(123, param1);
150     EXPECT_DOUBLE_EQ(0.0, *param2);
151     called = true;
152   };
153   EXPECT_TRUE((
154       DBusParamReader<true, int, double*>::Invoke(callback, &reader, nullptr)));
155   EXPECT_TRUE(called);
156 }
157 
TEST(DBusParamReader,OneArg_After_OUT)158 TEST(DBusParamReader, OneArg_After_OUT) {
159   std::unique_ptr<Response> message = Response::CreateEmpty();
160   MessageWriter writer(message.get());
161   AppendValueToWriter(&writer, 123);
162   MessageReader reader(message.get());
163   bool called = false;
164   auto callback = [&called](double* param1, int param2) {
165     EXPECT_DOUBLE_EQ(0.0, *param1);
166     EXPECT_EQ(123, param2);
167     called = true;
168   };
169   EXPECT_TRUE((
170       DBusParamReader<true, double*, int>::Invoke(callback, &reader, nullptr)));
171   EXPECT_TRUE(called);
172 }
173 
TEST(DBusParamReader,ManyArgs_With_OUT)174 TEST(DBusParamReader, ManyArgs_With_OUT) {
175   std::unique_ptr<Response> message = Response::CreateEmpty();
176   MessageWriter writer(message.get());
177   AppendValueToWriter(&writer, true);
178   AppendValueToWriter(&writer, 1972);
179   AppendValueToWriter(&writer,
180                       VariantDictionary{{"key", std::string{"value"}}});
181   MessageReader reader(message.get());
182   bool called = false;
183   auto callback = [&called](bool p1,
184                             std::string* p2,
185                             int p3,
186                             int* p4,
187                             const VariantDictionary& p5,
188                             bool* p6) {
189     EXPECT_TRUE(p1);
190     EXPECT_EQ("", *p2);
191     EXPECT_EQ(1972, p3);
192     EXPECT_EQ(0, *p4);
193     EXPECT_EQ(1, p5.size());
194     EXPECT_EQ("value", p5.find("key")->second.Get<std::string>());
195     EXPECT_FALSE(*p6);
196     called = true;
197   };
198   EXPECT_TRUE((DBusParamReader<true,
199                                bool,
200                                std::string*,
201                                int,
202                                int*,
203                                VariantDictionary,
204                                bool*>::Invoke(callback, &reader, nullptr)));
205   EXPECT_TRUE(called);
206 }
207 
TEST(DBusParamReader,TooManyArgs_With_OUT)208 TEST(DBusParamReader, TooManyArgs_With_OUT) {
209   std::unique_ptr<Response> message = Response::CreateEmpty();
210   MessageWriter writer(message.get());
211   AppendValueToWriter(&writer, true);
212   AppendValueToWriter(&writer, 1972);
213   AppendValueToWriter(&writer,
214                       VariantDictionary{{"key", std::string{"value"}}});
215   MessageReader reader(message.get());
216   bool called = false;
217   auto callback = [&called](bool param1, int param2, int* param3) {
218     EXPECT_TRUE(param1);
219     EXPECT_EQ(1972, param2);
220     EXPECT_EQ(0, *param3);
221     called = true;
222   };
223   ErrorPtr error;
224   EXPECT_FALSE((DBusParamReader<true, bool, int, int*>::Invoke(
225       callback, &reader, &error)));
226   EXPECT_FALSE(called);
227   EXPECT_EQ(errors::dbus::kDomain, error->GetDomain());
228   EXPECT_EQ(DBUS_ERROR_INVALID_ARGS, error->GetCode());
229   EXPECT_EQ("Too many parameters in a method call", error->GetMessage());
230 }
231 
TEST(DBusParamReader,TooFewArgs_With_OUT)232 TEST(DBusParamReader, TooFewArgs_With_OUT) {
233   std::unique_ptr<Response> message = Response::CreateEmpty();
234   MessageWriter writer(message.get());
235   AppendValueToWriter(&writer, true);
236   MessageReader reader(message.get());
237   bool called = false;
238   auto callback = [&called](bool param1, int param2, int* param3) {
239     EXPECT_TRUE(param1);
240     EXPECT_EQ(1972, param2);
241     EXPECT_EQ(0, *param3);
242     called = true;
243   };
244   ErrorPtr error;
245   EXPECT_FALSE((DBusParamReader<true, bool, int, int*>::Invoke(
246       callback, &reader, &error)));
247   EXPECT_FALSE(called);
248   EXPECT_EQ(errors::dbus::kDomain, error->GetDomain());
249   EXPECT_EQ(DBUS_ERROR_INVALID_ARGS, error->GetCode());
250   EXPECT_EQ("Too few parameters in a method call", error->GetMessage());
251 }
252 
253 }  // namespace dbus_utils
254 }  // namespace brillo
255