blob: a42079d2280632b92db529b79682a2303099540d [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"
Ramin Halavatia621c1f2018-02-14 20:50:4612#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
sergeyu786463e2016-02-04 18:46:1013#include "remoting/proto/video.pb.h"
14#include "remoting/protocol/message_pipe.h"
15#include "remoting/protocol/message_serialization.h"
sergeyuaa22c082015-07-20 19:41:1316#include "remoting/protocol/p2p_datagram_socket.h"
17#include "remoting/protocol/p2p_stream_socket.h"
[email protected]57651a82011-12-13 03:54:2818#include "testing/gtest/include/gtest/gtest.h"
19
20namespace remoting {
21namespace protocol {
22
sergeyuaa22c082015-07-20 19:41:1323StreamConnectionTester::StreamConnectionTester(P2PStreamSocket* client_socket,
24 P2PStreamSocket* host_socket,
[email protected]57651a82011-12-13 03:54:2825 int message_size,
26 int message_count)
fdoray6d056ff2016-07-04 21:56:4227 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
[email protected]57651a82011-12-13 03:54:2828 host_socket_(host_socket),
29 client_socket_(client_socket),
30 message_size_(message_size),
[email protected]57651a82011-12-13 03:54:2831 test_data_size_(message_size * message_count),
32 done_(false),
33 write_errors_(0),
fdoray6d056ff2016-07-04 21:56:4234 read_errors_(0) {}
[email protected]57651a82011-12-13 03:54:2835
Chris Watkins6fe52aa2017-11-28 03:24:0536StreamConnectionTester::~StreamConnectionTester() = default;
[email protected]57651a82011-12-13 03:54:2837
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_);
[email protected]57651a82011-12-13 03:54:2880 result = client_socket_->Write(
[email protected]f94cd9702017-12-07 06:09:4081 output_buffer_.get(), bytes_to_write,
82 base::Bind(&StreamConnectionTester::OnWritten, base::Unretained(this)),
Ramin Halavatia621c1f2018-02-14 20:50:4683 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]57651a82011-12-13 03:54:2884 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
Chris Watkins6fe52aa2017-11-28 03:24:05155DatagramConnectionTester::~DatagramConnectionTester() = default;
[email protected]57651a82011-12-13 03:54:28156
157void DatagramConnectionTester::Start() {
158 DoRead();
159 DoWrite();
160}
161
162void DatagramConnectionTester::CheckResults() {
163 EXPECT_EQ(0, write_errors_);
164 EXPECT_EQ(0, read_errors_);
165
166 EXPECT_EQ(0, bad_packets_received_);
167
168 // Verify that we've received at least one packet.
169 EXPECT_GT(packets_received_, 0);
[email protected]5cbe3cf2013-11-25 17:05:04170 VLOG(0) << "Received " << packets_received_ << " packets out of "
171 << message_count_;
[email protected]57651a82011-12-13 03:54:28172}
173
174void DatagramConnectionTester::Done() {
175 done_ = true;
fdoray6d056ff2016-07-04 21:56:42176 task_runner_->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
[email protected]57651a82011-12-13 03:54:28177}
178
179void DatagramConnectionTester::DoWrite() {
180 if (packets_sent_ >= message_count_) {
181 Done();
182 return;
183 }
184
185 scoped_refptr<net::IOBuffer> packet(new net::IOBuffer(message_size_));
[email protected]16934f32011-12-13 22:04:38186 for (int i = 0; i < message_size_; ++i) {
187 packet->data()[i] = static_cast<char>(i);
188 }
[email protected]57651a82011-12-13 03:54:28189 sent_packets_[packets_sent_] = packet;
190 // Put index of this packet in the beginning of the packet body.
191 memcpy(packet->data(), &packets_sent_, sizeof(packets_sent_));
192
sergeyuaa22c082015-07-20 19:41:13193 int result = client_socket_->Send(
194 packet.get(), message_size_,
[email protected]57651a82011-12-13 03:54:28195 base::Bind(&DatagramConnectionTester::OnWritten, base::Unretained(this)));
196 HandleWriteResult(result);
197}
198
199void DatagramConnectionTester::OnWritten(int result) {
200 HandleWriteResult(result);
201}
202
203void DatagramConnectionTester::HandleWriteResult(int result) {
204 if (result <= 0 && result != net::ERR_IO_PENDING) {
205 LOG(ERROR) << "Received error " << result << " when trying to write";
206 write_errors_++;
207 Done();
208 } else if (result > 0) {
209 EXPECT_EQ(message_size_, result);
210 packets_sent_++;
fdoray6d056ff2016-07-04 21:56:42211 task_runner_->PostDelayedTask(
[email protected]1e2076be2012-03-05 01:16:33212 FROM_HERE,
213 base::Bind(&DatagramConnectionTester::DoWrite, base::Unretained(this)),
214 base::TimeDelta::FromMilliseconds(delay_ms_));
[email protected]57651a82011-12-13 03:54:28215 }
216}
217
218void DatagramConnectionTester::DoRead() {
219 int result = 1;
220 while (result > 0) {
221 int kReadSize = message_size_ * 2;
222 read_buffer_ = new net::IOBuffer(kReadSize);
223
sergeyuaa22c082015-07-20 19:41:13224 result = host_socket_->Recv(
225 read_buffer_.get(), kReadSize,
[email protected]57651a82011-12-13 03:54:28226 base::Bind(&DatagramConnectionTester::OnRead, base::Unretained(this)));
227 HandleReadResult(result);
228 };
229}
230
231void DatagramConnectionTester::OnRead(int result) {
232 HandleReadResult(result);
233 DoRead();
234}
235
236void DatagramConnectionTester::HandleReadResult(int result) {
237 if (result <= 0 && result != net::ERR_IO_PENDING) {
238 // Error will be received after the socket is closed.
239 LOG(ERROR) << "Received error " << result << " when trying to read";
240 read_errors_++;
241 Done();
242 } else if (result > 0) {
243 packets_received_++;
244 if (message_size_ != result) {
245 // Invalid packet size;
246 bad_packets_received_++;
247 } else {
248 // Validate packet body.
249 int packet_id;
250 memcpy(&packet_id, read_buffer_->data(), sizeof(packet_id));
251 if (packet_id < 0 || packet_id >= message_count_) {
252 bad_packets_received_++;
253 } else {
254 if (memcmp(read_buffer_->data(), sent_packets_[packet_id]->data(),
255 message_size_) != 0)
256 bad_packets_received_++;
257 }
258 }
259 }
260}
261
sergeyu5b4667b2017-03-17 19:12:48262class MessagePipeConnectionTester::MessageSender
263 : public MessagePipe::EventHandler {
264 public:
265 MessageSender(MessagePipe* pipe, int message_size, int message_count)
266 : pipe_(pipe),
267 message_size_(message_size),
268 message_count_(message_count) {}
269
270 void Start() { pipe_->Start(this); }
271
272 const std::vector<std::unique_ptr<VideoPacket>>& sent_messages() {
273 return sent_messages_;
274 }
275
276 // MessagePipe::EventHandler interface.
277 void OnMessagePipeOpen() override {
278 for (int i = 0; i < message_count_; ++i) {
279 std::unique_ptr<VideoPacket> message(new VideoPacket());
280 message->mutable_data()->resize(message_size_);
281 for (int p = 0; p < message_size_; ++p) {
282 message->mutable_data()[0] = static_cast<char>(i + p);
283 }
284 pipe_->Send(message.get(), base::Closure());
285 sent_messages_.push_back(std::move(message));
286 }
287 }
288 void OnMessageReceived(std::unique_ptr<CompoundBuffer> message) override {
289 NOTREACHED();
290 }
291 void OnMessagePipeClosed() override { NOTREACHED(); }
292
293 private:
294 MessagePipe* pipe_;
295 int message_size_;
296 int message_count_;
297
298 std::vector<std::unique_ptr<VideoPacket>> sent_messages_;
299};
300
sergeyu786463e2016-02-04 18:46:10301MessagePipeConnectionTester::MessagePipeConnectionTester(
sergeyu786463e2016-02-04 18:46:10302 MessagePipe* host_pipe,
sergeyu5b4667b2017-03-17 19:12:48303 MessagePipe* client_pipe,
sergeyu786463e2016-02-04 18:46:10304 int message_size,
305 int message_count)
sergeyu5b4667b2017-03-17 19:12:48306 : client_pipe_(client_pipe),
307 sender_(new MessageSender(host_pipe, message_size, message_count)) {}
308
Chris Watkins6fe52aa2017-11-28 03:24:05309MessagePipeConnectionTester::~MessagePipeConnectionTester() = default;
sergeyu786463e2016-02-04 18:46:10310
311void MessagePipeConnectionTester::RunAndCheckResults() {
sergeyu5b4667b2017-03-17 19:12:48312 sender_->Start();
313 client_pipe_->Start(this);
sergeyu786463e2016-02-04 18:46:10314
315 run_loop_.Run();
316
sergeyu5b4667b2017-03-17 19:12:48317 ASSERT_EQ(sender_->sent_messages().size(), received_messages_.size());
318 for (size_t i = 0; i < sender_->sent_messages().size(); ++i) {
319 EXPECT_TRUE(sender_->sent_messages()[i]->data() ==
320 received_messages_[i]->data());
sergeyu786463e2016-02-04 18:46:10321 }
322}
323
sergeyu5b4667b2017-03-17 19:12:48324void MessagePipeConnectionTester::OnMessagePipeOpen() {}
325
sergeyu786463e2016-02-04 18:46:10326void MessagePipeConnectionTester::OnMessageReceived(
dcheng0765c492016-04-06 22:41:53327 std::unique_ptr<CompoundBuffer> message) {
sergeyu786463e2016-02-04 18:46:10328 received_messages_.push_back(ParseMessage<VideoPacket>(message.get()));
sergeyu5b4667b2017-03-17 19:12:48329 if (received_messages_.size() >= sender_->sent_messages().size()) {
sergeyu786463e2016-02-04 18:46:10330 run_loop_.Quit();
331 }
332}
333
sergeyud059c462016-07-20 19:34:10334void MessagePipeConnectionTester::OnMessagePipeClosed() {
335 run_loop_.Quit();
336 FAIL();
337}
338
[email protected]57651a82011-12-13 03:54:28339} // namespace protocol
340} // namespace remoting