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 "media/cast/net/udp_transport_impl.h"
6 
7 #include <algorithm>
8 #include <string>
9 #include <vector>
10 
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/macros.h"
14 #include "base/run_loop.h"
15 #include "base/test/mock_callback.h"
16 #include "base/test/task_environment.h"
17 #include "media/cast/net/cast_transport_config.h"
18 #include "media/cast/net/udp_packet_pipe.h"
19 #include "media/cast/test/utility/net_utility.h"
20 #include "net/base/ip_address.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 
23 namespace media {
24 namespace cast {
25 
26 namespace {
27 
28 class MockPacketReceiver final : public UdpTransportReceiver {
29  public:
MockPacketReceiver(const base::RepeatingClosure & callback)30   MockPacketReceiver(const base::RepeatingClosure& callback)
31       : packet_callback_(callback) {}
32 
ReceivedPacket(std::unique_ptr<Packet> packet)33   bool ReceivedPacket(std::unique_ptr<Packet> packet) {
34     packet_ = std::move(packet);
35     packet_callback_.Run();
36     return true;
37   }
38 
39   // UdpTransportReceiver implementation.
OnPacketReceived(const std::vector<uint8_t> & packet)40   void OnPacketReceived(const std::vector<uint8_t>& packet) override {
41     EXPECT_GT(packet.size(), 0u);
42     packet_.reset(new Packet(packet));
43     packet_callback_.Run();
44   }
45 
packet_receiver()46   PacketReceiverCallbackWithStatus packet_receiver() {
47     return base::BindRepeating(&MockPacketReceiver::ReceivedPacket,
48                                base::Unretained(this));
49   }
50 
TakePacket()51   std::unique_ptr<Packet> TakePacket() { return std::move(packet_); }
52 
53  private:
54   base::RepeatingClosure packet_callback_;
55   std::unique_ptr<Packet> packet_;
56 
57   DISALLOW_COPY_AND_ASSIGN(MockPacketReceiver);
58 };
59 
SendPacket(UdpTransportImpl * transport,Packet packet)60 void SendPacket(UdpTransportImpl* transport, Packet packet) {
61   base::Closure cb;
62   transport->SendPacket(new base::RefCountedData<Packet>(packet), cb);
63 }
64 
UpdateCastTransportStatus(CastTransportStatus status)65 static void UpdateCastTransportStatus(CastTransportStatus status) {
66   NOTREACHED();
67 }
68 
69 }  // namespace
70 
71 class UdpTransportImplTest : public ::testing::Test {
72  public:
UdpTransportImplTest()73   UdpTransportImplTest()
74       : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {
75     net::IPEndPoint free_local_port1 = test::GetFreeLocalPort();
76     net::IPEndPoint free_local_port2 = test::GetFreeLocalPort();
77 
78     send_transport_ = std::make_unique<UdpTransportImpl>(
79         task_environment_.GetMainThreadTaskRunner(), free_local_port1,
80         free_local_port2, base::BindRepeating(&UpdateCastTransportStatus));
81     send_transport_->SetSendBufferSize(65536);
82 
83     recv_transport_ = std::make_unique<UdpTransportImpl>(
84         task_environment_.GetMainThreadTaskRunner(), free_local_port2,
85         free_local_port1, base::BindRepeating(&UpdateCastTransportStatus));
86     recv_transport_->SetSendBufferSize(65536);
87   }
88 
89   ~UdpTransportImplTest() override = default;
90 
91  protected:
92   base::test::TaskEnvironment task_environment_;
93 
94   std::unique_ptr<UdpTransportImpl> send_transport_;
95 
96   // A receiver side transport to receiver/send packets from/to sender.
97   std::unique_ptr<UdpTransportImpl> recv_transport_;
98 
99  private:
100   DISALLOW_COPY_AND_ASSIGN(UdpTransportImplTest);
101 };
102 
103 // Test the sending/receiving functions as a PacketSender.
TEST_F(UdpTransportImplTest,PacketSenderSendAndReceive)104 TEST_F(UdpTransportImplTest, PacketSenderSendAndReceive) {
105   std::string data = "Test";
106   Packet packet(data.begin(), data.end());
107 
108   base::RunLoop run_loop;
109   MockPacketReceiver packet_receiver_on_sender(run_loop.QuitClosure());
110   MockPacketReceiver packet_receiver_on_receiver(
111       base::BindRepeating(&SendPacket, recv_transport_.get(), packet));
112   send_transport_->StartReceiving(packet_receiver_on_sender.packet_receiver());
113   recv_transport_->StartReceiving(
114       packet_receiver_on_receiver.packet_receiver());
115 
116   base::Closure cb;
117   SendPacket(send_transport_.get(), packet);
118   run_loop.Run();
119   std::unique_ptr<Packet> received_packet =
120       packet_receiver_on_sender.TakePacket();
121   EXPECT_TRUE(received_packet);
122   EXPECT_TRUE(
123       std::equal(packet.begin(), packet.end(), received_packet->begin()));
124   received_packet = packet_receiver_on_receiver.TakePacket();
125   EXPECT_TRUE(received_packet);
126   EXPECT_TRUE(
127       std::equal(packet.begin(), packet.end(), (*received_packet).begin()));
128 }
129 
130 // Test the sending/receiving functions as a UdpTransport.
TEST_F(UdpTransportImplTest,UdpTransportSendAndReceive)131 TEST_F(UdpTransportImplTest, UdpTransportSendAndReceive) {
132   std::string data = "Hello!";
133   Packet packet(data.begin(), data.end());
134 
135   base::RunLoop run_loop;
136   MockPacketReceiver packet_receiver_on_sender(run_loop.QuitClosure());
137   MockPacketReceiver packet_receiver_on_receiver(
138       base::BindRepeating(&SendPacket, recv_transport_.get(), packet));
139   send_transport_->StartReceiving(&packet_receiver_on_sender);
140   recv_transport_->StartReceiving(
141       packet_receiver_on_receiver.packet_receiver());
142 
143   mojo::DataPipe data_pipe(5);
144   send_transport_->StartSending(std::move(data_pipe.consumer_handle));
145   UdpPacketPipeWriter writer(std::move(data_pipe.producer_handle));
146   base::MockCallback<base::OnceClosure> done_callback;
147   EXPECT_CALL(done_callback, Run()).Times(1);
148   writer.Write(new base::RefCountedData<Packet>(packet), done_callback.Get());
149   run_loop.Run();
150   std::unique_ptr<Packet> received_packet =
151       packet_receiver_on_sender.TakePacket();
152   EXPECT_TRUE(received_packet);
153   EXPECT_TRUE(
154       std::equal(packet.begin(), packet.end(), received_packet->begin()));
155   received_packet = packet_receiver_on_receiver.TakePacket();
156   EXPECT_TRUE(received_packet);
157   EXPECT_TRUE(
158       std::equal(packet.begin(), packet.end(), (*received_packet).begin()));
159 }
160 
161 }  // namespace cast
162 }  // namespace media
163