blob: 214f6ea13a95b68091698581f3f146f4b32ed4ef [file] [log] [blame]
[email protected]1e2076be2012-03-05 01:16:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]57651a82011-12-13 03:54:282// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "remoting/protocol/connection_tester.h"
6
7#include "base/bind.h"
[email protected]f368eeb2013-07-17 23:53:328#include "base/message_loop/message_loop.h"
fdoray6d056ff2016-07-04 21:56:429#include "base/threading/thread_task_runner_handle.h"
[email protected]57651a82011-12-13 03:54:2810#include "net/base/io_buffer.h"
11#include "net/base/net_errors.h"
sergeyu786463e2016-02-04 18:46:1012#include "remoting/proto/video.pb.h"
13#include "remoting/protocol/message_pipe.h"
14#include "remoting/protocol/message_serialization.h"
sergeyuaa22c082015-07-20 19:41:1315#include "remoting/protocol/p2p_datagram_socket.h"
16#include "remoting/protocol/p2p_stream_socket.h"
[email protected]57651a82011-12-13 03:54:2817#include "testing/gtest/include/gtest/gtest.h"
18
19namespace remoting {
20namespace protocol {
21
sergeyuaa22c082015-07-20 19:41:1322StreamConnectionTester::StreamConnectionTester(P2PStreamSocket* client_socket,
23 P2PStreamSocket* host_socket,
[email protected]57651a82011-12-13 03:54:2824 int message_size,
25 int message_count)
fdoray6d056ff2016-07-04 21:56:4226 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
[email protected]57651a82011-12-13 03:54:2827 host_socket_(host_socket),
28 client_socket_(client_socket),
29 message_size_(message_size),
[email protected]57651a82011-12-13 03:54:2830 test_data_size_(message_size * message_count),
31 done_(false),
32 write_errors_(0),
fdoray6d056ff2016-07-04 21:56:4233 read_errors_(0) {}
[email protected]57651a82011-12-13 03:54:2834
35StreamConnectionTester::~StreamConnectionTester() {
36}
37
38void StreamConnectionTester::Start() {
39 InitBuffers();
40 DoRead();
41 DoWrite();
42}
43
44void StreamConnectionTester::CheckResults() {
45 EXPECT_EQ(0, write_errors_);
46 EXPECT_EQ(0, read_errors_);
47
48 ASSERT_EQ(test_data_size_, input_buffer_->offset());
49
50 output_buffer_->SetOffset(0);
51 ASSERT_EQ(test_data_size_, output_buffer_->size());
52
53 EXPECT_EQ(0, memcmp(output_buffer_->data(),
54 input_buffer_->StartOfBuffer(), test_data_size_));
55}
56
57void StreamConnectionTester::Done() {
58 done_ = true;
fdoray6d056ff2016-07-04 21:56:4259 task_runner_->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
[email protected]57651a82011-12-13 03:54:2860}
61
62void StreamConnectionTester::InitBuffers() {
63 output_buffer_ = new net::DrainableIOBuffer(
64 new net::IOBuffer(test_data_size_), test_data_size_);
[email protected]16934f32011-12-13 22:04:3865 for (int i = 0; i < test_data_size_; ++i) {
66 output_buffer_->data()[i] = static_cast<char>(i);
67 }
[email protected]57651a82011-12-13 03:54:2868
69 input_buffer_ = new net::GrowableIOBuffer();
70}
71
72void StreamConnectionTester::DoWrite() {
73 int result = 1;
74 while (result > 0) {
75 if (output_buffer_->BytesRemaining() == 0)
76 break;
77
78 int bytes_to_write = std::min(output_buffer_->BytesRemaining(),
79 message_size_);
80 result = client_socket_->Write(
[email protected]f9d8a772013-06-01 04:33:1781 output_buffer_.get(),
82 bytes_to_write,
[email protected]57651a82011-12-13 03:54:2883 base::Bind(&StreamConnectionTester::OnWritten, base::Unretained(this)));
84 HandleWriteResult(result);
85 }
86}
87
88void StreamConnectionTester::OnWritten(int result) {
89 HandleWriteResult(result);
90 DoWrite();
91}
92
93void StreamConnectionTester::HandleWriteResult(int result) {
94 if (result <= 0 && result != net::ERR_IO_PENDING) {
95 LOG(ERROR) << "Received error " << result << " when trying to write";
96 write_errors_++;
97 Done();
98 } else if (result > 0) {
99 output_buffer_->DidConsume(result);
100 }
101}
102
103void StreamConnectionTester::DoRead() {
104 int result = 1;
105 while (result > 0) {
106 input_buffer_->SetCapacity(input_buffer_->offset() + message_size_);
107 result = host_socket_->Read(
[email protected]f9d8a772013-06-01 04:33:17108 input_buffer_.get(),
109 message_size_,
[email protected]57651a82011-12-13 03:54:28110 base::Bind(&StreamConnectionTester::OnRead, base::Unretained(this)));
111 HandleReadResult(result);
112 };
113}
114
115void StreamConnectionTester::OnRead(int result) {
116 HandleReadResult(result);
117 if (!done_)
118 DoRead(); // Don't try to read again when we are done reading.
119}
120
121void StreamConnectionTester::HandleReadResult(int result) {
122 if (result <= 0 && result != net::ERR_IO_PENDING) {
123 LOG(ERROR) << "Received error " << result << " when trying to read";
124 read_errors_++;
125 Done();
126 } else if (result > 0) {
127 // Allocate memory for the next read.
128 input_buffer_->set_offset(input_buffer_->offset() + result);
129 if (input_buffer_->offset() == test_data_size_)
130 Done();
131 }
132}
133
sergeyuaa22c082015-07-20 19:41:13134DatagramConnectionTester::DatagramConnectionTester(
135 P2PDatagramSocket* client_socket,
136 P2PDatagramSocket* host_socket,
137 int message_size,
138 int message_count,
139 int delay_ms)
fdoray6d056ff2016-07-04 21:56:42140 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
[email protected]57651a82011-12-13 03:54:28141 host_socket_(host_socket),
142 client_socket_(client_socket),
143 message_size_(message_size),
144 message_count_(message_count),
145 delay_ms_(delay_ms),
146 done_(false),
147 write_errors_(0),
148 read_errors_(0),
149 packets_sent_(0),
150 packets_received_(0),
151 bad_packets_received_(0) {
152 sent_packets_.resize(message_count_);
153}
154
155DatagramConnectionTester::~DatagramConnectionTester() {
156}
157
158void DatagramConnectionTester::Start() {
159 DoRead();
160 DoWrite();
161}
162
163void DatagramConnectionTester::CheckResults() {
164 EXPECT_EQ(0, write_errors_);
165 EXPECT_EQ(0, read_errors_);
166
167 EXPECT_EQ(0, bad_packets_received_);
168
169 // Verify that we've received at least one packet.
170 EXPECT_GT(packets_received_, 0);
[email protected]5cbe3cf2013-11-25 17:05:04171 VLOG(0) << "Received " << packets_received_ << " packets out of "
172 << message_count_;
[email protected]57651a82011-12-13 03:54:28173}
174
175void DatagramConnectionTester::Done() {
176 done_ = true;
fdoray6d056ff2016-07-04 21:56:42177 task_runner_->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
[email protected]57651a82011-12-13 03:54:28178}
179
180void DatagramConnectionTester::DoWrite() {
181 if (packets_sent_ >= message_count_) {
182 Done();
183 return;
184 }
185
186 scoped_refptr<net::IOBuffer> packet(new net::IOBuffer(message_size_));
[email protected]16934f32011-12-13 22:04:38187 for (int i = 0; i < message_size_; ++i) {
188 packet->data()[i] = static_cast<char>(i);
189 }
[email protected]57651a82011-12-13 03:54:28190 sent_packets_[packets_sent_] = packet;
191 // Put index of this packet in the beginning of the packet body.
192 memcpy(packet->data(), &packets_sent_, sizeof(packets_sent_));
193
sergeyuaa22c082015-07-20 19:41:13194 int result = client_socket_->Send(
195 packet.get(), message_size_,
[email protected]57651a82011-12-13 03:54:28196 base::Bind(&DatagramConnectionTester::OnWritten, base::Unretained(this)));
197 HandleWriteResult(result);
198}
199
200void DatagramConnectionTester::OnWritten(int result) {
201 HandleWriteResult(result);
202}
203
204void DatagramConnectionTester::HandleWriteResult(int result) {
205 if (result <= 0 && result != net::ERR_IO_PENDING) {
206 LOG(ERROR) << "Received error " << result << " when trying to write";
207 write_errors_++;
208 Done();
209 } else if (result > 0) {
210 EXPECT_EQ(message_size_, result);
211 packets_sent_++;
fdoray6d056ff2016-07-04 21:56:42212 task_runner_->PostDelayedTask(
[email protected]1e2076be2012-03-05 01:16:33213 FROM_HERE,
214 base::Bind(&DatagramConnectionTester::DoWrite, base::Unretained(this)),
215 base::TimeDelta::FromMilliseconds(delay_ms_));
[email protected]57651a82011-12-13 03:54:28216 }
217}
218
219void DatagramConnectionTester::DoRead() {
220 int result = 1;
221 while (result > 0) {
222 int kReadSize = message_size_ * 2;
223 read_buffer_ = new net::IOBuffer(kReadSize);
224
sergeyuaa22c082015-07-20 19:41:13225 result = host_socket_->Recv(
226 read_buffer_.get(), kReadSize,
[email protected]57651a82011-12-13 03:54:28227 base::Bind(&DatagramConnectionTester::OnRead, base::Unretained(this)));
228 HandleReadResult(result);
229 };
230}
231
232void DatagramConnectionTester::OnRead(int result) {
233 HandleReadResult(result);
234 DoRead();
235}
236
237void DatagramConnectionTester::HandleReadResult(int result) {
238 if (result <= 0 && result != net::ERR_IO_PENDING) {
239 // Error will be received after the socket is closed.
240 LOG(ERROR) << "Received error " << result << " when trying to read";
241 read_errors_++;
242 Done();
243 } else if (result > 0) {
244 packets_received_++;
245 if (message_size_ != result) {
246 // Invalid packet size;
247 bad_packets_received_++;
248 } else {
249 // Validate packet body.
250 int packet_id;
251 memcpy(&packet_id, read_buffer_->data(), sizeof(packet_id));
252 if (packet_id < 0 || packet_id >= message_count_) {
253 bad_packets_received_++;
254 } else {
255 if (memcmp(read_buffer_->data(), sent_packets_[packet_id]->data(),
256 message_size_) != 0)
257 bad_packets_received_++;
258 }
259 }
260 }
261}
262
sergeyu786463e2016-02-04 18:46:10263MessagePipeConnectionTester::MessagePipeConnectionTester(
264 MessagePipe* client_pipe,
265 MessagePipe* host_pipe,
266 int message_size,
267 int message_count)
268 : host_pipe_(host_pipe),
269 client_pipe_(client_pipe),
270 message_size_(message_size),
271 message_count_(message_count) {}
272MessagePipeConnectionTester::~MessagePipeConnectionTester() {}
273
274void MessagePipeConnectionTester::RunAndCheckResults() {
sergeyud059c462016-07-20 19:34:10275 host_pipe_->Start(this);
sergeyu786463e2016-02-04 18:46:10276
277 for (int i = 0; i < message_count_; ++i) {
dcheng0765c492016-04-06 22:41:53278 std::unique_ptr<VideoPacket> message(new VideoPacket());
sergeyu786463e2016-02-04 18:46:10279 message->mutable_data()->resize(message_size_);
280 for (int p = 0; p < message_size_; ++p) {
281 message->mutable_data()[0] = static_cast<char>(i + p);
282 }
283 client_pipe_->Send(message.get(), base::Closure());
284 sent_messages_.push_back(std::move(message));
285 }
286
287 run_loop_.Run();
288
289 ASSERT_EQ(sent_messages_.size(), received_messages_.size());
290 for (size_t i = 0; i < sent_messages_.size(); ++i) {
291 EXPECT_TRUE(sent_messages_[i]->data() == received_messages_[i]->data());
292 }
293}
294
295void MessagePipeConnectionTester::OnMessageReceived(
dcheng0765c492016-04-06 22:41:53296 std::unique_ptr<CompoundBuffer> message) {
sergeyu786463e2016-02-04 18:46:10297 received_messages_.push_back(ParseMessage<VideoPacket>(message.get()));
298 if (received_messages_.size() >= sent_messages_.size()) {
299 run_loop_.Quit();
300 }
301}
302
sergeyud059c462016-07-20 19:34:10303void MessagePipeConnectionTester::OnMessagePipeClosed() {
304 run_loop_.Quit();
305 FAIL();
306}
307
[email protected]57651a82011-12-13 03:54:28308} // namespace protocol
309} // namespace remoting