network_state_handler_unittest.cc revision a93a17c8d99d686bd4a1511e5504e5e6cc9fcadf
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 = "stub_ethernet"; 33const std::string kShillManagerClientStubDefaultWireless = "stub_wifi1"; 34const std::string kShillManagerClientStubWireless2 = "stub_wifi2"; 35const std::string kShillManagerClientStubCellular = "stub_cellular"; 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_.reset(); 139 test_observer_.reset(); 140 DBusThreadManager::Shutdown(); 141 } 142 143 void SetupNetworkStateHandler() { 144 SetupDefaultShillState(); 145 network_state_handler_.reset(new NetworkStateHandler); 146 test_observer_.reset(new TestObserver(network_state_handler_.get())); 147 network_state_handler_->AddObserver(test_observer_.get()); 148 network_state_handler_->InitShillPropertyHandler(); 149 } 150 151 protected: 152 void SetupDefaultShillState() { 153 message_loop_.RunUntilIdle(); // Process any pending updates 154 ShillDeviceClient::TestInterface* device_test = 155 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface(); 156 device_test->ClearDevices(); 157 device_test->AddDevice("/device/stub_wifi_device1", 158 flimflam::kTypeWifi, "stub_wifi_device1"); 159 device_test->AddDevice("/device/stub_cellular_device1", 160 flimflam::kTypeCellular, "stub_cellular_device1"); 161 162 ShillServiceClient::TestInterface* service_test = 163 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 164 service_test->ClearServices(); 165 const bool add_to_watchlist = true; 166 service_test->AddService(kShillManagerClientStubDefaultService, 167 kShillManagerClientStubDefaultService, 168 flimflam::kTypeEthernet, flimflam::kStateOnline, 169 add_to_watchlist); 170 service_test->AddService(kShillManagerClientStubDefaultWireless, 171 kShillManagerClientStubDefaultWireless, 172 flimflam::kTypeWifi, flimflam::kStateOnline, 173 add_to_watchlist); 174 service_test->AddService(kShillManagerClientStubWireless2, 175 kShillManagerClientStubWireless2, 176 flimflam::kTypeWifi, flimflam::kStateIdle, 177 add_to_watchlist); 178 service_test->AddService(kShillManagerClientStubCellular, 179 kShillManagerClientStubCellular, 180 flimflam::kTypeCellular, flimflam::kStateIdle, 181 add_to_watchlist); 182 } 183 184 MessageLoopForUI message_loop_; 185 scoped_ptr<NetworkStateHandler> network_state_handler_; 186 scoped_ptr<TestObserver> test_observer_; 187 188 private: 189 DISALLOW_COPY_AND_ASSIGN(NetworkStateHandlerTest); 190}; 191 192TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStub) { 193 EXPECT_EQ(1u, test_observer_->manager_changed_count()); 194 // Ensure that the network list is the expected size. 195 const size_t kNumShillManagerClientStubImplServices = 4; 196 EXPECT_EQ(kNumShillManagerClientStubImplServices, 197 test_observer_->network_count()); 198 // Ensure that the first stub network is the default network. 199 EXPECT_EQ(kShillManagerClientStubDefaultService, 200 test_observer_->default_network()); 201 EXPECT_EQ(kShillManagerClientStubDefaultService, 202 network_state_handler_->ConnectedNetworkByType( 203 NetworkStateHandler::kMatchTypeDefault)->path()); 204 EXPECT_EQ(kShillManagerClientStubDefaultService, 205 network_state_handler_->ConnectedNetworkByType( 206 flimflam::kTypeEthernet)->path()); 207 EXPECT_EQ(kShillManagerClientStubDefaultWireless, 208 network_state_handler_->ConnectedNetworkByType( 209 NetworkStateHandler::kMatchTypeWireless)->path()); 210 EXPECT_EQ(flimflam::kStateOnline, 211 test_observer_->default_network_connection_state()); 212} 213 214TEST_F(NetworkStateHandlerTest, TechnologyChanged) { 215 EXPECT_EQ(1u, test_observer_->manager_changed_count()); 216 // Enable a technology. 217 EXPECT_NE(NetworkStateHandler::TECHNOLOGY_ENABLED, 218 network_state_handler_->GetTechnologyState(flimflam::kTypeWimax)); 219 network_state_handler_->SetTechnologyEnabled( 220 flimflam::kTypeWimax, true, network_handler::ErrorCallback()); 221 // The technology state should immediately change to ENABLING and we should 222 // receive a manager changed callback. 223 EXPECT_EQ(2u, test_observer_->manager_changed_count()); 224 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_ENABLING, 225 network_state_handler_->GetTechnologyState(flimflam::kTypeWimax)); 226 message_loop_.RunUntilIdle(); 227 // Ensure we receive another manager changed callbacks when the technology 228 // becomes enabled. 229 EXPECT_EQ(3u, test_observer_->manager_changed_count()); 230 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_ENABLED, 231 network_state_handler_->GetTechnologyState(flimflam::kTypeWimax)); 232} 233 234TEST_F(NetworkStateHandlerTest, TechnologyState) { 235 ShillManagerClient::TestInterface* manager_test = 236 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface(); 237 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_UNAVAILABLE, 238 network_state_handler_->GetTechnologyState(flimflam::kTypeWimax)); 239 240 manager_test->AddTechnology(flimflam::kTypeWimax, false); 241 message_loop_.RunUntilIdle(); 242 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_AVAILABLE, 243 network_state_handler_->GetTechnologyState(flimflam::kTypeWimax)); 244 245 manager_test->SetTechnologyInitializing(flimflam::kTypeWimax, true); 246 message_loop_.RunUntilIdle(); 247 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_UNINITIALIZED, 248 network_state_handler_->GetTechnologyState(flimflam::kTypeWimax)); 249 250 manager_test->SetTechnologyInitializing(flimflam::kTypeWimax, false); 251 network_state_handler_->SetTechnologyEnabled( 252 flimflam::kTypeWimax, true, network_handler::ErrorCallback()); 253 message_loop_.RunUntilIdle(); 254 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_ENABLED, 255 network_state_handler_->GetTechnologyState(flimflam::kTypeWimax)); 256 257 manager_test->RemoveTechnology(flimflam::kTypeWimax); 258 message_loop_.RunUntilIdle(); 259 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_UNAVAILABLE, 260 network_state_handler_->GetTechnologyState(flimflam::kTypeWimax)); 261} 262 263TEST_F(NetworkStateHandlerTest, ServicePropertyChanged) { 264 // Set a service property. 265 const std::string eth0 = kShillManagerClientStubDefaultService; 266 EXPECT_EQ("", network_state_handler_->GetNetworkState(eth0)->security()); 267 EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth0)); 268 base::StringValue security_value("TestSecurity"); 269 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 270 dbus::ObjectPath(eth0), 271 flimflam::kSecurityProperty, security_value, 272 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 273 message_loop_.RunUntilIdle(); 274 EXPECT_EQ("TestSecurity", 275 network_state_handler_->GetNetworkState(eth0)->security()); 276 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth0)); 277} 278 279TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) { 280 // Change a network state. 281 ShillServiceClient::TestInterface* service_test = 282 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 283 const std::string eth0 = kShillManagerClientStubDefaultService; 284 base::StringValue connection_state_idle_value(flimflam::kStateIdle); 285 service_test->SetServiceProperty(eth0, flimflam::kStateProperty, 286 connection_state_idle_value); 287 message_loop_.RunUntilIdle(); 288 EXPECT_EQ(flimflam::kStateIdle, 289 test_observer_->NetworkConnectionStateForService(eth0)); 290 EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth0)); 291 // Confirm that changing the connection state to the same value does *not* 292 // signal the observer. 293 service_test->SetServiceProperty(eth0, flimflam::kStateProperty, 294 connection_state_idle_value); 295 message_loop_.RunUntilIdle(); 296 EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth0)); 297} 298 299TEST_F(NetworkStateHandlerTest, DefaultServiceChanged) { 300 ShillManagerClient::TestInterface* manager_test = 301 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface(); 302 ASSERT_TRUE(manager_test); 303 ShillServiceClient::TestInterface* service_test = 304 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 305 ASSERT_TRUE(service_test); 306 307 // Change the default network by moving wifi1 to the front of the list 308 // and changing the state of stub_ethernet to Idle. 309 const std::string wifi1 = kShillManagerClientStubDefaultWireless; 310 manager_test->MoveServiceToIndex(wifi1, 0, true); 311 const std::string eth0 = kShillManagerClientStubDefaultService; 312 base::StringValue connection_state_idle_value(flimflam::kStateIdle); 313 service_test->SetServiceProperty(eth0, flimflam::kStateProperty, 314 connection_state_idle_value); 315 message_loop_.RunUntilIdle(); 316 EXPECT_EQ(wifi1, test_observer_->default_network()); 317 EXPECT_EQ(flimflam::kStateOnline, 318 test_observer_->default_network_connection_state()); 319 // We should have seen 2 default network updates - for the default 320 // service change, and for the state change. 321 EXPECT_EQ(2u, test_observer_->default_network_change_count()); 322 323 // Updating a property on the default network should trigger 324 // a default network change. 325 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 326 dbus::ObjectPath(wifi1), 327 flimflam::kSecurityProperty, base::StringValue("TestSecurity"), 328 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 329 message_loop_.RunUntilIdle(); 330 EXPECT_EQ(3u, test_observer_->default_network_change_count()); 331 332 // No default network updates for signal strength changes. 333 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 334 dbus::ObjectPath(wifi1), 335 flimflam::kSignalStrengthProperty, base::FundamentalValue(32), 336 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 337 message_loop_.RunUntilIdle(); 338 EXPECT_EQ(3u, test_observer_->default_network_change_count()); 339} 340 341} // namespace chromeos 342