123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- // Copyright 2015 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 "remoting/protocol/ice_transport.h"
- #include <memory>
- #include <utility>
- #include "base/bind.h"
- #include "base/location.h"
- #include "base/logging.h"
- #include "base/run_loop.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/test/task_environment.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/time/time.h"
- #include "build/build_config.h"
- #include "components/webrtc/thread_wrapper.h"
- #include "net/url_request/url_request_context_getter.h"
- #include "remoting/base/url_request.h"
- #include "remoting/protocol/chromium_port_allocator_factory.h"
- #include "remoting/protocol/connection_tester.h"
- #include "remoting/protocol/fake_authenticator.h"
- #include "remoting/protocol/message_channel_factory.h"
- #include "remoting/protocol/message_pipe.h"
- #include "remoting/protocol/transport_context.h"
- #include "services/network/public/cpp/shared_url_loader_factory.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
- using testing::_;
- namespace remoting {
- namespace protocol {
- namespace {
- // Send 100 messages 1024 bytes each. UDP messages are sent with 10ms delay
- // between messages (about 1 second for 100 messages).
- const int kMessageSize = 1024;
- const int kMessages = 100;
- const char kChannelName[] = "test_channel";
- ACTION_P2(QuitRunLoopOnCounter, run_loop, counter) {
- --(*counter);
- EXPECT_GE(*counter, 0);
- if (*counter == 0)
- run_loop->Quit();
- }
- class MockChannelCreatedCallback {
- public:
- MOCK_METHOD1(OnDone, void(MessagePipe* socket));
- };
- class TestTransportEventHandler : public IceTransport::EventHandler {
- public:
- typedef base::RepeatingCallback<void(ErrorCode error)> ErrorCallback;
- TestTransportEventHandler() = default;
- TestTransportEventHandler(const TestTransportEventHandler&) = delete;
- TestTransportEventHandler& operator=(const TestTransportEventHandler&) =
- delete;
- ~TestTransportEventHandler() = default;
- void set_error_callback(const ErrorCallback& callback) {
- error_callback_ = callback;
- }
- // IceTransport::EventHandler interface.
- void OnIceTransportRouteChange(const std::string& channel_name,
- const TransportRoute& route) override {}
- void OnIceTransportError(ErrorCode error) override {
- error_callback_.Run(error);
- }
- private:
- ErrorCallback error_callback_;
- };
- } // namespace
- class IceTransportTest : public testing::Test {
- public:
- IceTransportTest() {
- webrtc::ThreadWrapper::EnsureForCurrentMessageLoop();
- network_settings_ =
- NetworkSettings(NetworkSettings::NAT_TRAVERSAL_OUTGOING);
- }
- void TearDown() override {
- client_message_pipe_.reset();
- host_message_pipe_.reset();
- client_transport_.reset();
- host_transport_.reset();
- base::RunLoop().RunUntilIdle();
- }
- void ProcessTransportInfo(std::unique_ptr<IceTransport>* target_transport,
- std::unique_ptr<jingle_xmpp::XmlElement> transport_info) {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&IceTransportTest::DeliverTransportInfo,
- base::Unretained(this), target_transport,
- std::move(transport_info)),
- transport_info_delay_);
- }
- void DeliverTransportInfo(std::unique_ptr<IceTransport>* target_transport,
- std::unique_ptr<jingle_xmpp::XmlElement> transport_info) {
- ASSERT_TRUE(target_transport);
- EXPECT_TRUE(
- (*target_transport)->ProcessTransportInfo(transport_info.get()));
- }
- void InitializeConnection() {
- webrtc::ThreadWrapper::EnsureForCurrentMessageLoop();
- rtc::SocketFactory* socket_factory =
- webrtc::ThreadWrapper::current()->SocketServer();
- host_transport_ = std::make_unique<IceTransport>(
- new TransportContext(std::make_unique<ChromiumPortAllocatorFactory>(),
- socket_factory, nullptr, nullptr,
- network_settings_, TransportRole::SERVER),
- &host_event_handler_);
- if (!host_authenticator_) {
- host_authenticator_ =
- std::make_unique<FakeAuthenticator>(FakeAuthenticator::ACCEPT);
- }
- client_transport_ = std::make_unique<IceTransport>(
- new TransportContext(std::make_unique<ChromiumPortAllocatorFactory>(),
- socket_factory, nullptr, nullptr,
- network_settings_, TransportRole::CLIENT),
- &client_event_handler_);
- if (!client_authenticator_) {
- client_authenticator_ =
- std::make_unique<FakeAuthenticator>(FakeAuthenticator::ACCEPT);
- }
- host_event_handler_.set_error_callback(base::BindRepeating(
- &IceTransportTest::OnTransportError, base::Unretained(this)));
- client_event_handler_.set_error_callback(base::BindRepeating(
- &IceTransportTest::OnTransportError, base::Unretained(this)));
- // Start both transports.
- host_transport_->Start(
- host_authenticator_.get(),
- base::BindRepeating(&IceTransportTest::ProcessTransportInfo,
- base::Unretained(this), &client_transport_));
- client_transport_->Start(
- client_authenticator_.get(),
- base::BindRepeating(&IceTransportTest::ProcessTransportInfo,
- base::Unretained(this), &host_transport_));
- }
- void WaitUntilConnected() {
- run_loop_ = std::make_unique<base::RunLoop>();
- int counter = 2;
- EXPECT_CALL(client_channel_callback_, OnDone(_))
- .WillOnce(QuitRunLoopOnCounter(run_loop_.get(), &counter));
- EXPECT_CALL(host_channel_callback_, OnDone(_))
- .WillOnce(QuitRunLoopOnCounter(run_loop_.get(), &counter));
- run_loop_->Run();
- EXPECT_TRUE(client_message_pipe_.get());
- EXPECT_TRUE(host_message_pipe_.get());
- }
- void OnClientChannelCreated(std::unique_ptr<MessagePipe> message_pipe) {
- client_message_pipe_ = std::move(message_pipe);
- client_channel_callback_.OnDone(client_message_pipe_.get());
- }
- void OnHostChannelCreated(std::unique_ptr<MessagePipe> message_pipe) {
- host_message_pipe_ = std::move(message_pipe);
- host_channel_callback_.OnDone(host_message_pipe_.get());
- }
- void OnTransportError(ErrorCode error) {
- LOG(ERROR) << "Transport Error";
- error_ = error;
- run_loop_->Quit();
- }
- protected:
- base::test::SingleThreadTaskEnvironment task_environment_{
- base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
- std::unique_ptr<base::RunLoop> run_loop_;
- NetworkSettings network_settings_;
- base::TimeDelta transport_info_delay_;
- std::unique_ptr<IceTransport> host_transport_;
- TestTransportEventHandler host_event_handler_;
- std::unique_ptr<FakeAuthenticator> host_authenticator_;
- std::unique_ptr<IceTransport> client_transport_;
- TestTransportEventHandler client_event_handler_;
- std::unique_ptr<FakeAuthenticator> client_authenticator_;
- MockChannelCreatedCallback client_channel_callback_;
- MockChannelCreatedCallback host_channel_callback_;
- std::unique_ptr<MessagePipe> client_message_pipe_;
- std::unique_ptr<MessagePipe> host_message_pipe_;
- ErrorCode error_ = OK;
- };
- // crbug.com/1224862: Tests are flaky on Mac.
- #if BUILDFLAG(IS_MAC)
- #define MAYBE_DataStream DISABLED_DataStream
- #else
- #define MAYBE_DataStream DataStream
- #endif
- TEST_F(IceTransportTest, MAYBE_DataStream) {
- InitializeConnection();
- client_transport_->GetChannelFactory()->CreateChannel(
- kChannelName, base::BindOnce(&IceTransportTest::OnClientChannelCreated,
- base::Unretained(this)));
- host_transport_->GetChannelFactory()->CreateChannel(
- kChannelName, base::BindOnce(&IceTransportTest::OnHostChannelCreated,
- base::Unretained(this)));
- WaitUntilConnected();
- MessagePipeConnectionTester tester(host_message_pipe_.get(),
- client_message_pipe_.get(), kMessageSize,
- kMessages);
- tester.RunAndCheckResults();
- }
- // crbug.com/1224862: Tests are flaky on Mac.
- #if BUILDFLAG(IS_MAC)
- #define MAYBE_MuxDataStream DISABLED_MuxDataStream
- #else
- #define MAYBE_MuxDataStream MuxDataStream
- #endif
- TEST_F(IceTransportTest, MAYBE_MuxDataStream) {
- InitializeConnection();
- client_transport_->GetMultiplexedChannelFactory()->CreateChannel(
- kChannelName, base::BindOnce(&IceTransportTest::OnClientChannelCreated,
- base::Unretained(this)));
- host_transport_->GetMultiplexedChannelFactory()->CreateChannel(
- kChannelName, base::BindOnce(&IceTransportTest::OnHostChannelCreated,
- base::Unretained(this)));
- WaitUntilConnected();
- MessagePipeConnectionTester tester(host_message_pipe_.get(),
- client_message_pipe_.get(), kMessageSize,
- kMessages);
- tester.RunAndCheckResults();
- }
- // crbug.com/1224862: Tests are flaky on Mac.
- #if BUILDFLAG(IS_MAC)
- #define MAYBE_FailedChannelAuth DISABLED_FailedChannelAuth
- #else
- #define MAYBE_FailedChannelAuth FailedChannelAuth
- #endif
- TEST_F(IceTransportTest, MAYBE_FailedChannelAuth) {
- // Use host authenticator with one that rejects channel authentication.
- host_authenticator_ =
- std::make_unique<FakeAuthenticator>(FakeAuthenticator::REJECT_CHANNEL);
- InitializeConnection();
- client_transport_->GetChannelFactory()->CreateChannel(
- kChannelName, base::BindOnce(&IceTransportTest::OnClientChannelCreated,
- base::Unretained(this)));
- host_transport_->GetChannelFactory()->CreateChannel(
- kChannelName, base::BindOnce(&IceTransportTest::OnHostChannelCreated,
- base::Unretained(this)));
- run_loop_ = std::make_unique<base::RunLoop>();
- // The callback should never be called.
- EXPECT_CALL(host_channel_callback_, OnDone(_)).Times(0);
- run_loop_->Run();
- EXPECT_FALSE(host_message_pipe_);
- EXPECT_EQ(CHANNEL_CONNECTION_ERROR, error_);
- client_transport_->GetChannelFactory()->CancelChannelCreation(
- kChannelName);
- }
- // Verify that channels are never marked connected if connection cannot be
- // established.
- TEST_F(IceTransportTest, TestBrokenTransport) {
- // Allow only incoming connections on both ends, which effectively renders
- // transport unusable. Also reduce connection timeout so the test finishes
- // quickly.
- network_settings_ = NetworkSettings(NetworkSettings::NAT_TRAVERSAL_DISABLED);
- network_settings_.ice_timeout = base::Seconds(1);
- network_settings_.ice_reconnect_attempts = 1;
- InitializeConnection();
- client_transport_->GetChannelFactory()->CreateChannel(
- kChannelName, base::BindOnce(&IceTransportTest::OnClientChannelCreated,
- base::Unretained(this)));
- host_transport_->GetChannelFactory()->CreateChannel(
- kChannelName, base::BindOnce(&IceTransportTest::OnHostChannelCreated,
- base::Unretained(this)));
- // The RunLoop should quit in OnTransportError().
- run_loop_ = std::make_unique<base::RunLoop>();
- run_loop_->Run();
- // Verify that neither of the two ends of the channel is connected.
- EXPECT_FALSE(client_message_pipe_);
- EXPECT_FALSE(host_message_pipe_);
- EXPECT_EQ(CHANNEL_CONNECTION_ERROR, error_);
- client_transport_->GetChannelFactory()->CancelChannelCreation(
- kChannelName);
- host_transport_->GetChannelFactory()->CancelChannelCreation(
- kChannelName);
- }
- TEST_F(IceTransportTest, TestCancelChannelCreation) {
- InitializeConnection();
- client_transport_->GetChannelFactory()->CreateChannel(
- kChannelName, base::BindOnce(&IceTransportTest::OnClientChannelCreated,
- base::Unretained(this)));
- client_transport_->GetChannelFactory()->CancelChannelCreation(
- kChannelName);
- EXPECT_TRUE(!client_message_pipe_.get());
- }
- // crbug.com/1224862: Tests are flaky on Mac.
- #if BUILDFLAG(IS_MAC)
- #define MAYBE_TestDelayedSignaling DISABLED_TestDelayedSignaling
- #else
- #define MAYBE_TestDelayedSignaling TestDelayedSignaling
- #endif
- // Verify that we can still connect even when there is a delay in signaling
- // messages delivery.
- TEST_F(IceTransportTest, MAYBE_TestDelayedSignaling) {
- transport_info_delay_ = base::Milliseconds(100);
- InitializeConnection();
- client_transport_->GetChannelFactory()->CreateChannel(
- kChannelName, base::BindOnce(&IceTransportTest::OnClientChannelCreated,
- base::Unretained(this)));
- host_transport_->GetChannelFactory()->CreateChannel(
- kChannelName, base::BindOnce(&IceTransportTest::OnHostChannelCreated,
- base::Unretained(this)));
- WaitUntilConnected();
- MessagePipeConnectionTester tester(host_message_pipe_.get(),
- client_message_pipe_.get(), kMessageSize,
- kMessages);
- tester.RunAndCheckResults();
- }
- } // namespace protocol
- } // namespace remoting
|