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