OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 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/components/tether/tether_disconnector.h" | |
6 | |
7 #include "base/memory/ptr_util.h" | |
8 #include "base/message_loop/message_loop.h" | |
9 #include "chromeos/components/tether/connect_tethering_operation.h" | |
10 #include "chromeos/components/tether/device_id_tether_network_guid_map.h" | |
11 #include "chromeos/components/tether/fake_active_host.h" | |
12 #include "chromeos/components/tether/fake_ble_connection_manager.h" | |
13 #include "chromeos/components/tether/fake_network_configuration_remover.h" | |
14 #include "chromeos/components/tether/fake_tether_host_fetcher.h" | |
15 #include "chromeos/components/tether/fake_wifi_hotspot_connector.h" | |
16 #include "chromeos/components/tether/mock_tether_host_response_recorder.h" | |
17 #include "chromeos/components/tether/tether_connector.h" | |
18 #include "chromeos/dbus/dbus_thread_manager.h" | |
19 #include "chromeos/network/network_connection_handler.h" | |
20 #include "chromeos/network/network_state.h" | |
21 #include "chromeos/network/network_state_handler.h" | |
22 #include "chromeos/network/network_state_test.h" | |
23 #include "components/cryptauth/remote_device.h" | |
24 #include "components/cryptauth/remote_device_test_util.h" | |
25 #include "testing/gmock/include/gmock/gmock.h" | |
26 #include "testing/gtest/include/gtest/gtest.h" | |
27 #include "third_party/cros_system_api/dbus/shill/dbus-constants.h" | |
28 | |
29 namespace chromeos { | |
30 | |
31 namespace tether { | |
32 | |
33 namespace { | |
34 | |
35 const char kSuccessResult[] = "success"; | |
36 | |
37 const char kWifiNetworkGuid[] = "wifiNetworkGuid"; | |
38 | |
39 std::string CreateConnectedWifiConfigurationJsonString() { | |
40 std::stringstream ss; | |
41 ss << "{" | |
42 << " \"GUID\": \"" << kWifiNetworkGuid << "\"," | |
43 << " \"Type\": \"" << shill::kTypeWifi << "\"," | |
44 << " \"State\": \"" << shill::kStateOnline << "\"" | |
45 << "}"; | |
46 return ss.str(); | |
47 } | |
48 | |
49 class TestNetworkConnectionHandler : public NetworkConnectionHandler { | |
50 public: | |
51 TestNetworkConnectionHandler(base::Closure disconnect_callback) | |
52 : disconnect_callback_(disconnect_callback) {} | |
53 ~TestNetworkConnectionHandler() override {} | |
54 | |
55 std::string last_disconnect_service_path() { | |
56 return last_disconnect_service_path_; | |
57 } | |
58 | |
59 base::Closure last_disconnect_success_callback() { | |
60 return last_disconnect_success_callback_; | |
61 } | |
62 | |
63 network_handler::ErrorCallback last_disconnect_error_callback() { | |
64 return last_disconnect_error_callback_; | |
65 } | |
66 | |
67 // NetworkConnectionHandler: | |
68 void DisconnectNetwork( | |
69 const std::string& service_path, | |
70 const base::Closure& success_callback, | |
71 const network_handler::ErrorCallback& error_callback) override { | |
72 last_disconnect_service_path_ = service_path; | |
73 last_disconnect_success_callback_ = success_callback; | |
74 last_disconnect_error_callback_ = error_callback; | |
75 | |
76 disconnect_callback_.Run(); | |
77 } | |
78 void ConnectToNetwork(const std::string& service_path, | |
79 const base::Closure& success_callback, | |
80 const network_handler::ErrorCallback& error_callback, | |
81 bool check_error_state) override {} | |
82 bool HasConnectingNetwork(const std::string& service_path) override { | |
83 return false; | |
84 } | |
85 bool HasPendingConnectRequest() override { return false; } | |
86 void Init(NetworkStateHandler* network_state_handler, | |
87 NetworkConfigurationHandler* network_configuration_handler, | |
88 ManagedNetworkConfigurationHandler* | |
89 managed_network_configuration_handler) override {} | |
90 | |
91 private: | |
92 base::Closure disconnect_callback_; | |
93 | |
94 std::string last_disconnect_service_path_; | |
95 base::Closure last_disconnect_success_callback_; | |
96 network_handler::ErrorCallback last_disconnect_error_callback_; | |
97 }; | |
98 | |
99 class TestTetherConnector : public TetherConnector { | |
100 public: | |
101 TestTetherConnector() | |
102 : TetherConnector(nullptr /* network_state_handler */, | |
103 nullptr /* wifi_hotspot_connector */, | |
104 nullptr /* active_host */, | |
105 nullptr /* tether_host_fetcher */, | |
106 nullptr /* connection_manager */, | |
107 nullptr /* tether_host_response_recorder */, | |
108 nullptr /* device_id_tether_network_guid_map */), | |
109 should_cancel_successfully_(true) {} | |
110 ~TestTetherConnector() override {} | |
111 | |
112 void set_should_cancel_successfully(bool should_cancel_successfully) { | |
113 should_cancel_successfully_ = should_cancel_successfully; | |
114 } | |
115 | |
116 std::string last_canceled_tether_network_guid() { | |
117 return last_canceled_tether_network_guid_; | |
118 } | |
119 | |
120 // TetherConnector: | |
121 bool CancelConnectionAttempt( | |
122 const std::string& tether_network_guid) override { | |
123 last_canceled_tether_network_guid_ = tether_network_guid; | |
124 return should_cancel_successfully_; | |
125 } | |
126 | |
127 private: | |
128 bool should_cancel_successfully_; | |
129 std::string last_canceled_tether_network_guid_; | |
130 }; | |
131 | |
132 class FakeDisconnectTetheringOperation : public DisconnectTetheringOperation { | |
133 public: | |
134 FakeDisconnectTetheringOperation( | |
135 const cryptauth::RemoteDevice& device_to_connect, | |
136 BleConnectionManager* connection_manager) | |
137 : DisconnectTetheringOperation(device_to_connect, connection_manager) {} | |
138 | |
139 ~FakeDisconnectTetheringOperation() override {} | |
140 | |
141 void NotifyFinished(bool success) { | |
142 NotifyObserversOperationFinished(success); | |
143 } | |
144 | |
145 cryptauth::RemoteDevice GetRemoteDevice() { | |
146 EXPECT_EQ(1u, remote_devices().size()); | |
147 return remote_devices()[0]; | |
148 } | |
149 }; | |
150 | |
151 class FakeDisconnectTetheringOperationFactory | |
152 : public DisconnectTetheringOperation::Factory { | |
153 public: | |
154 FakeDisconnectTetheringOperationFactory() {} | |
155 virtual ~FakeDisconnectTetheringOperationFactory() {} | |
156 | |
157 std::vector<FakeDisconnectTetheringOperation*>& created_operations() { | |
158 return created_operations_; | |
159 } | |
160 | |
161 protected: | |
162 // DisconnectTetheringOperation::Factory: | |
163 std::unique_ptr<DisconnectTetheringOperation> BuildInstance( | |
164 const cryptauth::RemoteDevice& device_to_connect, | |
165 BleConnectionManager* connection_manager) override { | |
166 FakeDisconnectTetheringOperation* operation = | |
167 new FakeDisconnectTetheringOperation(device_to_connect, | |
168 connection_manager); | |
169 created_operations_.push_back(operation); | |
170 return base::WrapUnique(operation); | |
171 } | |
172 | |
173 private: | |
174 std::vector<FakeDisconnectTetheringOperation*> created_operations_; | |
175 }; | |
176 | |
177 } // namespace | |
178 | |
179 class TetherDisconnectorTest : public NetworkStateTest { | |
180 public: | |
181 TetherDisconnectorTest() | |
182 : test_devices_(cryptauth::GenerateTestRemoteDevices(2u)) {} | |
183 ~TetherDisconnectorTest() override {} | |
184 | |
185 void SetUp() override { | |
186 DBusThreadManager::Initialize(); | |
187 NetworkStateTest::SetUp(); | |
188 | |
189 should_disconnect_successfully_ = true; | |
190 | |
191 test_network_connection_handler_ = | |
192 base::WrapUnique(new TestNetworkConnectionHandler(base::Bind( | |
193 &TetherDisconnectorTest::OnNetworkConnectionManagerDisconnect, | |
194 base::Unretained(this)))); | |
195 fake_active_host_ = base::MakeUnique<FakeActiveHost>(); | |
196 fake_ble_connection_manager_ = base::MakeUnique<FakeBleConnectionManager>(); | |
197 fake_network_configuration_remover_ = | |
198 base::MakeUnique<FakeNetworkConfigurationRemover>(); | |
199 test_tether_connector_ = base::WrapUnique(new TestTetherConnector()); | |
200 device_id_tether_network_guid_map_ = | |
201 base::MakeUnique<DeviceIdTetherNetworkGuidMap>(); | |
202 fake_tether_host_fetcher_ = base::MakeUnique<FakeTetherHostFetcher>( | |
203 test_devices_, true /* synchronously_reply_with_results */); | |
204 | |
205 fake_operation_factory_ = | |
206 base::WrapUnique(new FakeDisconnectTetheringOperationFactory()); | |
207 DisconnectTetheringOperation::Factory::SetInstanceForTesting( | |
208 fake_operation_factory_.get()); | |
209 | |
210 SetUpTetherNetworks(); | |
211 | |
212 tether_disconnector_ = base::MakeUnique<TetherDisconnector>( | |
213 test_network_connection_handler_.get(), network_state_handler(), | |
214 fake_active_host_.get(), fake_ble_connection_manager_.get(), | |
215 fake_network_configuration_remover_.get(), test_tether_connector_.get(), | |
216 device_id_tether_network_guid_map_.get(), | |
217 fake_tether_host_fetcher_.get()); | |
218 } | |
219 | |
220 void TearDown() override { | |
221 ShutdownNetworkState(); | |
222 NetworkStateTest::TearDown(); | |
223 DBusThreadManager::Shutdown(); | |
224 } | |
225 | |
226 std::string GetTetherNetworkGuid(const std::string& device_id) { | |
227 return device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId( | |
228 device_id); | |
229 } | |
230 | |
231 void SetUpTetherNetworks() { | |
232 network_state_handler()->SetTetherTechnologyState( | |
233 NetworkStateHandler::TECHNOLOGY_ENABLED); | |
234 | |
235 // Add a tether network corresponding to both of the test devices. These | |
236 // networks are expected to be added already before | |
237 // TetherDisconnector::DisconnectFromNetwork() is called. | |
238 network_state_handler()->AddTetherNetworkState( | |
239 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), | |
240 "TetherNetworkName1", "TetherNetworkCarrier1", | |
241 85 /* battery_percentage */, 75 /* signal_strength */, | |
242 true /* has_connected_to_host */); | |
243 network_state_handler()->AddTetherNetworkState( | |
244 GetTetherNetworkGuid(test_devices_[1].GetDeviceId()), | |
245 "TetherNetworkName2", "TetherNetworkCarrier2", | |
246 90 /* battery_percentage */, 50 /* signal_strength */, | |
247 true /* has_connected_to_host */); | |
248 } | |
249 | |
250 void SimulateConnectionToWifiNetwork() { | |
251 wifi_service_path_ = | |
252 ConfigureService(CreateConnectedWifiConfigurationJsonString()); | |
253 EXPECT_FALSE(wifi_service_path_.empty()); | |
254 } | |
255 | |
256 void SuccessCallback() { result_ = kSuccessResult; } | |
257 | |
258 void ErrorCallback(const std::string& error_name) { result_ = error_name; } | |
259 | |
260 void CallDisconnect(const std::string& tether_network_guid) { | |
261 tether_disconnector_->DisconnectFromNetwork( | |
262 tether_network_guid, | |
263 base::Bind(&TetherDisconnectorTest::SuccessCallback, | |
264 base::Unretained(this)), | |
265 base::Bind(&TetherDisconnectorTest::ErrorCallback, | |
266 base::Unretained(this))); | |
267 } | |
268 | |
269 // This function is called by | |
270 // TestNetworkConnectionHandler::DisconnectFromNetwork(). | |
271 void OnNetworkConnectionManagerDisconnect() { | |
272 EXPECT_EQ(wifi_service_path_, | |
273 test_network_connection_handler_->last_disconnect_service_path()); | |
274 | |
275 if (should_disconnect_successfully_) { | |
276 SetServiceProperty(wifi_service_path_, shill::kStateProperty, | |
277 base::Value(shill::kStateIdle)); | |
278 EXPECT_FALSE( | |
279 test_network_connection_handler_->last_disconnect_success_callback() | |
280 .is_null()); | |
281 test_network_connection_handler_->last_disconnect_success_callback() | |
282 .Run(); | |
283 } else { | |
284 EXPECT_FALSE( | |
285 test_network_connection_handler_->last_disconnect_error_callback() | |
286 .is_null()); | |
287 network_handler::RunErrorCallback( | |
288 test_network_connection_handler_->last_disconnect_error_callback(), | |
289 wifi_service_path_, NetworkConnectionHandler::kErrorDisconnectFailed, | |
290 "" /* error_detail */); | |
291 } | |
292 } | |
293 | |
294 std::string GetResultAndReset() { | |
295 std::string result; | |
296 result.swap(result_); | |
Ryan Hansberry
2017/05/04 01:56:28
Please use a more descriptive name.
Kyle Horimoto
2017/05/04 02:00:14
Done.
| |
297 return result; | |
298 } | |
299 | |
300 const std::vector<cryptauth::RemoteDevice> test_devices_; | |
301 const base::MessageLoop message_loop_; | |
302 | |
303 std::unique_ptr<TestNetworkConnectionHandler> | |
304 test_network_connection_handler_; | |
305 std::unique_ptr<FakeActiveHost> fake_active_host_; | |
306 std::unique_ptr<FakeBleConnectionManager> fake_ble_connection_manager_; | |
307 std::unique_ptr<FakeNetworkConfigurationRemover> | |
308 fake_network_configuration_remover_; | |
309 std::unique_ptr<TestTetherConnector> test_tether_connector_; | |
310 // TODO(hansberry): Use a fake for this when a real mapping scheme is created. | |
311 std::unique_ptr<DeviceIdTetherNetworkGuidMap> | |
312 device_id_tether_network_guid_map_; | |
313 std::unique_ptr<FakeTetherHostFetcher> fake_tether_host_fetcher_; | |
314 | |
315 std::unique_ptr<FakeDisconnectTetheringOperationFactory> | |
316 fake_operation_factory_; | |
317 | |
318 std::string wifi_service_path_; | |
319 std::string result_; | |
320 bool should_disconnect_successfully_; | |
321 | |
322 std::unique_ptr<TetherDisconnector> tether_disconnector_; | |
323 | |
324 private: | |
325 DISALLOW_COPY_AND_ASSIGN(TetherDisconnectorTest); | |
326 }; | |
327 | |
328 TEST_F(TetherDisconnectorTest, DisconnectWhenAlreadyDisconnected) { | |
329 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
330 EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset()); | |
331 | |
332 // Should still be disconnected. | |
333 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, | |
334 fake_active_host_->GetActiveHostStatus()); | |
335 } | |
336 | |
337 TEST_F(TetherDisconnectorTest, DisconnectWhenOtherDeviceConnected) { | |
338 fake_active_host_->SetActiveHostConnected( | |
339 test_devices_[1].GetDeviceId(), | |
340 GetTetherNetworkGuid(test_devices_[1].GetDeviceId()), | |
341 "otherWifiNetworkGuid"); | |
342 | |
343 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
344 EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset()); | |
345 | |
346 // Should still be connected to the other host. | |
347 EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTED, | |
348 fake_active_host_->GetActiveHostStatus()); | |
349 EXPECT_EQ(test_devices_[1].GetDeviceId(), | |
350 fake_active_host_->GetActiveHostDeviceId()); | |
351 } | |
352 | |
353 TEST_F(TetherDisconnectorTest, DisconnectWhenConnecting_CancelFails) { | |
354 fake_active_host_->SetActiveHostConnecting( | |
355 test_devices_[0].GetDeviceId(), | |
356 GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
357 test_tether_connector_->set_should_cancel_successfully(false); | |
358 | |
359 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
360 EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed, | |
361 GetResultAndReset()); | |
362 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), | |
363 test_tether_connector_->last_canceled_tether_network_guid()); | |
364 | |
365 // Note: This test does not check the active host's status because it will be | |
366 // changed by TetherConnector. | |
367 } | |
368 | |
369 TEST_F(TetherDisconnectorTest, DisconnectWhenConnecting_CancelSucceeds) { | |
370 fake_active_host_->SetActiveHostConnecting( | |
371 test_devices_[0].GetDeviceId(), | |
372 GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
373 test_tether_connector_->set_should_cancel_successfully(true); | |
374 | |
375 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
376 EXPECT_EQ(kSuccessResult, GetResultAndReset()); | |
377 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), | |
378 test_tether_connector_->last_canceled_tether_network_guid()); | |
379 | |
380 // Note: This test does not check the active host's status because it will be | |
381 // changed by TetherConnector. | |
382 } | |
383 | |
384 TEST_F(TetherDisconnectorTest, DisconnectWhenConnected_NotActuallyConnected) { | |
385 fake_active_host_->SetActiveHostConnected( | |
386 test_devices_[0].GetDeviceId(), | |
387 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), | |
388 "nonExistentWifiGuid"); | |
389 | |
390 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
391 EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed, | |
392 GetResultAndReset()); | |
393 | |
394 // Should be disconnected. | |
395 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, | |
396 fake_active_host_->GetActiveHostStatus()); | |
397 } | |
398 | |
399 TEST_F(TetherDisconnectorTest, | |
400 DisconnectWhenConnected_WifiConnectionFails_CannotFetchHost) { | |
401 fake_active_host_->SetActiveHostConnected( | |
402 test_devices_[0].GetDeviceId(), | |
403 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); | |
404 SimulateConnectionToWifiNetwork(); | |
405 | |
406 // Remove hosts from |fake_tether_host_fetcher_|; this will cause the fetcher | |
407 // to return a null RemoteDevice. | |
408 fake_tether_host_fetcher_->SetTetherHosts( | |
409 std::vector<cryptauth::RemoteDevice>()); | |
410 | |
411 should_disconnect_successfully_ = false; | |
412 | |
413 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
414 EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed, | |
415 GetResultAndReset()); | |
416 | |
417 // The Wi-Fi network should still be connected since disconnection failed. | |
418 EXPECT_EQ( | |
419 shill::kStateOnline, | |
420 GetServiceStringProperty(wifi_service_path_, shill::kStateProperty)); | |
421 | |
422 // Should not have created any operations since the fetch failed. | |
423 EXPECT_TRUE(fake_operation_factory_->created_operations().empty()); | |
424 | |
425 // Should be disconnected. | |
426 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, | |
427 fake_active_host_->GetActiveHostStatus()); | |
428 } | |
429 | |
430 TEST_F(TetherDisconnectorTest, | |
431 DisconnectWhenConnected_WifiConnectionSucceeds_CannotFetchHost) { | |
432 fake_active_host_->SetActiveHostConnected( | |
433 test_devices_[0].GetDeviceId(), | |
434 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); | |
435 SimulateConnectionToWifiNetwork(); | |
436 | |
437 // Remove hosts from |fake_tether_host_fetcher_|; this will cause the fetcher | |
438 // to return a null RemoteDevice. | |
439 fake_tether_host_fetcher_->SetTetherHosts( | |
440 std::vector<cryptauth::RemoteDevice>()); | |
441 | |
442 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
443 EXPECT_EQ(kSuccessResult, GetResultAndReset()); | |
444 | |
445 // The Wi-Fi network should be disconnected since disconnection failed. | |
446 EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_, | |
447 shill::kStateProperty)); | |
448 | |
449 // Should not have created any operations since the fetch failed. | |
450 EXPECT_TRUE(fake_operation_factory_->created_operations().empty()); | |
451 | |
452 // Should be disconnected. | |
453 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, | |
454 fake_active_host_->GetActiveHostStatus()); | |
455 } | |
456 | |
457 TEST_F(TetherDisconnectorTest, | |
458 DisconnectWhenConnected_WifiConnectionFails_OperationFails) { | |
459 fake_active_host_->SetActiveHostConnected( | |
460 test_devices_[0].GetDeviceId(), | |
461 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); | |
462 SimulateConnectionToWifiNetwork(); | |
463 | |
464 should_disconnect_successfully_ = false; | |
465 | |
466 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
467 EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed, | |
468 GetResultAndReset()); | |
469 | |
470 // The Wi-Fi network should still be connected since disconnection failed. | |
471 EXPECT_EQ( | |
472 shill::kStateOnline, | |
473 GetServiceStringProperty(wifi_service_path_, shill::kStateProperty)); | |
474 | |
475 // Fail the operation. | |
476 ASSERT_EQ(1u, fake_operation_factory_->created_operations().size()); | |
477 EXPECT_EQ( | |
478 test_devices_[0], | |
479 fake_operation_factory_->created_operations()[0]->GetRemoteDevice()); | |
480 fake_operation_factory_->created_operations()[0]->NotifyFinished( | |
481 false /* success */); | |
482 | |
483 // Should be disconnected. | |
484 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, | |
485 fake_active_host_->GetActiveHostStatus()); | |
486 } | |
487 | |
488 TEST_F(TetherDisconnectorTest, | |
489 DisconnectWhenConnected_WifiConnectionSucceeds_OperationFails) { | |
490 fake_active_host_->SetActiveHostConnected( | |
491 test_devices_[0].GetDeviceId(), | |
492 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); | |
493 SimulateConnectionToWifiNetwork(); | |
494 | |
495 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
496 EXPECT_EQ(kSuccessResult, GetResultAndReset()); | |
497 | |
498 // The Wi-Fi network should be disconnected since disconnection failed. | |
499 EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_, | |
500 shill::kStateProperty)); | |
501 | |
502 ASSERT_EQ(1u, fake_operation_factory_->created_operations().size()); | |
503 EXPECT_EQ( | |
504 test_devices_[0], | |
505 fake_operation_factory_->created_operations()[0]->GetRemoteDevice()); | |
506 fake_operation_factory_->created_operations()[0]->NotifyFinished( | |
507 false /* success */); | |
508 | |
509 // Should be disconnected. | |
510 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, | |
511 fake_active_host_->GetActiveHostStatus()); | |
512 } | |
513 | |
514 TEST_F(TetherDisconnectorTest, | |
515 DisconnectWhenConnected_WifiConnectionFails_OperationSucceeds) { | |
516 fake_active_host_->SetActiveHostConnected( | |
517 test_devices_[0].GetDeviceId(), | |
518 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); | |
519 SimulateConnectionToWifiNetwork(); | |
520 | |
521 should_disconnect_successfully_ = false; | |
522 | |
523 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
524 EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed, | |
525 GetResultAndReset()); | |
526 | |
527 // The Wi-Fi network should still be connected since disconnection failed. | |
528 EXPECT_EQ( | |
529 shill::kStateOnline, | |
530 GetServiceStringProperty(wifi_service_path_, shill::kStateProperty)); | |
531 | |
532 // Fail the operation. | |
533 ASSERT_EQ(1u, fake_operation_factory_->created_operations().size()); | |
534 EXPECT_EQ( | |
535 test_devices_[0], | |
536 fake_operation_factory_->created_operations()[0]->GetRemoteDevice()); | |
537 fake_operation_factory_->created_operations()[0]->NotifyFinished( | |
538 true /* success */); | |
539 | |
540 // Should be disconnected. | |
541 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, | |
542 fake_active_host_->GetActiveHostStatus()); | |
543 } | |
544 | |
545 TEST_F(TetherDisconnectorTest, | |
546 DisconnectWhenConnected_WifiConnectionSucceeds_OperationSucceeds) { | |
547 fake_active_host_->SetActiveHostConnected( | |
548 test_devices_[0].GetDeviceId(), | |
549 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); | |
550 SimulateConnectionToWifiNetwork(); | |
551 | |
552 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
553 EXPECT_EQ(kSuccessResult, GetResultAndReset()); | |
554 | |
555 // The Wi-Fi network should be disconnected since disconnection failed. | |
556 EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_, | |
557 shill::kStateProperty)); | |
558 | |
559 ASSERT_EQ(1u, fake_operation_factory_->created_operations().size()); | |
560 EXPECT_EQ( | |
561 test_devices_[0], | |
562 fake_operation_factory_->created_operations()[0]->GetRemoteDevice()); | |
563 fake_operation_factory_->created_operations()[0]->NotifyFinished( | |
564 true /* success */); | |
565 | |
566 // Should be disconnected. | |
567 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, | |
568 fake_active_host_->GetActiveHostStatus()); | |
569 } | |
570 | |
571 TEST_F(TetherDisconnectorTest, | |
572 DisconnectWhenConnected_DestroyBeforeOperationComplete) { | |
573 fake_active_host_->SetActiveHostConnected( | |
574 test_devices_[0].GetDeviceId(), | |
575 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); | |
576 SimulateConnectionToWifiNetwork(); | |
577 | |
578 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | |
579 EXPECT_EQ(kSuccessResult, GetResultAndReset()); | |
580 | |
581 // Stop the test here, before the operation responds in any way. This test | |
582 // ensures that TetherDisconnector properly removes existing listeners if it | |
583 // is destroyed while there are still active operations. | |
584 } | |
585 | |
586 } // namespace tether | |
587 | |
588 } // namespace chromeos | |
OLD | NEW |