Home | History | Annotate | Download | only in network
      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