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