Home | History | Annotate | Download | only in protocol
      1 // Copyright 2014 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 "remoting/protocol/chromium_socket_factory.h"
      6 
      7 #include "base/message_loop/message_loop.h"
      8 #include "base/run_loop.h"
      9 #include "testing/gmock/include/gmock/gmock.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 #include "third_party/webrtc/base/asyncpacketsocket.h"
     12 #include "third_party/webrtc/base/socketaddress.h"
     13 
     14 namespace remoting {
     15 namespace protocol {
     16 
     17 class ChromiumSocketFactoryTest : public testing::Test,
     18                                   public sigslot::has_slots<> {
     19  public:
     20   virtual void SetUp() OVERRIDE {
     21     socket_factory_.reset(new ChromiumPacketSocketFactory());
     22 
     23     socket_.reset(socket_factory_->CreateUdpSocket(
     24         rtc::SocketAddress("127.0.0.1", 0), 0, 0));
     25     ASSERT_TRUE(socket_.get() != NULL);
     26     EXPECT_EQ(socket_->GetState(), rtc::AsyncPacketSocket::STATE_BOUND);
     27     socket_->SignalReadPacket.connect(
     28         this, &ChromiumSocketFactoryTest::OnPacket);
     29   }
     30 
     31   void OnPacket(rtc::AsyncPacketSocket* socket,
     32                 const char* data, size_t size,
     33                 const rtc::SocketAddress& address,
     34                 const rtc::PacketTime& packet_time) {
     35     EXPECT_EQ(socket, socket_.get());
     36     last_packet_.assign(data, data + size);
     37     last_address_ = address;
     38     run_loop_.Quit();
     39   }
     40 
     41   void VerifyCanSendAndReceive(rtc::AsyncPacketSocket* sender) {
     42     // UDP packets may be lost, so we have to retry sending it more than once.
     43     const int kMaxAttempts = 3;
     44     const base::TimeDelta kAttemptPeriod = base::TimeDelta::FromSeconds(1);
     45     std::string test_packet("TEST PACKET");
     46     int attempts = 0;
     47     rtc::PacketOptions options;
     48     while (last_packet_.empty() && attempts++ < kMaxAttempts) {
     49       sender->SendTo(test_packet.data(), test_packet.size(),
     50                      socket_->GetLocalAddress(), options);
     51       message_loop_.PostDelayedTask(FROM_HERE, run_loop_.QuitClosure(),
     52                                     kAttemptPeriod);
     53       run_loop_.Run();
     54     }
     55     EXPECT_EQ(test_packet, last_packet_);
     56     EXPECT_EQ(sender->GetLocalAddress(), last_address_);
     57   }
     58 
     59  protected:
     60   base::MessageLoopForIO message_loop_;
     61   base::RunLoop run_loop_;
     62 
     63   scoped_ptr<rtc::PacketSocketFactory> socket_factory_;
     64   scoped_ptr<rtc::AsyncPacketSocket> socket_;
     65 
     66   std::string last_packet_;
     67   rtc::SocketAddress last_address_;
     68 };
     69 
     70 TEST_F(ChromiumSocketFactoryTest, SendAndReceive) {
     71   scoped_ptr<rtc::AsyncPacketSocket> sending_socket(
     72       socket_factory_->CreateUdpSocket(
     73           rtc::SocketAddress("127.0.0.1", 0), 0, 0));
     74   ASSERT_TRUE(sending_socket.get() != NULL);
     75   EXPECT_EQ(sending_socket->GetState(),
     76             rtc::AsyncPacketSocket::STATE_BOUND);
     77 
     78   VerifyCanSendAndReceive(sending_socket.get());
     79 }
     80 
     81 TEST_F(ChromiumSocketFactoryTest, SetOptions) {
     82   EXPECT_EQ(0, socket_->SetOption(rtc::Socket::OPT_SNDBUF, 4096));
     83   EXPECT_EQ(0, socket_->SetOption(rtc::Socket::OPT_RCVBUF, 4096));
     84 }
     85 
     86 TEST_F(ChromiumSocketFactoryTest, PortRange) {
     87   const int kMinPort = 12400;
     88   const int kMaxPort = 12410;
     89   socket_.reset(socket_factory_->CreateUdpSocket(
     90       rtc::SocketAddress("127.0.0.1", 0), kMaxPort, kMaxPort));
     91   ASSERT_TRUE(socket_.get() != NULL);
     92   EXPECT_EQ(socket_->GetState(), rtc::AsyncPacketSocket::STATE_BOUND);
     93   EXPECT_GE(socket_->GetLocalAddress().port(), kMinPort);
     94   EXPECT_LE(socket_->GetLocalAddress().port(), kMaxPort);
     95 }
     96 
     97 TEST_F(ChromiumSocketFactoryTest, TransientError) {
     98   scoped_ptr<rtc::AsyncPacketSocket> sending_socket(
     99       socket_factory_->CreateUdpSocket(
    100           rtc::SocketAddress("127.0.0.1", 0), 0, 0));
    101   std::string test_packet("TEST");
    102 
    103   // Try sending a packet to an IPv6 address from a socket that's bound to an
    104   // IPv4 address. This send is expected to fail, but the socket should still be
    105   // functional.
    106   sending_socket->SendTo(test_packet.data(), test_packet.size(),
    107                          rtc::SocketAddress("::1", 0),
    108                          rtc::PacketOptions());
    109 
    110   // Verify that socket is still usable.
    111   VerifyCanSendAndReceive(sending_socket.get());
    112 }
    113 
    114 }  // namespace protocol
    115 }  // namespace remoting
    116