network_state_handler_unittest.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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 manager_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 NetworkManagerChanged() OVERRIDE { 56 ++manager_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 manager_changed_count() { return manager_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 manager_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 131namespace chromeos { 132 133class 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 flimflam::kTypeWifi, "stub_wifi_device1"); 168 device_test->AddDevice("/device/stub_cellular_device1", 169 flimflam::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 flimflam::kTypeEthernet, flimflam::kStateOnline, 179 add_to_visible, add_to_watchlist); 180 service_test->AddService(kShillManagerClientStubDefaultWireless, 181 kShillManagerClientStubDefaultWireless, 182 flimflam::kTypeWifi, flimflam::kStateOnline, 183 add_to_visible, add_to_watchlist); 184 service_test->AddService(kShillManagerClientStubWireless2, 185 kShillManagerClientStubWireless2, 186 flimflam::kTypeWifi, flimflam::kStateIdle, 187 add_to_visible, add_to_watchlist); 188 service_test->AddService(kShillManagerClientStubCellular, 189 kShillManagerClientStubCellular, 190 flimflam::kTypeCellular, flimflam::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 202TEST_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(flimflam::kStateOnline, 227 test_observer_->default_network_connection_state()); 228} 229 230TEST_F(NetworkStateHandlerTest, TechnologyChanged) { 231 // There may be several manager changes during initialization. 232 size_t initial_changed_count = test_observer_->manager_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, test_observer_->manager_changed_count()); 240 // Enable a technology. 241 network_state_handler_->SetTechnologyEnabled( 242 NetworkTypePattern::Wimax(), true, network_handler::ErrorCallback()); 243 // The technology state should immediately change to ENABLING and we should 244 // receive a manager changed callback. 245 EXPECT_EQ(initial_changed_count + 2, test_observer_->manager_changed_count()); 246 EXPECT_EQ( 247 NetworkStateHandler::TECHNOLOGY_ENABLING, 248 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 249 message_loop_.RunUntilIdle(); 250 // Ensure we receive 2 manager changed callbacks when the technology becomes 251 // avalable and enabled. 252 EXPECT_EQ(initial_changed_count + 4, test_observer_->manager_changed_count()); 253 EXPECT_EQ( 254 NetworkStateHandler::TECHNOLOGY_ENABLED, 255 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 256} 257 258TEST_F(NetworkStateHandlerTest, TechnologyState) { 259 ShillManagerClient::TestInterface* manager_test = 260 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface(); 261 manager_test->RemoveTechnology(flimflam::kTypeWimax); 262 message_loop_.RunUntilIdle(); 263 EXPECT_EQ( 264 NetworkStateHandler::TECHNOLOGY_UNAVAILABLE, 265 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 266 267 manager_test->AddTechnology(flimflam::kTypeWimax, false); 268 message_loop_.RunUntilIdle(); 269 EXPECT_EQ( 270 NetworkStateHandler::TECHNOLOGY_AVAILABLE, 271 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 272 273 manager_test->SetTechnologyInitializing(flimflam::kTypeWimax, true); 274 message_loop_.RunUntilIdle(); 275 EXPECT_EQ( 276 NetworkStateHandler::TECHNOLOGY_UNINITIALIZED, 277 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 278 279 manager_test->SetTechnologyInitializing(flimflam::kTypeWimax, false); 280 network_state_handler_->SetTechnologyEnabled( 281 NetworkTypePattern::Wimax(), true, network_handler::ErrorCallback()); 282 message_loop_.RunUntilIdle(); 283 EXPECT_EQ( 284 NetworkStateHandler::TECHNOLOGY_ENABLED, 285 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 286 287 manager_test->RemoveTechnology(flimflam::kTypeWimax); 288 message_loop_.RunUntilIdle(); 289 EXPECT_EQ( 290 NetworkStateHandler::TECHNOLOGY_UNAVAILABLE, 291 network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); 292} 293 294TEST_F(NetworkStateHandlerTest, ServicePropertyChanged) { 295 // Set a service property. 296 const std::string eth1 = kShillManagerClientStubDefaultService; 297 EXPECT_EQ("", network_state_handler_->GetNetworkState(eth1)->security()); 298 EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth1)); 299 base::StringValue security_value("TestSecurity"); 300 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 301 dbus::ObjectPath(eth1), 302 flimflam::kSecurityProperty, security_value, 303 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 304 message_loop_.RunUntilIdle(); 305 EXPECT_EQ("TestSecurity", 306 network_state_handler_->GetNetworkState(eth1)->security()); 307 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth1)); 308 309 // Changing a service to the existing value should not trigger an update. 310 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 311 dbus::ObjectPath(eth1), 312 flimflam::kSecurityProperty, security_value, 313 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 314 message_loop_.RunUntilIdle(); 315 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth1)); 316} 317 318TEST_F(NetworkStateHandlerTest, FavoriteState) { 319 // Set the profile entry of a service 320 const std::string wifi1 = kShillManagerClientStubDefaultWireless; 321 ShillProfileClient::TestInterface* profile_test = 322 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface(); 323 EXPECT_TRUE(profile_test->AddService("/profile/default", wifi1)); 324 message_loop_.RunUntilIdle(); 325 network_state_handler_->UpdateManagerProperties(); 326 message_loop_.RunUntilIdle(); 327 EXPECT_EQ(1u, test_observer_->favorite_count()); 328} 329 330TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) { 331 // Change a network state. 332 ShillServiceClient::TestInterface* service_test = 333 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 334 const std::string eth1 = kShillManagerClientStubDefaultService; 335 base::StringValue connection_state_idle_value(flimflam::kStateIdle); 336 service_test->SetServiceProperty(eth1, flimflam::kStateProperty, 337 connection_state_idle_value); 338 message_loop_.RunUntilIdle(); 339 EXPECT_EQ(flimflam::kStateIdle, 340 test_observer_->NetworkConnectionStateForService(eth1)); 341 EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth1)); 342 // Confirm that changing the connection state to the same value does *not* 343 // signal the observer. 344 service_test->SetServiceProperty(eth1, flimflam::kStateProperty, 345 connection_state_idle_value); 346 message_loop_.RunUntilIdle(); 347 EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth1)); 348} 349 350TEST_F(NetworkStateHandlerTest, DefaultServiceChanged) { 351 ShillManagerClient::TestInterface* manager_test = 352 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface(); 353 ASSERT_TRUE(manager_test); 354 ShillServiceClient::TestInterface* service_test = 355 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 356 ASSERT_TRUE(service_test); 357 358 // Change the default network by changing the state of eth1 to Idle which 359 // should re-sort Manager.Services. 360 const std::string eth1 = kShillManagerClientStubDefaultService; 361 const std::string wifi1 = kShillManagerClientStubDefaultWireless; 362 base::StringValue connection_state_idle_value(flimflam::kStateIdle); 363 service_test->SetServiceProperty(eth1, flimflam::kStateProperty, 364 connection_state_idle_value); 365 message_loop_.RunUntilIdle(); 366 EXPECT_EQ(wifi1, test_observer_->default_network()); 367 EXPECT_EQ(flimflam::kStateOnline, 368 test_observer_->default_network_connection_state()); 369 // We should have seen 2 default network updates - for the default 370 // service change, and for the state change. 371 EXPECT_EQ(2u, test_observer_->default_network_change_count()); 372 373 // Updating a property on the default network should trigger 374 // a default network change. 375 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 376 dbus::ObjectPath(wifi1), 377 flimflam::kSecurityProperty, base::StringValue("TestSecurity"), 378 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 379 message_loop_.RunUntilIdle(); 380 EXPECT_EQ(3u, test_observer_->default_network_change_count()); 381 382 // No default network updates for signal strength changes. 383 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 384 dbus::ObjectPath(wifi1), 385 flimflam::kSignalStrengthProperty, base::FundamentalValue(32), 386 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 387 message_loop_.RunUntilIdle(); 388 EXPECT_EQ(3u, test_observer_->default_network_change_count()); 389} 390 391TEST_F(NetworkStateHandlerTest, RequestUpdate) { 392 // Request an update for kShillManagerClientStubDefaultWireless. 393 EXPECT_EQ(1, test_observer_->PropertyUpdatesForService( 394 kShillManagerClientStubDefaultWireless)); 395 network_state_handler_->RequestUpdateForNetwork( 396 kShillManagerClientStubDefaultWireless); 397 message_loop_.RunUntilIdle(); 398 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService( 399 kShillManagerClientStubDefaultWireless)); 400 401 // Request an update for all networks. 402 network_state_handler_->RequestUpdateForAllNetworks(); 403 message_loop_.RunUntilIdle(); 404 // kShillManagerClientStubDefaultWireless should now have 3 updates 405 EXPECT_EQ(3, test_observer_->PropertyUpdatesForService( 406 kShillManagerClientStubDefaultWireless)); 407 // Other networks should have 2 updates (inital + request). 408 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService( 409 kShillManagerClientStubDefaultService)); 410 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService( 411 kShillManagerClientStubWireless2)); 412 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService( 413 kShillManagerClientStubCellular)); 414} 415 416} // namespace chromeos 417