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. 4 5 #include "base/bind.h" 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" 14 15 using testing::_; 16 using testing::ByRef; 17 18 namespace chromeos { 19 20 namespace { 21 22 void ExpectStringArguments(const std::vector<std::string>& arguments, 23 dbus::MessageReader* reader) { 24 for (std::vector<std::string>::const_iterator iter = arguments.begin(); 25 iter != arguments.end(); ++iter) { 26 std::string arg_string; 27 ASSERT_TRUE(reader->PopString(&arg_string)); 28 EXPECT_EQ(*iter, arg_string); 29 } 30 EXPECT_FALSE(reader->HasMoreData()); 31 } 32 33 void ExpectStringArgumentsFollowedByObjectPath( 34 const std::vector<std::string>& arguments, 35 const dbus::ObjectPath& object_path, 36 dbus::MessageReader* reader) { 37 for (std::vector<std::string>::const_iterator iter = arguments.begin(); 38 iter != arguments.end(); ++iter) { 39 std::string arg_string; 40 ASSERT_TRUE(reader->PopString(&arg_string)); 41 EXPECT_EQ(*iter, arg_string); 42 } 43 dbus::ObjectPath path; 44 ASSERT_TRUE(reader->PopObjectPath(&path)); 45 EXPECT_EQ(object_path, path); 46 EXPECT_FALSE(reader->HasMoreData()); 47 } 48 49 50 } // namespace 51 52 class ShillManagerClientTest : public ShillClientUnittestBase { 53 public: 54 ShillManagerClientTest() 55 : ShillClientUnittestBase( 56 flimflam::kFlimflamManagerInterface, 57 dbus::ObjectPath(flimflam::kFlimflamServicePath)) { 58 } 59 60 virtual void SetUp() { 61 ShillClientUnittestBase::SetUp(); 62 // Create a client with the mock bus. 63 client_.reset(ShillManagerClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION, 64 mock_bus_.get())); 65 // Run the message loop to run the signal connection result callback. 66 message_loop_.RunUntilIdle(); 67 } 68 69 virtual void TearDown() { 70 ShillClientUnittestBase::TearDown(); 71 } 72 73 protected: 74 scoped_ptr<ShillManagerClient> client_; 75 }; 76 77 TEST_F(ShillManagerClientTest, PropertyChanged) { 78 // Create a signal. 79 base::FundamentalValue kOfflineMode(true); 80 dbus::Signal signal(flimflam::kFlimflamManagerInterface, 81 flimflam::kMonitorPropertyChanged); 82 dbus::MessageWriter writer(&signal); 83 writer.AppendString(flimflam::kOfflineModeProperty); 84 dbus::AppendBasicTypeValueData(&writer, kOfflineMode); 85 86 // Set expectations. 87 MockPropertyChangeObserver observer; 88 EXPECT_CALL(observer, 89 OnPropertyChanged(flimflam::kOfflineModeProperty, 90 ValueEq(ByRef(kOfflineMode)))).Times(1); 91 92 // Add the observer 93 client_->AddPropertyChangedObserver(&observer); 94 95 // Run the signal callback. 96 SendPropertyChangedSignal(&signal); 97 98 // Remove the observer. 99 client_->RemovePropertyChangedObserver(&observer); 100 101 // Make sure it's not called anymore. 102 EXPECT_CALL(observer, OnPropertyChanged(_, _)).Times(0); 103 104 // Run the signal callback again and make sure the observer isn't called. 105 SendPropertyChangedSignal(&signal); 106 } 107 108 TEST_F(ShillManagerClientTest, GetProperties) { 109 // Create response. 110 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 111 dbus::MessageWriter writer(response.get()); 112 dbus::MessageWriter array_writer(NULL); 113 writer.OpenArray("{sv}", &array_writer); 114 dbus::MessageWriter entry_writer(NULL); 115 array_writer.OpenDictEntry(&entry_writer); 116 entry_writer.AppendString(flimflam::kOfflineModeProperty); 117 entry_writer.AppendVariantOfBool(true); 118 array_writer.CloseContainer(&entry_writer); 119 writer.CloseContainer(&array_writer); 120 121 // Create the expected value. 122 base::DictionaryValue value; 123 value.SetWithoutPathExpansion(flimflam::kOfflineModeProperty, 124 base::Value::CreateBooleanValue(true)); 125 // Set expectations. 126 PrepareForMethodCall(flimflam::kGetPropertiesFunction, 127 base::Bind(&ExpectNoArgument), 128 response.get()); 129 // Call method. 130 client_->GetProperties(base::Bind(&ExpectDictionaryValueResult, 131 &value)); 132 // Run the message loop. 133 message_loop_.RunUntilIdle(); 134 } 135 136 TEST_F(ShillManagerClientTest, GetNetworksForGeolocation) { 137 // Create response. 138 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 139 140 dbus::MessageWriter writer(response.get()); 141 dbus::MessageWriter type_dict_writer(NULL); 142 writer.OpenArray("{sv}", &type_dict_writer); 143 dbus::MessageWriter type_entry_writer(NULL); 144 type_dict_writer.OpenDictEntry(&type_entry_writer); 145 type_entry_writer.AppendString(flimflam::kTypeWifi); 146 dbus::MessageWriter variant_writer(NULL); 147 type_entry_writer.OpenVariant("aa{ss}", &variant_writer); 148 dbus::MessageWriter wap_list_writer(NULL); 149 variant_writer.OpenArray("a{ss}", &wap_list_writer); 150 dbus::MessageWriter property_dict_writer(NULL); 151 wap_list_writer.OpenArray("{ss}", &property_dict_writer); 152 dbus::MessageWriter property_entry_writer(NULL); 153 property_dict_writer.OpenDictEntry(&property_entry_writer); 154 property_entry_writer.AppendString(shill::kGeoMacAddressProperty); 155 property_entry_writer.AppendString("01:23:45:67:89:AB"); 156 property_dict_writer.CloseContainer(&property_entry_writer); 157 wap_list_writer.CloseContainer(&property_dict_writer); 158 variant_writer.CloseContainer(&wap_list_writer); 159 type_entry_writer.CloseContainer(&wap_list_writer); 160 type_dict_writer.CloseContainer(&type_entry_writer); 161 writer.CloseContainer(&type_dict_writer); 162 163 164 // Create the expected value. 165 base::DictionaryValue type_dict_value; 166 base::ListValue* type_entry_value = new base::ListValue; 167 base::DictionaryValue* property_dict_value = new base::DictionaryValue; 168 property_dict_value->SetWithoutPathExpansion( 169 shill::kGeoMacAddressProperty, 170 base::Value::CreateStringValue("01:23:45:67:89:AB")); 171 type_entry_value->Append(property_dict_value); 172 type_dict_value.SetWithoutPathExpansion("wifi", type_entry_value); 173 174 // Set expectations. 175 PrepareForMethodCall(shill::kGetNetworksForGeolocation, 176 base::Bind(&ExpectNoArgument), 177 response.get()); 178 // Call method. 179 client_->GetNetworksForGeolocation(base::Bind(&ExpectDictionaryValueResult, 180 &type_dict_value)); 181 182 // Run the message loop. 183 message_loop_.RunUntilIdle(); 184 } 185 186 TEST_F(ShillManagerClientTest, SetProperty) { 187 // Create response. 188 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 189 // Set expectations. 190 base::StringValue value("portal list"); 191 PrepareForMethodCall(flimflam::kSetPropertyFunction, 192 base::Bind(ExpectStringAndValueArguments, 193 flimflam::kCheckPortalListProperty, 194 &value), 195 response.get()); 196 // Call method. 197 MockClosure mock_closure; 198 MockErrorCallback mock_error_callback; 199 client_->SetProperty(flimflam::kCheckPortalListProperty, 200 value, 201 mock_closure.GetCallback(), 202 mock_error_callback.GetCallback()); 203 EXPECT_CALL(mock_closure, Run()).Times(1); 204 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 205 206 // Run the message loop. 207 message_loop_.RunUntilIdle(); 208 } 209 210 TEST_F(ShillManagerClientTest, RequestScan) { 211 // Create response. 212 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 213 // Set expectations. 214 PrepareForMethodCall(flimflam::kRequestScanFunction, 215 base::Bind(&ExpectStringArgument, flimflam::kTypeWifi), 216 response.get()); 217 // Call method. 218 MockClosure mock_closure; 219 MockErrorCallback mock_error_callback; 220 client_->RequestScan(flimflam::kTypeWifi, 221 mock_closure.GetCallback(), 222 mock_error_callback.GetCallback()); 223 EXPECT_CALL(mock_closure, Run()).Times(1); 224 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 225 226 // Run the message loop. 227 message_loop_.RunUntilIdle(); 228 } 229 230 TEST_F(ShillManagerClientTest, EnableTechnology) { 231 // Create response. 232 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 233 // Set expectations. 234 PrepareForMethodCall(flimflam::kEnableTechnologyFunction, 235 base::Bind(&ExpectStringArgument, flimflam::kTypeWifi), 236 response.get()); 237 // Call method. 238 MockClosure mock_closure; 239 MockErrorCallback mock_error_callback; 240 client_->EnableTechnology(flimflam::kTypeWifi, 241 mock_closure.GetCallback(), 242 mock_error_callback.GetCallback()); 243 EXPECT_CALL(mock_closure, Run()).Times(1); 244 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 245 246 // Run the message loop. 247 message_loop_.RunUntilIdle(); 248 } 249 250 TEST_F(ShillManagerClientTest, DisableTechnology) { 251 // Create response. 252 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 253 // Set expectations. 254 PrepareForMethodCall(flimflam::kDisableTechnologyFunction, 255 base::Bind(&ExpectStringArgument, flimflam::kTypeWifi), 256 response.get()); 257 // Call method. 258 MockClosure mock_closure; 259 MockErrorCallback mock_error_callback; 260 client_->DisableTechnology(flimflam::kTypeWifi, 261 mock_closure.GetCallback(), 262 mock_error_callback.GetCallback()); 263 EXPECT_CALL(mock_closure, Run()).Times(1); 264 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 265 266 // Run the message loop. 267 message_loop_.RunUntilIdle(); 268 } 269 270 TEST_F(ShillManagerClientTest, ConfigureService) { 271 // Create response. 272 const dbus::ObjectPath object_path("/"); 273 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 274 dbus::MessageWriter writer(response.get()); 275 writer.AppendObjectPath(object_path); 276 // Create the argument dictionary. 277 scoped_ptr<base::DictionaryValue> arg(CreateExampleServiceProperties()); 278 // Set expectations. 279 PrepareForMethodCall(flimflam::kConfigureServiceFunction, 280 base::Bind(&ExpectDictionaryValueArgument, arg.get()), 281 response.get()); 282 // Call method. 283 MockErrorCallback mock_error_callback; 284 client_->ConfigureService(*arg, 285 base::Bind(&ExpectObjectPathResultWithoutStatus, 286 object_path), 287 mock_error_callback.GetCallback()); 288 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 289 290 // Run the message loop. 291 message_loop_.RunUntilIdle(); 292 } 293 294 TEST_F(ShillManagerClientTest, GetService) { 295 // Create response. 296 const dbus::ObjectPath object_path("/"); 297 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 298 dbus::MessageWriter writer(response.get()); 299 writer.AppendObjectPath(object_path); 300 // Create the argument dictionary. 301 scoped_ptr<base::DictionaryValue> arg(CreateExampleServiceProperties()); 302 // Set expectations. 303 PrepareForMethodCall(flimflam::kGetServiceFunction, 304 base::Bind(&ExpectDictionaryValueArgument, arg.get()), 305 response.get()); 306 // Call method. 307 MockErrorCallback mock_error_callback; 308 client_->GetService(*arg, 309 base::Bind(&ExpectObjectPathResultWithoutStatus, 310 object_path), 311 mock_error_callback.GetCallback()); 312 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 313 314 // Run the message loop. 315 message_loop_.RunUntilIdle(); 316 } 317 318 TEST_F(ShillManagerClientTest, VerifyDestination) { 319 // Create response. 320 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 321 dbus::MessageWriter writer(response.get()); 322 bool expected = true; 323 writer.AppendBool(expected); 324 // Set expectations. 325 std::vector<std::string> arguments; 326 arguments.push_back("certificate"); 327 arguments.push_back("public_key"); 328 arguments.push_back("nonce"); 329 arguments.push_back("signed_data"); 330 arguments.push_back("device_serial"); 331 arguments.push_back("device_ssid"); 332 arguments.push_back("device_bssid"); 333 PrepareForMethodCall(shill::kVerifyDestinationFunction, 334 base::Bind(&ExpectStringArguments, arguments), 335 response.get()); 336 337 // Call method. 338 MockErrorCallback mock_error_callback; 339 ShillManagerClient::VerificationProperties properties; 340 properties.certificate = arguments[0]; 341 properties.public_key = arguments[1]; 342 properties.nonce = arguments[2]; 343 properties.signed_data = arguments[3]; 344 properties.device_serial = arguments[4]; 345 properties.device_ssid = arguments[5]; 346 properties.device_bssid = arguments[6]; 347 client_->VerifyDestination( 348 properties, 349 base::Bind(&ExpectBoolResultWithoutStatus, expected), 350 mock_error_callback.GetCallback()); 351 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 352 353 // Run the message loop. 354 message_loop_.RunUntilIdle(); 355 } 356 357 TEST_F(ShillManagerClientTest, VerifyAndEncryptCredentials) { 358 // Create response. 359 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 360 dbus::MessageWriter writer(response.get()); 361 std::string expected = "encrypted_credentials"; 362 writer.AppendString(expected); 363 // Set expectations. 364 std::vector<std::string> arguments; 365 arguments.push_back("certificate"); 366 arguments.push_back("public_key"); 367 arguments.push_back("nonce"); 368 arguments.push_back("signed_data"); 369 arguments.push_back("device_serial"); 370 arguments.push_back("device_ssid"); 371 arguments.push_back("device_bssid"); 372 std::string service_path = "/"; 373 dbus::ObjectPath service_path_obj(service_path); 374 PrepareForMethodCall(shill::kVerifyAndEncryptCredentialsFunction, 375 base::Bind(&ExpectStringArgumentsFollowedByObjectPath, 376 arguments, 377 service_path_obj), 378 response.get()); 379 380 // Call method. 381 MockErrorCallback mock_error_callback; 382 ShillManagerClient::VerificationProperties properties; 383 properties.certificate = arguments[0]; 384 properties.public_key = arguments[1]; 385 properties.nonce = arguments[2]; 386 properties.signed_data = arguments[3]; 387 properties.device_serial = arguments[4]; 388 properties.device_ssid = arguments[5]; 389 properties.device_bssid = arguments[6]; 390 client_->VerifyAndEncryptCredentials( 391 properties, 392 service_path, 393 base::Bind(&ExpectStringResultWithoutStatus, expected), 394 mock_error_callback.GetCallback()); 395 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 396 397 // Run the message loop. 398 message_loop_.RunUntilIdle(); 399 } 400 401 TEST_F(ShillManagerClientTest, VerifyAndEncryptData) { 402 // Create response. 403 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 404 dbus::MessageWriter writer(response.get()); 405 std::string expected = "encrypted_data"; 406 writer.AppendString(expected); 407 // Set expectations. 408 std::vector<std::string> arguments; 409 arguments.push_back("certificate"); 410 arguments.push_back("public_key"); 411 arguments.push_back("nonce"); 412 arguments.push_back("signed_data"); 413 arguments.push_back("device_serial"); 414 arguments.push_back("device_ssid"); 415 arguments.push_back("device_bssid"); 416 arguments.push_back("data"); 417 PrepareForMethodCall(shill::kVerifyAndEncryptDataFunction, 418 base::Bind(&ExpectStringArguments, arguments), 419 response.get()); 420 421 // Call method. 422 MockErrorCallback mock_error_callback; 423 ShillManagerClient::VerificationProperties properties; 424 properties.certificate = arguments[0]; 425 properties.public_key = arguments[1]; 426 properties.nonce = arguments[2]; 427 properties.signed_data = arguments[3]; 428 properties.device_serial = arguments[4]; 429 properties.device_ssid = arguments[5]; 430 properties.device_bssid = arguments[6]; 431 client_->VerifyAndEncryptData( 432 properties, 433 arguments[7], 434 base::Bind(&ExpectStringResultWithoutStatus, expected), 435 mock_error_callback.GetCallback()); 436 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 437 438 // Run the message loop. 439 message_loop_.RunUntilIdle(); 440 } 441 442 } // namespace chromeos 443