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