network_state_handler_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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 } 47 48 virtual ~TestObserver() { 49 } 50 51 virtual void NetworkManagerChanged() OVERRIDE { 52 ++manager_changed_count_; 53 } 54 55 virtual void NetworkListChanged() OVERRIDE { 56 NetworkStateHandler::NetworkStateList networks; 57 handler_->GetNetworkList(&networks); 58 network_count_ = networks.size(); 59 if (network_count_ == 0) { 60 default_network_ = ""; 61 default_network_connection_state_ = ""; 62 } 63 } 64 65 virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE { 66 default_network_ = network ? network->path() : ""; 67 default_network_connection_state_ = 68 network ? network->connection_state() : ""; 69 } 70 71 virtual void NetworkConnectionStateChanged( 72 const NetworkState* network) OVERRIDE { 73 network_connection_state_[network->path()] = network->connection_state(); 74 connection_state_changes_[network->path()]++; 75 } 76 77 virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE { 78 DCHECK(network); 79 property_updates_[network->path()]++; 80 } 81 82 size_t manager_changed_count() { return manager_changed_count_; } 83 size_t network_count() { return network_count_; } 84 std::string default_network() { return default_network_; } 85 std::string default_network_connection_state() { 86 return default_network_connection_state_; 87 } 88 89 int PropertyUpdatesForService(const std::string& service_path) { 90 return property_updates_[service_path]; 91 } 92 93 int ConnectionStateChangesForService(const std::string& service_path) { 94 return connection_state_changes_[service_path]; 95 } 96 97 std::string NetworkConnectionStateForService( 98 const std::string& service_path) { 99 return network_connection_state_[service_path]; 100 } 101 102 private: 103 NetworkStateHandler* handler_; 104 size_t manager_changed_count_; 105 size_t network_count_; 106 std::string default_network_; 107 std::string default_network_connection_state_; 108 std::map<std::string, int> property_updates_; 109 std::map<std::string, int> connection_state_changes_; 110 std::map<std::string, std::string> network_connection_state_; 111 112 DISALLOW_COPY_AND_ASSIGN(TestObserver); 113}; 114 115} // namespace 116 117namespace chromeos { 118 119class NetworkStateHandlerTest : public testing::Test { 120 public: 121 NetworkStateHandlerTest() {} 122 virtual ~NetworkStateHandlerTest() {} 123 124 virtual void SetUp() OVERRIDE { 125 // Initialize DBusThreadManager with a stub implementation. 126 DBusThreadManager::InitializeWithStub(); 127 } 128 129 virtual void TearDown() OVERRIDE { 130 network_state_handler_.reset(); 131 test_observer_.reset(); 132 DBusThreadManager::Shutdown(); 133 } 134 135 void SetupNetworkStateHandler() { 136 SetupDefaultShillState(); 137 network_state_handler_.reset(new NetworkStateHandler); 138 test_observer_.reset(new TestObserver(network_state_handler_.get())); 139 network_state_handler_->AddObserver(test_observer_.get()); 140 network_state_handler_->InitShillPropertyHandler(); 141 } 142 143 protected: 144 void SetupDefaultShillState() { 145 message_loop_.RunUntilIdle(); // Process any pending updates 146 ShillDeviceClient::TestInterface* device_test = 147 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface(); 148 device_test->ClearDevices(); 149 device_test->AddDevice("/device/stub_wifi_device1", 150 flimflam::kTypeWifi, "stub_wifi_device1"); 151 device_test->AddDevice("/device/stub_cellular_device1", 152 flimflam::kTypeCellular, "stub_cellular_device1"); 153 154 ShillServiceClient::TestInterface* service_test = 155 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 156 service_test->ClearServices(); 157 const bool add_to_watchlist = true; 158 service_test->AddService(kShillManagerClientStubDefaultService, 159 kShillManagerClientStubDefaultService, 160 flimflam::kTypeEthernet, flimflam::kStateOnline, 161 add_to_watchlist); 162 service_test->AddService(kShillManagerClientStubDefaultWireless, 163 kShillManagerClientStubDefaultWireless, 164 flimflam::kTypeWifi, flimflam::kStateOnline, 165 add_to_watchlist); 166 service_test->AddService(kShillManagerClientStubWireless2, 167 kShillManagerClientStubWireless2, 168 flimflam::kTypeWifi, flimflam::kStateIdle, 169 add_to_watchlist); 170 service_test->AddService(kShillManagerClientStubCellular, 171 kShillManagerClientStubCellular, 172 flimflam::kTypeCellular, flimflam::kStateIdle, 173 add_to_watchlist); 174 } 175 176 MessageLoopForUI message_loop_; 177 scoped_ptr<NetworkStateHandler> network_state_handler_; 178 scoped_ptr<TestObserver> test_observer_; 179 180 private: 181 DISALLOW_COPY_AND_ASSIGN(NetworkStateHandlerTest); 182}; 183 184TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStub) { 185 SetupNetworkStateHandler(); 186 message_loop_.RunUntilIdle(); 187 EXPECT_EQ(1u, test_observer_->manager_changed_count()); 188 // Ensure that the network list is the expected size. 189 const size_t kNumShillManagerClientStubImplServices = 4; 190 EXPECT_EQ(kNumShillManagerClientStubImplServices, 191 test_observer_->network_count()); 192 // Ensure that the first stub network is the default network. 193 EXPECT_EQ(kShillManagerClientStubDefaultService, 194 test_observer_->default_network()); 195 EXPECT_EQ(kShillManagerClientStubDefaultService, 196 network_state_handler_->ConnectedNetworkByType( 197 NetworkStateHandler::kMatchTypeDefault)->path()); 198 EXPECT_EQ(kShillManagerClientStubDefaultService, 199 network_state_handler_->ConnectedNetworkByType( 200 flimflam::kTypeEthernet)->path()); 201 EXPECT_EQ(kShillManagerClientStubDefaultWireless, 202 network_state_handler_->ConnectedNetworkByType( 203 NetworkStateHandler::kMatchTypeWireless)->path()); 204 EXPECT_EQ(flimflam::kStateOnline, 205 test_observer_->default_network_connection_state()); 206} 207 208TEST_F(NetworkStateHandlerTest, TechnologyChanged) { 209 SetupNetworkStateHandler(); 210 message_loop_.RunUntilIdle(); 211 EXPECT_EQ(1u, test_observer_->manager_changed_count()); 212 // Enable a technology. 213 EXPECT_FALSE(network_state_handler_->TechnologyEnabled(flimflam::kTypeWimax)); 214 network_state_handler_->SetTechnologyEnabled( 215 flimflam::kTypeWimax, true, network_handler::ErrorCallback()); 216 message_loop_.RunUntilIdle(); 217 // Ensure we get a manager changed callback when we change a property. 218 EXPECT_EQ(2u, test_observer_->manager_changed_count()); 219 EXPECT_TRUE(network_state_handler_->TechnologyEnabled(flimflam::kTypeWimax)); 220} 221 222TEST_F(NetworkStateHandlerTest, ServicePropertyChanged) { 223 SetupNetworkStateHandler(); 224 message_loop_.RunUntilIdle(); 225 // Set a service property. 226 const std::string eth0 = "stub_ethernet"; 227 EXPECT_EQ("", network_state_handler_->GetNetworkState(eth0)->security()); 228 EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth0)); 229 base::StringValue security_value("TestSecurity"); 230 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 231 dbus::ObjectPath(eth0), 232 flimflam::kSecurityProperty, security_value, 233 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); 234 message_loop_.RunUntilIdle(); 235 EXPECT_EQ("TestSecurity", 236 network_state_handler_->GetNetworkState(eth0)->security()); 237 EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth0)); 238} 239 240TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) { 241 SetupNetworkStateHandler(); 242 message_loop_.RunUntilIdle(); 243 // Change a network state. 244 ShillServiceClient::TestInterface* service_test = 245 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 246 const std::string eth0 = "stub_ethernet"; 247 base::StringValue connection_state_idle_value(flimflam::kStateIdle); 248 service_test->SetServiceProperty(eth0, flimflam::kStateProperty, 249 connection_state_idle_value); 250 message_loop_.RunUntilIdle(); 251 EXPECT_EQ(flimflam::kStateIdle, 252 test_observer_->NetworkConnectionStateForService(eth0)); 253 EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth0)); 254 // Confirm that changing the connection state to the same value does *not* 255 // signal the observer. 256 service_test->SetServiceProperty(eth0, flimflam::kStateProperty, 257 connection_state_idle_value); 258 message_loop_.RunUntilIdle(); 259 EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth0)); 260} 261 262TEST_F(NetworkStateHandlerTest, DefaultServiceChanged) { 263 SetupNetworkStateHandler(); 264 message_loop_.RunUntilIdle(); 265 266 ShillManagerClient::TestInterface* manager_test = 267 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface(); 268 ASSERT_TRUE(manager_test); 269 ShillServiceClient::TestInterface* service_test = 270 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 271 ASSERT_TRUE(service_test); 272 273 // Change the default network by inserting wifi1 at the front of the list 274 // and changing the state of stub_ethernet to Idle. 275 const std::string wifi1 = "stub_wifi1"; 276 manager_test->AddServiceAtIndex(wifi1, 0, true); 277 const std::string eth0 = "stub_ethernet"; 278 base::StringValue connection_state_idle_value(flimflam::kStateIdle); 279 service_test->SetServiceProperty(eth0, flimflam::kStateProperty, 280 connection_state_idle_value); 281 message_loop_.RunUntilIdle(); 282 EXPECT_EQ(wifi1, test_observer_->default_network()); 283 EXPECT_EQ(flimflam::kStateOnline, 284 test_observer_->default_network_connection_state()); 285} 286 287} // namespace chromeos 288