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.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"
27 void ErrorCallbackFunction(const std::string
& error_name
,
28 const std::string
& error_message
) {
29 LOG(ERROR
) << "Shill Error: " << error_name
<< " : " << error_message
;
32 const std::string kShillManagerClientStubDefaultService
= "stub_ethernet";
33 const std::string kShillManagerClientStubDefaultWireless
= "stub_wifi1";
34 const std::string kShillManagerClientStubWireless2
= "stub_wifi2";
35 const std::string kShillManagerClientStubCellular
= "stub_cellular";
37 using chromeos::NetworkState
;
38 using chromeos::NetworkStateHandler
;
40 class TestObserver
: public chromeos::NetworkStateHandlerObserver
{
42 explicit TestObserver(NetworkStateHandler
* handler
)
44 manager_changed_count_(0),
46 default_network_change_count_(0) {
49 virtual ~TestObserver() {
52 virtual void NetworkManagerChanged() OVERRIDE
{
53 ++manager_changed_count_
;
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_
= "";
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() : "";
73 virtual void NetworkConnectionStateChanged(
74 const NetworkState
* network
) OVERRIDE
{
75 network_connection_state_
[network
->path()] = network
->connection_state();
76 connection_state_changes_
[network
->path()]++;
79 virtual void NetworkPropertiesUpdated(const NetworkState
* network
) OVERRIDE
{
81 property_updates_
[network
->path()]++;
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_
;
89 std::string
default_network() { return default_network_
; }
90 std::string
default_network_connection_state() {
91 return default_network_connection_state_
;
94 int PropertyUpdatesForService(const std::string
& service_path
) {
95 return property_updates_
[service_path
];
98 int ConnectionStateChangesForService(const std::string
& service_path
) {
99 return connection_state_changes_
[service_path
];
102 std::string
NetworkConnectionStateForService(
103 const std::string
& service_path
) {
104 return network_connection_state_
[service_path
];
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_
;
118 DISALLOW_COPY_AND_ASSIGN(TestObserver
);
125 class NetworkStateHandlerTest
: public testing::Test
{
127 NetworkStateHandlerTest() {}
128 virtual ~NetworkStateHandlerTest() {}
130 virtual void SetUp() OVERRIDE
{
131 // Initialize DBusThreadManager with a stub implementation.
132 DBusThreadManager::InitializeWithStub();
133 SetupNetworkStateHandler();
134 message_loop_
.RunUntilIdle();
137 virtual void TearDown() OVERRIDE
{
138 network_state_handler_
.reset();
139 test_observer_
.reset();
140 DBusThreadManager::Shutdown();
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();
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");
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
,
170 service_test
->AddService(kShillManagerClientStubDefaultWireless
,
171 kShillManagerClientStubDefaultWireless
,
172 flimflam::kTypeWifi
, flimflam::kStateOnline
,
174 service_test
->AddService(kShillManagerClientStubWireless2
,
175 kShillManagerClientStubWireless2
,
176 flimflam::kTypeWifi
, flimflam::kStateIdle
,
178 service_test
->AddService(kShillManagerClientStubCellular
,
179 kShillManagerClientStubCellular
,
180 flimflam::kTypeCellular
, flimflam::kStateIdle
,
184 MessageLoopForUI message_loop_
;
185 scoped_ptr
<NetworkStateHandler
> network_state_handler_
;
186 scoped_ptr
<TestObserver
> test_observer_
;
189 DISALLOW_COPY_AND_ASSIGN(NetworkStateHandlerTest
);
192 TEST_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());
214 TEST_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
229 EXPECT_EQ(3u, test_observer_
->manager_changed_count());
230 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_ENABLED
,
231 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
234 TEST_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
));
240 manager_test
->AddTechnology(flimflam::kTypeWimax
, false);
241 message_loop_
.RunUntilIdle();
242 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_AVAILABLE
,
243 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
245 manager_test
->SetTechnologyInitializing(flimflam::kTypeWimax
, true);
246 message_loop_
.RunUntilIdle();
247 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_UNINITIALIZED
,
248 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
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
));
257 manager_test
->RemoveTechnology(flimflam::kTypeWimax
);
258 message_loop_
.RunUntilIdle();
259 EXPECT_EQ(NetworkStateHandler::TECHNOLOGY_UNAVAILABLE
,
260 network_state_handler_
->GetTechnologyState(flimflam::kTypeWimax
));
263 TEST_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
));
278 // Changing a service to the exsiting value should not trigger an update.
279 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
280 dbus::ObjectPath(eth0
),
281 flimflam::kSecurityProperty
, security_value
,
282 base::Bind(&base::DoNothing
), base::Bind(&ErrorCallbackFunction
));
283 message_loop_
.RunUntilIdle();
284 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(eth0
));
287 TEST_F(NetworkStateHandlerTest
, NetworkConnectionStateChanged
) {
288 // Change a network state.
289 ShillServiceClient::TestInterface
* service_test
=
290 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
291 const std::string eth0
= kShillManagerClientStubDefaultService
;
292 base::StringValue
connection_state_idle_value(flimflam::kStateIdle
);
293 service_test
->SetServiceProperty(eth0
, flimflam::kStateProperty
,
294 connection_state_idle_value
);
295 message_loop_
.RunUntilIdle();
296 EXPECT_EQ(flimflam::kStateIdle
,
297 test_observer_
->NetworkConnectionStateForService(eth0
));
298 EXPECT_EQ(2, test_observer_
->ConnectionStateChangesForService(eth0
));
299 // Confirm that changing the connection state to the same value does *not*
300 // signal the observer.
301 service_test
->SetServiceProperty(eth0
, flimflam::kStateProperty
,
302 connection_state_idle_value
);
303 message_loop_
.RunUntilIdle();
304 EXPECT_EQ(2, test_observer_
->ConnectionStateChangesForService(eth0
));
307 TEST_F(NetworkStateHandlerTest
, DefaultServiceChanged
) {
308 ShillManagerClient::TestInterface
* manager_test
=
309 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
310 ASSERT_TRUE(manager_test
);
311 ShillServiceClient::TestInterface
* service_test
=
312 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
313 ASSERT_TRUE(service_test
);
315 // Change the default network by moving wifi1 to the front of the list
316 // and changing the state of stub_ethernet to Idle.
317 const std::string wifi1
= kShillManagerClientStubDefaultWireless
;
318 manager_test
->MoveServiceToIndex(wifi1
, 0, true);
319 const std::string eth0
= kShillManagerClientStubDefaultService
;
320 base::StringValue
connection_state_idle_value(flimflam::kStateIdle
);
321 service_test
->SetServiceProperty(eth0
, flimflam::kStateProperty
,
322 connection_state_idle_value
);
323 message_loop_
.RunUntilIdle();
324 EXPECT_EQ(wifi1
, test_observer_
->default_network());
325 EXPECT_EQ(flimflam::kStateOnline
,
326 test_observer_
->default_network_connection_state());
327 // We should have seen 2 default network updates - for the default
328 // service change, and for the state change.
329 EXPECT_EQ(2u, test_observer_
->default_network_change_count());
331 // Updating a property on the default network should trigger
332 // a default network change.
333 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
334 dbus::ObjectPath(wifi1
),
335 flimflam::kSecurityProperty
, base::StringValue("TestSecurity"),
336 base::Bind(&base::DoNothing
), base::Bind(&ErrorCallbackFunction
));
337 message_loop_
.RunUntilIdle();
338 EXPECT_EQ(3u, test_observer_
->default_network_change_count());
340 // No default network updates for signal strength changes.
341 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
342 dbus::ObjectPath(wifi1
),
343 flimflam::kSignalStrengthProperty
, base::FundamentalValue(32),
344 base::Bind(&base::DoNothing
), base::Bind(&ErrorCallbackFunction
));
345 message_loop_
.RunUntilIdle();
346 EXPECT_EQ(3u, test_observer_
->default_network_change_count());
349 } // namespace chromeos