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.
5 #include "chromeos/network/network_state_handler.h"
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 "dbus/object_path.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "third_party/cros_system_api/dbus/service_constants.h"
28 void ErrorCallbackFunction(const std::string
& error_name
,
29 const std::string
& error_message
) {
30 LOG(ERROR
) << "Shill Error: " << error_name
<< " : " << error_message
;
33 const std::string kShillManagerClientStubDefaultService
= "eth1";
34 const std::string kShillManagerClientStubDefaultWireless
= "wifi1";
35 const std::string kShillManagerClientStubWireless2
= "wifi2";
36 const std::string kShillManagerClientStubCellular
= "cellular1";
38 using chromeos::NetworkState
;
39 using chromeos::NetworkStateHandler
;
41 class TestObserver
: public chromeos::NetworkStateHandlerObserver
{
43 explicit TestObserver(NetworkStateHandler
* handler
)
45 manager_changed_count_(0),
47 default_network_change_count_(0),
51 virtual ~TestObserver() {
54 virtual void NetworkManagerChanged() OVERRIDE
{
55 ++manager_changed_count_
;
58 virtual void NetworkListChanged() OVERRIDE
{
59 NetworkStateHandler::NetworkStateList networks
;
60 handler_
->GetNetworkList(&networks
);
61 network_count_
= networks
.size();
62 if (network_count_
== 0) {
63 default_network_
= "";
64 default_network_connection_state_
= "";
66 NetworkStateHandler::FavoriteStateList favorites
;
67 handler_
->GetFavoriteList(&favorites
);
68 favorite_count_
= favorites
.size();
71 virtual void DefaultNetworkChanged(const NetworkState
* network
) OVERRIDE
{
72 ++default_network_change_count_
;
73 default_network_
= network
? network
->path() : "";
74 default_network_connection_state_
=
75 network
? network
->connection_state() : "";
78 virtual void NetworkConnectionStateChanged(
79 const NetworkState
* network
) OVERRIDE
{
80 network_connection_state_
[network
->path()] = network
->connection_state();
81 connection_state_changes_
[network
->path()]++;
84 virtual void NetworkPropertiesUpdated(const NetworkState
* network
) OVERRIDE
{
86 property_updates_
[network
->path()]++;
89 size_t manager_changed_count() { return manager_changed_count_
; }
90 size_t network_count() { return network_count_
; }
91 size_t default_network_change_count() {
92 return default_network_change_count_
;
94 std::string
default_network() { return default_network_
; }
95 std::string
default_network_connection_state() {
96 return default_network_connection_state_
;
98 size_t favorite_count() { return favorite_count_
; }
100 int PropertyUpdatesForService(const std::string
& service_path
) {
101 return property_updates_
[service_path
];
104 int ConnectionStateChangesForService(const std::string
& service_path
) {
105 return connection_state_changes_
[service_path
];
108 std::string
NetworkConnectionStateForService(
109 const std::string
& service_path
) {
110 return network_connection_state_
[service_path
];
114 NetworkStateHandler
* handler_
;
115 size_t manager_changed_count_
;
116 size_t network_count_
;
117 size_t default_network_change_count_
;
118 std::string default_network_
;
119 std::string default_network_connection_state_
;
120 size_t favorite_count_
;
121 std::map
<std::string
, int> property_updates_
;
122 std::map
<std::string
, int> connection_state_changes_
;
123 std::map
<std::string
, std::string
> network_connection_state_
;
125 DISALLOW_COPY_AND_ASSIGN(TestObserver
);
132 class NetworkStateHandlerTest
: public testing::Test
{
134 NetworkStateHandlerTest() {}
135 virtual ~NetworkStateHandlerTest() {}
137 virtual void SetUp() OVERRIDE
{
138 // Initialize DBusThreadManager with a stub implementation.
139 DBusThreadManager::InitializeWithStub();
140 SetupNetworkStateHandler();
141 message_loop_
.RunUntilIdle();
144 virtual void TearDown() OVERRIDE
{
145 network_state_handler_
->RemoveObserver(test_observer_
.get(), FROM_HERE
);
146 test_observer_
.reset();
147 network_state_handler_
.reset();
148 DBusThreadManager::Shutdown();
151 void SetupNetworkStateHandler() {
152 SetupDefaultShillState();
153 network_state_handler_
.reset(new NetworkStateHandler
);
154 test_observer_
.reset(new TestObserver(network_state_handler_
.get()));
155 network_state_handler_
->AddObserver(test_observer_
.get(), FROM_HERE
);
156 network_state_handler_
->InitShillPropertyHandler();
160 void SetupDefaultShillState() {
161 message_loop_
.RunUntilIdle(); // Process any pending updates
162 ShillDeviceClient::TestInterface
* device_test
=
163 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
164 device_test
->ClearDevices();
165 device_test
->AddDevice("/device/stub_wifi_device1",
166 flimflam::kTypeWifi
, "stub_wifi_device1");
167 device_test
->AddDevice("/device/stub_cellular_device1",
168 flimflam::kTypeCellular
, "stub_cellular_device1");
170 ShillServiceClient::TestInterface
* service_test
=
171 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
172 service_test
->ClearServices();
173 const bool add_to_visible
= true;
174 const bool add_to_watchlist
= true;
175 service_test
->AddService(kShillManagerClientStubDefaultService
,
176 kShillManagerClientStubDefaultService
,
177 flimflam::kTypeEthernet
, flimflam::kStateOnline
,
178 add_to_visible
, add_to_watchlist
);
179 service_test
->AddService(kShillManagerClientStubDefaultWireless
,
180 kShillManagerClientStubDefaultWireless
,
181 flimflam::kTypeWifi
, flimflam::kStateOnline
,
182 add_to_visible
, add_to_watchlist
);
183 service_test
->AddService(kShillManagerClientStubWireless2
,
184 kShillManagerClientStubWireless2
,
185 flimflam::kTypeWifi
, flimflam::kStateIdle
,
186 add_to_visible
, add_to_watchlist
);
187 service_test
->AddService(kShillManagerClientStubCellular
,
188 kShillManagerClientStubCellular
,
189 flimflam::kTypeCellular
, flimflam::kStateIdle
,
190 add_to_visible
, add_to_watchlist
);
193 base::MessageLoopForUI message_loop_
;
194 scoped_ptr
<NetworkStateHandler
> network_state_handler_
;
195 scoped_ptr
<TestObserver
> test_observer_
;
198 DISALLOW_COPY_AND_ASSIGN(NetworkStateHandlerTest
);
201 TEST_F(NetworkStateHandlerTest
, NetworkStateHandlerStub
) {
202 // Ensure that the network list is the expected size.
203 const size_t kNumShillManagerClientStubImplServices
= 4;
204 EXPECT_EQ(kNumShillManagerClientStubImplServices
,
205 test_observer_
->network_count());
206 // Ensure that the first stub network is the default network.
207 EXPECT_EQ(kShillManagerClientStubDefaultService
,
208 test_observer_
->default_network());
209 EXPECT_EQ(kShillManagerClientStubDefaultService
,
210 network_state_handler_
->ConnectedNetworkByType(
211 NetworkStateHandler::kMatchTypeDefault
)->path());
212 EXPECT_EQ(kShillManagerClientStubDefaultService
,
213 network_state_handler_
->ConnectedNetworkByType(
214 flimflam::kTypeEthernet
)->path());
215 EXPECT_EQ(kShillManagerClientStubDefaultWireless
,
216 network_state_handler_
->ConnectedNetworkByType(
217 NetworkStateHandler::kMatchTypeWireless
)->path());
218 EXPECT_EQ(flimflam::kStateOnline
,
219 test_observer_
->default_network_connection_state());
222 TEST_F(NetworkStateHandlerTest
, TechnologyChanged
) {
223 // There may be several manager changes during initialization.
224 size_t initial_changed_count
= test_observer_
->manager_changed_count();
225 // Disable a technology.
226 network_state_handler_
->SetTechnologyEnabled(
227 flimflam::kTypeWimax
, false, network_handler::ErrorCallback());
228 EXPECT_NE(NetworkStateHandler::TECHNOLOGY_ENABLED
,
229 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
230 EXPECT_EQ(initial_changed_count
+ 1, test_observer_
->manager_changed_count());
231 // Enable a technology.
232 network_state_handler_
->SetTechnologyEnabled(
233 flimflam::kTypeWimax
, true, network_handler::ErrorCallback());
234 // The technology state should immediately change to ENABLING and we should
235 // receive a manager changed callback.
236 EXPECT_EQ(initial_changed_count
+ 2, test_observer_
->manager_changed_count());
237 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_ENABLING
,
238 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
239 message_loop_
.RunUntilIdle();
240 // Ensure we receive 2 manager changed callbacks when the technology becomes
241 // avalable and enabled.
242 EXPECT_EQ(initial_changed_count
+ 4, test_observer_
->manager_changed_count());
243 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_ENABLED
,
244 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
247 TEST_F(NetworkStateHandlerTest
, TechnologyState
) {
248 ShillManagerClient::TestInterface
* manager_test
=
249 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
250 manager_test
->RemoveTechnology(flimflam::kTypeWimax
);
251 message_loop_
.RunUntilIdle();
252 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_UNAVAILABLE
,
253 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
255 manager_test
->AddTechnology(flimflam::kTypeWimax
, false);
256 message_loop_
.RunUntilIdle();
257 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_AVAILABLE
,
258 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
260 manager_test
->SetTechnologyInitializing(flimflam::kTypeWimax
, true);
261 message_loop_
.RunUntilIdle();
262 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_UNINITIALIZED
,
263 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
265 manager_test
->SetTechnologyInitializing(flimflam::kTypeWimax
, false);
266 network_state_handler_
->SetTechnologyEnabled(
267 flimflam::kTypeWimax
, true, network_handler::ErrorCallback());
268 message_loop_
.RunUntilIdle();
269 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_ENABLED
,
270 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
272 manager_test
->RemoveTechnology(flimflam::kTypeWimax
);
273 message_loop_
.RunUntilIdle();
274 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_UNAVAILABLE
,
275 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
278 TEST_F(NetworkStateHandlerTest
, ServicePropertyChanged
) {
279 // Set a service property.
280 const std::string eth1
= kShillManagerClientStubDefaultService
;
281 EXPECT_EQ("", network_state_handler_
->GetNetworkState(eth1
)->security());
282 EXPECT_EQ(1, test_observer_
->PropertyUpdatesForService(eth1
));
283 base::StringValue
security_value("TestSecurity");
284 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
285 dbus::ObjectPath(eth1
),
286 flimflam::kSecurityProperty
, security_value
,
287 base::Bind(&base::DoNothing
), base::Bind(&ErrorCallbackFunction
));
288 message_loop_
.RunUntilIdle();
289 EXPECT_EQ("TestSecurity",
290 network_state_handler_
->GetNetworkState(eth1
)->security());
291 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(eth1
));
293 // Changing a service to the existing value should not trigger an update.
294 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
295 dbus::ObjectPath(eth1
),
296 flimflam::kSecurityProperty
, security_value
,
297 base::Bind(&base::DoNothing
), base::Bind(&ErrorCallbackFunction
));
298 message_loop_
.RunUntilIdle();
299 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(eth1
));
302 TEST_F(NetworkStateHandlerTest
, FavoriteState
) {
303 // Set the profile entry of a service
304 const std::string wifi1
= kShillManagerClientStubDefaultWireless
;
305 ShillProfileClient::TestInterface
* profile_test
=
306 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
307 EXPECT_TRUE(profile_test
->AddService("/profile/default", wifi1
));
308 message_loop_
.RunUntilIdle();
309 network_state_handler_
->UpdateManagerProperties();
310 message_loop_
.RunUntilIdle();
311 EXPECT_EQ(1u, test_observer_
->favorite_count());
314 TEST_F(NetworkStateHandlerTest
, NetworkConnectionStateChanged
) {
315 // Change a network state.
316 ShillServiceClient::TestInterface
* service_test
=
317 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
318 const std::string eth1
= kShillManagerClientStubDefaultService
;
319 base::StringValue
connection_state_idle_value(flimflam::kStateIdle
);
320 service_test
->SetServiceProperty(eth1
, flimflam::kStateProperty
,
321 connection_state_idle_value
);
322 message_loop_
.RunUntilIdle();
323 EXPECT_EQ(flimflam::kStateIdle
,
324 test_observer_
->NetworkConnectionStateForService(eth1
));
325 EXPECT_EQ(2, test_observer_
->ConnectionStateChangesForService(eth1
));
326 // Confirm that changing the connection state to the same value does *not*
327 // signal the observer.
328 service_test
->SetServiceProperty(eth1
, flimflam::kStateProperty
,
329 connection_state_idle_value
);
330 message_loop_
.RunUntilIdle();
331 EXPECT_EQ(2, test_observer_
->ConnectionStateChangesForService(eth1
));
334 TEST_F(NetworkStateHandlerTest
, DefaultServiceChanged
) {
335 ShillManagerClient::TestInterface
* manager_test
=
336 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
337 ASSERT_TRUE(manager_test
);
338 ShillServiceClient::TestInterface
* service_test
=
339 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
340 ASSERT_TRUE(service_test
);
342 // Change the default network by changing the state of eth1 to Idle which
343 // should re-sort Manager.Services.
344 const std::string eth1
= kShillManagerClientStubDefaultService
;
345 const std::string wifi1
= kShillManagerClientStubDefaultWireless
;
346 base::StringValue
connection_state_idle_value(flimflam::kStateIdle
);
347 service_test
->SetServiceProperty(eth1
, flimflam::kStateProperty
,
348 connection_state_idle_value
);
349 message_loop_
.RunUntilIdle();
350 EXPECT_EQ(wifi1
, test_observer_
->default_network());
351 EXPECT_EQ(flimflam::kStateOnline
,
352 test_observer_
->default_network_connection_state());
353 // We should have seen 2 default network updates - for the default
354 // service change, and for the state change.
355 EXPECT_EQ(2u, test_observer_
->default_network_change_count());
357 // Updating a property on the default network should trigger
358 // a default network change.
359 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
360 dbus::ObjectPath(wifi1
),
361 flimflam::kSecurityProperty
, base::StringValue("TestSecurity"),
362 base::Bind(&base::DoNothing
), base::Bind(&ErrorCallbackFunction
));
363 message_loop_
.RunUntilIdle();
364 EXPECT_EQ(3u, test_observer_
->default_network_change_count());
366 // No default network updates for signal strength changes.
367 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
368 dbus::ObjectPath(wifi1
),
369 flimflam::kSignalStrengthProperty
, base::FundamentalValue(32),
370 base::Bind(&base::DoNothing
), base::Bind(&ErrorCallbackFunction
));
371 message_loop_
.RunUntilIdle();
372 EXPECT_EQ(3u, test_observer_
->default_network_change_count());
375 TEST_F(NetworkStateHandlerTest
, RequestUpdate
) {
376 // Request an update for kShillManagerClientStubDefaultWireless.
377 EXPECT_EQ(1, test_observer_
->PropertyUpdatesForService(
378 kShillManagerClientStubDefaultWireless
));
379 network_state_handler_
->RequestUpdateForNetwork(
380 kShillManagerClientStubDefaultWireless
);
381 message_loop_
.RunUntilIdle();
382 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(
383 kShillManagerClientStubDefaultWireless
));
385 // Request an update for all networks.
386 network_state_handler_
->RequestUpdateForAllNetworks();
387 message_loop_
.RunUntilIdle();
388 // kShillManagerClientStubDefaultWireless should now have 3 updates
389 EXPECT_EQ(3, test_observer_
->PropertyUpdatesForService(
390 kShillManagerClientStubDefaultWireless
));
391 // Other networks should have 2 updates (inital + request).
392 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(
393 kShillManagerClientStubDefaultService
));
394 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(
395 kShillManagerClientStubWireless2
));
396 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(
397 kShillManagerClientStubCellular
));
400 } // namespace chromeos