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/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/network/network_configuration_handler.h"
     16 #include "chromeos/network/network_profile_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 type = "wifi";
    350   std::string profile = "profile path";
    351   base::DictionaryValue value;
    352   shill_property_util::SetSSID(networkName, &value);
    353   value.SetWithoutPathExpansion(shill::kTypeProperty,
    354                                 base::Value::CreateStringValue(type));
    355   value.SetWithoutPathExpansion(shill::kProfileProperty,
    356                                 base::Value::CreateStringValue(profile));
    357 
    358   EXPECT_CALL(*mock_manager_client_,
    359               ConfigureServiceForProfile(dbus::ObjectPath(profile), _, _, _))
    360       .WillOnce(
    361            Invoke(this, &NetworkConfigurationHandlerTest::OnConfigureService));
    362   network_configuration_handler_->CreateConfiguration(
    363       value,
    364       base::Bind(&StringResultCallback, std::string("/service/2")),
    365       base::Bind(&ErrorCallback, false, std::string()));
    366   message_loop_.RunUntilIdle();
    367 }
    368 
    369 TEST_F(NetworkConfigurationHandlerTest, RemoveConfiguration) {
    370   std::string service_path = "/service/1";
    371 
    372   TestCallback test_callback;
    373   EXPECT_CALL(
    374       *mock_service_client_,
    375       GetLoadableProfileEntries(_, _)).WillOnce(Invoke(
    376           this,
    377           &NetworkConfigurationHandlerTest::OnGetLoadableProfileEntries));
    378   EXPECT_CALL(
    379       *mock_profile_client_,
    380       DeleteEntry(_, _, _, _)).WillRepeatedly(Invoke(
    381           this,
    382           &NetworkConfigurationHandlerTest::OnDeleteEntry));
    383 
    384   network_configuration_handler_->RemoveConfiguration(
    385       service_path,
    386       base::Bind(&TestCallback::Run, base::Unretained(&test_callback)),
    387       base::Bind(&ErrorCallback, false, service_path));
    388   message_loop_.RunUntilIdle();
    389   EXPECT_EQ(1, test_callback.run_count());
    390   EXPECT_FALSE(PendingProfileEntryDeleterForTest(service_path));
    391 }
    392 
    393 ////////////////////////////////////////////////////////////////////////////////
    394 // Stub based tests
    395 
    396 namespace {
    397 
    398 class TestObserver : public chromeos::NetworkStateHandlerObserver {
    399  public:
    400   TestObserver() : network_list_changed_count_(0) {}
    401   virtual ~TestObserver() {}
    402 
    403   virtual void NetworkListChanged() OVERRIDE {
    404     ++network_list_changed_count_;
    405   }
    406 
    407   virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE {
    408     property_updates_[network->path()]++;
    409   }
    410 
    411   size_t network_list_changed_count() { return network_list_changed_count_; }
    412 
    413   int PropertyUpdatesForService(const std::string& service_path) {
    414     return property_updates_[service_path];
    415   }
    416 
    417   void ClearPropertyUpdates() {
    418     property_updates_.clear();
    419   }
    420 
    421  private:
    422   size_t network_list_changed_count_;
    423   std::map<std::string, int> property_updates_;
    424 
    425   DISALLOW_COPY_AND_ASSIGN(TestObserver);
    426 };
    427 
    428 }  // namespace
    429 
    430 class NetworkConfigurationHandlerStubTest : public testing::Test {
    431  public:
    432   NetworkConfigurationHandlerStubTest()  {
    433   }
    434 
    435   virtual ~NetworkConfigurationHandlerStubTest() {
    436   }
    437 
    438   virtual void SetUp() OVERRIDE {
    439     DBusThreadManager::InitializeWithStub();
    440 
    441     network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
    442     test_observer_.reset(new TestObserver());
    443     network_state_handler_->AddObserver(test_observer_.get(), FROM_HERE);
    444 
    445     network_configuration_handler_.reset(new NetworkConfigurationHandler());
    446     network_configuration_handler_->Init(network_state_handler_.get());
    447 
    448     message_loop_.RunUntilIdle();
    449     test_observer_->ClearPropertyUpdates();
    450   }
    451 
    452   virtual void TearDown() OVERRIDE {
    453     network_configuration_handler_.reset();
    454     network_state_handler_->RemoveObserver(test_observer_.get(), FROM_HERE);
    455     network_state_handler_.reset();
    456     DBusThreadManager::Shutdown();
    457   }
    458 
    459   void SuccessCallback(const std::string& callback_name) {
    460     success_callback_name_ = callback_name;
    461   }
    462 
    463   void GetPropertiesCallback(const std::string& service_path,
    464                              const base::DictionaryValue& dictionary) {
    465     get_properties_path_ = service_path;
    466     get_properties_.reset(dictionary.DeepCopy());
    467   }
    468 
    469   void CreateConfigurationCallback(const std::string& service_path) {
    470     create_service_path_ = service_path;
    471   }
    472 
    473  protected:
    474   bool GetServiceStringProperty(const std::string& service_path,
    475                                 const std::string& key,
    476                                 std::string* result) {
    477     ShillServiceClient::TestInterface* service_test =
    478         DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
    479     const base::DictionaryValue* properties =
    480         service_test->GetServiceProperties(service_path);
    481     if (properties && properties->GetStringWithoutPathExpansion(key, result))
    482       return true;
    483     return false;
    484   }
    485 
    486   bool GetReceivedStringProperty(const std::string& service_path,
    487                                  const std::string& key,
    488                                  std::string* result) {
    489     if (get_properties_path_ != service_path)
    490       return false;
    491     if (get_properties_ &&
    492         get_properties_->GetStringWithoutPathExpansion(key, result))
    493       return true;
    494     return false;
    495   }
    496 
    497   scoped_ptr<NetworkStateHandler> network_state_handler_;
    498   scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_;
    499   scoped_ptr<TestObserver> test_observer_;
    500   base::MessageLoopForUI message_loop_;
    501   std::string success_callback_name_;
    502   std::string get_properties_path_;
    503   scoped_ptr<base::DictionaryValue> get_properties_;
    504   std::string create_service_path_;
    505 };
    506 
    507 TEST_F(NetworkConfigurationHandlerStubTest, StubSetAndClearProperties) {
    508   // TODO(stevenjb): Remove dependency on default Stub service.
    509   const std::string service_path("/service/wifi1");
    510   const std::string test_identity("test_identity");
    511   const std::string test_passphrase("test_passphrase");
    512 
    513   // Set Properties
    514   base::DictionaryValue properties_to_set;
    515   properties_to_set.SetStringWithoutPathExpansion(
    516       shill::kIdentityProperty, test_identity);
    517   properties_to_set.SetStringWithoutPathExpansion(
    518       shill::kPassphraseProperty, test_passphrase);
    519   network_configuration_handler_->SetProperties(
    520       service_path,
    521       properties_to_set,
    522       base::Bind(
    523           &NetworkConfigurationHandlerStubTest::SuccessCallback,
    524           base::Unretained(this), "SetProperties"),
    525       base::Bind(&ErrorCallback, false, service_path));
    526   message_loop_.RunUntilIdle();
    527 
    528   EXPECT_EQ("SetProperties", success_callback_name_);
    529   std::string identity, passphrase;
    530   EXPECT_TRUE(GetServiceStringProperty(
    531       service_path, shill::kIdentityProperty, &identity));
    532   EXPECT_TRUE(GetServiceStringProperty(
    533       service_path, shill::kPassphraseProperty, &passphrase));
    534   EXPECT_EQ(test_identity, identity);
    535   EXPECT_EQ(test_passphrase, passphrase);
    536   EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(service_path));
    537 
    538   // Clear Properties
    539   std::vector<std::string> properties_to_clear;
    540   properties_to_clear.push_back(shill::kIdentityProperty);
    541   properties_to_clear.push_back(shill::kPassphraseProperty);
    542   network_configuration_handler_->ClearProperties(
    543       service_path,
    544       properties_to_clear,
    545       base::Bind(
    546           &NetworkConfigurationHandlerStubTest::SuccessCallback,
    547           base::Unretained(this), "ClearProperties"),
    548       base::Bind(&ErrorCallback, false, service_path));
    549   message_loop_.RunUntilIdle();
    550 
    551   EXPECT_EQ("ClearProperties", success_callback_name_);
    552   EXPECT_FALSE(GetServiceStringProperty(
    553       service_path, shill::kIdentityProperty, &identity));
    554   EXPECT_FALSE(GetServiceStringProperty(
    555       service_path, shill::kIdentityProperty, &passphrase));
    556   EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(service_path));
    557 }
    558 
    559 TEST_F(NetworkConfigurationHandlerStubTest, StubGetNameFromWifiHex) {
    560   // TODO(stevenjb): Remove dependency on default Stub service.
    561   const std::string service_path("/service/wifi1");
    562   std::string wifi_hex = "5468697320697320484558205353494421";
    563   std::string expected_name = "This is HEX SSID!";
    564 
    565   // Set Properties
    566   base::DictionaryValue properties_to_set;
    567   properties_to_set.SetStringWithoutPathExpansion(
    568       shill::kWifiHexSsid, wifi_hex);
    569   network_configuration_handler_->SetProperties(
    570       service_path,
    571       properties_to_set,
    572       base::Bind(&base::DoNothing),
    573       base::Bind(&ErrorCallback, false, service_path));
    574   message_loop_.RunUntilIdle();
    575   std::string wifi_hex_result;
    576   EXPECT_TRUE(GetServiceStringProperty(
    577       service_path, shill::kWifiHexSsid, &wifi_hex_result));
    578   EXPECT_EQ(wifi_hex, wifi_hex_result);
    579 
    580   // Get Properties
    581   network_configuration_handler_->GetProperties(
    582       service_path,
    583       base::Bind(&NetworkConfigurationHandlerStubTest::GetPropertiesCallback,
    584                  base::Unretained(this)),
    585       base::Bind(&ErrorCallback, false, service_path));
    586   message_loop_.RunUntilIdle();
    587 
    588   EXPECT_EQ(service_path, get_properties_path_);
    589   std::string name_result;
    590   EXPECT_TRUE(GetReceivedStringProperty(
    591       service_path, shill::kNameProperty, &name_result));
    592   EXPECT_EQ(expected_name, name_result);
    593 }
    594 
    595 TEST_F(NetworkConfigurationHandlerStubTest, StubCreateConfiguration) {
    596   const std::string service_path("/service/test_wifi");
    597   base::DictionaryValue properties;
    598   shill_property_util::SetSSID(service_path, &properties);
    599   properties.SetStringWithoutPathExpansion(shill::kNameProperty, service_path);
    600   properties.SetStringWithoutPathExpansion(shill::kGuidProperty, service_path);
    601   properties.SetStringWithoutPathExpansion(
    602       shill::kTypeProperty, shill::kTypeWifi);
    603   properties.SetStringWithoutPathExpansion(
    604       shill::kStateProperty, shill::kStateIdle);
    605   properties.SetStringWithoutPathExpansion(
    606       shill::kProfileProperty, NetworkProfileHandler::GetSharedProfilePath());
    607 
    608   network_configuration_handler_->CreateConfiguration(
    609       properties,
    610       base::Bind(
    611           &NetworkConfigurationHandlerStubTest::CreateConfigurationCallback,
    612           base::Unretained(this)),
    613       base::Bind(&ErrorCallback, false, service_path));
    614   message_loop_.RunUntilIdle();
    615 
    616   EXPECT_FALSE(create_service_path_.empty());
    617 
    618   std::string guid;
    619   EXPECT_TRUE(GetServiceStringProperty(
    620       create_service_path_, shill::kGuidProperty, &guid));
    621   EXPECT_EQ(service_path, guid);
    622 
    623   std::string actual_profile;
    624   EXPECT_TRUE(GetServiceStringProperty(
    625       create_service_path_, shill::kProfileProperty, &actual_profile));
    626   EXPECT_EQ(NetworkProfileHandler::GetSharedProfilePath(), actual_profile);
    627 }
    628 
    629 }  // namespace chromeos
    630