chromium_socket_factory_unittest.cc 4.29 KB
Newer Older
1
// Copyright 2014 The Chromium Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
#include "remoting/protocol/chromium_socket_factory.h"
6

7 8 9
#include <stddef.h>
#include <stdint.h>

10 11
#include <memory>

12
#include "base/message_loop/message_loop.h"
13
#include "base/run_loop.h"
14
#include "base/single_thread_task_runner.h"
15 16
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
17 18
#include "third_party/webrtc/rtc_base/asyncpacketsocket.h"
#include "third_party/webrtc/rtc_base/socketaddress.h"
19 20

namespace remoting {
21
namespace protocol {
22 23 24 25

class ChromiumSocketFactoryTest : public testing::Test,
                                  public sigslot::has_slots<> {
 public:
26
  void SetUp() override {
27 28 29
    socket_factory_.reset(new ChromiumPacketSocketFactory());

    socket_.reset(socket_factory_->CreateUdpSocket(
30
        rtc::SocketAddress("127.0.0.1", 0), 0, 0));
31
    ASSERT_TRUE(socket_.get() != nullptr);
32
    EXPECT_EQ(socket_->GetState(), rtc::AsyncPacketSocket::STATE_BOUND);
33 34 35 36
    socket_->SignalReadPacket.connect(
        this, &ChromiumSocketFactoryTest::OnPacket);
  }

37
  void OnPacket(rtc::AsyncPacketSocket* socket,
38
                const char* data, size_t size,
39 40
                const rtc::SocketAddress& address,
                const rtc::PacketTime& packet_time) {
41 42 43 44 45 46
    EXPECT_EQ(socket, socket_.get());
    last_packet_.assign(data, data + size);
    last_address_ = address;
    run_loop_.Quit();
  }

47
  void VerifyCanSendAndReceive(rtc::AsyncPacketSocket* sender) {
48 49 50 51 52
    // UDP packets may be lost, so we have to retry sending it more than once.
    const int kMaxAttempts = 3;
    const base::TimeDelta kAttemptPeriod = base::TimeDelta::FromSeconds(1);
    std::string test_packet("TEST PACKET");
    int attempts = 0;
53
    rtc::PacketOptions options;
54 55 56
    while (last_packet_.empty() && attempts++ < kMaxAttempts) {
      sender->SendTo(test_packet.data(), test_packet.size(),
                     socket_->GetLocalAddress(), options);
57 58
      message_loop_.task_runner()->PostDelayedTask(
          FROM_HERE, run_loop_.QuitClosure(), kAttemptPeriod);
59 60 61 62 63 64
      run_loop_.Run();
    }
    EXPECT_EQ(test_packet, last_packet_);
    EXPECT_EQ(sender->GetLocalAddress(), last_address_);
  }

65
 protected:
66
  base::MessageLoopForIO message_loop_;
67 68
  base::RunLoop run_loop_;

69 70
  std::unique_ptr<rtc::PacketSocketFactory> socket_factory_;
  std::unique_ptr<rtc::AsyncPacketSocket> socket_;
71 72

  std::string last_packet_;
73
  rtc::SocketAddress last_address_;
74 75 76
};

TEST_F(ChromiumSocketFactoryTest, SendAndReceive) {
77 78 79
  std::unique_ptr<rtc::AsyncPacketSocket> sending_socket(
      socket_factory_->CreateUdpSocket(rtc::SocketAddress("127.0.0.1", 0), 0,
                                       0));
80
  ASSERT_TRUE(sending_socket.get() != nullptr);
81
  EXPECT_EQ(sending_socket->GetState(),
82
            rtc::AsyncPacketSocket::STATE_BOUND);
83 84

  VerifyCanSendAndReceive(sending_socket.get());
85 86 87
}

TEST_F(ChromiumSocketFactoryTest, SetOptions) {
88 89
  EXPECT_EQ(0, socket_->SetOption(rtc::Socket::OPT_SNDBUF, 4096));
  EXPECT_EQ(0, socket_->SetOption(rtc::Socket::OPT_RCVBUF, 4096));
90 91 92
}

TEST_F(ChromiumSocketFactoryTest, PortRange) {
93 94
  const uint16_t kMinPort = 12400;
  const uint16_t kMaxPort = 12410;
95
  socket_.reset(socket_factory_->CreateUdpSocket(
96
      rtc::SocketAddress("127.0.0.1", 0), kMaxPort, kMaxPort));
97
  ASSERT_TRUE(socket_.get() != nullptr);
98
  EXPECT_EQ(socket_->GetState(), rtc::AsyncPacketSocket::STATE_BOUND);
99 100 101 102
  EXPECT_GE(socket_->GetLocalAddress().port(), kMinPort);
  EXPECT_LE(socket_->GetLocalAddress().port(), kMaxPort);
}

103
TEST_F(ChromiumSocketFactoryTest, TransientError) {
104 105 106
  std::unique_ptr<rtc::AsyncPacketSocket> sending_socket(
      socket_factory_->CreateUdpSocket(rtc::SocketAddress("127.0.0.1", 0), 0,
                                       0));
107 108 109 110 111 112
  std::string test_packet("TEST");

  // Try sending a packet to an IPv6 address from a socket that's bound to an
  // IPv4 address. This send is expected to fail, but the socket should still be
  // functional.
  sending_socket->SendTo(test_packet.data(), test_packet.size(),
113 114
                         rtc::SocketAddress("::1", 0),
                         rtc::PacketOptions());
115 116 117 118 119

  // Verify that socket is still usable.
  VerifyCanSendAndReceive(sending_socket.get());
}

120
}  // namespace protocol
121
}  // namespace remoting