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.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/message_loop/message_loop.h"
14#include "base/run_loop.h"
15#include "media/cast/net/cast_transport_config.h"
16#include "media/cast/test/utility/net_utility.h"
17#include "net/base/net_util.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
20namespace media {
21namespace cast {
22
23class MockPacketReceiver {
24 public:
25  MockPacketReceiver(const base::Closure& callback)
26      : packet_callback_(callback) {}
27
28  void ReceivedPacket(scoped_ptr<Packet> packet) {
29    packet_ = std::string(packet->size(), '\0');
30    std::copy(packet->begin(), packet->end(), packet_.begin());
31    packet_callback_.Run();
32  }
33
34  std::string packet() const { return packet_; }
35  PacketReceiverCallback packet_receiver() {
36    return base::Bind(&MockPacketReceiver::ReceivedPacket,
37                      base::Unretained(this));
38  }
39
40 private:
41  std::string packet_;
42  base::Closure packet_callback_;
43
44  DISALLOW_COPY_AND_ASSIGN(MockPacketReceiver);
45};
46
47void SendPacket(UdpTransport* transport, Packet packet) {
48  base::Closure cb;
49  transport->SendPacket(new base::RefCountedData<Packet>(packet), cb);
50}
51
52static void UpdateCastTransportStatus(CastTransportStatus status) {
53  NOTREACHED();
54}
55
56TEST(UdpTransport, SendAndReceive) {
57  base::MessageLoopForIO message_loop;
58
59  net::IPEndPoint free_local_port1 = test::GetFreeLocalPort();
60  net::IPEndPoint free_local_port2 = test::GetFreeLocalPort();
61  net::IPAddressNumber empty_addr_number;
62  net::ParseIPLiteralToNumber("0.0.0.0", &empty_addr_number);
63
64  UdpTransport send_transport(NULL,
65                              message_loop.message_loop_proxy(),
66                              free_local_port1,
67                              free_local_port2,
68                              base::Bind(&UpdateCastTransportStatus));
69  UdpTransport recv_transport(NULL,
70                              message_loop.message_loop_proxy(),
71                              free_local_port2,
72                              net::IPEndPoint(empty_addr_number, 0),
73                              base::Bind(&UpdateCastTransportStatus));
74
75  Packet packet;
76  packet.push_back('t');
77  packet.push_back('e');
78  packet.push_back('s');
79  packet.push_back('t');
80
81  base::RunLoop run_loop;
82  MockPacketReceiver receiver1(run_loop.QuitClosure());
83  MockPacketReceiver receiver2(
84      base::Bind(&SendPacket, &recv_transport, packet));
85  send_transport.StartReceiving(receiver1.packet_receiver());
86  recv_transport.StartReceiving(receiver2.packet_receiver());
87
88  base::Closure cb;
89  send_transport.SendPacket(new base::RefCountedData<Packet>(packet), cb);
90  run_loop.Run();
91  EXPECT_TRUE(
92      std::equal(packet.begin(), packet.end(), receiver1.packet().begin()));
93  EXPECT_TRUE(
94      std::equal(packet.begin(), packet.end(), receiver2.packet().begin()));
95}
96
97}  // namespace cast
98}  // namespace media
99