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