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