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/json/json_writer.h" 7 #include "base/message_loop/message_loop.h" 8 #include "base/strings/string_piece.h" 9 #include "base/values.h" 10 #include "chromeos/dbus/dbus_thread_manager.h" 11 #include "chromeos/dbus/fake_dbus_thread_manager.h" 12 #include "chromeos/dbus/mock_shill_manager_client.h" 13 #include "chromeos/dbus/mock_shill_profile_client.h" 14 #include "chromeos/dbus/mock_shill_service_client.h" 15 #include "chromeos/dbus/shill_stub_helper.h" 16 #include "chromeos/network/network_configuration_handler.h" 17 #include "chromeos/network/network_state.h" 18 #include "chromeos/network/network_state_handler.h" 19 #include "chromeos/network/network_state_handler_observer.h" 20 #include "chromeos/network/shill_property_util.h" 21 #include "testing/gmock/include/gmock/gmock.h" 22 #include "testing/gtest/include/gtest/gtest.h" 23 #include "third_party/cros_system_api/dbus/service_constants.h" 24 25 using ::testing::_; 26 using ::testing::AnyNumber; 27 using ::testing::Invoke; 28 using ::testing::Pointee; 29 using ::testing::Return; 30 using ::testing::SaveArg; 31 using ::testing::StrEq; 32 33 // Matcher to match base::Value. 34 MATCHER_P(IsEqualTo, value, "") { return arg.Equals(value); } 35 36 namespace chromeos { 37 38 namespace { 39 40 static std::string PrettyJson(const base::DictionaryValue& value) { 41 std::string pretty; 42 base::JSONWriter::WriteWithOptions(&value, 43 base::JSONWriter::OPTIONS_PRETTY_PRINT, 44 &pretty); 45 return pretty; 46 } 47 48 void DictionaryValueCallback( 49 const std::string& expected_id, 50 const std::string& expected_json, 51 const std::string& service_path, 52 const base::DictionaryValue& dictionary) { 53 std::string dict_str = PrettyJson(dictionary); 54 EXPECT_EQ(expected_json, dict_str); 55 EXPECT_EQ(expected_id, service_path); 56 } 57 58 void ErrorCallback(bool error_expected, 59 const std::string& expected_id, 60 const std::string& error_name, 61 scoped_ptr<base::DictionaryValue> error_data) { 62 EXPECT_TRUE(error_expected) << "Unexpected error: " << error_name 63 << " with associated data: \n" 64 << PrettyJson(*error_data); 65 } 66 67 void StringResultCallback(const std::string& expected_result, 68 const std::string& result) { 69 EXPECT_EQ(expected_result, result); 70 } 71 72 void DBusErrorCallback(const std::string& error_name, 73 const std::string& error_message) { 74 EXPECT_TRUE(false) << "DBus Error: " << error_name << "(" 75 << error_message << ")"; 76 } 77 78 class TestCallback { 79 public: 80 TestCallback() : run_count_(0) {} 81 void Run() { 82 ++run_count_; 83 } 84 int run_count() const { return run_count_; } 85 86 private: 87 int run_count_; 88 }; 89 90 } // namespace 91 92 class NetworkConfigurationHandlerTest : public testing::Test { 93 public: 94 NetworkConfigurationHandlerTest() 95 : mock_manager_client_(NULL), 96 mock_profile_client_(NULL), 97 mock_service_client_(NULL), 98 dictionary_value_result_(NULL) {} 99 virtual ~NetworkConfigurationHandlerTest() {} 100 101 virtual void SetUp() OVERRIDE { 102 FakeDBusThreadManager* dbus_thread_manager = new FakeDBusThreadManager; 103 mock_manager_client_ = new MockShillManagerClient(); 104 mock_profile_client_ = new MockShillProfileClient(); 105 mock_service_client_ = new MockShillServiceClient(); 106 dbus_thread_manager->SetShillManagerClient( 107 scoped_ptr<ShillManagerClient>(mock_manager_client_).Pass()); 108 dbus_thread_manager->SetShillProfileClient( 109 scoped_ptr<ShillProfileClient>(mock_profile_client_).Pass()); 110 dbus_thread_manager->SetShillServiceClient( 111 scoped_ptr<ShillServiceClient>(mock_service_client_).Pass()); 112 113 EXPECT_CALL(*mock_service_client_, GetProperties(_, _)) 114 .Times(AnyNumber()); 115 EXPECT_CALL(*mock_manager_client_, GetProperties(_)) 116 .Times(AnyNumber()); 117 EXPECT_CALL(*mock_manager_client_, AddPropertyChangedObserver(_)) 118 .Times(AnyNumber()); 119 EXPECT_CALL(*mock_manager_client_, RemovePropertyChangedObserver(_)) 120 .Times(AnyNumber()); 121 122 DBusThreadManager::InitializeForTesting(dbus_thread_manager); 123 124 network_state_handler_.reset(NetworkStateHandler::InitializeForTest()); 125 network_configuration_handler_.reset(new NetworkConfigurationHandler()); 126 network_configuration_handler_->Init(network_state_handler_.get()); 127 message_loop_.RunUntilIdle(); 128 } 129 130 virtual void TearDown() OVERRIDE { 131 network_configuration_handler_.reset(); 132 network_state_handler_.reset(); 133 DBusThreadManager::Shutdown(); 134 } 135 136 // Handles responses for GetProperties method calls. 137 void OnGetProperties( 138 const dbus::ObjectPath& path, 139 const ShillClientHelper::DictionaryValueCallback& callback) { 140 callback.Run(DBUS_METHOD_CALL_SUCCESS, *dictionary_value_result_); 141 } 142 143 // Handles responses for SetProperties method calls. 144 void OnSetProperties(const dbus::ObjectPath& service_path, 145 const base::DictionaryValue& properties, 146 const base::Closure& callback, 147 const ShillClientHelper::ErrorCallback& error_callback) { 148 callback.Run(); 149 } 150 151 // Handles responses for ClearProperties method calls. 152 void OnClearProperties( 153 const dbus::ObjectPath& service_path, 154 const std::vector<std::string>& names, 155 const ShillClientHelper::ListValueCallback& callback, 156 const ShillClientHelper::ErrorCallback& error_callback) { 157 base::ListValue result; 158 result.AppendBoolean(true); 159 callback.Run(result); 160 } 161 162 // Handles responses for ClearProperties method calls, and simulates an error 163 // result. 164 void OnClearPropertiesError( 165 const dbus::ObjectPath& service_path, 166 const std::vector<std::string>& names, 167 const ShillClientHelper::ListValueCallback& callback, 168 const ShillClientHelper::ErrorCallback& error_callback) { 169 base::ListValue result; 170 result.AppendBoolean(false); 171 callback.Run(result); 172 } 173 174 void OnConfigureService( 175 const dbus::ObjectPath& profile_path, 176 const base::DictionaryValue& properties, 177 const ObjectPathCallback& callback, 178 const ShillClientHelper::ErrorCallback& error_callback) { 179 callback.Run(dbus::ObjectPath("/service/2")); 180 } 181 182 void OnGetLoadableProfileEntries( 183 const dbus::ObjectPath& service_path, 184 const ShillClientHelper::DictionaryValueCallback& callback) { 185 base::DictionaryValue entries; 186 entries.SetString("profile1", "entry1"); 187 entries.SetString("profile2", "entry2"); 188 callback.Run(DBUS_METHOD_CALL_SUCCESS, entries); 189 } 190 191 void OnDeleteEntry(const dbus::ObjectPath& profile_path, 192 const std::string& entry_path, 193 const base::Closure& callback, 194 const ShillClientHelper::ErrorCallback& error_callback) { 195 // Don't run the callback immediately to emulate actual behavior. 196 message_loop_.PostTask(FROM_HERE, callback); 197 } 198 199 bool PendingProfileEntryDeleterForTest(const std::string& service_path) { 200 return network_configuration_handler_-> 201 PendingProfileEntryDeleterForTest(service_path); 202 } 203 204 protected: 205 MockShillManagerClient* mock_manager_client_; 206 MockShillProfileClient* mock_profile_client_; 207 MockShillServiceClient* mock_service_client_; 208 scoped_ptr<NetworkStateHandler> network_state_handler_; 209 scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_; 210 base::MessageLoopForUI message_loop_; 211 base::DictionaryValue* dictionary_value_result_; 212 }; 213 214 TEST_F(NetworkConfigurationHandlerTest, GetProperties) { 215 std::string service_path = "/service/1"; 216 std::string expected_json = "{\n \"SSID\": \"MyNetwork\"\n}\n"; 217 std::string networkName = "MyNetwork"; 218 std::string key = "SSID"; 219 scoped_ptr<base::StringValue> networkNameValue( 220 base::Value::CreateStringValue(networkName)); 221 222 base::DictionaryValue value; 223 value.Set(key, base::Value::CreateStringValue(networkName)); 224 dictionary_value_result_ = &value; 225 EXPECT_CALL(*mock_service_client_, 226 SetProperty(dbus::ObjectPath(service_path), key, 227 IsEqualTo(networkNameValue.get()), _, _)).Times(1); 228 mock_service_client_->SetProperty(dbus::ObjectPath(service_path), 229 key, 230 *networkNameValue, 231 base::Bind(&base::DoNothing), 232 base::Bind(&DBusErrorCallback)); 233 message_loop_.RunUntilIdle(); 234 235 ShillServiceClient::DictionaryValueCallback get_properties_callback; 236 EXPECT_CALL(*mock_service_client_, 237 GetProperties(_, _)).WillOnce( 238 Invoke(this, 239 &NetworkConfigurationHandlerTest::OnGetProperties)); 240 network_configuration_handler_->GetProperties( 241 service_path, 242 base::Bind(&DictionaryValueCallback, 243 service_path, 244 expected_json), 245 base::Bind(&ErrorCallback, false, service_path)); 246 message_loop_.RunUntilIdle(); 247 } 248 249 TEST_F(NetworkConfigurationHandlerTest, SetProperties) { 250 std::string service_path = "/service/1"; 251 std::string networkName = "MyNetwork"; 252 std::string key = "SSID"; 253 scoped_ptr<base::StringValue> networkNameValue( 254 base::Value::CreateStringValue(networkName)); 255 256 base::DictionaryValue value; 257 value.Set(key, base::Value::CreateStringValue(networkName)); 258 dictionary_value_result_ = &value; 259 EXPECT_CALL(*mock_service_client_, 260 SetProperties(_, _, _, _)).WillOnce( 261 Invoke(this, 262 &NetworkConfigurationHandlerTest::OnSetProperties)); 263 network_configuration_handler_->SetProperties( 264 service_path, 265 value, 266 base::Bind(&base::DoNothing), 267 base::Bind(&ErrorCallback, false, service_path)); 268 message_loop_.RunUntilIdle(); 269 } 270 271 TEST_F(NetworkConfigurationHandlerTest, ClearProperties) { 272 std::string service_path = "/service/1"; 273 std::string networkName = "MyNetwork"; 274 std::string key = "SSID"; 275 scoped_ptr<base::StringValue> networkNameValue( 276 base::Value::CreateStringValue(networkName)); 277 278 // First set up a value to clear. 279 base::DictionaryValue value; 280 value.Set(key, base::Value::CreateStringValue(networkName)); 281 dictionary_value_result_ = &value; 282 EXPECT_CALL(*mock_service_client_, 283 SetProperties(_, _, _, _)).WillOnce( 284 Invoke(this, 285 &NetworkConfigurationHandlerTest::OnSetProperties)); 286 network_configuration_handler_->SetProperties( 287 service_path, 288 value, 289 base::Bind(&base::DoNothing), 290 base::Bind(&ErrorCallback, false, service_path)); 291 message_loop_.RunUntilIdle(); 292 293 // Now clear it. 294 std::vector<std::string> values_to_clear; 295 values_to_clear.push_back(key); 296 EXPECT_CALL(*mock_service_client_, 297 ClearProperties(_, _, _, _)).WillOnce( 298 Invoke(this, 299 &NetworkConfigurationHandlerTest::OnClearProperties)); 300 network_configuration_handler_->ClearProperties( 301 service_path, 302 values_to_clear, 303 base::Bind(&base::DoNothing), 304 base::Bind(&ErrorCallback, false, service_path)); 305 message_loop_.RunUntilIdle(); 306 } 307 308 TEST_F(NetworkConfigurationHandlerTest, ClearPropertiesError) { 309 std::string service_path = "/service/1"; 310 std::string networkName = "MyNetwork"; 311 std::string key = "SSID"; 312 scoped_ptr<base::StringValue> networkNameValue( 313 base::Value::CreateStringValue(networkName)); 314 315 // First set up a value to clear. 316 base::DictionaryValue value; 317 value.Set(key, base::Value::CreateStringValue(networkName)); 318 dictionary_value_result_ = &value; 319 EXPECT_CALL(*mock_service_client_, 320 SetProperties(_, _, _, _)).WillOnce( 321 Invoke(this, 322 &NetworkConfigurationHandlerTest::OnSetProperties)); 323 network_configuration_handler_->SetProperties( 324 service_path, 325 value, 326 base::Bind(&base::DoNothing), 327 base::Bind(&ErrorCallback, false, service_path)); 328 message_loop_.RunUntilIdle(); 329 330 // Now clear it. 331 std::vector<std::string> values_to_clear; 332 values_to_clear.push_back(key); 333 EXPECT_CALL( 334 *mock_service_client_, 335 ClearProperties(_, _, _, _)).WillOnce( 336 Invoke(this, 337 &NetworkConfigurationHandlerTest::OnClearPropertiesError)); 338 network_configuration_handler_->ClearProperties( 339 service_path, 340 values_to_clear, 341 base::Bind(&base::DoNothing), 342 base::Bind(&ErrorCallback, true, service_path)); 343 message_loop_.RunUntilIdle(); 344 } 345 346 TEST_F(NetworkConfigurationHandlerTest, CreateConfiguration) { 347 std::string networkName = "MyNetwork"; 348 std::string key = "SSID"; 349 std::string profile = "profile path"; 350 base::DictionaryValue value; 351 shill_property_util::SetSSID(networkName, &value); 352 value.SetWithoutPathExpansion(shill::kProfileProperty, 353 base::Value::CreateStringValue(profile)); 354 355 EXPECT_CALL(*mock_manager_client_, 356 ConfigureServiceForProfile(dbus::ObjectPath(profile), _, _, _)) 357 .WillOnce( 358 Invoke(this, &NetworkConfigurationHandlerTest::OnConfigureService)); 359 network_configuration_handler_->CreateConfiguration( 360 value, 361 base::Bind(&StringResultCallback, std::string("/service/2")), 362 base::Bind(&ErrorCallback, false, std::string(""))); 363 message_loop_.RunUntilIdle(); 364 } 365 366 TEST_F(NetworkConfigurationHandlerTest, RemoveConfiguration) { 367 std::string service_path = "/service/1"; 368 369 TestCallback test_callback; 370 EXPECT_CALL( 371 *mock_service_client_, 372 GetLoadableProfileEntries(_, _)).WillOnce(Invoke( 373 this, 374 &NetworkConfigurationHandlerTest::OnGetLoadableProfileEntries)); 375 EXPECT_CALL( 376 *mock_profile_client_, 377 DeleteEntry(_, _, _, _)).WillRepeatedly(Invoke( 378 this, 379 &NetworkConfigurationHandlerTest::OnDeleteEntry)); 380 381 network_configuration_handler_->RemoveConfiguration( 382 service_path, 383 base::Bind(&TestCallback::Run, base::Unretained(&test_callback)), 384 base::Bind(&ErrorCallback, false, service_path)); 385 message_loop_.RunUntilIdle(); 386 EXPECT_EQ(1, test_callback.run_count()); 387 EXPECT_FALSE(PendingProfileEntryDeleterForTest(service_path)); 388 } 389 390 //////////////////////////////////////////////////////////////////////////////// 391 // Stub based tests 392 393 namespace { 394 395 class TestObserver : public chromeos::NetworkStateHandlerObserver { 396 public: 397 TestObserver() : network_list_changed_count_(0) {} 398 virtual ~TestObserver() {} 399 400 virtual void NetworkListChanged() OVERRIDE { 401 ++network_list_changed_count_; 402 } 403 404 virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE { 405 property_updates_[network->path()]++; 406 } 407 408 size_t network_list_changed_count() { return network_list_changed_count_; } 409 410 int PropertyUpdatesForService(const std::string& service_path) { 411 return property_updates_[service_path]; 412 } 413 414 void ClearPropertyUpdates() { 415 property_updates_.clear(); 416 } 417 418 private: 419 size_t network_list_changed_count_; 420 std::map<std::string, int> property_updates_; 421 422 DISALLOW_COPY_AND_ASSIGN(TestObserver); 423 }; 424 425 } // namespace 426 427 class NetworkConfigurationHandlerStubTest : public testing::Test { 428 public: 429 NetworkConfigurationHandlerStubTest() { 430 } 431 432 virtual ~NetworkConfigurationHandlerStubTest() { 433 } 434 435 virtual void SetUp() OVERRIDE { 436 DBusThreadManager::InitializeWithStub(); 437 438 network_state_handler_.reset(NetworkStateHandler::InitializeForTest()); 439 test_observer_.reset(new TestObserver()); 440 network_state_handler_->AddObserver(test_observer_.get(), FROM_HERE); 441 442 network_configuration_handler_.reset(new NetworkConfigurationHandler()); 443 network_configuration_handler_->Init(network_state_handler_.get()); 444 445 message_loop_.RunUntilIdle(); 446 test_observer_->ClearPropertyUpdates(); 447 } 448 449 virtual void TearDown() OVERRIDE { 450 network_configuration_handler_.reset(); 451 network_state_handler_->RemoveObserver(test_observer_.get(), FROM_HERE); 452 network_state_handler_.reset(); 453 DBusThreadManager::Shutdown(); 454 } 455 456 void SuccessCallback(const std::string& callback_name) { 457 success_callback_name_ = callback_name; 458 } 459 460 void GetPropertiesCallback(const std::string& service_path, 461 const base::DictionaryValue& dictionary) { 462 get_properties_path_ = service_path; 463 get_properties_.reset(dictionary.DeepCopy()); 464 } 465 466 void CreateConfigurationCallback(const std::string& service_path) { 467 create_service_path_ = service_path; 468 } 469 470 protected: 471 bool GetServiceStringProperty(const std::string& service_path, 472 const std::string& key, 473 std::string* result) { 474 ShillServiceClient::TestInterface* service_test = 475 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 476 const base::DictionaryValue* properties = 477 service_test->GetServiceProperties(service_path); 478 if (properties && properties->GetStringWithoutPathExpansion(key, result)) 479 return true; 480 return false; 481 } 482 483 bool GetReceivedStringProperty(const std::string& service_path, 484 const std::string& key, 485 std::string* result) { 486 if (get_properties_path_ != service_path) 487 return false; 488 if (get_properties_ && 489 get_properties_->GetStringWithoutPathExpansion(key, result)) 490 return true; 491 return false; 492 } 493 494 scoped_ptr<NetworkStateHandler> network_state_handler_; 495 scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_; 496 scoped_ptr<TestObserver> test_observer_; 497 base::MessageLoopForUI message_loop_; 498 std::string success_callback_name_; 499 std::string get_properties_path_; 500 scoped_ptr<DictionaryValue> get_properties_; 501 std::string create_service_path_; 502 }; 503 504 TEST_F(NetworkConfigurationHandlerStubTest, StubSetAndClearProperties) { 505 // TODO(stevenjb): Remove dependency on default Stub service. 506 const std::string service_path("wifi1"); 507 const std::string test_identity("test_identity"); 508 const std::string test_passphrase("test_passphrase"); 509 510 // Set Properties 511 base::DictionaryValue properties_to_set; 512 properties_to_set.SetStringWithoutPathExpansion( 513 shill::kIdentityProperty, test_identity); 514 properties_to_set.SetStringWithoutPathExpansion( 515 shill::kPassphraseProperty, test_passphrase); 516 network_configuration_handler_->SetProperties( 517 service_path, 518 properties_to_set, 519 base::Bind( 520 &NetworkConfigurationHandlerStubTest::SuccessCallback, 521 base::Unretained(this), "SetProperties"), 522 base::Bind(&ErrorCallback, false, service_path)); 523 message_loop_.RunUntilIdle(); 524 525 EXPECT_EQ("SetProperties", success_callback_name_); 526 std::string identity, passphrase; 527 EXPECT_TRUE(GetServiceStringProperty( 528 service_path, shill::kIdentityProperty, &identity)); 529 EXPECT_TRUE(GetServiceStringProperty( 530 service_path, shill::kPassphraseProperty, &passphrase)); 531 EXPECT_EQ(test_identity, identity); 532 EXPECT_EQ(test_passphrase, passphrase); 533 EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(service_path)); 534 535 // Clear Properties 536 std::vector<std::string> properties_to_clear; 537 properties_to_clear.push_back(shill::kIdentityProperty); 538 properties_to_clear.push_back(shill::kPassphraseProperty); 539 network_configuration_handler_->ClearProperties( 540 service_path, 541 properties_to_clear, 542 base::Bind( 543 &NetworkConfigurationHandlerStubTest::SuccessCallback, 544 base::Unretained(this), "ClearProperties"), 545 base::Bind(&ErrorCallback, false, service_path)); 546 message_loop_.RunUntilIdle(); 547 548 EXPECT_EQ("ClearProperties", success_callback_name_); 549 EXPECT_FALSE(GetServiceStringProperty( 550 service_path, shill::kIdentityProperty, &identity)); 551 EXPECT_FALSE(GetServiceStringProperty( 552 service_path, shill::kIdentityProperty, &passphrase)); 553 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(service_path)); 554 } 555 556 TEST_F(NetworkConfigurationHandlerStubTest, StubGetNameFromWifiHex) { 557 // TODO(stevenjb): Remove dependency on default Stub service. 558 const std::string service_path("wifi1"); 559 std::string wifi_hex = "5468697320697320484558205353494421"; 560 std::string expected_name = "This is HEX SSID!"; 561 562 // Set Properties 563 base::DictionaryValue properties_to_set; 564 properties_to_set.SetStringWithoutPathExpansion( 565 shill::kWifiHexSsid, wifi_hex); 566 network_configuration_handler_->SetProperties( 567 service_path, 568 properties_to_set, 569 base::Bind(&base::DoNothing), 570 base::Bind(&ErrorCallback, false, service_path)); 571 message_loop_.RunUntilIdle(); 572 std::string wifi_hex_result; 573 EXPECT_TRUE(GetServiceStringProperty( 574 service_path, shill::kWifiHexSsid, &wifi_hex_result)); 575 EXPECT_EQ(wifi_hex, wifi_hex_result); 576 577 // Get Properties 578 network_configuration_handler_->GetProperties( 579 service_path, 580 base::Bind(&NetworkConfigurationHandlerStubTest::GetPropertiesCallback, 581 base::Unretained(this)), 582 base::Bind(&ErrorCallback, false, service_path)); 583 message_loop_.RunUntilIdle(); 584 585 EXPECT_EQ(service_path, get_properties_path_); 586 std::string name_result; 587 EXPECT_TRUE(GetReceivedStringProperty( 588 service_path, shill::kNameProperty, &name_result)); 589 EXPECT_EQ(expected_name, name_result); 590 } 591 592 TEST_F(NetworkConfigurationHandlerStubTest, StubCreateConfiguration) { 593 const std::string service_path("test_wifi"); 594 base::DictionaryValue properties; 595 shill_property_util::SetSSID(service_path, &properties); 596 properties.SetStringWithoutPathExpansion(shill::kNameProperty, service_path); 597 properties.SetStringWithoutPathExpansion(shill::kGuidProperty, service_path); 598 properties.SetStringWithoutPathExpansion( 599 shill::kTypeProperty, shill::kTypeWifi); 600 properties.SetStringWithoutPathExpansion( 601 shill::kStateProperty, shill::kStateIdle); 602 properties.SetStringWithoutPathExpansion( 603 shill::kProfileProperty, shill_stub_helper::kSharedProfilePath); 604 605 network_configuration_handler_->CreateConfiguration( 606 properties, 607 base::Bind( 608 &NetworkConfigurationHandlerStubTest::CreateConfigurationCallback, 609 base::Unretained(this)), 610 base::Bind(&ErrorCallback, false, service_path)); 611 message_loop_.RunUntilIdle(); 612 613 EXPECT_FALSE(create_service_path_.empty()); 614 615 std::string guid; 616 EXPECT_TRUE(GetServiceStringProperty( 617 create_service_path_, shill::kGuidProperty, &guid)); 618 EXPECT_EQ(service_path, guid); 619 620 std::string actual_profile; 621 EXPECT_TRUE(GetServiceStringProperty( 622 create_service_path_, shill::kProfileProperty, &actual_profile)); 623 EXPECT_EQ(shill_stub_helper::kSharedProfilePath, actual_profile); 624 } 625 626 } // namespace chromeos 627