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