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 "chromeos/network/network_state_handler.h"
      6 
      7 #include <map>
      8 #include <set>
      9 #include <string>
     10 
     11 #include "base/bind.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/message_loop/message_loop.h"
     14 #include "base/values.h"
     15 #include "chromeos/dbus/dbus_thread_manager.h"
     16 #include "chromeos/dbus/shill_device_client.h"
     17 #include "chromeos/dbus/shill_manager_client.h"
     18 #include "chromeos/dbus/shill_profile_client.h"
     19 #include "chromeos/dbus/shill_service_client.h"
     20 #include "chromeos/network/network_state.h"
     21 #include "chromeos/network/network_state_handler_observer.h"
     22 #include "chromeos/network/shill_property_util.h"
     23 #include "dbus/object_path.h"
     24 #include "testing/gtest/include/gtest/gtest.h"
     25 #include "third_party/cros_system_api/dbus/service_constants.h"
     26 
     27 namespace {
     28 
     29 void ErrorCallbackFunction(const std::string& error_name,
     30                            const std::string& error_message) {
     31   LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
     32 }
     33 
     34 const std::string kShillManagerClientStubDefaultService = "eth1";
     35 const std::string kShillManagerClientStubDefaultWireless = "wifi1";
     36 const std::string kShillManagerClientStubWireless2 = "wifi2";
     37 const std::string kShillManagerClientStubCellular = "cellular1";
     38 
     39 using chromeos::NetworkState;
     40 using chromeos::NetworkStateHandler;
     41 
     42 class TestObserver : public chromeos::NetworkStateHandlerObserver {
     43  public:
     44   explicit TestObserver(NetworkStateHandler* handler)
     45       : handler_(handler),
     46         device_list_changed_count_(0),
     47         network_count_(0),
     48         default_network_change_count_(0),
     49         favorite_count_(0) {
     50   }
     51 
     52   virtual ~TestObserver() {
     53   }
     54 
     55   virtual void DeviceListChanged() OVERRIDE {
     56     ++device_list_changed_count_;
     57   }
     58 
     59   virtual void NetworkListChanged() OVERRIDE {
     60     NetworkStateHandler::NetworkStateList networks;
     61     handler_->GetNetworkList(&networks);
     62     network_count_ = networks.size();
     63     if (network_count_ == 0) {
     64       default_network_ = "";
     65       default_network_connection_state_ = "";
     66     }
     67     NetworkStateHandler::FavoriteStateList favorites;
     68     handler_->GetFavoriteList(&favorites);
     69     favorite_count_ = favorites.size();
     70   }
     71 
     72   virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE {
     73     ++default_network_change_count_;
     74     default_network_ = network ? network->path() : "";
     75     default_network_connection_state_ =
     76         network ?  network->connection_state() : "";
     77   }
     78 
     79   virtual void NetworkConnectionStateChanged(
     80       const NetworkState* network) OVERRIDE {
     81     network_connection_state_[network->path()] = network->connection_state();
     82     connection_state_changes_[network->path()]++;
     83   }
     84 
     85   virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE {
     86     DCHECK(network);
     87     property_updates_[network->path()]++;
     88   }
     89 
     90   size_t device_list_changed_count() { return device_list_changed_count_; }
     91   size_t network_count() { return network_count_; }
     92   size_t default_network_change_count() {
     93     return default_network_change_count_;
     94   }
     95   std::string default_network() { return default_network_; }
     96   std::string default_network_connection_state() {
     97     return default_network_connection_state_;
     98   }
     99   size_t favorite_count() { return favorite_count_; }
    100 
    101   int PropertyUpdatesForService(const std::string& service_path) {
    102     return property_updates_[service_path];
    103   }
    104 
    105   int ConnectionStateChangesForService(const std::string& service_path) {
    106     return connection_state_changes_[service_path];
    107   }
    108 
    109   std::string NetworkConnectionStateForService(
    110       const std::string& service_path) {
    111     return network_connection_state_[service_path];
    112   }
    113 
    114  private:
    115   NetworkStateHandler* handler_;
    116   size_t device_list_changed_count_;
    117   size_t network_count_;
    118   size_t default_network_change_count_;
    119   std::string default_network_;
    120   std::string default_network_connection_state_;
    121   size_t favorite_count_;
    122   std::map<std::string, int> property_updates_;
    123   std::map<std::string, int> connection_state_changes_;
    124   std::map<std::string, std::string> network_connection_state_;
    125 
    126   DISALLOW_COPY_AND_ASSIGN(TestObserver);
    127 };
    128 
    129 }  // namespace
    130 
    131 namespace chromeos {
    132 
    133 class NetworkStateHandlerTest : public testing::Test {
    134  public:
    135   NetworkStateHandlerTest() {}
    136   virtual ~NetworkStateHandlerTest() {}
    137 
    138   virtual void SetUp() OVERRIDE {
    139     // Initialize DBusThreadManager with a stub implementation.
    140     DBusThreadManager::InitializeWithStub();
    141     SetupNetworkStateHandler();
    142     message_loop_.RunUntilIdle();
    143   }
    144 
    145   virtual void TearDown() OVERRIDE {
    146     network_state_handler_->RemoveObserver(test_observer_.get(), FROM_HERE);
    147     test_observer_.reset();
    148     network_state_handler_.reset();
    149     DBusThreadManager::Shutdown();
    150   }
    151 
    152   void SetupNetworkStateHandler() {
    153     SetupDefaultShillState();
    154     network_state_handler_.reset(new NetworkStateHandler);
    155     test_observer_.reset(new TestObserver(network_state_handler_.get()));
    156     network_state_handler_->AddObserver(test_observer_.get(), FROM_HERE);
    157     network_state_handler_->InitShillPropertyHandler();
    158   }
    159 
    160  protected:
    161   void SetupDefaultShillState() {
    162     message_loop_.RunUntilIdle();  // Process any pending updates
    163     ShillDeviceClient::TestInterface* device_test =
    164         DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
    165     device_test->ClearDevices();
    166     device_test->AddDevice("/device/stub_wifi_device1",
    167                            shill::kTypeWifi, "stub_wifi_device1");
    168     device_test->AddDevice("/device/stub_cellular_device1",
    169                            shill::kTypeCellular, "stub_cellular_device1");
    170 
    171     ShillServiceClient::TestInterface* service_test =
    172         DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
    173     service_test->ClearServices();
    174     const bool add_to_visible = true;
    175     const bool add_to_watchlist = true;
    176     service_test->AddService(kShillManagerClientStubDefaultService,
    177                              kShillManagerClientStubDefaultService,
    178                              shill::kTypeEthernet, shill::kStateOnline,
    179                              add_to_visible, add_to_watchlist);
    180     service_test->AddService(kShillManagerClientStubDefaultWireless,
    181                              kShillManagerClientStubDefaultWireless,
    182                              shill::kTypeWifi, shill::kStateOnline,
    183                              add_to_visible, add_to_watchlist);
    184     service_test->AddService(kShillManagerClientStubWireless2,
    185                              kShillManagerClientStubWireless2,
    186                              shill::kTypeWifi, shill::kStateIdle,
    187                              add_to_visible, add_to_watchlist);
    188     service_test->AddService(kShillManagerClientStubCellular,
    189                              kShillManagerClientStubCellular,
    190                              shill::kTypeCellular, shill::kStateIdle,
    191                              add_to_visible, add_to_watchlist);
    192   }
    193 
    194   base::MessageLoopForUI message_loop_;
    195   scoped_ptr<NetworkStateHandler> network_state_handler_;
    196   scoped_ptr<TestObserver> test_observer_;
    197 
    198  private:
    199   DISALLOW_COPY_AND_ASSIGN(NetworkStateHandlerTest);
    200 };
    201 
    202 TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStub) {
    203   // Ensure that the network list is the expected size.
    204   const size_t kNumShillManagerClientStubImplServices = 4;
    205   EXPECT_EQ(kNumShillManagerClientStubImplServices,
    206             test_observer_->network_count());
    207   // Ensure that the first stub network is the default network.
    208   EXPECT_EQ(kShillManagerClientStubDefaultService,
    209             test_observer_->default_network());
    210   EXPECT_EQ(kShillManagerClientStubDefaultService,
    211             network_state_handler_->ConnectedNetworkByType(
    212                 NetworkTypePattern::Default())->path());
    213   EXPECT_EQ(kShillManagerClientStubDefaultService,
    214             network_state_handler_->ConnectedNetworkByType(
    215                 NetworkTypePattern::Ethernet())->path());
    216   EXPECT_EQ(kShillManagerClientStubDefaultWireless,
    217             network_state_handler_->ConnectedNetworkByType(
    218                 NetworkTypePattern::Wireless())->path());
    219   EXPECT_EQ(kShillManagerClientStubCellular,
    220             network_state_handler_->FirstNetworkByType(
    221                 NetworkTypePattern::Mobile())->path());
    222   EXPECT_EQ(
    223       kShillManagerClientStubCellular,
    224       network_state_handler_->FirstNetworkByType(NetworkTypePattern::Cellular())
    225           ->path());
    226   EXPECT_EQ(shill::kStateOnline,
    227             test_observer_->default_network_connection_state());
    228 }
    229 
    230 TEST_F(NetworkStateHandlerTest, TechnologyChanged) {
    231   // There may be several manager changes during initialization.
    232   size_t initial_changed_count = test_observer_->device_list_changed_count();
    233   // Disable a technology.
    234   network_state_handler_->SetTechnologyEnabled(
    235       NetworkTypePattern::Wimax(), false, network_handler::ErrorCallback());
    236   EXPECT_NE(
    237       NetworkStateHandler::TECHNOLOGY_ENABLED,
    238       network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));
    239   EXPECT_EQ(initial_changed_count + 1,
    240             test_observer_->device_list_changed_count());
    241   // Enable a technology.
    242   network_state_handler_->SetTechnologyEnabled(
    243       NetworkTypePattern::Wimax(), true, network_handler::ErrorCallback());
    244   // The technology state should immediately change to ENABLING and we should
    245   // receive a manager changed callback.
    246   EXPECT_EQ(initial_changed_count + 2,
    247             test_observer_->device_list_changed_count());
    248   EXPECT_EQ(
    249       NetworkStateHandler::TECHNOLOGY_ENABLING,
    250       network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));
    251   message_loop_.RunUntilIdle();
    252   // Ensure we receive 2 manager changed callbacks when the technology becomes
    253   // avalable and enabled.
    254   EXPECT_EQ(initial_changed_count + 4,
    255             test_observer_->device_list_changed_count());
    256   EXPECT_EQ(
    257       NetworkStateHandler::TECHNOLOGY_ENABLED,
    258       network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));
    259 }
    260 
    261 TEST_F(NetworkStateHandlerTest, TechnologyState) {
    262   ShillManagerClient::TestInterface* manager_test =
    263       DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
    264   manager_test->RemoveTechnology(shill::kTypeWimax);
    265   message_loop_.RunUntilIdle();
    266   EXPECT_EQ(
    267       NetworkStateHandler::TECHNOLOGY_UNAVAILABLE,
    268       network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));
    269 
    270   manager_test->AddTechnology(shill::kTypeWimax, false);
    271   message_loop_.RunUntilIdle();
    272   EXPECT_EQ(
    273       NetworkStateHandler::TECHNOLOGY_AVAILABLE,
    274       network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));
    275 
    276   manager_test->SetTechnologyInitializing(shill::kTypeWimax, true);
    277   message_loop_.RunUntilIdle();
    278   EXPECT_EQ(
    279       NetworkStateHandler::TECHNOLOGY_UNINITIALIZED,
    280       network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));
    281 
    282   manager_test->SetTechnologyInitializing(shill::kTypeWimax, false);
    283   network_state_handler_->SetTechnologyEnabled(
    284       NetworkTypePattern::Wimax(), true, network_handler::ErrorCallback());
    285   message_loop_.RunUntilIdle();
    286   EXPECT_EQ(
    287       NetworkStateHandler::TECHNOLOGY_ENABLED,
    288       network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));
    289 
    290   manager_test->RemoveTechnology(shill::kTypeWimax);
    291   message_loop_.RunUntilIdle();
    292   EXPECT_EQ(
    293       NetworkStateHandler::TECHNOLOGY_UNAVAILABLE,
    294       network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));
    295 }
    296 
    297 TEST_F(NetworkStateHandlerTest, ServicePropertyChanged) {
    298   // Set a service property.
    299   const std::string eth1 = kShillManagerClientStubDefaultService;
    300   EXPECT_EQ("", network_state_handler_->GetNetworkState(eth1)->security());
    301   EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth1));
    302   base::StringValue security_value("TestSecurity");
    303   DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
    304       dbus::ObjectPath(eth1),
    305       shill::kSecurityProperty, security_value,
    306       base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
    307   message_loop_.RunUntilIdle();
    308   EXPECT_EQ("TestSecurity",
    309             network_state_handler_->GetNetworkState(eth1)->security());
    310   EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth1));
    311 
    312   // Changing a service to the existing value should not trigger an update.
    313   DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
    314       dbus::ObjectPath(eth1),
    315       shill::kSecurityProperty, security_value,
    316       base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
    317   message_loop_.RunUntilIdle();
    318   EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth1));
    319 }
    320 
    321 TEST_F(NetworkStateHandlerTest, FavoriteState) {
    322   // Set the profile entry of a service
    323   const std::string wifi1 = kShillManagerClientStubDefaultWireless;
    324   ShillProfileClient::TestInterface* profile_test =
    325       DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
    326   EXPECT_TRUE(profile_test->AddService("/profile/default", wifi1));
    327   message_loop_.RunUntilIdle();
    328   network_state_handler_->UpdateManagerProperties();
    329   message_loop_.RunUntilIdle();
    330   EXPECT_EQ(1u, test_observer_->favorite_count());
    331 }
    332 
    333 TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) {
    334   // Change a network state.
    335   ShillServiceClient::TestInterface* service_test =
    336       DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
    337   const std::string eth1 = kShillManagerClientStubDefaultService;
    338   base::StringValue connection_state_idle_value(shill::kStateIdle);
    339   service_test->SetServiceProperty(eth1, shill::kStateProperty,
    340                                    connection_state_idle_value);
    341   message_loop_.RunUntilIdle();
    342   EXPECT_EQ(shill::kStateIdle,
    343             test_observer_->NetworkConnectionStateForService(eth1));
    344   EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth1));
    345   // Confirm that changing the connection state to the same value does *not*
    346   // signal the observer.
    347   service_test->SetServiceProperty(eth1, shill::kStateProperty,
    348                                    connection_state_idle_value);
    349   message_loop_.RunUntilIdle();
    350   EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth1));
    351 }
    352 
    353 TEST_F(NetworkStateHandlerTest, DefaultServiceChanged) {
    354   ShillManagerClient::TestInterface* manager_test =
    355       DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
    356   ASSERT_TRUE(manager_test);
    357   ShillServiceClient::TestInterface* service_test =
    358       DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
    359   ASSERT_TRUE(service_test);
    360 
    361   // Change the default network by  changing the state of eth1 to Idle which
    362   // should re-sort Manager.Services.
    363   const std::string eth1 = kShillManagerClientStubDefaultService;
    364   const std::string wifi1 = kShillManagerClientStubDefaultWireless;
    365   base::StringValue connection_state_idle_value(shill::kStateIdle);
    366   service_test->SetServiceProperty(eth1, shill::kStateProperty,
    367                                    connection_state_idle_value);
    368   message_loop_.RunUntilIdle();
    369   EXPECT_EQ(wifi1, test_observer_->default_network());
    370   EXPECT_EQ(shill::kStateOnline,
    371             test_observer_->default_network_connection_state());
    372   // We should have seen 2 default network updates - for the default
    373   // service change, and for the state change.
    374   EXPECT_EQ(2u, test_observer_->default_network_change_count());
    375 
    376   // Updating a property on the default network should trigger
    377   // a default network change.
    378   DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
    379       dbus::ObjectPath(wifi1),
    380       shill::kSecurityProperty, base::StringValue("TestSecurity"),
    381       base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
    382   message_loop_.RunUntilIdle();
    383   EXPECT_EQ(3u, test_observer_->default_network_change_count());
    384 
    385   // No default network updates for signal strength changes.
    386   DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
    387       dbus::ObjectPath(wifi1),
    388       shill::kSignalStrengthProperty, base::FundamentalValue(32),
    389       base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
    390   message_loop_.RunUntilIdle();
    391   EXPECT_EQ(3u, test_observer_->default_network_change_count());
    392 }
    393 
    394 TEST_F(NetworkStateHandlerTest, RequestUpdate) {
    395   // Request an update for kShillManagerClientStubDefaultWireless.
    396   EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(
    397       kShillManagerClientStubDefaultWireless));
    398   network_state_handler_->RequestUpdateForNetwork(
    399       kShillManagerClientStubDefaultWireless);
    400   message_loop_.RunUntilIdle();
    401   EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(
    402       kShillManagerClientStubDefaultWireless));
    403 
    404   // Request an update for all networks.
    405   network_state_handler_->RequestUpdateForAllNetworks();
    406   message_loop_.RunUntilIdle();
    407   // kShillManagerClientStubDefaultWireless should now have 3 updates
    408   EXPECT_EQ(3, test_observer_->PropertyUpdatesForService(
    409       kShillManagerClientStubDefaultWireless));
    410   // Other networks should have 2 updates (inital + request).
    411   EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(
    412       kShillManagerClientStubDefaultService));
    413   EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(
    414       kShillManagerClientStubWireless2));
    415   EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(
    416       kShillManagerClientStubCellular));
    417 }
    418 
    419 }  // namespace chromeos
    420