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