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