blob: 406ef4a43331f3f4a46d6773d37b35af7ac5bc57 [file] [log] [blame]
Avi Drissmand6cdf9b2022-09-15 19:52:531// Copyright 2012 The Chromium Authors
[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"
Keishi Hattori0e45c022021-11-27 09:25:526#include "base/memory/raw_ptr.h"
[email protected]57651a82011-12-13 03:54:287
8#include "base/bind.h"
[email protected]57651a82011-12-13 03:54:289#include "net/base/io_buffer.h"
10#include "net/base/net_errors.h"
Ramin Halavatia621c1f2018-02-14 20:50:4611#include "net/traffic_annotation/network_traffic_annotation_test_helper.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
Joe Downing39d710e2022-08-25 20:11:4519namespace remoting::protocol {
[email protected]57651a82011-12-13 03:54:2820
sergeyuaa22c082015-07-20 19:41:1321StreamConnectionTester::StreamConnectionTester(P2PStreamSocket* client_socket,
22 P2PStreamSocket* host_socket,
[email protected]57651a82011-12-13 03:54:2823 int message_size,
24 int message_count)
Gabriel Charetteb79557e2019-06-20 19:17:0025 : host_socket_(host_socket),
[email protected]57651a82011-12-13 03:54:2826 client_socket_(client_socket),
27 message_size_(message_size),
[email protected]57651a82011-12-13 03:54:2828 test_data_size_(message_size * message_count),
[email protected]57651a82011-12-13 03:54:2829 write_errors_(0),
fdoray6d056ff2016-07-04 21:56:4230 read_errors_(0) {}
[email protected]57651a82011-12-13 03:54:2831
Chris Watkins6fe52aa2017-11-28 03:24:0532StreamConnectionTester::~StreamConnectionTester() = default;
[email protected]57651a82011-12-13 03:54:2833
Gabriel Charetteb79557e2019-06-20 19:17:0034void StreamConnectionTester::Start(base::OnceClosure on_done) {
35 on_done_ = std::move(on_done);
[email protected]57651a82011-12-13 03:54:2836 InitBuffers();
37 DoRead();
38 DoWrite();
39}
40
41void StreamConnectionTester::CheckResults() {
42 EXPECT_EQ(0, write_errors_);
43 EXPECT_EQ(0, read_errors_);
44
45 ASSERT_EQ(test_data_size_, input_buffer_->offset());
46
47 output_buffer_->SetOffset(0);
48 ASSERT_EQ(test_data_size_, output_buffer_->size());
49
Joe Downing353ba2c72023-01-11 22:37:3450 EXPECT_EQ(0, memcmp(output_buffer_->data(), input_buffer_->StartOfBuffer(),
51 test_data_size_));
[email protected]57651a82011-12-13 03:54:2852}
53
54void StreamConnectionTester::Done() {
Gabriel Charetteb79557e2019-06-20 19:17:0055 std::move(on_done_).Run();
[email protected]57651a82011-12-13 03:54:2856}
57
58void StreamConnectionTester::InitBuffers() {
Victor Costancd439782018-08-30 07:27:5759 output_buffer_ = base::MakeRefCounted<net::DrainableIOBuffer>(
60 base::MakeRefCounted<net::IOBuffer>(test_data_size_), test_data_size_);
[email protected]16934f32011-12-13 22:04:3861 for (int i = 0; i < test_data_size_; ++i) {
62 output_buffer_->data()[i] = static_cast<char>(i);
63 }
[email protected]57651a82011-12-13 03:54:2864
Victor Costan8a7a19a2018-09-10 21:57:1665 input_buffer_ = base::MakeRefCounted<net::GrowableIOBuffer>();
[email protected]57651a82011-12-13 03:54:2866}
67
68void StreamConnectionTester::DoWrite() {
69 int result = 1;
70 while (result > 0) {
Joe Downing353ba2c72023-01-11 22:37:3471 if (output_buffer_->BytesRemaining() == 0) {
[email protected]57651a82011-12-13 03:54:2872 break;
Joe Downing353ba2c72023-01-11 22:37:3473 }
[email protected]57651a82011-12-13 03:54:2874
Joe Downing353ba2c72023-01-11 22:37:3475 int bytes_to_write =
76 std::min(output_buffer_->BytesRemaining(), message_size_);
Jan Wilken Dörriea0e772a2020-04-01 18:28:1977 result =
78 client_socket_->Write(output_buffer_.get(), bytes_to_write,
79 base::BindOnce(&StreamConnectionTester::OnWritten,
80 base::Unretained(this)),
81 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]57651a82011-12-13 03:54:2882 HandleWriteResult(result);
83 }
84}
85
86void StreamConnectionTester::OnWritten(int result) {
87 HandleWriteResult(result);
88 DoWrite();
89}
90
91void StreamConnectionTester::HandleWriteResult(int result) {
92 if (result <= 0 && result != net::ERR_IO_PENDING) {
93 LOG(ERROR) << "Received error " << result << " when trying to write";
94 write_errors_++;
95 Done();
96 } else if (result > 0) {
97 output_buffer_->DidConsume(result);
98 }
99}
100
101void StreamConnectionTester::DoRead() {
102 int result = 1;
103 while (result > 0) {
104 input_buffer_->SetCapacity(input_buffer_->offset() + message_size_);
Jan Wilken Dörriea0e772a2020-04-01 18:28:19105 result = host_socket_->Read(input_buffer_.get(), message_size_,
106 base::BindOnce(&StreamConnectionTester::OnRead,
107 base::Unretained(this)));
[email protected]57651a82011-12-13 03:54:28108 HandleReadResult(result);
109 };
110}
111
112void StreamConnectionTester::OnRead(int result) {
113 HandleReadResult(result);
Joe Downing353ba2c72023-01-11 22:37:34114 if (!on_done_.is_null()) {
[email protected]57651a82011-12-13 03:54:28115 DoRead(); // Don't try to read again when we are done reading.
Joe Downing353ba2c72023-01-11 22:37:34116 }
[email protected]57651a82011-12-13 03:54:28117}
118
119void StreamConnectionTester::HandleReadResult(int result) {
120 if (result <= 0 && result != net::ERR_IO_PENDING) {
121 LOG(ERROR) << "Received error " << result << " when trying to read";
122 read_errors_++;
123 Done();
124 } else if (result > 0) {
125 // Allocate memory for the next read.
126 input_buffer_->set_offset(input_buffer_->offset() + result);
Joe Downing353ba2c72023-01-11 22:37:34127 if (input_buffer_->offset() == test_data_size_) {
[email protected]57651a82011-12-13 03:54:28128 Done();
Joe Downing353ba2c72023-01-11 22:37:34129 }
[email protected]57651a82011-12-13 03:54:28130 }
131}
132
sergeyu5b4667b2017-03-17 19:12:48133class MessagePipeConnectionTester::MessageSender
134 : public MessagePipe::EventHandler {
135 public:
136 MessageSender(MessagePipe* pipe, int message_size, int message_count)
137 : pipe_(pipe),
138 message_size_(message_size),
139 message_count_(message_count) {}
140
141 void Start() { pipe_->Start(this); }
142
143 const std::vector<std::unique_ptr<VideoPacket>>& sent_messages() {
144 return sent_messages_;
145 }
146
147 // MessagePipe::EventHandler interface.
148 void OnMessagePipeOpen() override {
149 for (int i = 0; i < message_count_; ++i) {
150 std::unique_ptr<VideoPacket> message(new VideoPacket());
151 message->mutable_data()->resize(message_size_);
152 for (int p = 0; p < message_size_; ++p) {
153 message->mutable_data()[0] = static_cast<char>(i + p);
154 }
Evan Stade86dadf152020-03-16 20:06:33155 pipe_->Send(message.get(), {});
sergeyu5b4667b2017-03-17 19:12:48156 sent_messages_.push_back(std::move(message));
157 }
158 }
159 void OnMessageReceived(std::unique_ptr<CompoundBuffer> message) override {
160 NOTREACHED();
161 }
162 void OnMessagePipeClosed() override { NOTREACHED(); }
163
164 private:
Keishi Hattori0e45c022021-11-27 09:25:52165 raw_ptr<MessagePipe> pipe_;
sergeyu5b4667b2017-03-17 19:12:48166 int message_size_;
167 int message_count_;
168
169 std::vector<std::unique_ptr<VideoPacket>> sent_messages_;
170};
171
sergeyu786463e2016-02-04 18:46:10172MessagePipeConnectionTester::MessagePipeConnectionTester(
sergeyu786463e2016-02-04 18:46:10173 MessagePipe* host_pipe,
sergeyu5b4667b2017-03-17 19:12:48174 MessagePipe* client_pipe,
sergeyu786463e2016-02-04 18:46:10175 int message_size,
176 int message_count)
sergeyu5b4667b2017-03-17 19:12:48177 : client_pipe_(client_pipe),
178 sender_(new MessageSender(host_pipe, message_size, message_count)) {}
179
Chris Watkins6fe52aa2017-11-28 03:24:05180MessagePipeConnectionTester::~MessagePipeConnectionTester() = default;
sergeyu786463e2016-02-04 18:46:10181
182void MessagePipeConnectionTester::RunAndCheckResults() {
sergeyu5b4667b2017-03-17 19:12:48183 sender_->Start();
184 client_pipe_->Start(this);
sergeyu786463e2016-02-04 18:46:10185
186 run_loop_.Run();
187
sergeyu5b4667b2017-03-17 19:12:48188 ASSERT_EQ(sender_->sent_messages().size(), received_messages_.size());
189 for (size_t i = 0; i < sender_->sent_messages().size(); ++i) {
190 EXPECT_TRUE(sender_->sent_messages()[i]->data() ==
191 received_messages_[i]->data());
sergeyu786463e2016-02-04 18:46:10192 }
193}
194
sergeyu5b4667b2017-03-17 19:12:48195void MessagePipeConnectionTester::OnMessagePipeOpen() {}
196
sergeyu786463e2016-02-04 18:46:10197void MessagePipeConnectionTester::OnMessageReceived(
dcheng0765c492016-04-06 22:41:53198 std::unique_ptr<CompoundBuffer> message) {
sergeyu786463e2016-02-04 18:46:10199 received_messages_.push_back(ParseMessage<VideoPacket>(message.get()));
sergeyu5b4667b2017-03-17 19:12:48200 if (received_messages_.size() >= sender_->sent_messages().size()) {
sergeyu786463e2016-02-04 18:46:10201 run_loop_.Quit();
202 }
203}
204
sergeyud059c462016-07-20 19:34:10205void MessagePipeConnectionTester::OnMessagePipeClosed() {
206 run_loop_.Quit();
207 FAIL();
208}
209
Joe Downing39d710e2022-08-25 20:11:45210} // namespace remoting::protocol