15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/p2p/socket_host_tcp.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sys_byteorder.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/stream_socket.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::DeleteArg;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::DoAll;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Return;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass P2PSocketHostTcpTestBase : public testing::Test {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  explicit P2PSocketHostTcpTestBase(P2PSocketType type)
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : socket_type_(type) {
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(sender_, Send(
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (socket_type_ == P2P_SOCKET_TCP_CLIENT) {
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      socket_host_.reset(
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          new P2PSocketHostTcp(&sender_, 0, P2P_SOCKET_TCP_CLIENT, NULL));
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else {
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      socket_host_.reset(new P2PSocketHostStunTcp(
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          &sender_, 0, P2P_SOCKET_STUN_TCP_CLIENT, NULL));
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_ = new FakeSocket(&sent_data_);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_host_->socket_.reset(socket_);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    dest_.ip_address = ParseAddress(kTestIpAddress1, kTestPort1);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    local_address_ = ParseAddress(kTestLocalIpAddress, kTestPort1);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_host_->remote_address_ = dest_;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_host_->state_ = P2PSocketHost::STATE_CONNECTING;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_host_->OnConnected(net::OK);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string IntToSize(int size) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint16 size16 = base::HostToNet16(size);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.resize(sizeof(size16));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&result[0], &size16, sizeof(size16));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string sent_data_;
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FakeSocket* socket_;  // Owned by |socket_host_|.
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<P2PSocketHostTcpBase> socket_host_;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockIPCSender sender_;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::IPEndPoint local_address_;
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  P2PHostAndIPEndPoint dest_;
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  P2PSocketType socket_type_;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass P2PSocketHostTcpTest : public P2PSocketHostTcpTestBase {
73b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) protected:
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  P2PSocketHostTcpTest() : P2PSocketHostTcpTestBase(P2P_SOCKET_TCP_CLIENT) { }
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
76b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass P2PSocketHostStunTcpTest : public P2PSocketHostTcpTestBase {
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protected:
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  P2PSocketHostStunTcpTest()
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : P2PSocketHostTcpTestBase(P2P_SOCKET_STUN_TCP_CLIENT) {
81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)};
83b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that we can send STUN message and that they are formatted
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// properly.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(P2PSocketHostTcpTest, SendStunNoAuth) {
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(sender_, Send(
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .Times(3)
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::PacketOptions options;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<char> packet1;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateStunRequest(&packet1);
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet1, options, 0);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<char> packet2;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateStunResponse(&packet2);
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet2, options, 0);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<char> packet3;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateStunError(&packet3);
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet3, options, 0);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string expected_data;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_data.append(IntToSize(packet1.size()));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_data.append(packet1.begin(), packet1.end());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_data.append(IntToSize(packet2.size()));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_data.append(packet2.begin(), packet2.end());
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_data.append(IntToSize(packet3.size()));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_data.append(packet3.begin(), packet3.end());
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_data, sent_data_);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that we can receive STUN messages from the socket, and that
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the messages are parsed properly.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(P2PSocketHostTcpTest, ReceiveStun) {
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(sender_, Send(
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .Times(3)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::PacketOptions options;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<char> packet1;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateStunRequest(&packet1);
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet1, options, 0);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<char> packet2;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateStunResponse(&packet2);
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet2, options, 0);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<char> packet3;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateStunError(&packet3);
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet3, options, 0);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string received_data;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  received_data.append(IntToSize(packet1.size()));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  received_data.append(packet1.begin(), packet1.end());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  received_data.append(IntToSize(packet2.size()));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  received_data.append(packet2.begin(), packet2.end());
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  received_data.append(IntToSize(packet3.size()));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  received_data.append(packet3.begin(), packet3.end());
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchPacketMessage(packet1)))
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchPacketMessage(packet2)))
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchPacketMessage(packet3)))
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = 0;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t step_sizes[] = {3, 2, 1};
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t step = 0;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (pos < received_data.size()) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t step_size = std::min(step_sizes[step], received_data.size() - pos);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_->AppendInputData(&received_data[pos], step_size);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pos += step_size;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (++step >= arraysize(step_sizes))
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      step = 0;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that we can't send data before we've received STUN response
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from the other side.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(P2PSocketHostTcpTest, SendDataNoAuth) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(sender_, Send(
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::PacketOptions options;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<char> packet;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateRandomPacket(&packet);
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet, options, 0);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, sent_data_.size());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that we can send data after we've received STUN response
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from the other side.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(P2PSocketHostTcpTest, SendAfterStunRequest) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Receive packet from |dest_|.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<char> request_packet;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateStunRequest(&request_packet);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string received_data;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  received_data.append(IntToSize(request_packet.size()));
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  received_data.append(request_packet.begin(), request_packet.end());
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(sender_, Send(
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_->AppendInputData(&received_data[0], received_data.size());
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::PacketOptions options;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now we should be able to send any data to |dest_|.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<char> packet;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateRandomPacket(&packet);
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet, options, 0);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string expected_data;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_data.append(IntToSize(packet.size()));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_data.append(packet.begin(), packet.end());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_data, sent_data_);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Verify that asynchronous writes are handled correctly.
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(P2PSocketHostTcpTest, AsyncWrites) {
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop;
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  socket_->set_async_write(true);
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(sender_, Send(
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .Times(2)
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::PacketOptions options;
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<char> packet1;
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CreateStunRequest(&packet1);
2248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet1, options, 0);
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<char> packet2;
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CreateStunResponse(&packet2);
229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet2, options, 0);
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.RunUntilIdle();
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string expected_data;
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expected_data.append(IntToSize(packet1.size()));
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expected_data.append(packet1.begin(), packet1.end());
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expected_data.append(IntToSize(packet2.size()));
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expected_data.append(packet2.begin(), packet2.end());
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(expected_data, sent_data_);
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
242effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_F(P2PSocketHostTcpTest, SendDataWithPacketOptions) {
243effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<char> request_packet;
244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  CreateStunRequest(&request_packet);
245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::string received_data;
247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  received_data.append(IntToSize(request_packet.size()));
248effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  received_data.append(request_packet.begin(), request_packet.end());
249effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
250effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_CALL(sender_, Send(
251effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
252effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
253effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
254effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
255effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  socket_->AppendInputData(&received_data[0], received_data.size());
256effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::PacketOptions options;
258effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  options.packet_time_params.rtp_sendtime_extension_id = 3;
259effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Now we should be able to send any data to |dest_|.
260effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<char> packet;
261effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  CreateRandomPacket(&packet);
262effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Make it a RTP packet.
263effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  *reinterpret_cast<uint16*>(&*packet.begin()) = base::HostToNet16(0x8000);
264effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  socket_host_->Send(dest_.ip_address, packet, options, 0);
265effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
266effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::string expected_data;
267effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  expected_data.append(IntToSize(packet.size()));
268effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  expected_data.append(packet.begin(), packet.end());
269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(expected_data, sent_data_);
271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
273b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Verify that we can send STUN message and that they are formatted
274b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// properly.
275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)TEST_F(P2PSocketHostStunTcpTest, SendStunNoAuth) {
276b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(sender_, Send(
277b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
278b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      .Times(3)
279b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
280b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::PacketOptions options;
282b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::vector<char> packet1;
283b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CreateStunRequest(&packet1);
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet1, options, 0);
285b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
286b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::vector<char> packet2;
287b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CreateStunResponse(&packet2);
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet2, options, 0);
289b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
290b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::vector<char> packet3;
291b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CreateStunError(&packet3);
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet3, options, 0);
293b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string expected_data;
295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  expected_data.append(packet1.begin(), packet1.end());
296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  expected_data.append(packet2.begin(), packet2.end());
297b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  expected_data.append(packet3.begin(), packet3.end());
298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(expected_data, sent_data_);
300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
302b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Verify that we can receive STUN messages from the socket, and that
303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// the messages are parsed properly.
304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)TEST_F(P2PSocketHostStunTcpTest, ReceiveStun) {
305b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(sender_, Send(
306b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      .Times(3)
308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::PacketOptions options;
311b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::vector<char> packet1;
312b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CreateStunRequest(&packet1);
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet1, options, 0);
314b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
315b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::vector<char> packet2;
316b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CreateStunResponse(&packet2);
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet2, options, 0);
318b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
319b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::vector<char> packet3;
320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CreateStunError(&packet3);
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet3, options, 0);
322b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
323b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string received_data;
324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  received_data.append(packet1.begin(), packet1.end());
325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  received_data.append(packet2.begin(), packet2.end());
326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  received_data.append(packet3.begin(), packet3.end());
327b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
328b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchPacketMessage(packet1)))
329b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
330b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchPacketMessage(packet2)))
331b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchPacketMessage(packet3)))
333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
335b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  size_t pos = 0;
336b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  size_t step_sizes[] = {3, 2, 1};
337b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  size_t step = 0;
338b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  while (pos < received_data.size()) {
339b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    size_t step_size = std::min(step_sizes[step], received_data.size() - pos);
340b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    socket_->AppendInputData(&received_data[pos], step_size);
341b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    pos += step_size;
342b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (++step >= arraysize(step_sizes))
343b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      step = 0;
344b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
345b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
346b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
347b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Verify that we can't send data before we've received STUN response
348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// from the other side.
349b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)TEST_F(P2PSocketHostStunTcpTest, SendDataNoAuth) {
350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(sender_, Send(
351b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
352b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
353b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::PacketOptions options;
355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::vector<char> packet;
356b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CreateRandomPacket(&packet);
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet, options, 0);
358b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0U, sent_data_.size());
360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Verify that asynchronous writes are handled correctly.
363b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)TEST_F(P2PSocketHostStunTcpTest, AsyncWrites) {
364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop message_loop;
365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  socket_->set_async_write(true);
367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
368b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(sender_, Send(
369b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
370b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      .Times(2)
371b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
372b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::PacketOptions options;
374b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::vector<char> packet1;
375b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CreateStunRequest(&packet1);
376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet1, options, 0);
377b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
378b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::vector<char> packet2;
379b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CreateStunResponse(&packet2);
380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_host_->Send(dest_.ip_address, packet2, options, 0);
381b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
382b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  message_loop.RunUntilIdle();
383b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
384b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string expected_data;
385b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  expected_data.append(packet1.begin(), packet1.end());
386b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  expected_data.append(packet2.begin(), packet2.end());
387b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
388b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(expected_data, sent_data_);
389b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
390b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
392