OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 "components/cast_channel/cast_transport.h" | |
6 | |
7 #include <stddef.h> | |
8 #include <stdint.h> | |
9 | |
10 #include <queue> | |
11 | |
12 #include "base/macros.h" | |
13 #include "base/memory/ptr_util.h" | |
14 #include "base/message_loop/message_loop.h" | |
15 #include "base/run_loop.h" | |
16 #include "base/test/simple_test_clock.h" | |
17 #include "components/cast_channel/cast_framer.h" | |
18 #include "components/cast_channel/cast_socket.h" | |
19 #include "components/cast_channel/cast_test_util.h" | |
20 #include "components/cast_channel/logger.h" | |
21 #include "components/cast_channel/proto/cast_channel.pb.h" | |
22 #include "net/base/completion_callback.h" | |
23 #include "net/base/net_errors.h" | |
24 #include "net/log/test_net_log.h" | |
25 #include "net/socket/socket.h" | |
26 #include "testing/gmock/include/gmock/gmock.h" | |
27 #include "testing/gtest/include/gtest/gtest.h" | |
28 | |
29 using testing::_; | |
30 using testing::DoAll; | |
31 using testing::InSequence; | |
32 using testing::Invoke; | |
33 using testing::NotNull; | |
34 using testing::Return; | |
35 using testing::WithArg; | |
36 | |
37 namespace cast_channel { | |
38 namespace { | |
39 | |
40 const int kChannelId = 0; | |
41 | |
42 // Mockable placeholder for write completion events. | |
43 class CompleteHandler { | |
44 public: | |
45 CompleteHandler() {} | |
46 MOCK_METHOD1(Complete, void(int result)); | |
47 | |
48 private: | |
49 DISALLOW_COPY_AND_ASSIGN(CompleteHandler); | |
50 }; | |
51 | |
52 // Creates a CastMessage proto with the bare minimum required fields set. | |
53 CastMessage CreateCastMessage() { | |
54 CastMessage output; | |
55 output.set_protocol_version(CastMessage::CASTV2_1_0); | |
56 output.set_namespace_("x"); | |
57 output.set_source_id("source"); | |
58 output.set_destination_id("destination"); | |
59 output.set_payload_type(CastMessage::STRING); | |
60 output.set_payload_utf8("payload"); | |
61 return output; | |
62 } | |
63 | |
64 // FIFO queue of completion callbacks. Outstanding write operations are | |
65 // Push()ed into the queue. Callback completion is simulated by invoking | |
66 // Pop() in the same order as Push(). | |
67 class CompletionQueue { | |
68 public: | |
69 CompletionQueue() {} | |
70 ~CompletionQueue() { CHECK_EQ(0u, cb_queue_.size()); } | |
71 | |
72 // Enqueues a pending completion callback. | |
73 void Push(const net::CompletionCallback& cb) { cb_queue_.push(cb); } | |
74 // Runs the next callback and removes it from the queue. | |
75 void Pop(int rv) { | |
76 CHECK_GT(cb_queue_.size(), 0u); | |
77 cb_queue_.front().Run(rv); | |
78 cb_queue_.pop(); | |
79 } | |
80 | |
81 private: | |
82 std::queue<net::CompletionCallback> cb_queue_; | |
83 DISALLOW_COPY_AND_ASSIGN(CompletionQueue); | |
84 }; | |
85 | |
86 // GMock action that reads data from an IOBuffer and writes it to a string | |
87 // variable. | |
88 // | |
89 // buf_idx (template parameter 0): 0-based index of the net::IOBuffer | |
90 // in the function mock arg list. | |
91 // size_idx (template parameter 1): 0-based index of the byte count arg. | |
92 // str: pointer to the string which will receive data from the buffer. | |
93 ACTION_TEMPLATE(ReadBufferToString, | |
94 HAS_2_TEMPLATE_PARAMS(int, buf_idx, int, size_idx), | |
95 AND_1_VALUE_PARAMS(str)) { | |
96 str->assign(testing::get<buf_idx>(args)->data(), | |
97 testing::get<size_idx>(args)); | |
98 } | |
99 | |
100 // GMock action that writes data from a string to an IOBuffer. | |
101 // | |
102 // buf_idx (template parameter 0): 0-based index of the IOBuffer arg. | |
103 // str: the string containing data to be written to the IOBuffer. | |
104 ACTION_TEMPLATE(FillBufferFromString, | |
105 HAS_1_TEMPLATE_PARAMS(int, buf_idx), | |
106 AND_1_VALUE_PARAMS(str)) { | |
107 memcpy(testing::get<buf_idx>(args)->data(), str.data(), str.size()); | |
108 } | |
109 | |
110 // GMock action that enqueues a write completion callback in a queue. | |
111 // | |
112 // buf_idx (template parameter 0): 0-based index of the CompletionCallback. | |
113 // completion_queue: a pointer to the CompletionQueue. | |
114 ACTION_TEMPLATE(EnqueueCallback, | |
115 HAS_1_TEMPLATE_PARAMS(int, cb_idx), | |
116 AND_1_VALUE_PARAMS(completion_queue)) { | |
117 completion_queue->Push(testing::get<cb_idx>(args)); | |
118 } | |
119 | |
120 } // namespace | |
121 | |
122 class MockSocket : public net::Socket { | |
123 public: | |
124 MOCK_METHOD3(Read, | |
125 int(net::IOBuffer* buf, | |
126 int buf_len, | |
127 const net::CompletionCallback& callback)); | |
128 | |
129 MOCK_METHOD3(Write, | |
130 int(net::IOBuffer* buf, | |
131 int buf_len, | |
132 const net::CompletionCallback& callback)); | |
133 | |
134 virtual int SetReceiveBufferSize(int32_t size) { | |
135 NOTREACHED(); | |
136 return 0; | |
137 } | |
138 | |
139 virtual int SetSendBufferSize(int32_t size) { | |
140 NOTREACHED(); | |
141 return 0; | |
142 } | |
143 }; | |
144 | |
145 class CastTransportTest : public testing::Test { | |
146 public: | |
147 using ChannelError = ::cast_channel::ChannelError; | |
148 using ChannelAuthType = ::cast_channel::ChannelAuthType; | |
149 | |
150 CastTransportTest() : logger_(new Logger()) { | |
151 delegate_ = new MockCastTransportDelegate; | |
152 transport_.reset(new CastTransportImpl(&mock_socket_, kChannelId, | |
153 CreateIPEndPointForTest(), | |
154 auth_type_, logger_)); | |
155 transport_->SetReadDelegate(base::WrapUnique(delegate_)); | |
156 } | |
157 ~CastTransportTest() override {} | |
158 | |
159 protected: | |
160 // Runs all pending tasks in the message loop. | |
161 void RunPendingTasks() { | |
162 base::RunLoop run_loop; | |
163 run_loop.RunUntilIdle(); | |
164 } | |
165 | |
166 base::MessageLoop message_loop_; | |
167 MockCastTransportDelegate* delegate_; | |
168 MockSocket mock_socket_; | |
169 ChannelAuthType auth_type_; | |
170 Logger* logger_; | |
171 std::unique_ptr<CastTransport> transport_; | |
172 }; | |
173 | |
174 // ---------------------------------------------------------------------------- | |
175 // Asynchronous write tests | |
176 TEST_F(CastTransportTest, TestFullWriteAsync) { | |
177 CompletionQueue socket_cbs; | |
178 CompleteHandler write_handler; | |
179 std::string output; | |
180 | |
181 CastMessage message = CreateCastMessage(); | |
182 std::string serialized_message; | |
183 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
184 | |
185 EXPECT_CALL(mock_socket_, Write(NotNull(), serialized_message.size(), _)) | |
186 .WillOnce(DoAll(ReadBufferToString<0, 1>(&output), | |
187 EnqueueCallback<2>(&socket_cbs), | |
188 Return(net::ERR_IO_PENDING))); | |
189 EXPECT_CALL(write_handler, Complete(net::OK)); | |
190 transport_->SendMessage( | |
191 message, | |
192 base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler))); | |
193 RunPendingTasks(); | |
194 socket_cbs.Pop(serialized_message.size()); | |
195 RunPendingTasks(); | |
196 EXPECT_EQ(serialized_message, output); | |
197 } | |
198 | |
199 TEST_F(CastTransportTest, TestPartialWritesAsync) { | |
200 InSequence seq; | |
201 CompletionQueue socket_cbs; | |
202 CompleteHandler write_handler; | |
203 std::string output; | |
204 | |
205 CastMessage message = CreateCastMessage(); | |
206 std::string serialized_message; | |
207 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
208 | |
209 // Only one byte is written. | |
210 EXPECT_CALL(mock_socket_, | |
211 Write(NotNull(), static_cast<int>(serialized_message.size()), _)) | |
212 .WillOnce(DoAll(ReadBufferToString<0, 1>(&output), | |
213 EnqueueCallback<2>(&socket_cbs), | |
214 Return(net::ERR_IO_PENDING))); | |
215 // Remainder of bytes are written. | |
216 EXPECT_CALL( | |
217 mock_socket_, | |
218 Write(NotNull(), static_cast<int>(serialized_message.size() - 1), _)) | |
219 .WillOnce(DoAll(ReadBufferToString<0, 1>(&output), | |
220 EnqueueCallback<2>(&socket_cbs), | |
221 Return(net::ERR_IO_PENDING))); | |
222 | |
223 transport_->SendMessage( | |
224 message, | |
225 base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler))); | |
226 RunPendingTasks(); | |
227 EXPECT_EQ(serialized_message, output); | |
228 socket_cbs.Pop(1); | |
229 RunPendingTasks(); | |
230 | |
231 EXPECT_CALL(write_handler, Complete(net::OK)); | |
232 socket_cbs.Pop(serialized_message.size() - 1); | |
233 RunPendingTasks(); | |
234 EXPECT_EQ(serialized_message.substr(1, serialized_message.size() - 1), | |
235 output); | |
236 } | |
237 | |
238 TEST_F(CastTransportTest, TestWriteFailureAsync) { | |
239 CompletionQueue socket_cbs; | |
240 CompleteHandler write_handler; | |
241 CastMessage message = CreateCastMessage(); | |
242 EXPECT_CALL(mock_socket_, Write(NotNull(), _, _)) | |
243 .WillOnce( | |
244 DoAll(EnqueueCallback<2>(&socket_cbs), Return(net::ERR_IO_PENDING))); | |
245 EXPECT_CALL(write_handler, Complete(net::ERR_FAILED)); | |
246 EXPECT_CALL(*delegate_, OnError(ChannelError::CAST_SOCKET_ERROR)); | |
247 transport_->SendMessage( | |
248 message, | |
249 base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler))); | |
250 RunPendingTasks(); | |
251 socket_cbs.Pop(net::ERR_CONNECTION_RESET); | |
252 RunPendingTasks(); | |
253 EXPECT_EQ(proto::SOCKET_WRITE, logger_->GetLastErrors(kChannelId).event_type); | |
254 EXPECT_EQ(net::ERR_CONNECTION_RESET, | |
255 logger_->GetLastErrors(kChannelId).net_return_value); | |
256 } | |
257 | |
258 // ---------------------------------------------------------------------------- | |
259 // Synchronous write tests | |
260 TEST_F(CastTransportTest, TestFullWriteSync) { | |
261 CompleteHandler write_handler; | |
262 std::string output; | |
263 CastMessage message = CreateCastMessage(); | |
264 std::string serialized_message; | |
265 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
266 EXPECT_CALL(mock_socket_, Write(NotNull(), serialized_message.size(), _)) | |
267 .WillOnce(DoAll(ReadBufferToString<0, 1>(&output), | |
268 Return(serialized_message.size()))); | |
269 EXPECT_CALL(write_handler, Complete(net::OK)); | |
270 transport_->SendMessage( | |
271 message, | |
272 base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler))); | |
273 RunPendingTasks(); | |
274 EXPECT_EQ(serialized_message, output); | |
275 } | |
276 | |
277 TEST_F(CastTransportTest, TestPartialWritesSync) { | |
278 InSequence seq; | |
279 CompleteHandler write_handler; | |
280 std::string output; | |
281 | |
282 CastMessage message = CreateCastMessage(); | |
283 std::string serialized_message; | |
284 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
285 | |
286 // Only one byte is written. | |
287 EXPECT_CALL(mock_socket_, Write(NotNull(), serialized_message.size(), _)) | |
288 .WillOnce(DoAll(ReadBufferToString<0, 1>(&output), Return(1))); | |
289 // Remainder of bytes are written. | |
290 EXPECT_CALL(mock_socket_, Write(NotNull(), serialized_message.size() - 1, _)) | |
291 .WillOnce(DoAll(ReadBufferToString<0, 1>(&output), | |
292 Return(serialized_message.size() - 1))); | |
293 | |
294 EXPECT_CALL(write_handler, Complete(net::OK)); | |
295 transport_->SendMessage( | |
296 message, | |
297 base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler))); | |
298 RunPendingTasks(); | |
299 EXPECT_EQ(serialized_message.substr(1, serialized_message.size() - 1), | |
300 output); | |
301 } | |
302 | |
303 TEST_F(CastTransportTest, TestWriteFailureSync) { | |
304 CompleteHandler write_handler; | |
305 CastMessage message = CreateCastMessage(); | |
306 EXPECT_CALL(mock_socket_, Write(NotNull(), _, _)) | |
307 .WillOnce(Return(net::ERR_CONNECTION_RESET)); | |
308 EXPECT_CALL(write_handler, Complete(net::ERR_FAILED)); | |
309 transport_->SendMessage( | |
310 message, | |
311 base::Bind(&CompleteHandler::Complete, base::Unretained(&write_handler))); | |
312 RunPendingTasks(); | |
313 EXPECT_EQ(proto::SOCKET_WRITE, logger_->GetLastErrors(kChannelId).event_type); | |
314 EXPECT_EQ(net::ERR_CONNECTION_RESET, | |
315 logger_->GetLastErrors(kChannelId).net_return_value); | |
316 } | |
317 | |
318 // ---------------------------------------------------------------------------- | |
319 // Asynchronous read tests | |
320 TEST_F(CastTransportTest, TestFullReadAsync) { | |
321 InSequence s; | |
322 CompletionQueue socket_cbs; | |
323 | |
324 CastMessage message = CreateCastMessage(); | |
325 std::string serialized_message; | |
326 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
327 EXPECT_CALL(*delegate_, Start()); | |
328 | |
329 // Read bytes [0, 3]. | |
330 EXPECT_CALL(mock_socket_, | |
331 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
332 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message), | |
333 EnqueueCallback<2>(&socket_cbs), | |
334 Return(net::ERR_IO_PENDING))); | |
335 | |
336 // Read bytes [4, n]. | |
337 EXPECT_CALL(mock_socket_, | |
338 Read(NotNull(), | |
339 serialized_message.size() - | |
340 MessageFramer::MessageHeader::header_size(), | |
341 _)) | |
342 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr( | |
343 MessageFramer::MessageHeader::header_size(), | |
344 serialized_message.size() - | |
345 MessageFramer::MessageHeader::header_size())), | |
346 EnqueueCallback<2>(&socket_cbs), | |
347 Return(net::ERR_IO_PENDING))) | |
348 .RetiresOnSaturation(); | |
349 | |
350 EXPECT_CALL(*delegate_, OnMessage(EqualsProto(message))); | |
351 EXPECT_CALL(mock_socket_, | |
352 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
353 .WillOnce(Return(net::ERR_IO_PENDING)); | |
354 transport_->Start(); | |
355 RunPendingTasks(); | |
356 socket_cbs.Pop(MessageFramer::MessageHeader::header_size()); | |
357 socket_cbs.Pop(serialized_message.size() - | |
358 MessageFramer::MessageHeader::header_size()); | |
359 RunPendingTasks(); | |
360 } | |
361 | |
362 TEST_F(CastTransportTest, TestPartialReadAsync) { | |
363 InSequence s; | |
364 CompletionQueue socket_cbs; | |
365 | |
366 CastMessage message = CreateCastMessage(); | |
367 std::string serialized_message; | |
368 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
369 | |
370 EXPECT_CALL(*delegate_, Start()); | |
371 | |
372 // Read bytes [0, 3]. | |
373 EXPECT_CALL(mock_socket_, | |
374 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
375 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message), | |
376 EnqueueCallback<2>(&socket_cbs), | |
377 Return(net::ERR_IO_PENDING))) | |
378 .RetiresOnSaturation(); | |
379 // Read bytes [4, n-1]. | |
380 EXPECT_CALL(mock_socket_, | |
381 Read(NotNull(), | |
382 serialized_message.size() - | |
383 MessageFramer::MessageHeader::header_size(), | |
384 _)) | |
385 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr( | |
386 MessageFramer::MessageHeader::header_size(), | |
387 serialized_message.size() - | |
388 MessageFramer::MessageHeader::header_size() - 1)), | |
389 EnqueueCallback<2>(&socket_cbs), | |
390 Return(net::ERR_IO_PENDING))) | |
391 .RetiresOnSaturation(); | |
392 // Read final byte. | |
393 EXPECT_CALL(mock_socket_, Read(NotNull(), 1, _)) | |
394 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr( | |
395 serialized_message.size() - 1, 1)), | |
396 EnqueueCallback<2>(&socket_cbs), | |
397 Return(net::ERR_IO_PENDING))) | |
398 .RetiresOnSaturation(); | |
399 EXPECT_CALL(*delegate_, OnMessage(EqualsProto(message))); | |
400 transport_->Start(); | |
401 socket_cbs.Pop(MessageFramer::MessageHeader::header_size()); | |
402 socket_cbs.Pop(serialized_message.size() - | |
403 MessageFramer::MessageHeader::header_size() - 1); | |
404 EXPECT_CALL(mock_socket_, | |
405 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
406 .WillOnce(Return(net::ERR_IO_PENDING)); | |
407 socket_cbs.Pop(1); | |
408 } | |
409 | |
410 TEST_F(CastTransportTest, TestReadErrorInHeaderAsync) { | |
411 CompletionQueue socket_cbs; | |
412 | |
413 CastMessage message = CreateCastMessage(); | |
414 std::string serialized_message; | |
415 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
416 | |
417 EXPECT_CALL(*delegate_, Start()); | |
418 | |
419 // Read bytes [0, 3]. | |
420 EXPECT_CALL(mock_socket_, | |
421 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
422 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message), | |
423 EnqueueCallback<2>(&socket_cbs), | |
424 Return(net::ERR_IO_PENDING))) | |
425 .RetiresOnSaturation(); | |
426 | |
427 EXPECT_CALL(*delegate_, OnError(ChannelError::CAST_SOCKET_ERROR)); | |
428 transport_->Start(); | |
429 // Header read failure. | |
430 socket_cbs.Pop(net::ERR_CONNECTION_RESET); | |
431 EXPECT_EQ(proto::SOCKET_READ, logger_->GetLastErrors(kChannelId).event_type); | |
432 EXPECT_EQ(net::ERR_CONNECTION_RESET, | |
433 logger_->GetLastErrors(kChannelId).net_return_value); | |
434 } | |
435 | |
436 TEST_F(CastTransportTest, TestReadErrorInBodyAsync) { | |
437 CompletionQueue socket_cbs; | |
438 | |
439 CastMessage message = CreateCastMessage(); | |
440 std::string serialized_message; | |
441 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
442 | |
443 EXPECT_CALL(*delegate_, Start()); | |
444 | |
445 // Read bytes [0, 3]. | |
446 EXPECT_CALL(mock_socket_, | |
447 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
448 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message), | |
449 EnqueueCallback<2>(&socket_cbs), | |
450 Return(net::ERR_IO_PENDING))) | |
451 .RetiresOnSaturation(); | |
452 // Read bytes [4, n-1]. | |
453 EXPECT_CALL(mock_socket_, | |
454 Read(NotNull(), | |
455 serialized_message.size() - | |
456 MessageFramer::MessageHeader::header_size(), | |
457 _)) | |
458 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr( | |
459 MessageFramer::MessageHeader::header_size(), | |
460 serialized_message.size() - | |
461 MessageFramer::MessageHeader::header_size() - 1)), | |
462 EnqueueCallback<2>(&socket_cbs), | |
463 Return(net::ERR_IO_PENDING))) | |
464 .RetiresOnSaturation(); | |
465 EXPECT_CALL(*delegate_, OnError(ChannelError::CAST_SOCKET_ERROR)); | |
466 transport_->Start(); | |
467 // Header read is OK. | |
468 socket_cbs.Pop(MessageFramer::MessageHeader::header_size()); | |
469 // Body read fails. | |
470 socket_cbs.Pop(net::ERR_CONNECTION_RESET); | |
471 EXPECT_EQ(proto::SOCKET_READ, logger_->GetLastErrors(kChannelId).event_type); | |
472 EXPECT_EQ(net::ERR_CONNECTION_RESET, | |
473 logger_->GetLastErrors(kChannelId).net_return_value); | |
474 } | |
475 | |
476 TEST_F(CastTransportTest, TestReadCorruptedMessageAsync) { | |
477 CompletionQueue socket_cbs; | |
478 | |
479 CastMessage message = CreateCastMessage(); | |
480 std::string serialized_message; | |
481 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
482 | |
483 // Corrupt the serialized message body(set it to X's). | |
484 for (size_t i = MessageFramer::MessageHeader::header_size(); | |
485 i < serialized_message.size(); ++i) { | |
486 serialized_message[i] = 'x'; | |
487 } | |
488 | |
489 EXPECT_CALL(*delegate_, Start()); | |
490 // Read bytes [0, 3]. | |
491 EXPECT_CALL(mock_socket_, | |
492 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
493 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message), | |
494 EnqueueCallback<2>(&socket_cbs), | |
495 Return(net::ERR_IO_PENDING))) | |
496 .RetiresOnSaturation(); | |
497 // Read bytes [4, n]. | |
498 EXPECT_CALL(mock_socket_, | |
499 Read(NotNull(), | |
500 serialized_message.size() - | |
501 MessageFramer::MessageHeader::header_size(), | |
502 _)) | |
503 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr( | |
504 MessageFramer::MessageHeader::header_size(), | |
505 serialized_message.size() - | |
506 MessageFramer::MessageHeader::header_size() - 1)), | |
507 EnqueueCallback<2>(&socket_cbs), | |
508 Return(net::ERR_IO_PENDING))) | |
509 .RetiresOnSaturation(); | |
510 | |
511 EXPECT_CALL(*delegate_, OnError(ChannelError::INVALID_MESSAGE)); | |
512 transport_->Start(); | |
513 socket_cbs.Pop(MessageFramer::MessageHeader::header_size()); | |
514 socket_cbs.Pop(serialized_message.size() - | |
515 MessageFramer::MessageHeader::header_size()); | |
516 } | |
517 | |
518 // ---------------------------------------------------------------------------- | |
519 // Synchronous read tests | |
520 TEST_F(CastTransportTest, TestFullReadSync) { | |
521 InSequence s; | |
522 CastMessage message = CreateCastMessage(); | |
523 std::string serialized_message; | |
524 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
525 | |
526 EXPECT_CALL(*delegate_, Start()); | |
527 | |
528 // Read bytes [0, 3]. | |
529 EXPECT_CALL(mock_socket_, | |
530 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
531 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message), | |
532 Return(MessageFramer::MessageHeader::header_size()))) | |
533 .RetiresOnSaturation(); | |
534 // Read bytes [4, n]. | |
535 EXPECT_CALL(mock_socket_, | |
536 Read(NotNull(), | |
537 serialized_message.size() - | |
538 MessageFramer::MessageHeader::header_size(), | |
539 _)) | |
540 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr( | |
541 MessageFramer::MessageHeader::header_size(), | |
542 serialized_message.size() - | |
543 MessageFramer::MessageHeader::header_size())), | |
544 Return(serialized_message.size() - | |
545 MessageFramer::MessageHeader::header_size()))) | |
546 .RetiresOnSaturation(); | |
547 EXPECT_CALL(*delegate_, OnMessage(EqualsProto(message))); | |
548 // Async result in order to discontinue the read loop. | |
549 EXPECT_CALL(mock_socket_, | |
550 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
551 .WillOnce(Return(net::ERR_IO_PENDING)); | |
552 transport_->Start(); | |
553 } | |
554 | |
555 TEST_F(CastTransportTest, TestPartialReadSync) { | |
556 InSequence s; | |
557 | |
558 CastMessage message = CreateCastMessage(); | |
559 std::string serialized_message; | |
560 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
561 | |
562 EXPECT_CALL(*delegate_, Start()); | |
563 | |
564 // Read bytes [0, 3]. | |
565 EXPECT_CALL(mock_socket_, | |
566 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
567 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message), | |
568 Return(MessageFramer::MessageHeader::header_size()))) | |
569 .RetiresOnSaturation(); | |
570 // Read bytes [4, n-1]. | |
571 EXPECT_CALL(mock_socket_, | |
572 Read(NotNull(), | |
573 serialized_message.size() - | |
574 MessageFramer::MessageHeader::header_size(), | |
575 _)) | |
576 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr( | |
577 MessageFramer::MessageHeader::header_size(), | |
578 serialized_message.size() - | |
579 MessageFramer::MessageHeader::header_size() - 1)), | |
580 Return(serialized_message.size() - | |
581 MessageFramer::MessageHeader::header_size() - 1))) | |
582 .RetiresOnSaturation(); | |
583 // Read final byte. | |
584 EXPECT_CALL(mock_socket_, Read(NotNull(), 1, _)) | |
585 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr( | |
586 serialized_message.size() - 1, 1)), | |
587 Return(1))) | |
588 .RetiresOnSaturation(); | |
589 EXPECT_CALL(*delegate_, OnMessage(EqualsProto(message))); | |
590 EXPECT_CALL(mock_socket_, | |
591 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
592 .WillOnce(Return(net::ERR_IO_PENDING)); | |
593 transport_->Start(); | |
594 } | |
595 | |
596 TEST_F(CastTransportTest, TestReadErrorInHeaderSync) { | |
597 InSequence s; | |
598 CastMessage message = CreateCastMessage(); | |
599 std::string serialized_message; | |
600 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
601 | |
602 EXPECT_CALL(*delegate_, Start()); | |
603 | |
604 // Read bytes [0, 3]. | |
605 EXPECT_CALL(mock_socket_, | |
606 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
607 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message), | |
608 Return(net::ERR_CONNECTION_RESET))) | |
609 .RetiresOnSaturation(); | |
610 EXPECT_CALL(*delegate_, OnError(ChannelError::CAST_SOCKET_ERROR)); | |
611 transport_->Start(); | |
612 } | |
613 | |
614 TEST_F(CastTransportTest, TestReadErrorInBodySync) { | |
615 CastMessage message = CreateCastMessage(); | |
616 std::string serialized_message; | |
617 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
618 | |
619 EXPECT_CALL(*delegate_, Start()); | |
620 | |
621 // Read bytes [0, 3]. | |
622 EXPECT_CALL(mock_socket_, | |
623 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
624 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message), | |
625 Return(MessageFramer::MessageHeader::header_size()))) | |
626 .RetiresOnSaturation(); | |
627 // Read bytes [4, n-1]. | |
628 EXPECT_CALL(mock_socket_, | |
629 Read(NotNull(), | |
630 serialized_message.size() - | |
631 MessageFramer::MessageHeader::header_size(), | |
632 _)) | |
633 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr( | |
634 MessageFramer::MessageHeader::header_size(), | |
635 serialized_message.size() - | |
636 MessageFramer::MessageHeader::header_size() - 1)), | |
637 Return(net::ERR_CONNECTION_RESET))) | |
638 .RetiresOnSaturation(); | |
639 EXPECT_CALL(*delegate_, OnError(ChannelError::CAST_SOCKET_ERROR)); | |
640 transport_->Start(); | |
641 EXPECT_EQ(proto::SOCKET_READ, logger_->GetLastErrors(kChannelId).event_type); | |
642 EXPECT_EQ(net::ERR_CONNECTION_RESET, | |
643 logger_->GetLastErrors(kChannelId).net_return_value); | |
644 } | |
645 | |
646 TEST_F(CastTransportTest, TestReadCorruptedMessageSync) { | |
647 InSequence s; | |
648 CastMessage message = CreateCastMessage(); | |
649 std::string serialized_message; | |
650 EXPECT_TRUE(MessageFramer::Serialize(message, &serialized_message)); | |
651 | |
652 // Corrupt the serialized message body(set it to X's). | |
653 for (size_t i = MessageFramer::MessageHeader::header_size(); | |
654 i < serialized_message.size(); ++i) { | |
655 serialized_message[i] = 'x'; | |
656 } | |
657 | |
658 EXPECT_CALL(*delegate_, Start()); | |
659 | |
660 // Read bytes [0, 3]. | |
661 EXPECT_CALL(mock_socket_, | |
662 Read(NotNull(), MessageFramer::MessageHeader::header_size(), _)) | |
663 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message), | |
664 Return(MessageFramer::MessageHeader::header_size()))) | |
665 .RetiresOnSaturation(); | |
666 // Read bytes [4, n]. | |
667 EXPECT_CALL(mock_socket_, | |
668 Read(NotNull(), | |
669 serialized_message.size() - | |
670 MessageFramer::MessageHeader::header_size(), | |
671 _)) | |
672 .WillOnce(DoAll(FillBufferFromString<0>(serialized_message.substr( | |
673 MessageFramer::MessageHeader::header_size(), | |
674 serialized_message.size() - | |
675 MessageFramer::MessageHeader::header_size() - 1)), | |
676 Return(serialized_message.size() - | |
677 MessageFramer::MessageHeader::header_size()))) | |
678 .RetiresOnSaturation(); | |
679 EXPECT_CALL(*delegate_, OnError(ChannelError::INVALID_MESSAGE)); | |
680 transport_->Start(); | |
681 } | |
682 } // namespace cast_channel | |
OLD | NEW |