| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chromeos/components/tether/asynchronous_shutdown_object_container_impl.h" |
| |
| #include <memory> |
| |
| #include "base/bind.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/test/scoped_task_environment.h" |
| #include "chromeos/components/multidevice/remote_device_test_util.h" |
| #include "chromeos/components/tether/fake_disconnect_tethering_request_sender.h" |
| #include "chromeos/components/tether/fake_tether_host_fetcher.h" |
| #include "chromeos/components/tether/tether_component_impl.h" |
| #include "chromeos/services/device_sync/fake_remote_device_provider.h" |
| #include "chromeos/services/device_sync/public/cpp/fake_device_sync_client.h" |
| #include "chromeos/services/device_sync/remote_device_provider_impl.h" |
| #include "chromeos/services/secure_channel/public/cpp/client/fake_secure_channel_client.h" |
| #include "components/sync_preferences/testing_pref_service_syncable.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using testing::Invoke; |
| using testing::NiceMock; |
| using testing::Return; |
| |
| namespace chromeos { |
| |
| namespace tether { |
| |
| namespace { |
| |
| class FakeRemoteDeviceProviderFactory |
| : public device_sync::RemoteDeviceProviderImpl::Factory { |
| public: |
| FakeRemoteDeviceProviderFactory() = default; |
| ~FakeRemoteDeviceProviderFactory() override = default; |
| |
| // device_sync::RemoteDeviceProviderImpl::Factory: |
| std::unique_ptr<device_sync::RemoteDeviceProvider> BuildInstance( |
| device_sync::CryptAuthDeviceManager* device_manager, |
| const std::string& user_id, |
| const std::string& user_private_key) override { |
| return std::make_unique<device_sync::FakeRemoteDeviceProvider>(); |
| } |
| }; |
| |
| } // namespace |
| |
| class AsynchronousShutdownObjectContainerImplTest : public testing::Test { |
| protected: |
| AsynchronousShutdownObjectContainerImplTest() |
| : test_device_(multidevice::CreateRemoteDeviceRefListForTest(1u)[0]) {} |
| |
| void SetUp() override { |
| was_shutdown_callback_invoked_ = false; |
| |
| fake_remote_device_provider_factory_ = |
| base::WrapUnique(new FakeRemoteDeviceProviderFactory()); |
| device_sync::RemoteDeviceProviderImpl::Factory::SetInstanceForTesting( |
| fake_remote_device_provider_factory_.get()); |
| |
| fake_device_sync_client_ = |
| std::make_unique<device_sync::FakeDeviceSyncClient>(); |
| fake_secure_channel_client_ = |
| std::make_unique<secure_channel::FakeSecureChannelClient>(); |
| fake_tether_host_fetcher_ = std::make_unique<FakeTetherHostFetcher>(); |
| |
| test_pref_service_ = |
| std::make_unique<sync_preferences::TestingPrefServiceSyncable>(); |
| TetherComponentImpl::RegisterProfilePrefs(test_pref_service_->registry()); |
| |
| // Note: The null pointers passed to the constructor are not actually used |
| // by the object itself; rather, they are simply passed to the constructors |
| // of objects created by the container. |
| container_ = base::WrapUnique(new AsynchronousShutdownObjectContainerImpl( |
| fake_device_sync_client_.get(), fake_secure_channel_client_.get(), |
| fake_tether_host_fetcher_.get() /* tether_host_fetcher */, |
| nullptr /* network_state_handler */, |
| nullptr /* managed_network_configuration_handler */, |
| nullptr /* network_connection_handler */, |
| test_pref_service_.get() /* pref_service */)); |
| |
| fake_disconnect_tethering_request_sender_ = |
| new FakeDisconnectTetheringRequestSender(); |
| |
| container_->SetTestDoubles( |
| base::WrapUnique(fake_disconnect_tethering_request_sender_)); |
| } |
| |
| void CallShutdown() { |
| container_->Shutdown(base::Bind( |
| &AsynchronousShutdownObjectContainerImplTest::OnShutdownComplete, |
| base::Unretained(this))); |
| } |
| |
| void OnShutdownComplete() { was_shutdown_callback_invoked_ = true; } |
| |
| base::test::ScopedTaskEnvironment scoped_task_environment_; |
| const multidevice::RemoteDeviceRef test_device_; |
| |
| std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; |
| std::unique_ptr<secure_channel::FakeSecureChannelClient> |
| fake_secure_channel_client_; |
| std::unique_ptr<FakeTetherHostFetcher> fake_tether_host_fetcher_; |
| std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> |
| test_pref_service_; |
| std::unique_ptr<FakeRemoteDeviceProviderFactory> |
| fake_remote_device_provider_factory_; |
| FakeDisconnectTetheringRequestSender* |
| fake_disconnect_tethering_request_sender_; |
| |
| bool was_shutdown_callback_invoked_; |
| |
| std::unique_ptr<AsynchronousShutdownObjectContainerImpl> container_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(AsynchronousShutdownObjectContainerImplTest); |
| }; |
| |
| TEST_F(AsynchronousShutdownObjectContainerImplTest, |
| TestShutdown_NoAsyncShutdown) { |
| CallShutdown(); |
| EXPECT_TRUE(was_shutdown_callback_invoked_); |
| } |
| |
| TEST_F(AsynchronousShutdownObjectContainerImplTest, |
| TestShutdown_AsyncDisconnectTetheringRequestSenderShutdown) { |
| fake_disconnect_tethering_request_sender_->set_has_pending_requests(true); |
| EXPECT_TRUE(fake_disconnect_tethering_request_sender_->HasPendingRequests()); |
| |
| // Start the shutdown; it should not yet succeed since there are pending |
| // requests. |
| CallShutdown(); |
| EXPECT_FALSE(was_shutdown_callback_invoked_); |
| |
| // Now, finish the pending requests; this should cause the shutdown to |
| // complete. |
| fake_disconnect_tethering_request_sender_->set_has_pending_requests(false); |
| fake_disconnect_tethering_request_sender_ |
| ->NotifyPendingDisconnectRequestsComplete(); |
| EXPECT_TRUE(was_shutdown_callback_invoked_); |
| } |
| |
| TEST_F(AsynchronousShutdownObjectContainerImplTest, |
| TestShutdown_MultipleSimultaneousAsyncShutdowns) { |
| fake_disconnect_tethering_request_sender_->set_has_pending_requests(true); |
| EXPECT_TRUE(fake_disconnect_tethering_request_sender_->HasPendingRequests()); |
| |
| // Start the shutdown; it should not yet succeed since there are pending |
| // requests. |
| CallShutdown(); |
| EXPECT_FALSE(was_shutdown_callback_invoked_); |
| |
| // Now, finish the pending requests; this should cause the shutdown to |
| // complete. |
| fake_disconnect_tethering_request_sender_->set_has_pending_requests(false); |
| fake_disconnect_tethering_request_sender_ |
| ->NotifyPendingDisconnectRequestsComplete(); |
| EXPECT_TRUE(was_shutdown_callback_invoked_); |
| } |
| |
| } // namespace tether |
| |
| } // namespace chromeos |