1 // Copyright (c) 2012 The Chromium 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.
6 #include "base/values.h"
7 #include "chromeos/dbus/shill_client_unittest_base.h"
8 #include "chromeos/dbus/shill_manager_client.h"
9 #include "dbus/message.h"
10 #include "dbus/object_path.h"
11 #include "dbus/values_util.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/cros_system_api/dbus/service_constants.h"
22 // Pops a string-to-string dictionary from the reader.
23 base::DictionaryValue
* PopStringToStringDictionary(
24 dbus::MessageReader
* reader
) {
25 dbus::MessageReader
array_reader(NULL
);
26 if (!reader
->PopArray(&array_reader
))
28 scoped_ptr
<base::DictionaryValue
> result(new base::DictionaryValue
);
29 while (array_reader
.HasMoreData()) {
30 dbus::MessageReader
entry_reader(NULL
);
33 if (!array_reader
.PopDictEntry(&entry_reader
) ||
34 !entry_reader
.PopString(&key
) ||
35 !entry_reader
.PopString(&value
))
37 result
->SetWithoutPathExpansion(key
,
38 base::Value::CreateStringValue(value
));
40 return result
.release();
43 // Expects the reader to have a string-to-variant dictionary.
44 void ExpectDictionaryValueArgument(
45 const base::DictionaryValue
* expected_dictionary
,
46 dbus::MessageReader
* reader
) {
47 dbus::MessageReader
array_reader(NULL
);
48 ASSERT_TRUE(reader
->PopArray(&array_reader
));
49 while (array_reader
.HasMoreData()) {
50 dbus::MessageReader
entry_reader(NULL
);
51 ASSERT_TRUE(array_reader
.PopDictEntry(&entry_reader
));
53 ASSERT_TRUE(entry_reader
.PopString(&key
));
54 dbus::MessageReader
variant_reader(NULL
);
55 ASSERT_TRUE(entry_reader
.PopVariant(&variant_reader
));
56 scoped_ptr
<base::Value
> value
;
57 // Variants in the dictionary can be basic types or string-to-string
59 switch (variant_reader
.GetDataType()) {
60 case dbus::Message::ARRAY
:
61 value
.reset(PopStringToStringDictionary(&variant_reader
));
63 case dbus::Message::BOOL
:
64 case dbus::Message::INT32
:
65 case dbus::Message::STRING
:
66 value
.reset(dbus::PopDataAsValue(&variant_reader
));
71 ASSERT_TRUE(value
.get());
72 const base::Value
* expected_value
= NULL
;
73 EXPECT_TRUE(expected_dictionary
->GetWithoutPathExpansion(key
,
75 EXPECT_TRUE(value
->Equals(expected_value
));
79 // Creates a DictionaryValue with example properties.
80 base::DictionaryValue
* CreateExampleProperties() {
81 base::DictionaryValue
* properties
= new base::DictionaryValue
;
82 properties
->SetWithoutPathExpansion(
83 flimflam::kGuidProperty
,
84 base::Value::CreateStringValue("00000000-0000-0000-0000-000000000000"));
85 properties
->SetWithoutPathExpansion(
86 flimflam::kModeProperty
,
87 base::Value::CreateStringValue(flimflam::kModeManaged
));
88 properties
->SetWithoutPathExpansion(
89 flimflam::kTypeProperty
,
90 base::Value::CreateStringValue(flimflam::kTypeWifi
));
91 properties
->SetWithoutPathExpansion(
92 flimflam::kSSIDProperty
,
93 base::Value::CreateStringValue("testssid"));
94 properties
->SetWithoutPathExpansion(
95 flimflam::kSecurityProperty
,
96 base::Value::CreateStringValue(flimflam::kSecurityPsk
));
100 void ExpectStringArguments(const std::vector
<std::string
>& arguments
,
101 dbus::MessageReader
* reader
) {
102 for (std::vector
<std::string
>::const_iterator iter
= arguments
.begin();
103 iter
!= arguments
.end(); ++iter
) {
104 std::string arg_string
;
105 ASSERT_TRUE(reader
->PopString(&arg_string
));
106 EXPECT_EQ(*iter
, arg_string
);
108 EXPECT_FALSE(reader
->HasMoreData());
111 void ExpectStringArgumentsFollowedByObjectPath(
112 const std::vector
<std::string
>& arguments
,
113 const dbus::ObjectPath
& object_path
,
114 dbus::MessageReader
* reader
) {
115 for (std::vector
<std::string
>::const_iterator iter
= arguments
.begin();
116 iter
!= arguments
.end(); ++iter
) {
117 std::string arg_string
;
118 ASSERT_TRUE(reader
->PopString(&arg_string
));
119 EXPECT_EQ(*iter
, arg_string
);
121 dbus::ObjectPath path
;
122 ASSERT_TRUE(reader
->PopObjectPath(&path
));
123 EXPECT_EQ(object_path
, path
);
124 EXPECT_FALSE(reader
->HasMoreData());
130 class ShillManagerClientTest
: public ShillClientUnittestBase
{
132 ShillManagerClientTest()
133 : ShillClientUnittestBase(
134 flimflam::kFlimflamManagerInterface
,
135 dbus::ObjectPath(flimflam::kFlimflamServicePath
)) {
138 virtual void SetUp() {
139 ShillClientUnittestBase::SetUp();
140 // Create a client with the mock bus.
141 client_
.reset(ShillManagerClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION
,
143 // Run the message loop to run the signal connection result callback.
144 message_loop_
.RunUntilIdle();
147 virtual void TearDown() {
148 ShillClientUnittestBase::TearDown();
152 scoped_ptr
<ShillManagerClient
> client_
;
155 TEST_F(ShillManagerClientTest
, PropertyChanged
) {
157 base::FundamentalValue
kOfflineMode(true);
158 dbus::Signal
signal(flimflam::kFlimflamManagerInterface
,
159 flimflam::kMonitorPropertyChanged
);
160 dbus::MessageWriter
writer(&signal
);
161 writer
.AppendString(flimflam::kOfflineModeProperty
);
162 dbus::AppendBasicTypeValueData(&writer
, kOfflineMode
);
165 MockPropertyChangeObserver observer
;
166 EXPECT_CALL(observer
,
167 OnPropertyChanged(flimflam::kOfflineModeProperty
,
168 ValueEq(ByRef(kOfflineMode
)))).Times(1);
171 client_
->AddPropertyChangedObserver(&observer
);
173 // Run the signal callback.
174 SendPropertyChangedSignal(&signal
);
176 // Remove the observer.
177 client_
->RemovePropertyChangedObserver(&observer
);
179 // Make sure it's not called anymore.
180 EXPECT_CALL(observer
, OnPropertyChanged(_
, _
)).Times(0);
182 // Run the signal callback again and make sure the observer isn't called.
183 SendPropertyChangedSignal(&signal
);
186 TEST_F(ShillManagerClientTest
, GetProperties
) {
188 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
189 dbus::MessageWriter
writer(response
.get());
190 dbus::MessageWriter
array_writer(NULL
);
191 writer
.OpenArray("{sv}", &array_writer
);
192 dbus::MessageWriter
entry_writer(NULL
);
193 array_writer
.OpenDictEntry(&entry_writer
);
194 entry_writer
.AppendString(flimflam::kOfflineModeProperty
);
195 entry_writer
.AppendVariantOfBool(true);
196 array_writer
.CloseContainer(&entry_writer
);
197 writer
.CloseContainer(&array_writer
);
199 // Create the expected value.
200 base::DictionaryValue value
;
201 value
.SetWithoutPathExpansion(flimflam::kOfflineModeProperty
,
202 base::Value::CreateBooleanValue(true));
204 PrepareForMethodCall(flimflam::kGetPropertiesFunction
,
205 base::Bind(&ExpectNoArgument
),
208 client_
->GetProperties(base::Bind(&ExpectDictionaryValueResult
,
210 // Run the message loop.
211 message_loop_
.RunUntilIdle();
214 TEST_F(ShillManagerClientTest
, CallGetPropertiesAndBlock
) {
216 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
217 dbus::MessageWriter
writer(response
.get());
218 dbus::MessageWriter
array_writer(NULL
);
219 writer
.OpenArray("{sv}", &array_writer
);
220 dbus::MessageWriter
entry_writer(NULL
);
221 array_writer
.OpenDictEntry(&entry_writer
);
222 entry_writer
.AppendString(flimflam::kOfflineModeProperty
);
223 entry_writer
.AppendVariantOfBool(true);
224 array_writer
.CloseContainer(&entry_writer
);
225 writer
.CloseContainer(&array_writer
);
227 // Create the expected value.
228 base::DictionaryValue value
;
229 value
.SetWithoutPathExpansion(flimflam::kOfflineModeProperty
,
230 base::Value::CreateBooleanValue(true));
232 PrepareForMethodCall(flimflam::kGetPropertiesFunction
,
233 base::Bind(&ExpectNoArgument
),
236 scoped_ptr
<base::DictionaryValue
> result(
237 client_
->CallGetPropertiesAndBlock());
238 EXPECT_TRUE(value
.Equals(result
.get()));
241 TEST_F(ShillManagerClientTest
, GetNetworksForGeolocation
) {
243 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
245 dbus::MessageWriter
writer(response
.get());
246 dbus::MessageWriter
type_dict_writer(NULL
);
247 writer
.OpenArray("{sv}", &type_dict_writer
);
248 dbus::MessageWriter
type_entry_writer(NULL
);
249 type_dict_writer
.OpenDictEntry(&type_entry_writer
);
250 type_entry_writer
.AppendString(flimflam::kTypeWifi
);
251 dbus::MessageWriter
variant_writer(NULL
);
252 type_entry_writer
.OpenVariant("aa{ss}", &variant_writer
);
253 dbus::MessageWriter
wap_list_writer(NULL
);
254 variant_writer
.OpenArray("a{ss}", &wap_list_writer
);
255 dbus::MessageWriter
property_dict_writer(NULL
);
256 wap_list_writer
.OpenArray("{ss}", &property_dict_writer
);
257 dbus::MessageWriter
property_entry_writer(NULL
);
258 property_dict_writer
.OpenDictEntry(&property_entry_writer
);
259 property_entry_writer
.AppendString(shill::kGeoMacAddressProperty
);
260 property_entry_writer
.AppendString("01:23:45:67:89:AB");
261 property_dict_writer
.CloseContainer(&property_entry_writer
);
262 wap_list_writer
.CloseContainer(&property_dict_writer
);
263 variant_writer
.CloseContainer(&wap_list_writer
);
264 type_entry_writer
.CloseContainer(&wap_list_writer
);
265 type_dict_writer
.CloseContainer(&type_entry_writer
);
266 writer
.CloseContainer(&type_dict_writer
);
269 // Create the expected value.
270 base::DictionaryValue type_dict_value
;
271 base::ListValue
* type_entry_value
= new base::ListValue
;
272 base::DictionaryValue
* property_dict_value
= new base::DictionaryValue
;
273 property_dict_value
->SetWithoutPathExpansion(
274 shill::kGeoMacAddressProperty
,
275 base::Value::CreateStringValue("01:23:45:67:89:AB"));
276 type_entry_value
->Append(property_dict_value
);
277 type_dict_value
.SetWithoutPathExpansion("wifi", type_entry_value
);
280 PrepareForMethodCall(shill::kGetNetworksForGeolocation
,
281 base::Bind(&ExpectNoArgument
),
284 client_
->GetNetworksForGeolocation(base::Bind(&ExpectDictionaryValueResult
,
287 // Run the message loop.
288 message_loop_
.RunUntilIdle();
291 TEST_F(ShillManagerClientTest
, SetProperty
) {
293 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
295 base::StringValue
value("portal list");
296 PrepareForMethodCall(flimflam::kSetPropertyFunction
,
297 base::Bind(ExpectStringAndValueArguments
,
298 flimflam::kCheckPortalListProperty
,
302 MockClosure mock_closure
;
303 MockErrorCallback mock_error_callback
;
304 client_
->SetProperty(flimflam::kCheckPortalListProperty
,
306 mock_closure
.GetCallback(),
307 mock_error_callback
.GetCallback());
308 EXPECT_CALL(mock_closure
, Run()).Times(1);
309 EXPECT_CALL(mock_error_callback
, Run(_
, _
)).Times(0);
311 // Run the message loop.
312 message_loop_
.RunUntilIdle();
315 TEST_F(ShillManagerClientTest
, RequestScan
) {
317 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
319 PrepareForMethodCall(flimflam::kRequestScanFunction
,
320 base::Bind(&ExpectStringArgument
, flimflam::kTypeWifi
),
323 MockClosure mock_closure
;
324 MockErrorCallback mock_error_callback
;
325 client_
->RequestScan(flimflam::kTypeWifi
,
326 mock_closure
.GetCallback(),
327 mock_error_callback
.GetCallback());
328 EXPECT_CALL(mock_closure
, Run()).Times(1);
329 EXPECT_CALL(mock_error_callback
, Run(_
, _
)).Times(0);
331 // Run the message loop.
332 message_loop_
.RunUntilIdle();
335 TEST_F(ShillManagerClientTest
, EnableTechnology
) {
337 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
339 PrepareForMethodCall(flimflam::kEnableTechnologyFunction
,
340 base::Bind(&ExpectStringArgument
, flimflam::kTypeWifi
),
343 MockClosure mock_closure
;
344 MockErrorCallback mock_error_callback
;
345 client_
->EnableTechnology(flimflam::kTypeWifi
,
346 mock_closure
.GetCallback(),
347 mock_error_callback
.GetCallback());
348 EXPECT_CALL(mock_closure
, Run()).Times(1);
349 EXPECT_CALL(mock_error_callback
, Run(_
, _
)).Times(0);
351 // Run the message loop.
352 message_loop_
.RunUntilIdle();
355 TEST_F(ShillManagerClientTest
, DisableTechnology
) {
357 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
359 PrepareForMethodCall(flimflam::kDisableTechnologyFunction
,
360 base::Bind(&ExpectStringArgument
, flimflam::kTypeWifi
),
363 MockClosure mock_closure
;
364 MockErrorCallback mock_error_callback
;
365 client_
->DisableTechnology(flimflam::kTypeWifi
,
366 mock_closure
.GetCallback(),
367 mock_error_callback
.GetCallback());
368 EXPECT_CALL(mock_closure
, Run()).Times(1);
369 EXPECT_CALL(mock_error_callback
, Run(_
, _
)).Times(0);
371 // Run the message loop.
372 message_loop_
.RunUntilIdle();
375 TEST_F(ShillManagerClientTest
, ConfigureService
) {
377 const dbus::ObjectPath
object_path("/");
378 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
379 dbus::MessageWriter
writer(response
.get());
380 writer
.AppendObjectPath(object_path
);
381 // Create the argument dictionary.
382 scoped_ptr
<base::DictionaryValue
> arg(CreateExampleProperties());
384 PrepareForMethodCall(flimflam::kConfigureServiceFunction
,
385 base::Bind(&ExpectDictionaryValueArgument
, arg
.get()),
388 MockErrorCallback mock_error_callback
;
389 client_
->ConfigureService(*arg
,
390 base::Bind(&ExpectObjectPathResultWithoutStatus
,
392 mock_error_callback
.GetCallback());
393 EXPECT_CALL(mock_error_callback
, Run(_
, _
)).Times(0);
395 // Run the message loop.
396 message_loop_
.RunUntilIdle();
399 TEST_F(ShillManagerClientTest
, GetService
) {
401 const dbus::ObjectPath
object_path("/");
402 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
403 dbus::MessageWriter
writer(response
.get());
404 writer
.AppendObjectPath(object_path
);
405 // Create the argument dictionary.
406 scoped_ptr
<base::DictionaryValue
> arg(CreateExampleProperties());
408 PrepareForMethodCall(flimflam::kGetServiceFunction
,
409 base::Bind(&ExpectDictionaryValueArgument
, arg
.get()),
412 MockErrorCallback mock_error_callback
;
413 client_
->GetService(*arg
,
414 base::Bind(&ExpectObjectPathResultWithoutStatus
,
416 mock_error_callback
.GetCallback());
417 EXPECT_CALL(mock_error_callback
, Run(_
, _
)).Times(0);
419 // Run the message loop.
420 message_loop_
.RunUntilIdle();
423 TEST_F(ShillManagerClientTest
, VerifyDestination
) {
425 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
426 dbus::MessageWriter
writer(response
.get());
427 bool expected
= true;
428 writer
.AppendBool(expected
);
430 std::vector
<std::string
> arguments
;
431 arguments
.push_back("certificate");
432 arguments
.push_back("public_key");
433 arguments
.push_back("nonce");
434 arguments
.push_back("signed_data");
435 arguments
.push_back("device_serial");
436 arguments
.push_back("device_ssid");
437 arguments
.push_back("device_bssid");
438 PrepareForMethodCall(shill::kVerifyDestinationFunction
,
439 base::Bind(&ExpectStringArguments
, arguments
),
443 MockErrorCallback mock_error_callback
;
444 ShillManagerClient::VerificationProperties properties
;
445 properties
.certificate
= arguments
[0];
446 properties
.public_key
= arguments
[1];
447 properties
.nonce
= arguments
[2];
448 properties
.signed_data
= arguments
[3];
449 properties
.device_serial
= arguments
[4];
450 properties
.device_ssid
= arguments
[5];
451 properties
.device_bssid
= arguments
[6];
452 client_
->VerifyDestination(
454 base::Bind(&ExpectBoolResultWithoutStatus
, expected
),
455 mock_error_callback
.GetCallback());
456 EXPECT_CALL(mock_error_callback
, Run(_
, _
)).Times(0);
458 // Run the message loop.
459 message_loop_
.RunUntilIdle();
462 TEST_F(ShillManagerClientTest
, VerifyAndEncryptCredentials
) {
464 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
465 dbus::MessageWriter
writer(response
.get());
466 std::string expected
= "encrypted_credentials";
467 writer
.AppendString(expected
);
469 std::vector
<std::string
> arguments
;
470 arguments
.push_back("certificate");
471 arguments
.push_back("public_key");
472 arguments
.push_back("nonce");
473 arguments
.push_back("signed_data");
474 arguments
.push_back("device_serial");
475 arguments
.push_back("device_ssid");
476 arguments
.push_back("device_bssid");
477 std::string service_path
= "/";
478 dbus::ObjectPath
service_path_obj(service_path
);
479 PrepareForMethodCall(shill::kVerifyAndEncryptCredentialsFunction
,
480 base::Bind(&ExpectStringArgumentsFollowedByObjectPath
,
486 MockErrorCallback mock_error_callback
;
487 ShillManagerClient::VerificationProperties properties
;
488 properties
.certificate
= arguments
[0];
489 properties
.public_key
= arguments
[1];
490 properties
.nonce
= arguments
[2];
491 properties
.signed_data
= arguments
[3];
492 properties
.device_serial
= arguments
[4];
493 properties
.device_ssid
= arguments
[5];
494 properties
.device_bssid
= arguments
[6];
495 client_
->VerifyAndEncryptCredentials(
498 base::Bind(&ExpectStringResultWithoutStatus
, expected
),
499 mock_error_callback
.GetCallback());
500 EXPECT_CALL(mock_error_callback
, Run(_
, _
)).Times(0);
502 // Run the message loop.
503 message_loop_
.RunUntilIdle();
506 TEST_F(ShillManagerClientTest
, VerifyAndEncryptData
) {
508 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
509 dbus::MessageWriter
writer(response
.get());
510 std::string expected
= "encrypted_data";
511 writer
.AppendString(expected
);
513 std::vector
<std::string
> arguments
;
514 arguments
.push_back("certificate");
515 arguments
.push_back("public_key");
516 arguments
.push_back("nonce");
517 arguments
.push_back("signed_data");
518 arguments
.push_back("device_serial");
519 arguments
.push_back("device_ssid");
520 arguments
.push_back("device_bssid");
521 arguments
.push_back("data");
522 PrepareForMethodCall(shill::kVerifyAndEncryptDataFunction
,
523 base::Bind(&ExpectStringArguments
, arguments
),
527 MockErrorCallback mock_error_callback
;
528 ShillManagerClient::VerificationProperties properties
;
529 properties
.certificate
= arguments
[0];
530 properties
.public_key
= arguments
[1];
531 properties
.nonce
= arguments
[2];
532 properties
.signed_data
= arguments
[3];
533 properties
.device_serial
= arguments
[4];
534 properties
.device_ssid
= arguments
[5];
535 properties
.device_bssid
= arguments
[6];
536 client_
->VerifyAndEncryptData(
539 base::Bind(&ExpectStringResultWithoutStatus
, expected
),
540 mock_error_callback
.GetCallback());
541 EXPECT_CALL(mock_error_callback
, Run(_
, _
)).Times(0);
543 // Run the message loop.
544 message_loop_
.RunUntilIdle();
547 } // namespace chromeos