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() { disconnection_result_ = kSuccessResult; } |
| 257 |
| 258 void ErrorCallback(const std::string& error_name) { |
| 259 disconnection_result_ = error_name; |
| 260 } |
| 261 |
| 262 void CallDisconnect(const std::string& tether_network_guid) { |
| 263 tether_disconnector_->DisconnectFromNetwork( |
| 264 tether_network_guid, |
| 265 base::Bind(&TetherDisconnectorTest::SuccessCallback, |
| 266 base::Unretained(this)), |
| 267 base::Bind(&TetherDisconnectorTest::ErrorCallback, |
| 268 base::Unretained(this))); |
| 269 } |
| 270 |
| 271 // This function is called by |
| 272 // TestNetworkConnectionHandler::DisconnectFromNetwork(). |
| 273 void OnNetworkConnectionManagerDisconnect() { |
| 274 EXPECT_EQ(wifi_service_path_, |
| 275 test_network_connection_handler_->last_disconnect_service_path()); |
| 276 |
| 277 if (should_disconnect_successfully_) { |
| 278 SetServiceProperty(wifi_service_path_, shill::kStateProperty, |
| 279 base::Value(shill::kStateIdle)); |
| 280 EXPECT_FALSE( |
| 281 test_network_connection_handler_->last_disconnect_success_callback() |
| 282 .is_null()); |
| 283 test_network_connection_handler_->last_disconnect_success_callback() |
| 284 .Run(); |
| 285 } else { |
| 286 EXPECT_FALSE( |
| 287 test_network_connection_handler_->last_disconnect_error_callback() |
| 288 .is_null()); |
| 289 network_handler::RunErrorCallback( |
| 290 test_network_connection_handler_->last_disconnect_error_callback(), |
| 291 wifi_service_path_, NetworkConnectionHandler::kErrorDisconnectFailed, |
| 292 "" /* error_detail */); |
| 293 } |
| 294 } |
| 295 |
| 296 std::string GetResultAndReset() { |
| 297 std::string result; |
| 298 result.swap(disconnection_result_); |
| 299 return result; |
| 300 } |
| 301 |
| 302 const std::vector<cryptauth::RemoteDevice> test_devices_; |
| 303 const base::MessageLoop message_loop_; |
| 304 |
| 305 std::unique_ptr<TestNetworkConnectionHandler> |
| 306 test_network_connection_handler_; |
| 307 std::unique_ptr<FakeActiveHost> fake_active_host_; |
| 308 std::unique_ptr<FakeBleConnectionManager> fake_ble_connection_manager_; |
| 309 std::unique_ptr<FakeNetworkConfigurationRemover> |
| 310 fake_network_configuration_remover_; |
| 311 std::unique_ptr<TestTetherConnector> test_tether_connector_; |
| 312 // TODO(hansberry): Use a fake for this when a real mapping scheme is created. |
| 313 std::unique_ptr<DeviceIdTetherNetworkGuidMap> |
| 314 device_id_tether_network_guid_map_; |
| 315 std::unique_ptr<FakeTetherHostFetcher> fake_tether_host_fetcher_; |
| 316 |
| 317 std::unique_ptr<FakeDisconnectTetheringOperationFactory> |
| 318 fake_operation_factory_; |
| 319 |
| 320 std::string wifi_service_path_; |
| 321 std::string disconnection_result_; |
| 322 bool should_disconnect_successfully_; |
| 323 |
| 324 std::unique_ptr<TetherDisconnector> tether_disconnector_; |
| 325 |
| 326 private: |
| 327 DISALLOW_COPY_AND_ASSIGN(TetherDisconnectorTest); |
| 328 }; |
| 329 |
| 330 TEST_F(TetherDisconnectorTest, DisconnectWhenAlreadyDisconnected) { |
| 331 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 332 EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset()); |
| 333 |
| 334 // Should still be disconnected. |
| 335 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| 336 fake_active_host_->GetActiveHostStatus()); |
| 337 } |
| 338 |
| 339 TEST_F(TetherDisconnectorTest, DisconnectWhenOtherDeviceConnected) { |
| 340 fake_active_host_->SetActiveHostConnected( |
| 341 test_devices_[1].GetDeviceId(), |
| 342 GetTetherNetworkGuid(test_devices_[1].GetDeviceId()), |
| 343 "otherWifiNetworkGuid"); |
| 344 |
| 345 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 346 EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset()); |
| 347 |
| 348 // Should still be connected to the other host. |
| 349 EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTED, |
| 350 fake_active_host_->GetActiveHostStatus()); |
| 351 EXPECT_EQ(test_devices_[1].GetDeviceId(), |
| 352 fake_active_host_->GetActiveHostDeviceId()); |
| 353 } |
| 354 |
| 355 TEST_F(TetherDisconnectorTest, DisconnectWhenConnecting_CancelFails) { |
| 356 fake_active_host_->SetActiveHostConnecting( |
| 357 test_devices_[0].GetDeviceId(), |
| 358 GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 359 test_tether_connector_->set_should_cancel_successfully(false); |
| 360 |
| 361 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 362 EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed, |
| 363 GetResultAndReset()); |
| 364 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| 365 test_tether_connector_->last_canceled_tether_network_guid()); |
| 366 |
| 367 // Note: This test does not check the active host's status because it will be |
| 368 // changed by TetherConnector. |
| 369 } |
| 370 |
| 371 TEST_F(TetherDisconnectorTest, DisconnectWhenConnecting_CancelSucceeds) { |
| 372 fake_active_host_->SetActiveHostConnecting( |
| 373 test_devices_[0].GetDeviceId(), |
| 374 GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 375 test_tether_connector_->set_should_cancel_successfully(true); |
| 376 |
| 377 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 378 EXPECT_EQ(kSuccessResult, GetResultAndReset()); |
| 379 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| 380 test_tether_connector_->last_canceled_tether_network_guid()); |
| 381 |
| 382 // Note: This test does not check the active host's status because it will be |
| 383 // changed by TetherConnector. |
| 384 } |
| 385 |
| 386 TEST_F(TetherDisconnectorTest, DisconnectWhenConnected_NotActuallyConnected) { |
| 387 fake_active_host_->SetActiveHostConnected( |
| 388 test_devices_[0].GetDeviceId(), |
| 389 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| 390 "nonExistentWifiGuid"); |
| 391 |
| 392 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 393 EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed, |
| 394 GetResultAndReset()); |
| 395 |
| 396 // Should be disconnected. |
| 397 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| 398 fake_active_host_->GetActiveHostStatus()); |
| 399 } |
| 400 |
| 401 TEST_F(TetherDisconnectorTest, |
| 402 DisconnectWhenConnected_WifiConnectionFails_CannotFetchHost) { |
| 403 fake_active_host_->SetActiveHostConnected( |
| 404 test_devices_[0].GetDeviceId(), |
| 405 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); |
| 406 SimulateConnectionToWifiNetwork(); |
| 407 |
| 408 // Remove hosts from |fake_tether_host_fetcher_|; this will cause the fetcher |
| 409 // to return a null RemoteDevice. |
| 410 fake_tether_host_fetcher_->SetTetherHosts( |
| 411 std::vector<cryptauth::RemoteDevice>()); |
| 412 |
| 413 should_disconnect_successfully_ = false; |
| 414 |
| 415 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 416 EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed, |
| 417 GetResultAndReset()); |
| 418 |
| 419 // The Wi-Fi network should still be connected since disconnection failed. |
| 420 EXPECT_EQ( |
| 421 shill::kStateOnline, |
| 422 GetServiceStringProperty(wifi_service_path_, shill::kStateProperty)); |
| 423 |
| 424 // Should not have created any operations since the fetch failed. |
| 425 EXPECT_TRUE(fake_operation_factory_->created_operations().empty()); |
| 426 |
| 427 // Should be disconnected. |
| 428 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| 429 fake_active_host_->GetActiveHostStatus()); |
| 430 } |
| 431 |
| 432 TEST_F(TetherDisconnectorTest, |
| 433 DisconnectWhenConnected_WifiConnectionSucceeds_CannotFetchHost) { |
| 434 fake_active_host_->SetActiveHostConnected( |
| 435 test_devices_[0].GetDeviceId(), |
| 436 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); |
| 437 SimulateConnectionToWifiNetwork(); |
| 438 |
| 439 // Remove hosts from |fake_tether_host_fetcher_|; this will cause the fetcher |
| 440 // to return a null RemoteDevice. |
| 441 fake_tether_host_fetcher_->SetTetherHosts( |
| 442 std::vector<cryptauth::RemoteDevice>()); |
| 443 |
| 444 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 445 EXPECT_EQ(kSuccessResult, GetResultAndReset()); |
| 446 |
| 447 // The Wi-Fi network should be disconnected since disconnection failed. |
| 448 EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_, |
| 449 shill::kStateProperty)); |
| 450 |
| 451 // Should not have created any operations since the fetch failed. |
| 452 EXPECT_TRUE(fake_operation_factory_->created_operations().empty()); |
| 453 |
| 454 // Should be disconnected. |
| 455 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| 456 fake_active_host_->GetActiveHostStatus()); |
| 457 } |
| 458 |
| 459 TEST_F(TetherDisconnectorTest, |
| 460 DisconnectWhenConnected_WifiConnectionFails_OperationFails) { |
| 461 fake_active_host_->SetActiveHostConnected( |
| 462 test_devices_[0].GetDeviceId(), |
| 463 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); |
| 464 SimulateConnectionToWifiNetwork(); |
| 465 |
| 466 should_disconnect_successfully_ = false; |
| 467 |
| 468 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 469 EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed, |
| 470 GetResultAndReset()); |
| 471 |
| 472 // The Wi-Fi network should still be connected since disconnection failed. |
| 473 EXPECT_EQ( |
| 474 shill::kStateOnline, |
| 475 GetServiceStringProperty(wifi_service_path_, shill::kStateProperty)); |
| 476 |
| 477 // Fail the operation. |
| 478 ASSERT_EQ(1u, fake_operation_factory_->created_operations().size()); |
| 479 EXPECT_EQ( |
| 480 test_devices_[0], |
| 481 fake_operation_factory_->created_operations()[0]->GetRemoteDevice()); |
| 482 fake_operation_factory_->created_operations()[0]->NotifyFinished( |
| 483 false /* success */); |
| 484 |
| 485 // Should be disconnected. |
| 486 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| 487 fake_active_host_->GetActiveHostStatus()); |
| 488 } |
| 489 |
| 490 TEST_F(TetherDisconnectorTest, |
| 491 DisconnectWhenConnected_WifiConnectionSucceeds_OperationFails) { |
| 492 fake_active_host_->SetActiveHostConnected( |
| 493 test_devices_[0].GetDeviceId(), |
| 494 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); |
| 495 SimulateConnectionToWifiNetwork(); |
| 496 |
| 497 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 498 EXPECT_EQ(kSuccessResult, GetResultAndReset()); |
| 499 |
| 500 // The Wi-Fi network should be disconnected since disconnection failed. |
| 501 EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_, |
| 502 shill::kStateProperty)); |
| 503 |
| 504 ASSERT_EQ(1u, fake_operation_factory_->created_operations().size()); |
| 505 EXPECT_EQ( |
| 506 test_devices_[0], |
| 507 fake_operation_factory_->created_operations()[0]->GetRemoteDevice()); |
| 508 fake_operation_factory_->created_operations()[0]->NotifyFinished( |
| 509 false /* success */); |
| 510 |
| 511 // Should be disconnected. |
| 512 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| 513 fake_active_host_->GetActiveHostStatus()); |
| 514 } |
| 515 |
| 516 TEST_F(TetherDisconnectorTest, |
| 517 DisconnectWhenConnected_WifiConnectionFails_OperationSucceeds) { |
| 518 fake_active_host_->SetActiveHostConnected( |
| 519 test_devices_[0].GetDeviceId(), |
| 520 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); |
| 521 SimulateConnectionToWifiNetwork(); |
| 522 |
| 523 should_disconnect_successfully_ = false; |
| 524 |
| 525 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 526 EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed, |
| 527 GetResultAndReset()); |
| 528 |
| 529 // The Wi-Fi network should still be connected since disconnection failed. |
| 530 EXPECT_EQ( |
| 531 shill::kStateOnline, |
| 532 GetServiceStringProperty(wifi_service_path_, shill::kStateProperty)); |
| 533 |
| 534 // Fail the operation. |
| 535 ASSERT_EQ(1u, fake_operation_factory_->created_operations().size()); |
| 536 EXPECT_EQ( |
| 537 test_devices_[0], |
| 538 fake_operation_factory_->created_operations()[0]->GetRemoteDevice()); |
| 539 fake_operation_factory_->created_operations()[0]->NotifyFinished( |
| 540 true /* success */); |
| 541 |
| 542 // Should be disconnected. |
| 543 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| 544 fake_active_host_->GetActiveHostStatus()); |
| 545 } |
| 546 |
| 547 TEST_F(TetherDisconnectorTest, |
| 548 DisconnectWhenConnected_WifiConnectionSucceeds_OperationSucceeds) { |
| 549 fake_active_host_->SetActiveHostConnected( |
| 550 test_devices_[0].GetDeviceId(), |
| 551 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); |
| 552 SimulateConnectionToWifiNetwork(); |
| 553 |
| 554 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 555 EXPECT_EQ(kSuccessResult, GetResultAndReset()); |
| 556 |
| 557 // The Wi-Fi network should be disconnected since disconnection failed. |
| 558 EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_, |
| 559 shill::kStateProperty)); |
| 560 |
| 561 ASSERT_EQ(1u, fake_operation_factory_->created_operations().size()); |
| 562 EXPECT_EQ( |
| 563 test_devices_[0], |
| 564 fake_operation_factory_->created_operations()[0]->GetRemoteDevice()); |
| 565 fake_operation_factory_->created_operations()[0]->NotifyFinished( |
| 566 true /* success */); |
| 567 |
| 568 // Should be disconnected. |
| 569 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| 570 fake_active_host_->GetActiveHostStatus()); |
| 571 } |
| 572 |
| 573 TEST_F(TetherDisconnectorTest, |
| 574 DisconnectWhenConnected_DestroyBeforeOperationComplete) { |
| 575 fake_active_host_->SetActiveHostConnected( |
| 576 test_devices_[0].GetDeviceId(), |
| 577 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); |
| 578 SimulateConnectionToWifiNetwork(); |
| 579 |
| 580 CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 581 EXPECT_EQ(kSuccessResult, GetResultAndReset()); |
| 582 |
| 583 // Stop the test here, before the operation responds in any way. This test |
| 584 // ensures that TetherDisconnector properly removes existing listeners if it |
| 585 // is destroyed while there are still active operations. |
| 586 } |
| 587 |
| 588 } // namespace tether |
| 589 |
| 590 } // namespace chromeos |
OLD | NEW |