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.
4
5 #include "remoting/protocol/fake_session.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "net/base/address_list.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/net_util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace remoting {
16 namespace protocol {
17
18 const char kTestJid[] = "host1@gmail.com/chromoting123";
19
FakeSocket()20 FakeSocket::FakeSocket()
21 : async_write_(false),
22 write_pending_(false),
23 write_limit_(0),
24 next_write_error_(net::OK),
25 next_read_error_(net::OK),
26 read_pending_(false),
27 read_buffer_size_(0),
28 input_pos_(0),
29 message_loop_(base::MessageLoop::current()),
30 weak_factory_(this) {
31 }
32
~FakeSocket()33 FakeSocket::~FakeSocket() {
34 EXPECT_EQ(message_loop_, base::MessageLoop::current());
35 }
36
AppendInputData(const std::vector<char> & data)37 void FakeSocket::AppendInputData(const std::vector<char>& data) {
38 EXPECT_EQ(message_loop_, base::MessageLoop::current());
39 input_data_.insert(input_data_.end(), data.begin(), data.end());
40 // Complete pending read if any.
41 if (read_pending_) {
42 read_pending_ = false;
43 int result = std::min(read_buffer_size_,
44 static_cast<int>(input_data_.size() - input_pos_));
45 CHECK(result > 0);
46 memcpy(read_buffer_->data(),
47 &(*input_data_.begin()) + input_pos_, result);
48 input_pos_ += result;
49 read_buffer_ = NULL;
50 read_callback_.Run(result);
51 }
52 }
53
PairWith(FakeSocket * peer_socket)54 void FakeSocket::PairWith(FakeSocket* peer_socket) {
55 EXPECT_EQ(message_loop_, base::MessageLoop::current());
56 peer_socket_ = peer_socket->weak_factory_.GetWeakPtr();
57 peer_socket->peer_socket_ = weak_factory_.GetWeakPtr();
58 }
59
Read(net::IOBuffer * buf,int buf_len,const net::CompletionCallback & callback)60 int FakeSocket::Read(net::IOBuffer* buf, int buf_len,
61 const net::CompletionCallback& callback) {
62 EXPECT_EQ(message_loop_, base::MessageLoop::current());
63
64 if (next_read_error_ != net::OK) {
65 int r = next_read_error_;
66 next_read_error_ = net::OK;
67 return r;
68 }
69
70 if (input_pos_ < static_cast<int>(input_data_.size())) {
71 int result = std::min(buf_len,
72 static_cast<int>(input_data_.size()) - input_pos_);
73 memcpy(buf->data(), &(*input_data_.begin()) + input_pos_, result);
74 input_pos_ += result;
75 return result;
76 } else {
77 read_pending_ = true;
78 read_buffer_ = buf;
79 read_buffer_size_ = buf_len;
80 read_callback_ = callback;
81 return net::ERR_IO_PENDING;
82 }
83 }
84
Write(net::IOBuffer * buf,int buf_len,const net::CompletionCallback & callback)85 int FakeSocket::Write(net::IOBuffer* buf, int buf_len,
86 const net::CompletionCallback& callback) {
87 EXPECT_EQ(message_loop_, base::MessageLoop::current());
88 EXPECT_FALSE(write_pending_);
89
90 if (write_limit_ > 0)
91 buf_len = std::min(write_limit_, buf_len);
92
93 if (async_write_) {
94 message_loop_->PostTask(FROM_HERE, base::Bind(
95 &FakeSocket::DoAsyncWrite, weak_factory_.GetWeakPtr(),
96 scoped_refptr<net::IOBuffer>(buf), buf_len, callback));
97 write_pending_ = true;
98 return net::ERR_IO_PENDING;
99 } else {
100 if (next_write_error_ != net::OK) {
101 int r = next_write_error_;
102 next_write_error_ = net::OK;
103 return r;
104 }
105
106 DoWrite(buf, buf_len);
107 return buf_len;
108 }
109 }
110
DoAsyncWrite(scoped_refptr<net::IOBuffer> buf,int buf_len,const net::CompletionCallback & callback)111 void FakeSocket::DoAsyncWrite(scoped_refptr<net::IOBuffer> buf, int buf_len,
112 const net::CompletionCallback& callback) {
113 write_pending_ = false;
114
115 if (next_write_error_ != net::OK) {
116 int r = next_write_error_;
117 next_write_error_ = net::OK;
118 callback.Run(r);
119 return;
120 }
121
122 DoWrite(buf.get(), buf_len);
123 callback.Run(buf_len);
124 }
125
DoWrite(net::IOBuffer * buf,int buf_len)126 void FakeSocket::DoWrite(net::IOBuffer* buf, int buf_len) {
127 written_data_.insert(written_data_.end(),
128 buf->data(), buf->data() + buf_len);
129
130 if (peer_socket_.get()) {
131 message_loop_->PostTask(
132 FROM_HERE,
133 base::Bind(&FakeSocket::AppendInputData,
134 peer_socket_,
135 std::vector<char>(buf->data(), buf->data() + buf_len)));
136 }
137 }
138
SetReceiveBufferSize(int32 size)139 bool FakeSocket::SetReceiveBufferSize(int32 size) {
140 NOTIMPLEMENTED();
141 return false;
142 }
SetSendBufferSize(int32 size)143 bool FakeSocket::SetSendBufferSize(int32 size) {
144 NOTIMPLEMENTED();
145 return false;
146 }
147
Connect(const net::CompletionCallback & callback)148 int FakeSocket::Connect(const net::CompletionCallback& callback) {
149 EXPECT_EQ(message_loop_, base::MessageLoop::current());
150 return net::OK;
151 }
152
Disconnect()153 void FakeSocket::Disconnect() {
154 peer_socket_.reset();
155 }
156
IsConnected() const157 bool FakeSocket::IsConnected() const {
158 EXPECT_EQ(message_loop_, base::MessageLoop::current());
159 return true;
160 }
161
IsConnectedAndIdle() const162 bool FakeSocket::IsConnectedAndIdle() const {
163 NOTIMPLEMENTED();
164 return false;
165 }
166
GetPeerAddress(net::IPEndPoint * address) const167 int FakeSocket::GetPeerAddress(net::IPEndPoint* address) const {
168 net::IPAddressNumber ip(net::kIPv4AddressSize);
169 *address = net::IPEndPoint(ip, 0);
170 return net::OK;
171 }
172
GetLocalAddress(net::IPEndPoint * address) const173 int FakeSocket::GetLocalAddress(net::IPEndPoint* address) const {
174 NOTIMPLEMENTED();
175 return net::ERR_FAILED;
176 }
177
NetLog() const178 const net::BoundNetLog& FakeSocket::NetLog() const {
179 EXPECT_EQ(message_loop_, base::MessageLoop::current());
180 return net_log_;
181 }
182
SetSubresourceSpeculation()183 void FakeSocket::SetSubresourceSpeculation() {
184 NOTIMPLEMENTED();
185 }
186
SetOmniboxSpeculation()187 void FakeSocket::SetOmniboxSpeculation() {
188 NOTIMPLEMENTED();
189 }
190
WasEverUsed() const191 bool FakeSocket::WasEverUsed() const {
192 NOTIMPLEMENTED();
193 return true;
194 }
195
UsingTCPFastOpen() const196 bool FakeSocket::UsingTCPFastOpen() const {
197 NOTIMPLEMENTED();
198 return true;
199 }
200
WasNpnNegotiated() const201 bool FakeSocket::WasNpnNegotiated() const {
202 return false;
203 }
204
GetNegotiatedProtocol() const205 net::NextProto FakeSocket::GetNegotiatedProtocol() const {
206 NOTIMPLEMENTED();
207 return net::kProtoUnknown;
208 }
209
GetSSLInfo(net::SSLInfo * ssl_info)210 bool FakeSocket::GetSSLInfo(net::SSLInfo* ssl_info) {
211 return false;
212 }
213
FakeUdpSocket()214 FakeUdpSocket::FakeUdpSocket()
215 : read_pending_(false),
216 input_pos_(0),
217 message_loop_(base::MessageLoop::current()) {
218 }
219
~FakeUdpSocket()220 FakeUdpSocket::~FakeUdpSocket() {
221 EXPECT_EQ(message_loop_, base::MessageLoop::current());
222 }
223
AppendInputPacket(const char * data,int data_size)224 void FakeUdpSocket::AppendInputPacket(const char* data, int data_size) {
225 EXPECT_EQ(message_loop_, base::MessageLoop::current());
226 input_packets_.push_back(std::string());
227 input_packets_.back().assign(data, data + data_size);
228
229 // Complete pending read if any.
230 if (read_pending_) {
231 read_pending_ = false;
232 int result = std::min(data_size, read_buffer_size_);
233 memcpy(read_buffer_->data(), data, result);
234 input_pos_ = input_packets_.size();
235 read_callback_.Run(result);
236 read_buffer_ = NULL;
237 }
238 }
239
Read(net::IOBuffer * buf,int buf_len,const net::CompletionCallback & callback)240 int FakeUdpSocket::Read(net::IOBuffer* buf, int buf_len,
241 const net::CompletionCallback& callback) {
242 EXPECT_EQ(message_loop_, base::MessageLoop::current());
243 if (input_pos_ < static_cast<int>(input_packets_.size())) {
244 int result = std::min(
245 buf_len, static_cast<int>(input_packets_[input_pos_].size()));
246 memcpy(buf->data(), &(*input_packets_[input_pos_].begin()), result);
247 ++input_pos_;
248 return result;
249 } else {
250 read_pending_ = true;
251 read_buffer_ = buf;
252 read_buffer_size_ = buf_len;
253 read_callback_ = callback;
254 return net::ERR_IO_PENDING;
255 }
256 }
257
Write(net::IOBuffer * buf,int buf_len,const net::CompletionCallback & callback)258 int FakeUdpSocket::Write(net::IOBuffer* buf, int buf_len,
259 const net::CompletionCallback& callback) {
260 EXPECT_EQ(message_loop_, base::MessageLoop::current());
261 written_packets_.push_back(std::string());
262 written_packets_.back().assign(buf->data(), buf->data() + buf_len);
263 return buf_len;
264 }
265
SetReceiveBufferSize(int32 size)266 bool FakeUdpSocket::SetReceiveBufferSize(int32 size) {
267 NOTIMPLEMENTED();
268 return false;
269 }
SetSendBufferSize(int32 size)270 bool FakeUdpSocket::SetSendBufferSize(int32 size) {
271 NOTIMPLEMENTED();
272 return false;
273 }
274
FakeSession()275 FakeSession::FakeSession()
276 : event_handler_(NULL),
277 candidate_config_(CandidateSessionConfig::CreateDefault()),
278 config_(SessionConfig::ForTest()),
279 message_loop_(base::MessageLoop::current()),
280 async_creation_(false),
281 jid_(kTestJid),
282 error_(OK),
283 closed_(false),
284 weak_factory_(this) {
285 }
286
~FakeSession()287 FakeSession::~FakeSession() { }
288
GetStreamChannel(const std::string & name)289 FakeSocket* FakeSession::GetStreamChannel(const std::string& name) {
290 return stream_channels_[name];
291 }
292
GetDatagramChannel(const std::string & name)293 FakeUdpSocket* FakeSession::GetDatagramChannel(const std::string& name) {
294 return datagram_channels_[name];
295 }
296
SetEventHandler(EventHandler * event_handler)297 void FakeSession::SetEventHandler(EventHandler* event_handler) {
298 event_handler_ = event_handler;
299 }
300
error()301 ErrorCode FakeSession::error() {
302 return error_;
303 }
304
jid()305 const std::string& FakeSession::jid() {
306 return jid_;
307 }
308
candidate_config()309 const CandidateSessionConfig* FakeSession::candidate_config() {
310 return candidate_config_.get();
311 }
312
config()313 const SessionConfig& FakeSession::config() {
314 return config_;
315 }
316
set_config(const SessionConfig & config)317 void FakeSession::set_config(const SessionConfig& config) {
318 config_ = config;
319 }
320
GetTransportChannelFactory()321 ChannelFactory* FakeSession::GetTransportChannelFactory() {
322 return this;
323 }
324
GetMultiplexedChannelFactory()325 ChannelFactory* FakeSession::GetMultiplexedChannelFactory() {
326 return this;
327 }
328
Close()329 void FakeSession::Close() {
330 closed_ = true;
331 }
332
CreateStreamChannel(const std::string & name,const StreamChannelCallback & callback)333 void FakeSession::CreateStreamChannel(
334 const std::string& name,
335 const StreamChannelCallback& callback) {
336 scoped_ptr<FakeSocket> channel;
337 // If we are in the error state then we put NULL in the channels list, so that
338 // NotifyStreamChannelCallback() still calls the callback.
339 if (error_ == OK)
340 channel.reset(new FakeSocket());
341 stream_channels_[name] = channel.release();
342
343 if (async_creation_) {
344 message_loop_->PostTask(FROM_HERE, base::Bind(
345 &FakeSession::NotifyStreamChannelCallback, weak_factory_.GetWeakPtr(),
346 name, callback));
347 } else {
348 NotifyStreamChannelCallback(name, callback);
349 }
350 }
351
NotifyStreamChannelCallback(const std::string & name,const StreamChannelCallback & callback)352 void FakeSession::NotifyStreamChannelCallback(
353 const std::string& name,
354 const StreamChannelCallback& callback) {
355 if (stream_channels_.find(name) != stream_channels_.end())
356 callback.Run(scoped_ptr<net::StreamSocket>(stream_channels_[name]));
357 }
358
CreateDatagramChannel(const std::string & name,const DatagramChannelCallback & callback)359 void FakeSession::CreateDatagramChannel(
360 const std::string& name,
361 const DatagramChannelCallback& callback) {
362 scoped_ptr<FakeUdpSocket> channel;
363 // If we are in the error state then we put NULL in the channels list, so that
364 // NotifyStreamChannelCallback() still calls the callback.
365 if (error_ == OK)
366 channel.reset(new FakeUdpSocket());
367 datagram_channels_[name] = channel.release();
368
369 if (async_creation_) {
370 message_loop_->PostTask(FROM_HERE, base::Bind(
371 &FakeSession::NotifyDatagramChannelCallback, weak_factory_.GetWeakPtr(),
372 name, callback));
373 } else {
374 NotifyDatagramChannelCallback(name, callback);
375 }
376 }
377
NotifyDatagramChannelCallback(const std::string & name,const DatagramChannelCallback & callback)378 void FakeSession::NotifyDatagramChannelCallback(
379 const std::string& name,
380 const DatagramChannelCallback& callback) {
381 if (datagram_channels_.find(name) != datagram_channels_.end())
382 callback.Run(scoped_ptr<net::Socket>(datagram_channels_[name]));
383 }
384
CancelChannelCreation(const std::string & name)385 void FakeSession::CancelChannelCreation(const std::string& name) {
386 stream_channels_.erase(name);
387 datagram_channels_.erase(name);
388 }
389
390 } // namespace protocol
391 } // namespace remoting
392