network_state_handler_unittest.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
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 27namespace { 28 29void ErrorCallbackFunction(const std::string& error_name, 30 const std::string& error_message) { 31 LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message; 32} 33 34const std::string kShillManagerClientStubDefaultService = "eth1"; 35const std::string kShillManagerClientStubDefaultWireless = "wifi1"; 36const std::string kShillManagerClientStubWireless2 = "wifi2"; 37const std::string kShillManagerClientStubCellular = "cellular1"; 38 39using chromeos::NetworkState; 40using chromeos::NetworkStateHandler; 41 42class 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 DVLOG(1) << "DefaultNetworkChanged: " << default_network_ 78 << " State: " << default_network_connection_state_; 79 } 80 81 virtual void NetworkConnectionStateChanged( 82 const NetworkState* network) OVERRIDE { 83 network_connection_state_[network->path()] = network->connection_state(); 84 connection_state_changes_[network->path()]++; 85 } 86 87 virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE { 88 DCHECK(network); 89 property_updates_[network->path()]++; 90 } 91 92 size_t device_list_changed_count() { return device_list_changed_count_; } 93 size_t network_count() { return network_count_; } 94 size_t default_network_change_count() { 95 return default_network_change_count_; 96 } 97 void reset_network_change_count() { 98 DVLOG(1) << "ResetNetworkChangeCount"; 99 default_network_change_count_ = 0; 100 } 101 std::string default_network() { return default_network_; } 102 std::string default_network_connection_state() { 103 return default_network_connection_state_; 104 } 105 size_t favorite_count() { return favorite_count_; } 106 107 int PropertyUpdatesForService(const std::string& service_path) { 108 return property_updates_[service_path]; 109 } 110 111 int ConnectionStateChangesForService(const std::string& service_path) { 112 return connection_state_changes_[service_path]; 113 } 114 115 std::string NetworkConnectionStateForService( 116 const std::string& service_path) { 117 return network_connection_state_[service_path]; 118 } 119 120 private: 121 NetworkStateHandler* handler_; 122 size_t device_list_changed_count_; 123 size_t network_count_; 124 size_t default_network_change_count_; 125 std::string default_network_; 126 std::string default_network_connection_state_; 127 size_t favorite_count_; 128 std::map<std::string, int> property_updates_; 129 std::map<std::string, int> connection_state_changes_; 130 std::map<std::string, std::string> network_connection_state_; 131 132 DISALLOW_COPY_AND_ASSIGN(TestObserver); 133}; 134 135} // namespace 136 137namespace chromeos { 138 139class NetworkStateHandlerTest : public testing::Test { 140 public: 141 NetworkStateHandlerTest() 142 : device_test_(NULL), manager_test_(NULL), service_test_(NULL) {} 143 virtual ~NetworkStateHandlerTest() {} 144 145 virtual void SetUp() OVERRIDE { 146 // Initialize DBusThreadManager with a stub implementation. 147 DBusThreadManager::InitializeWithStub(); 148 SetupNetworkStateHandler(); 149 message_loop_.RunUntilIdle(); 150 } 151 152 virtual void TearDown() OVERRIDE { 153 network_state_handler_->RemoveObserver(test_observer_.get(), FROM_HERE); 154 test_observer_.reset(); 155 network_state_handler_.reset(); 156 DBusThreadManager::Shutdown(); 157 } 158 159 void SetupNetworkStateHandler() { 160 SetupDefaultShillState(); 161 network_state_handler_.reset(new NetworkStateHandler); 162 test_observer_.reset(new TestObserver(network_state_handler_.get())); 163 network_state_handler_->AddObserver(test_observer_.get(), FROM_HERE); 164 network_state_handler_->InitShillPropertyHandler(); 165 } 166 167 protected: 168 void SetupDefaultShillState() { 169 message_loop_.RunUntilIdle(); // Process any pending updates 170 device_test_ = 171 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface(); 172 ASSERT_TRUE(device_test_); 173 device_test_->ClearDevices(); 174 device_test_->AddDevice( 175 "/device/stub_wifi_device1", shill::kTypeWifi, "stub_wifi_device1"); 176 device_test_->AddDevice("/device/stub_cellular_device1", 177 shill::kTypeCellular, 178 "stub_cellular_device1"); 179 180 manager_test_ = 181 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface(); 182 ASSERT_TRUE(manager_test_); 183 184 service_test_ = 185 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 186 ASSERT_TRUE(service_test_); 187 service_test_->ClearServices(); 188 const bool add_to_visible = true; 189 const bool add_to_watchlist = true; 190 service_test_->AddService(kShillManagerClientStubDefaultService, 191 kShillManagerClientStubDefaultService, 192 shill::kTypeEthernet, 193 shill::kStateOnline, 194 add_to_visible, 195 add_to_watchlist); 196 service_test_->AddService(kShillManagerClientStubDefaultWireless, 197 kShillManagerClientStubDefaultWireless, 198 shill::kTypeWifi, 199 shill::kStateOnline, 200 add_to_visible, 201 add_to_watchlist); 202 service_test_->AddService(kShillManagerClientStubWireless2, 203 kShillManagerClientStubWireless2, 204 shill::kTypeWifi, 205 shill::kStateIdle, 206 add_to_visible, 207 add_to_watchlist); 208 service_test_->AddService(kShillManagerClientStubCellular, 209 kShillManagerClientStubCellular, 210 shill::kTypeCellular, 211 shill::kStateIdle, 212 add_to_visible, 213 add_to_watchlist); 214 } 215 216 base::MessageLoopForUI message_loop_; 217 scoped_ptr<NetworkStateHandler> network_state_handler_; 218 scoped_ptr<TestObserver> test_observer_; 219 ShillDeviceClient::TestInterface* device_test_; 220 ShillManagerClient::TestInterface* manager_test_; 221 ShillServiceClient::TestInterface* service_test_; 222 223 private: 224 DISALLOW_COPY_AND_ASSIGN(NetworkStateHandlerTest); 225}; 226 227TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStub) { 228 // Ensure that the network list is the expected size. 229 const size_t kNumShillManagerClientStubImplServices = 4; 230 EXPECT_EQ(kNumShillManagerClientStubImplServices, 231 test_observer_->network_count()); 232 // Ensure that the first stub network is the default network. 233 EXPECT_EQ(kShillManagerClientStubDefaultService, 234 test_observer_->default_network()); 235 EXPECT_EQ(kShillManagerClientStubDefaultService, 236 network_state_handler_->ConnectedNetworkByType( 237 NetworkTypePattern::Default())->path()); 238 EXPECT_EQ(kShillManagerClientStubDefaultService, 239 network_state_handler_->ConnectedNetworkByType( 240 NetworkTypePattern::Ethernet())->path()); 241 EXPECT_EQ(kShillManagerClientStubDefaultWireless, 242 network_state_handler_->ConnectedNetworkByType( 243 NetworkTypePattern::Wireless())->path()); 244 EXPECT_EQ(kShillManagerClientStubCellular, 245 network_state_handler_->FirstNetworkByType( 246 NetworkTypePattern::Mobile())->path()); 247 EXPECT_EQ( 248 kShillManagerClientStubCellular, 249 network_state_handler_->FirstNetworkByType(NetworkTypePattern::Cellular()) 250 ->path()); 251 EXPECT_EQ(shill::kStateOnline, 252 test_observer_->default_network_connection_state()); 253} 254 255TEST_F(NetworkStateHandlerTest, TechnologyChanged) { 256 // There may be several manager changes during initialization. 257 size_t initial_changed_count = test_observer_->device_list_changed_count(); 258 // Disable a technology. 259 network_state_handler_->SetTechnologyEnabled( 260 NetworkTypePattern::Wimax(), false, network_handler::ErrorCallback()); 261 EXPECT_NE( 262 NetworkStateHandler::TECHNOLOGY_ENABLED, 263 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 264 EXPECT_EQ(initial_changed_count + 1, 265 test_observer_->device_list_changed_count()); 266 // Enable a technology. 267 network_state_handler_->SetTechnologyEnabled( 268 NetworkTypePattern::Wimax(), true, network_handler::ErrorCallback()); 269 // The technology state should immediately change to ENABLING and we should 270 // receive a manager changed callback. 271 EXPECT_EQ(initial_changed_count + 2, 272 test_observer_->device_list_changed_count()); 273 EXPECT_EQ( 274 NetworkStateHandler::TECHNOLOGY_ENABLING, 275 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 276 message_loop_.RunUntilIdle(); 277 // Ensure we receive 2 manager changed callbacks when the technology becomes 278 // avalable and enabled. 279 EXPECT_EQ(initial_changed_count + 4, 280 test_observer_->device_list_changed_count()); 281 EXPECT_EQ( 282 NetworkStateHandler::TECHNOLOGY_ENABLED, 283 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 284} 285 286TEST_F(NetworkStateHandlerTest, TechnologyState) { 287 manager_test_->RemoveTechnology(shill::kTypeWimax); 288 message_loop_.RunUntilIdle(); 289 EXPECT_EQ( 290 NetworkStateHandler::TECHNOLOGY_UNAVAILABLE, 291 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 292 293 manager_test_->AddTechnology(shill::kTypeWimax, false); 294 message_loop_.RunUntilIdle(); 295 EXPECT_EQ( 296 NetworkStateHandler::TECHNOLOGY_AVAILABLE, 297 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 298 299 manager_test_->SetTechnologyInitializing(shill::kTypeWimax, true); 300 message_loop_.RunUntilIdle(); 301 EXPECT_EQ( 302 NetworkStateHandler::TECHNOLOGY_UNINITIALIZED, 303 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 304 305 manager_test_->SetTechnologyInitializing(shill::kTypeWimax, false); 306 network_state_handler_->SetTechnologyEnabled( 307 NetworkTypePattern::Wimax(), true, network_handler::ErrorCallback()); 308 message_loop_.RunUntilIdle(); 309 EXPECT_EQ( 310 NetworkStateHandler::TECHNOLOGY_ENABLED, 311 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 312 313 manager_test_->RemoveTechnology(shill::kTypeWimax); 314 message_loop_.RunUntilIdle(); 315 EXPECT_EQ( 316 NetworkStateHandler::TECHNOLOGY_UNAVAILABLE, 317 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 318} 319 320TEST_F(NetworkStateHandlerTest, ServicePropertyChanged) { 321 // Set a service property. 322 const std::string eth1 = kShillManagerClientStubDefaultService; 323 const NetworkState* ethernet = network_state_handler_->GetNetworkState(eth1); 324 ASSERT_TRUE(ethernet); 325 EXPECT_EQ("", ethernet->security()); 326 EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth1)); 327 base::StringValue security_value("TestSecurity"); 328 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 329 dbus::ObjectPath(eth1), 330 shill::kSecurityProperty, security_value, 331 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 332 message_loop_.RunUntilIdle(); 333 ethernet = network_state_handler_->GetNetworkState(eth1); 334 EXPECT_EQ("TestSecurity", ethernet->security()); 335 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth1)); 336 337 // Changing a service to the existing value should not trigger an update. 338 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 339 dbus::ObjectPath(eth1), 340 shill::kSecurityProperty, security_value, 341 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 342 message_loop_.RunUntilIdle(); 343 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth1)); 344} 345 346TEST_F(NetworkStateHandlerTest, FavoriteState) { 347 // Set the profile entry of a service 348 const std::string wifi1 = kShillManagerClientStubDefaultWireless; 349 ShillProfileClient::TestInterface* profile_test = 350 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface(); 351 EXPECT_TRUE(profile_test->AddService("/profile/default", wifi1)); 352 message_loop_.RunUntilIdle(); 353 network_state_handler_->UpdateManagerProperties(); 354 message_loop_.RunUntilIdle(); 355 EXPECT_EQ(1u, test_observer_->favorite_count()); 356} 357 358TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) { 359 // Change a network state. 360 const std::string eth1 = kShillManagerClientStubDefaultService; 361 base::StringValue connection_state_idle_value(shill::kStateIdle); 362 service_test_->SetServiceProperty(eth1, shill::kStateProperty, 363 connection_state_idle_value); 364 message_loop_.RunUntilIdle(); 365 EXPECT_EQ(shill::kStateIdle, 366 test_observer_->NetworkConnectionStateForService(eth1)); 367 EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth1)); 368 // Confirm that changing the connection state to the same value does *not* 369 // signal the observer. 370 service_test_->SetServiceProperty(eth1, shill::kStateProperty, 371 connection_state_idle_value); 372 message_loop_.RunUntilIdle(); 373 EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth1)); 374} 375 376TEST_F(NetworkStateHandlerTest, DefaultServiceDisconnected) { 377 const std::string eth1 = kShillManagerClientStubDefaultService; 378 const std::string wifi1 = kShillManagerClientStubDefaultWireless; 379 380 // Disconnect ethernet. 381 test_observer_->reset_network_change_count(); 382 base::StringValue connection_state_idle_value(shill::kStateIdle); 383 service_test_->SetServiceProperty(eth1, shill::kStateProperty, 384 connection_state_idle_value); 385 message_loop_.RunUntilIdle(); 386 // Expect two changes: first when eth1 becomes disconnected, second when 387 // wifi1 becomes the default. 388 EXPECT_EQ(2u, test_observer_->default_network_change_count()); 389 EXPECT_EQ(wifi1, test_observer_->default_network()); 390 391 // Disconnect wifi. 392 test_observer_->reset_network_change_count(); 393 service_test_->SetServiceProperty(wifi1, shill::kStateProperty, 394 connection_state_idle_value); 395 message_loop_.RunUntilIdle(); 396 EXPECT_EQ(1u, test_observer_->default_network_change_count()); 397 EXPECT_EQ("", test_observer_->default_network()); 398} 399 400TEST_F(NetworkStateHandlerTest, DefaultServiceConnected) { 401 const std::string eth1 = kShillManagerClientStubDefaultService; 402 const std::string wifi1 = kShillManagerClientStubDefaultWireless; 403 404 // Disconnect ethernet and wifi. 405 base::StringValue connection_state_idle_value(shill::kStateIdle); 406 service_test_->SetServiceProperty(eth1, shill::kStateProperty, 407 connection_state_idle_value); 408 service_test_->SetServiceProperty(wifi1, shill::kStateProperty, 409 connection_state_idle_value); 410 message_loop_.RunUntilIdle(); 411 EXPECT_EQ(std::string(), test_observer_->default_network()); 412 413 // Connect ethernet, should become the default network. 414 test_observer_->reset_network_change_count(); 415 base::StringValue connection_state_ready_value(shill::kStateReady); 416 service_test_->SetServiceProperty(eth1, shill::kStateProperty, 417 connection_state_ready_value); 418 message_loop_.RunUntilIdle(); 419 EXPECT_EQ(eth1, test_observer_->default_network()); 420 EXPECT_EQ(shill::kStateReady, 421 test_observer_->default_network_connection_state()); 422 EXPECT_EQ(1u, test_observer_->default_network_change_count()); 423} 424 425TEST_F(NetworkStateHandlerTest, DefaultServiceChanged) { 426 const std::string eth1 = kShillManagerClientStubDefaultService; 427 // The default service should be eth1. 428 EXPECT_EQ(eth1, test_observer_->default_network()); 429 430 // Change the default network by changing Manager.DefaultService. 431 test_observer_->reset_network_change_count(); 432 const std::string wifi1 = kShillManagerClientStubDefaultWireless; 433 base::StringValue wifi1_value(wifi1); 434 manager_test_->SetManagerProperty( 435 shill::kDefaultServiceProperty, wifi1_value); 436 message_loop_.RunUntilIdle(); 437 EXPECT_EQ(wifi1, test_observer_->default_network()); 438 EXPECT_EQ(1u, test_observer_->default_network_change_count()); 439 440 // Change the state of the default network. 441 test_observer_->reset_network_change_count(); 442 base::StringValue connection_state_ready_value(shill::kStateReady); 443 service_test_->SetServiceProperty(wifi1, shill::kStateProperty, 444 connection_state_ready_value); 445 message_loop_.RunUntilIdle(); 446 EXPECT_EQ(shill::kStateReady, 447 test_observer_->default_network_connection_state()); 448 EXPECT_EQ(1u, test_observer_->default_network_change_count()); 449 450 // Updating a property on the default network should trigger 451 // a default network change. 452 test_observer_->reset_network_change_count(); 453 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 454 dbus::ObjectPath(wifi1), 455 shill::kSecurityProperty, base::StringValue("TestSecurity"), 456 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 457 message_loop_.RunUntilIdle(); 458 EXPECT_EQ(1u, test_observer_->default_network_change_count()); 459 460 // No default network updates for signal strength changes. 461 test_observer_->reset_network_change_count(); 462 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 463 dbus::ObjectPath(wifi1), 464 shill::kSignalStrengthProperty, base::FundamentalValue(32), 465 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 466 message_loop_.RunUntilIdle(); 467 EXPECT_EQ(0u, test_observer_->default_network_change_count()); 468} 469 470TEST_F(NetworkStateHandlerTest, RequestUpdate) { 471 // Request an update for kShillManagerClientStubDefaultWireless. 472 EXPECT_EQ(1, test_observer_->PropertyUpdatesForService( 473 kShillManagerClientStubDefaultWireless)); 474 network_state_handler_->RequestUpdateForNetwork( 475 kShillManagerClientStubDefaultWireless); 476 message_loop_.RunUntilIdle(); 477 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService( 478 kShillManagerClientStubDefaultWireless)); 479} 480 481} // namespace chromeos 482