ice_transport_unittest.cc 11.6 KB
Newer Older
1 2 3 4 5 6
// 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"

7 8
#include <utility>

9 10
#include "base/bind.h"
#include "base/location.h"
11
#include "base/macros.h"
12
#include "base/memory/ptr_util.h"
13 14 15
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
16
#include "base/threading/thread_task_runner_handle.h"
17 18
#include "jingle/glue/thread_wrapper.h"
#include "net/url_request/url_request_context_getter.h"
sergeyu's avatar
sergeyu committed
19 20
#include "remoting/base/url_request.h"
#include "remoting/protocol/chromium_port_allocator_factory.h"
21 22
#include "remoting/protocol/connection_tester.h"
#include "remoting/protocol/fake_authenticator.h"
23 24
#include "remoting/protocol/message_channel_factory.h"
#include "remoting/protocol/message_pipe.h"
sergeyu's avatar
sergeyu committed
25
#include "remoting/protocol/transport_context.h"
26 27
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
28
#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

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:
52
  MOCK_METHOD1(OnDone, void(MessagePipe* socket));
53 54
};

55
class TestTransportEventHandler : public IceTransport::EventHandler {
56 57 58 59 60 61 62 63 64 65
 public:
  typedef base::Callback<void(ErrorCode error)> ErrorCallback;

  TestTransportEventHandler() {}
  ~TestTransportEventHandler() {}

  void set_error_callback(const ErrorCallback& callback) {
    error_callback_ = callback;
  }

66 67
  // IceTransport::EventHandler interface.
  void OnIceTransportRouteChange(const std::string& channel_name,
68
                              const TransportRoute& route) override {}
69
  void OnIceTransportError(ErrorCode error) override {
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
    error_callback_.Run(error);
  }

 private:
  ErrorCallback error_callback_;

  DISALLOW_COPY_AND_ASSIGN(TestTransportEventHandler);
};

}  // namespace

class IceTransportTest : public testing::Test {
 public:
  IceTransportTest() {
    jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
    network_settings_ =
        NetworkSettings(NetworkSettings::NAT_TRAVERSAL_OUTGOING);
  }

  void TearDown() override {
90 91
    client_message_pipe_.reset();
    host_message_pipe_.reset();
92 93
    client_transport_.reset();
    host_transport_.reset();
94
    base::RunLoop().RunUntilIdle();
95 96
  }

97 98
  void ProcessTransportInfo(std::unique_ptr<IceTransport>* target_transport,
                            std::unique_ptr<buzz::XmlElement> transport_info) {
99 100 101 102 103 104 105
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, base::Bind(&IceTransportTest::DeliverTransportInfo,
                              base::Unretained(this), target_transport,
                              base::Passed(&transport_info)),
        transport_info_delay_);
  }

106 107
  void DeliverTransportInfo(std::unique_ptr<IceTransport>* target_transport,
                            std::unique_ptr<buzz::XmlElement> transport_info) {
108 109 110 111 112 113
    ASSERT_TRUE(target_transport);
    EXPECT_TRUE(
        (*target_transport)->ProcessTransportInfo(transport_info.get()));
  }

  void InitializeConnection() {
114 115 116
    jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();

    host_transport_.reset(new IceTransport(
117 118 119
        new TransportContext(nullptr,
                             base::MakeUnique<ChromiumPortAllocatorFactory>(),
                             nullptr, network_settings_, TransportRole::SERVER),
120
        &host_event_handler_));
121
    if (!host_authenticator_) {
sergeyu's avatar
sergeyu committed
122 123
      host_authenticator_.reset(
          new FakeAuthenticator(FakeAuthenticator::ACCEPT));
124 125
    }

126
    client_transport_.reset(new IceTransport(
127 128 129
        new TransportContext(nullptr,
                             base::MakeUnique<ChromiumPortAllocatorFactory>(),
                             nullptr, network_settings_, TransportRole::CLIENT),
130
        &client_event_handler_));
131
    if (!client_authenticator_) {
sergeyu's avatar
sergeyu committed
132 133
      client_authenticator_.reset(
          new FakeAuthenticator(FakeAuthenticator::ACCEPT));
134 135 136 137 138 139 140
    }

    host_event_handler_.set_error_callback(base::Bind(
        &IceTransportTest::OnTransportError, base::Unretained(this)));
    client_event_handler_.set_error_callback(base::Bind(
        &IceTransportTest::OnTransportError, base::Unretained(this)));

141 142 143 144 145 146 147 148 149
    // Start both transports.
    host_transport_->Start(
        host_authenticator_.get(),
        base::Bind(&IceTransportTest::ProcessTransportInfo,
                   base::Unretained(this), &client_transport_));
    client_transport_->Start(
        client_authenticator_.get(),
        base::Bind(&IceTransportTest::ProcessTransportInfo,
                   base::Unretained(this), &host_transport_));
150 151 152 153 154 155 156 157 158 159 160 161 162
  }

  void WaitUntilConnected() {
    run_loop_.reset(new 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();

163 164
    EXPECT_TRUE(client_message_pipe_.get());
    EXPECT_TRUE(host_message_pipe_.get());
165 166
  }

167
  void OnClientChannelCreated(std::unique_ptr<MessagePipe> message_pipe) {
168 169
    client_message_pipe_ = std::move(message_pipe);
    client_channel_callback_.OnDone(client_message_pipe_.get());
170 171
  }

172
  void OnHostChannelCreated(std::unique_ptr<MessagePipe> message_pipe) {
173 174
    host_message_pipe_ = std::move(message_pipe);
    host_channel_callback_.OnDone(host_message_pipe_.get());
175 176 177
  }

  void OnTransportError(ErrorCode error) {
178
    LOG(ERROR) << "Transport Error";
179 180 181 182 183 184
    error_ = error;
    run_loop_->Quit();
  }

 protected:
  base::MessageLoopForIO message_loop_;
185
  std::unique_ptr<base::RunLoop> run_loop_;
186 187 188 189 190

  NetworkSettings network_settings_;

  base::TimeDelta transport_info_delay_;

191
  std::unique_ptr<IceTransport> host_transport_;
192
  TestTransportEventHandler host_event_handler_;
193
  std::unique_ptr<FakeAuthenticator> host_authenticator_;
194

195
  std::unique_ptr<IceTransport> client_transport_;
196
  TestTransportEventHandler client_event_handler_;
197
  std::unique_ptr<FakeAuthenticator> client_authenticator_;
198 199 200 201

  MockChannelCreatedCallback client_channel_callback_;
  MockChannelCreatedCallback host_channel_callback_;

202 203
  std::unique_ptr<MessagePipe> client_message_pipe_;
  std::unique_ptr<MessagePipe> host_message_pipe_;
204 205 206 207 208 209 210

  ErrorCode error_ = OK;
};

TEST_F(IceTransportTest, DataStream) {
  InitializeConnection();

211
  client_transport_->GetChannelFactory()->CreateChannel(
212 213
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
214
  host_transport_->GetChannelFactory()->CreateChannel(
215 216 217 218 219
      kChannelName, base::Bind(&IceTransportTest::OnHostChannelCreated,
                               base::Unretained(this)));

  WaitUntilConnected();

220 221 222 223
  MessagePipeConnectionTester tester(host_message_pipe_.get(),
                                     client_message_pipe_.get(), kMessageSize,
                                     kMessages);
  tester.RunAndCheckResults();
224 225 226 227 228 229 230 231 232 233 234 235 236 237
}

TEST_F(IceTransportTest, MuxDataStream) {
  InitializeConnection();

  client_transport_->GetMultiplexedChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
  host_transport_->GetMultiplexedChannelFactory()->CreateChannel(
      kChannelName, base::Bind(&IceTransportTest::OnHostChannelCreated,
                               base::Unretained(this)));

  WaitUntilConnected();

238 239 240 241
  MessagePipeConnectionTester tester(host_message_pipe_.get(),
                                     client_message_pipe_.get(), kMessageSize,
                                     kMessages);
  tester.RunAndCheckResults();
242 243 244 245
}

TEST_F(IceTransportTest, FailedChannelAuth) {
  // Use host authenticator with one that rejects channel authentication.
sergeyu's avatar
sergeyu committed
246 247
  host_authenticator_.reset(
      new FakeAuthenticator(FakeAuthenticator::REJECT_CHANNEL));
248 249 250

  InitializeConnection();

251
  client_transport_->GetChannelFactory()->CreateChannel(
252 253
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
254
  host_transport_->GetChannelFactory()->CreateChannel(
255 256 257 258 259
      kChannelName, base::Bind(&IceTransportTest::OnHostChannelCreated,
                               base::Unretained(this)));

  run_loop_.reset(new base::RunLoop());

260 261
  // The callback should never be called.
  EXPECT_CALL(host_channel_callback_, OnDone(_)).Times(0);
262 263 264

  run_loop_->Run();

265 266
  EXPECT_FALSE(host_message_pipe_);
  EXPECT_EQ(CHANNEL_CONNECTION_ERROR, error_);
267

268
  client_transport_->GetChannelFactory()->CancelChannelCreation(
269 270 271 272 273 274 275
      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
276 277
  // transport unusable. Also reduce connection timeout so the test finishes
  // quickly.
278
  network_settings_ = NetworkSettings(NetworkSettings::NAT_TRAVERSAL_DISABLED);
279 280
  network_settings_.ice_timeout = base::TimeDelta::FromSeconds(1);
  network_settings_.ice_reconnect_attempts = 1;
281 282 283

  InitializeConnection();

284
  client_transport_->GetChannelFactory()->CreateChannel(
285 286
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
287
  host_transport_->GetChannelFactory()->CreateChannel(
288 289 290
      kChannelName, base::Bind(&IceTransportTest::OnHostChannelCreated,
                               base::Unretained(this)));

291 292 293
  // The RunLoop should quit in OnTransportError().
  run_loop_.reset(new base::RunLoop());
  run_loop_->Run();
294 295

  // Verify that neither of the two ends of the channel is connected.
296 297
  EXPECT_FALSE(client_message_pipe_);
  EXPECT_FALSE(host_message_pipe_);
298
  EXPECT_EQ(CHANNEL_CONNECTION_ERROR, error_);
299

300
  client_transport_->GetChannelFactory()->CancelChannelCreation(
301
      kChannelName);
302
  host_transport_->GetChannelFactory()->CancelChannelCreation(
303 304 305 306 307 308
      kChannelName);
}

TEST_F(IceTransportTest, TestCancelChannelCreation) {
  InitializeConnection();

309
  client_transport_->GetChannelFactory()->CreateChannel(
310 311
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
312
  client_transport_->GetChannelFactory()->CancelChannelCreation(
313 314
      kChannelName);

315
  EXPECT_TRUE(!client_message_pipe_.get());
316 317 318 319 320 321 322 323 324
}

// Verify that we can still connect even when there is a delay in signaling
// messages delivery.
TEST_F(IceTransportTest, TestDelayedSignaling) {
  transport_info_delay_ = base::TimeDelta::FromMilliseconds(100);

  InitializeConnection();

325
  client_transport_->GetChannelFactory()->CreateChannel(
326 327
      kChannelName, base::Bind(&IceTransportTest::OnClientChannelCreated,
                               base::Unretained(this)));
328
  host_transport_->GetChannelFactory()->CreateChannel(
329 330 331 332 333
      kChannelName, base::Bind(&IceTransportTest::OnHostChannelCreated,
                               base::Unretained(this)));

  WaitUntilConnected();

334 335 336 337
  MessagePipeConnectionTester tester(host_message_pipe_.get(),
                                     client_message_pipe_.get(), kMessageSize,
                                     kMessages);
  tester.RunAndCheckResults();
338 339 340 341 342
}


}  // namespace protocol
}  // namespace remoting