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 "net/socket/stream_socket.h"
12 #include "testing/gtest/include/gtest/gtest.h"
17 StreamConnectionTester::StreamConnectionTester(net::StreamSocket
* client_socket
,
18 net::StreamSocket
* host_socket
,
21 : message_loop_(base::MessageLoop::current()),
22 host_socket_(host_socket
),
23 client_socket_(client_socket
),
24 message_size_(message_size
),
25 test_data_size_(message_size
* message_count
),
31 StreamConnectionTester::~StreamConnectionTester() {
34 void StreamConnectionTester::Start() {
40 void StreamConnectionTester::CheckResults() {
41 EXPECT_EQ(0, write_errors_
);
42 EXPECT_EQ(0, read_errors_
);
44 ASSERT_EQ(test_data_size_
, input_buffer_
->offset());
46 output_buffer_
->SetOffset(0);
47 ASSERT_EQ(test_data_size_
, output_buffer_
->size());
49 EXPECT_EQ(0, memcmp(output_buffer_
->data(),
50 input_buffer_
->StartOfBuffer(), test_data_size_
));
53 void StreamConnectionTester::Done() {
55 message_loop_
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
58 void StreamConnectionTester::InitBuffers() {
59 output_buffer_
= new net::DrainableIOBuffer(
60 new net::IOBuffer(test_data_size_
), test_data_size_
);
61 for (int i
= 0; i
< test_data_size_
; ++i
) {
62 output_buffer_
->data()[i
] = static_cast<char>(i
);
65 input_buffer_
= new net::GrowableIOBuffer();
68 void StreamConnectionTester::DoWrite() {
71 if (output_buffer_
->BytesRemaining() == 0)
74 int bytes_to_write
= std::min(output_buffer_
->BytesRemaining(),
76 result
= client_socket_
->Write(
79 base::Bind(&StreamConnectionTester::OnWritten
, base::Unretained(this)));
80 HandleWriteResult(result
);
84 void StreamConnectionTester::OnWritten(int result
) {
85 HandleWriteResult(result
);
89 void StreamConnectionTester::HandleWriteResult(int result
) {
90 if (result
<= 0 && result
!= net::ERR_IO_PENDING
) {
91 LOG(ERROR
) << "Received error " << result
<< " when trying to write";
94 } else if (result
> 0) {
95 output_buffer_
->DidConsume(result
);
99 void StreamConnectionTester::DoRead() {
102 input_buffer_
->SetCapacity(input_buffer_
->offset() + message_size_
);
103 result
= host_socket_
->Read(
106 base::Bind(&StreamConnectionTester::OnRead
, base::Unretained(this)));
107 HandleReadResult(result
);
111 void StreamConnectionTester::OnRead(int result
) {
112 HandleReadResult(result
);
114 DoRead(); // Don't try to read again when we are done reading.
117 void StreamConnectionTester::HandleReadResult(int result
) {
118 if (result
<= 0 && result
!= net::ERR_IO_PENDING
) {
119 LOG(ERROR
) << "Received error " << result
<< " when trying to read";
122 } else if (result
> 0) {
123 // Allocate memory for the next read.
124 input_buffer_
->set_offset(input_buffer_
->offset() + result
);
125 if (input_buffer_
->offset() == test_data_size_
)
130 DatagramConnectionTester::DatagramConnectionTester(net::Socket
* client_socket
,
131 net::Socket
* host_socket
,
135 : message_loop_(base::MessageLoop::current()),
136 host_socket_(host_socket
),
137 client_socket_(client_socket
),
138 message_size_(message_size
),
139 message_count_(message_count
),
145 packets_received_(0),
146 bad_packets_received_(0) {
147 sent_packets_
.resize(message_count_
);
150 DatagramConnectionTester::~DatagramConnectionTester() {
153 void DatagramConnectionTester::Start() {
158 void DatagramConnectionTester::CheckResults() {
159 EXPECT_EQ(0, write_errors_
);
160 EXPECT_EQ(0, read_errors_
);
162 EXPECT_EQ(0, bad_packets_received_
);
164 // Verify that we've received at least one packet.
165 EXPECT_GT(packets_received_
, 0);
166 VLOG(0) << "Received " << packets_received_
<< " packets out of "
170 void DatagramConnectionTester::Done() {
172 message_loop_
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
175 void DatagramConnectionTester::DoWrite() {
176 if (packets_sent_
>= message_count_
) {
181 scoped_refptr
<net::IOBuffer
> packet(new net::IOBuffer(message_size_
));
182 for (int i
= 0; i
< message_size_
; ++i
) {
183 packet
->data()[i
] = static_cast<char>(i
);
185 sent_packets_
[packets_sent_
] = packet
;
186 // Put index of this packet in the beginning of the packet body.
187 memcpy(packet
->data(), &packets_sent_
, sizeof(packets_sent_
));
189 int result
= client_socket_
->Write(
192 base::Bind(&DatagramConnectionTester::OnWritten
, base::Unretained(this)));
193 HandleWriteResult(result
);
196 void DatagramConnectionTester::OnWritten(int result
) {
197 HandleWriteResult(result
);
200 void DatagramConnectionTester::HandleWriteResult(int result
) {
201 if (result
<= 0 && result
!= net::ERR_IO_PENDING
) {
202 LOG(ERROR
) << "Received error " << result
<< " when trying to write";
205 } else if (result
> 0) {
206 EXPECT_EQ(message_size_
, result
);
208 message_loop_
->PostDelayedTask(
210 base::Bind(&DatagramConnectionTester::DoWrite
, base::Unretained(this)),
211 base::TimeDelta::FromMilliseconds(delay_ms_
));
215 void DatagramConnectionTester::DoRead() {
218 int kReadSize
= message_size_
* 2;
219 read_buffer_
= new net::IOBuffer(kReadSize
);
221 result
= host_socket_
->Read(
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