1 // Copyright (c) 2012 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.
5 #include "remoting/protocol/connection_tester.h"
8 #include "base/message_loop/message_loop.h"
9 #include "net/base/io_buffer.h"
10 #include "net/base/net_errors.h"
11 #include "remoting/protocol/p2p_datagram_socket.h"
12 #include "remoting/protocol/p2p_stream_socket.h"
13 #include "testing/gtest/include/gtest/gtest.h"
18 StreamConnectionTester::StreamConnectionTester(P2PStreamSocket
* client_socket
,
19 P2PStreamSocket
* host_socket
,
22 : message_loop_(base::MessageLoop::current()),
23 host_socket_(host_socket
),
24 client_socket_(client_socket
),
25 message_size_(message_size
),
26 test_data_size_(message_size
* message_count
),
32 StreamConnectionTester::~StreamConnectionTester() {
35 void StreamConnectionTester::Start() {
41 void StreamConnectionTester::CheckResults() {
42 EXPECT_EQ(0, write_errors_
);
43 EXPECT_EQ(0, read_errors_
);
45 ASSERT_EQ(test_data_size_
, input_buffer_
->offset());
47 output_buffer_
->SetOffset(0);
48 ASSERT_EQ(test_data_size_
, output_buffer_
->size());
50 EXPECT_EQ(0, memcmp(output_buffer_
->data(),
51 input_buffer_
->StartOfBuffer(), test_data_size_
));
54 void StreamConnectionTester::Done() {
56 message_loop_
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
59 void StreamConnectionTester::InitBuffers() {
60 output_buffer_
= new net::DrainableIOBuffer(
61 new net::IOBuffer(test_data_size_
), test_data_size_
);
62 for (int i
= 0; i
< test_data_size_
; ++i
) {
63 output_buffer_
->data()[i
] = static_cast<char>(i
);
66 input_buffer_
= new net::GrowableIOBuffer();
69 void StreamConnectionTester::DoWrite() {
72 if (output_buffer_
->BytesRemaining() == 0)
75 int bytes_to_write
= std::min(output_buffer_
->BytesRemaining(),
77 result
= client_socket_
->Write(
80 base::Bind(&StreamConnectionTester::OnWritten
, base::Unretained(this)));
81 HandleWriteResult(result
);
85 void StreamConnectionTester::OnWritten(int result
) {
86 HandleWriteResult(result
);
90 void StreamConnectionTester::HandleWriteResult(int result
) {
91 if (result
<= 0 && result
!= net::ERR_IO_PENDING
) {
92 LOG(ERROR
) << "Received error " << result
<< " when trying to write";
95 } else if (result
> 0) {
96 output_buffer_
->DidConsume(result
);
100 void StreamConnectionTester::DoRead() {
103 input_buffer_
->SetCapacity(input_buffer_
->offset() + message_size_
);
104 result
= host_socket_
->Read(
107 base::Bind(&StreamConnectionTester::OnRead
, base::Unretained(this)));
108 HandleReadResult(result
);
112 void StreamConnectionTester::OnRead(int result
) {
113 HandleReadResult(result
);
115 DoRead(); // Don't try to read again when we are done reading.
118 void StreamConnectionTester::HandleReadResult(int result
) {
119 if (result
<= 0 && result
!= net::ERR_IO_PENDING
) {
120 LOG(ERROR
) << "Received error " << result
<< " when trying to read";
123 } else if (result
> 0) {
124 // Allocate memory for the next read.
125 input_buffer_
->set_offset(input_buffer_
->offset() + result
);
126 if (input_buffer_
->offset() == test_data_size_
)
131 DatagramConnectionTester::DatagramConnectionTester(
132 P2PDatagramSocket
* client_socket
,
133 P2PDatagramSocket
* host_socket
,
137 : message_loop_(base::MessageLoop::current()),
138 host_socket_(host_socket
),
139 client_socket_(client_socket
),
140 message_size_(message_size
),
141 message_count_(message_count
),
147 packets_received_(0),
148 bad_packets_received_(0) {
149 sent_packets_
.resize(message_count_
);
152 DatagramConnectionTester::~DatagramConnectionTester() {
155 void DatagramConnectionTester::Start() {
160 void DatagramConnectionTester::CheckResults() {
161 EXPECT_EQ(0, write_errors_
);
162 EXPECT_EQ(0, read_errors_
);
164 EXPECT_EQ(0, bad_packets_received_
);
166 // Verify that we've received at least one packet.
167 EXPECT_GT(packets_received_
, 0);
168 VLOG(0) << "Received " << packets_received_
<< " packets out of "
172 void DatagramConnectionTester::Done() {
174 message_loop_
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
177 void DatagramConnectionTester::DoWrite() {
178 if (packets_sent_
>= message_count_
) {
183 scoped_refptr
<net::IOBuffer
> packet(new net::IOBuffer(message_size_
));
184 for (int i
= 0; i
< message_size_
; ++i
) {
185 packet
->data()[i
] = static_cast<char>(i
);
187 sent_packets_
[packets_sent_
] = packet
;
188 // Put index of this packet in the beginning of the packet body.
189 memcpy(packet
->data(), &packets_sent_
, sizeof(packets_sent_
));
191 int result
= client_socket_
->Send(
192 packet
.get(), message_size_
,
193 base::Bind(&DatagramConnectionTester::OnWritten
, base::Unretained(this)));
194 HandleWriteResult(result
);
197 void DatagramConnectionTester::OnWritten(int result
) {
198 HandleWriteResult(result
);
201 void DatagramConnectionTester::HandleWriteResult(int result
) {
202 if (result
<= 0 && result
!= net::ERR_IO_PENDING
) {
203 LOG(ERROR
) << "Received error " << result
<< " when trying to write";
206 } else if (result
> 0) {
207 EXPECT_EQ(message_size_
, result
);
209 message_loop_
->PostDelayedTask(
211 base::Bind(&DatagramConnectionTester::DoWrite
, base::Unretained(this)),
212 base::TimeDelta::FromMilliseconds(delay_ms_
));
216 void DatagramConnectionTester::DoRead() {
219 int kReadSize
= message_size_
* 2;
220 read_buffer_
= new net::IOBuffer(kReadSize
);
222 result
= host_socket_
->Recv(
223 read_buffer_
.get(), kReadSize
,
224 base::Bind(&DatagramConnectionTester::OnRead
, base::Unretained(this)));
225 HandleReadResult(result
);
229 void DatagramConnectionTester::OnRead(int result
) {
230 HandleReadResult(result
);
234 void DatagramConnectionTester::HandleReadResult(int result
) {
235 if (result
<= 0 && result
!= net::ERR_IO_PENDING
) {
236 // Error will be received after the socket is closed.
237 LOG(ERROR
) << "Received error " << result
<< " when trying to read";
240 } else if (result
> 0) {
242 if (message_size_
!= result
) {
243 // Invalid packet size;
244 bad_packets_received_
++;
246 // Validate packet body.
248 memcpy(&packet_id
, read_buffer_
->data(), sizeof(packet_id
));
249 if (packet_id
< 0 || packet_id
>= message_count_
) {
250 bad_packets_received_
++;
252 if (memcmp(read_buffer_
->data(), sent_packets_
[packet_id
]->data(),
254 bad_packets_received_
++;
260 } // namespace protocol
261 } // namespace remoting