1 // Copyright 2015 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.
5 #include "content/child/shared_memory_data_consumer_handle.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/location.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h"
16 #include "base/task_runner.h"
17 #include "base/threading/thread.h"
18 #include "content/public/child/fixed_received_data.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
25 using blink::WebDataConsumerHandle
;
26 using Result
= WebDataConsumerHandle::Result
;
27 using Writer
= SharedMemoryDataConsumerHandle::Writer
;
28 using BackpressureMode
= SharedMemoryDataConsumerHandle::BackpressureMode
;
29 const BackpressureMode kApplyBackpressure
=
30 SharedMemoryDataConsumerHandle::kApplyBackpressure
;
31 const BackpressureMode kDoNotApplyBackpressure
=
32 SharedMemoryDataConsumerHandle::kDoNotApplyBackpressure
;
34 const WebDataConsumerHandle::Flags kNone
= WebDataConsumerHandle::FlagNone
;
35 const Result kOk
= WebDataConsumerHandle::Ok
;
36 const Result kDone
= WebDataConsumerHandle::Done
;
37 const Result kShouldWait
= WebDataConsumerHandle::ShouldWait
;
38 const Result kUnexpectedError
= WebDataConsumerHandle::UnexpectedError
;
41 using ::testing::InSequence
;
42 using ::testing::Invoke
;
43 using ::testing::MockFunction
;
44 using ::testing::Return
;
45 using ::testing::StrictMock
;
47 using Checkpoint
= StrictMock
<MockFunction
<void(int)>>;
48 using ReceivedData
= RequestPeer::ReceivedData
;
50 class Logger final
: public base::RefCounted
<Logger
> {
53 void Add(const std::string
& entry
) { log_
+= entry
+ "\n"; }
54 const std::string
& log() const { return log_
; }
57 friend class base::RefCounted
<Logger
>;
61 DISALLOW_COPY_AND_ASSIGN(Logger
);
64 class LoggingFixedReceivedData final
: public RequestPeer::ReceivedData
{
66 LoggingFixedReceivedData(const char* name
,
68 scoped_refptr
<Logger
> logger
)
69 : name_(name
), data_(s
, s
+ strlen(s
)), logger_(logger
) {}
70 ~LoggingFixedReceivedData() override
{
71 logger_
->Add(name_
+ " is destructed.");
74 const char* payload() const override
{
75 return data_
.empty() ? nullptr : &data_
[0];
77 int length() const override
{ return static_cast<int>(data_
.size()); }
78 int encoded_length() const override
{ return static_cast<int>(data_
.size()); }
81 const std::string name_
;
82 const std::vector
<char> data_
;
83 scoped_refptr
<Logger
> logger_
;
85 DISALLOW_COPY_AND_ASSIGN(LoggingFixedReceivedData
);
88 class DestructionTrackingFunction
89 : public base::RefCountedThreadSafe
<DestructionTrackingFunction
> {
91 MOCK_METHOD0(Destruct
, void(void));
92 MOCK_METHOD0(Call
, void(void));
95 friend class base::RefCountedThreadSafe
<DestructionTrackingFunction
>;
96 virtual ~DestructionTrackingFunction() { Destruct(); }
99 class MockClient
: public WebDataConsumerHandle::Client
{
101 MOCK_METHOD0(didGetReadable
, void());
104 std::string
ToString(const void* p
, size_t size
) {
105 const char* q
= static_cast<const char*>(p
);
106 return std::string(q
, q
+ size
);
109 class ThreadedSharedMemoryDataConsumerHandleTest
: public ::testing::Test
{
111 class ReadDataOperation
;
112 class ClientImpl final
: public WebDataConsumerHandle::Client
{
114 explicit ClientImpl(ReadDataOperation
* operation
) : operation_(operation
) {}
116 void didGetReadable() override
{ operation_
->ReadData(); }
119 ReadDataOperation
* operation_
;
122 class ReadDataOperation final
{
124 typedef WebDataConsumerHandle::Result Result
;
125 ReadDataOperation(scoped_ptr
<SharedMemoryDataConsumerHandle
> handle
,
126 base::MessageLoop
* main_message_loop
,
127 const base::Closure
& on_done
)
128 : handle_(handle
.Pass()),
129 main_message_loop_(main_message_loop
),
132 const std::string
& result() const { return result_
; }
136 client_
.reset(new ClientImpl(this));
137 reader_
= handle_
->ObtainReader(client_
.get());
141 size_t read_size
= 0;
145 rv
= reader_
->read(&buffer
, sizeof(buffer
), kNone
, &read_size
);
148 result_
.insert(result_
.size(), &buffer
[0], read_size
);
151 if (rv
== kShouldWait
) {
157 // Something is wrong.
161 // The operation is done.
163 main_message_loop_
->PostTask(FROM_HERE
, on_done_
);
167 scoped_ptr
<SharedMemoryDataConsumerHandle
> handle_
;
168 scoped_ptr
<WebDataConsumerHandle::Reader
> reader_
;
169 scoped_ptr
<WebDataConsumerHandle::Client
> client_
;
170 base::MessageLoop
* main_message_loop_
;
171 base::Closure on_done_
;
175 void SetUp() override
{
177 new SharedMemoryDataConsumerHandle(kApplyBackpressure
, &writer_
));
180 StrictMock
<MockClient
> client_
;
181 scoped_ptr
<SharedMemoryDataConsumerHandle
> handle_
;
182 scoped_ptr
<Writer
> writer_
;
183 base::MessageLoop loop_
;
186 class SharedMemoryDataConsumerHandleTest
187 : public ::testing::TestWithParam
<BackpressureMode
> {
189 void SetUp() override
{
190 handle_
.reset(new SharedMemoryDataConsumerHandle(GetParam(), &writer_
));
192 scoped_ptr
<FixedReceivedData
> NewFixedData(const char* s
) {
193 return make_scoped_ptr(new FixedReceivedData(s
, strlen(s
), strlen(s
)));
196 StrictMock
<MockClient
> client_
;
197 scoped_ptr
<SharedMemoryDataConsumerHandle
> handle_
;
198 scoped_ptr
<Writer
> writer_
;
199 base::MessageLoop loop_
;
202 void RunPostedTasks() {
203 base::RunLoop run_loop
;
204 base::MessageLoop::current()->task_runner()->PostTask(FROM_HERE
,
205 run_loop
.QuitClosure());
209 TEST_P(SharedMemoryDataConsumerHandleTest
, ReadFromEmpty
) {
212 auto reader
= handle_
->ObtainReader(nullptr);
213 Result result
= reader
->read(buffer
, 4, kNone
, &read
);
215 EXPECT_EQ(kShouldWait
, result
);
219 TEST_P(SharedMemoryDataConsumerHandleTest
, AutoClose
) {
224 auto reader
= handle_
->ObtainReader(nullptr);
225 Result result
= reader
->read(buffer
, 4, kNone
, &read
);
227 EXPECT_EQ(kDone
, result
);
231 TEST_P(SharedMemoryDataConsumerHandleTest
, ReadSimple
) {
232 writer_
->AddData(NewFixedData("hello"));
236 auto reader
= handle_
->ObtainReader(nullptr);
237 Result result
= reader
->read(buffer
, 3, kNone
, &read
);
239 EXPECT_EQ(kOk
, result
);
241 EXPECT_STREQ("hel", buffer
);
243 result
= reader
->read(buffer
, 3, kNone
, &read
);
244 EXPECT_EQ(kOk
, result
);
246 EXPECT_STREQ("lol", buffer
);
248 result
= reader
->read(buffer
, 3, kNone
, &read
);
249 EXPECT_EQ(kShouldWait
, result
);
254 result
= reader
->read(buffer
, 3, kNone
, &read
);
255 EXPECT_EQ(kDone
, result
);
259 TEST_P(SharedMemoryDataConsumerHandleTest
, ReadAfterHandleIsGone
) {
260 writer_
->AddData(NewFixedData("hello"));
264 auto reader
= handle_
->ObtainReader(nullptr);
268 Result result
= reader
->read(buffer
, sizeof(buffer
), kNone
, &read
);
270 EXPECT_EQ(kOk
, result
);
272 EXPECT_STREQ("hello", buffer
);
274 result
= reader
->read(buffer
, 3, kNone
, &read
);
275 EXPECT_EQ(kShouldWait
, result
);
280 result
= reader
->read(buffer
, 3, kNone
, &read
);
281 EXPECT_EQ(kDone
, result
);
285 TEST_P(SharedMemoryDataConsumerHandleTest
, ReObtainReader
) {
286 writer_
->AddData(NewFixedData("hello"));
290 auto reader
= handle_
->ObtainReader(nullptr);
291 Result result
= reader
->read(buffer
, 3, kNone
, &read
);
293 EXPECT_EQ(kOk
, result
);
295 EXPECT_STREQ("hel", buffer
);
298 reader
= handle_
->ObtainReader(nullptr);
300 result
= reader
->read(buffer
, 3, kNone
, &read
);
301 EXPECT_EQ(kOk
, result
);
303 EXPECT_STREQ("lol", buffer
);
305 result
= reader
->read(buffer
, 3, kNone
, &read
);
306 EXPECT_EQ(kShouldWait
, result
);
311 result
= reader
->read(buffer
, 3, kNone
, &read
);
312 EXPECT_EQ(kDone
, result
);
316 TEST_P(SharedMemoryDataConsumerHandleTest
, CloseBeforeReading
) {
317 writer_
->AddData(NewFixedData("hello"));
320 char buffer
[20] = {};
322 auto reader
= handle_
->ObtainReader(nullptr);
323 Result result
= reader
->read(buffer
, sizeof(buffer
), kNone
, &read
);
325 EXPECT_EQ(kOk
, result
);
327 EXPECT_STREQ("hello", buffer
);
329 result
= reader
->read(buffer
, sizeof(buffer
), kNone
, &read
);
330 EXPECT_EQ(kDone
, result
);
334 TEST_P(SharedMemoryDataConsumerHandleTest
, AddMultipleData
) {
335 writer_
->AddData(NewFixedData("Once "));
336 writer_
->AddData(NewFixedData("upon "));
337 writer_
->AddData(NewFixedData("a "));
338 writer_
->AddData(NewFixedData("time "));
339 writer_
->AddData(NewFixedData("there "));
340 writer_
->AddData(NewFixedData("was "));
341 writer_
->AddData(NewFixedData("a "));
348 auto reader
= handle_
->ObtainReader(nullptr);
349 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
350 result
= reader
->read(buffer
, 6, kNone
, &read
);
351 EXPECT_EQ(kOk
, result
);
353 EXPECT_STREQ("Once u", buffer
);
355 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
356 result
= reader
->read(buffer
, 2, kNone
, &read
);
357 EXPECT_EQ(kOk
, result
);
359 EXPECT_STREQ("po", buffer
);
361 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
362 result
= reader
->read(buffer
, 9, kNone
, &read
);
363 EXPECT_EQ(kOk
, result
);
365 EXPECT_STREQ("n a time ", buffer
);
367 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
368 result
= reader
->read(buffer
, 3, kNone
, &read
);
369 EXPECT_EQ(kOk
, result
);
371 EXPECT_STREQ("the", buffer
);
373 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
374 result
= reader
->read(buffer
, 20, kNone
, &read
);
375 EXPECT_EQ(kOk
, result
);
377 EXPECT_STREQ("re was a ", buffer
);
379 result
= reader
->read(buffer
, sizeof(buffer
), kNone
, &read
);
380 EXPECT_EQ(kDone
, result
);
384 TEST_P(SharedMemoryDataConsumerHandleTest
, AddMultipleDataInteractively
) {
385 writer_
->AddData(NewFixedData("Once "));
386 writer_
->AddData(NewFixedData("upon "));
392 auto reader
= handle_
->ObtainReader(nullptr);
393 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
394 result
= reader
->read(buffer
, 6, kNone
, &read
);
395 EXPECT_EQ(kOk
, result
);
397 EXPECT_STREQ("Once u", buffer
);
399 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
400 result
= reader
->read(buffer
, 2, kNone
, &read
);
401 EXPECT_EQ(kOk
, result
);
403 EXPECT_STREQ("po", buffer
);
405 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
406 result
= reader
->read(buffer
, 9, kNone
, &read
);
407 EXPECT_EQ(kOk
, result
);
409 EXPECT_STREQ("n ", buffer
);
411 writer_
->AddData(NewFixedData("a "));
413 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
414 result
= reader
->read(buffer
, 1, kNone
, &read
);
415 EXPECT_EQ(kOk
, result
);
417 EXPECT_STREQ("a", buffer
);
419 writer_
->AddData(NewFixedData("time "));
420 writer_
->AddData(NewFixedData("there "));
421 writer_
->AddData(NewFixedData("was "));
422 writer_
->AddData(NewFixedData("a "));
425 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
426 result
= reader
->read(buffer
, 9, kNone
, &read
);
427 EXPECT_EQ(kOk
, result
);
429 EXPECT_STREQ(" time the", buffer
);
431 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
432 result
= reader
->read(buffer
, 20, kNone
, &read
);
433 EXPECT_EQ(kOk
, result
);
435 EXPECT_STREQ("re was a ", buffer
);
437 result
= reader
->read(buffer
, sizeof(buffer
), kNone
, &read
);
438 EXPECT_EQ(kDone
, result
);
442 TEST_P(SharedMemoryDataConsumerHandleTest
, RegisterClient
) {
443 Checkpoint checkpoint
;
446 EXPECT_CALL(checkpoint
, Call(0));
447 EXPECT_CALL(checkpoint
, Call(1));
448 EXPECT_CALL(checkpoint
, Call(2));
449 EXPECT_CALL(checkpoint
, Call(3));
450 EXPECT_CALL(client_
, didGetReadable());
451 EXPECT_CALL(checkpoint
, Call(4));
454 auto reader
= handle_
->ObtainReader(&client_
);
464 TEST_P(SharedMemoryDataConsumerHandleTest
, RegisterClientWhenDataExists
) {
465 Checkpoint checkpoint
;
468 EXPECT_CALL(checkpoint
, Call(0));
469 EXPECT_CALL(checkpoint
, Call(1));
470 EXPECT_CALL(checkpoint
, Call(2));
471 EXPECT_CALL(client_
, didGetReadable());
472 EXPECT_CALL(checkpoint
, Call(3));
475 writer_
->AddData(NewFixedData("Once "));
477 auto reader
= handle_
->ObtainReader(&client_
);
483 TEST_P(SharedMemoryDataConsumerHandleTest
, AddDataWhenClientIsRegistered
) {
484 Checkpoint checkpoint
;
490 EXPECT_CALL(checkpoint
, Call(0));
491 EXPECT_CALL(checkpoint
, Call(1));
492 EXPECT_CALL(client_
, didGetReadable());
493 EXPECT_CALL(checkpoint
, Call(2));
494 EXPECT_CALL(checkpoint
, Call(3));
495 EXPECT_CALL(checkpoint
, Call(4));
496 EXPECT_CALL(client_
, didGetReadable());
497 EXPECT_CALL(checkpoint
, Call(5));
500 auto reader
= handle_
->ObtainReader(&client_
);
502 writer_
->AddData(NewFixedData("Once "));
504 writer_
->AddData(NewFixedData("upon "));
506 result
= reader
->read(buffer
, sizeof(buffer
), kNone
, &size
);
507 EXPECT_EQ(kOk
, result
);
508 EXPECT_EQ(10u, size
);
510 writer_
->AddData(NewFixedData("a "));
514 TEST_P(SharedMemoryDataConsumerHandleTest
, CloseWithClientAndData
) {
515 Checkpoint checkpoint
;
518 EXPECT_CALL(checkpoint
, Call(0));
519 EXPECT_CALL(checkpoint
, Call(1));
520 EXPECT_CALL(client_
, didGetReadable());
521 EXPECT_CALL(checkpoint
, Call(2));
522 EXPECT_CALL(checkpoint
, Call(3));
525 auto reader
= handle_
->ObtainReader(&client_
);
527 writer_
->AddData(NewFixedData("Once "));
533 TEST_P(SharedMemoryDataConsumerHandleTest
, ReleaseReader
) {
534 Checkpoint checkpoint
;
537 EXPECT_CALL(checkpoint
, Call(0));
538 EXPECT_CALL(checkpoint
, Call(1));
539 EXPECT_CALL(checkpoint
, Call(2));
542 auto reader
= handle_
->ObtainReader(&client_
);
545 writer_
->AddData(NewFixedData("Once "));
549 TEST_P(SharedMemoryDataConsumerHandleTest
, TwoPhaseReadShouldWait
) {
551 const void* buffer
= &result
;
554 auto reader
= handle_
->ObtainReader(nullptr);
555 result
= reader
->beginRead(&buffer
, kNone
, &size
);
556 EXPECT_EQ(kShouldWait
, result
);
557 EXPECT_EQ(nullptr, buffer
);
561 TEST_P(SharedMemoryDataConsumerHandleTest
, TwoPhaseReadSimple
) {
562 writer_
->AddData(NewFixedData("Once "));
565 const void* buffer
= &result
;
568 auto reader
= handle_
->ObtainReader(nullptr);
569 result
= reader
->beginRead(&buffer
, kNone
, &size
);
570 EXPECT_EQ(kOk
, result
);
572 EXPECT_EQ("Once ", ToString(buffer
, 5));
576 result
= reader
->beginRead(&buffer
, kNone
, &size
);
577 EXPECT_EQ(kOk
, result
);
579 EXPECT_EQ("nce ", ToString(buffer
, 4));
583 result
= reader
->beginRead(&buffer
, kNone
, &size
);
584 EXPECT_EQ(kShouldWait
, result
);
586 EXPECT_EQ(nullptr, buffer
);
590 result
= reader
->beginRead(&buffer
, kNone
, &size
);
591 EXPECT_EQ(kDone
, result
);
593 EXPECT_EQ(nullptr, buffer
);
596 TEST_P(SharedMemoryDataConsumerHandleTest
, CallOnClearWhenDestructed1
) {
597 // Call |on_clear| when the handle is gone and if there is no reader.
598 Checkpoint checkpoint
;
599 scoped_refptr
<DestructionTrackingFunction
> on_clear(
600 new StrictMock
<DestructionTrackingFunction
>);
603 EXPECT_CALL(checkpoint
, Call(0));
604 EXPECT_CALL(checkpoint
, Call(1));
605 EXPECT_CALL(*on_clear
, Call());
606 EXPECT_CALL(*on_clear
, Destruct());
607 EXPECT_CALL(checkpoint
, Call(2));
610 handle_
.reset(new SharedMemoryDataConsumerHandle(
612 base::Bind(&DestructionTrackingFunction::Call
, on_clear
), &writer_
));
620 TEST_P(SharedMemoryDataConsumerHandleTest
, CallOnClearWhenDestructed2
) {
621 // Call |on_clear| when the reader is gone if the handle is alredy gone.
622 Checkpoint checkpoint
;
623 scoped_refptr
<DestructionTrackingFunction
> on_clear(
624 new StrictMock
<DestructionTrackingFunction
>);
627 EXPECT_CALL(checkpoint
, Call(0));
628 EXPECT_CALL(checkpoint
, Call(1));
629 EXPECT_CALL(checkpoint
, Call(2));
630 EXPECT_CALL(checkpoint
, Call(3));
631 EXPECT_CALL(*on_clear
, Call());
632 EXPECT_CALL(*on_clear
, Destruct());
633 EXPECT_CALL(checkpoint
, Call(4));
636 handle_
.reset(new SharedMemoryDataConsumerHandle(
638 base::Bind(&DestructionTrackingFunction::Call
, on_clear
), &writer_
));
639 auto reader
= handle_
->ObtainReader(nullptr);
651 TEST_P(SharedMemoryDataConsumerHandleTest
, DoNotCallOnClearWhenDone
) {
652 Checkpoint checkpoint
;
653 scoped_refptr
<DestructionTrackingFunction
> on_clear(
654 new StrictMock
<DestructionTrackingFunction
>);
657 EXPECT_CALL(checkpoint
, Call(0));
658 EXPECT_CALL(checkpoint
, Call(1));
659 EXPECT_CALL(*on_clear
, Destruct());
660 EXPECT_CALL(checkpoint
, Call(2));
661 EXPECT_CALL(checkpoint
, Call(3));
662 EXPECT_CALL(checkpoint
, Call(4));
665 handle_
.reset(new SharedMemoryDataConsumerHandle(
667 base::Bind(&DestructionTrackingFunction::Call
, on_clear
), &writer_
));
678 TEST_P(SharedMemoryDataConsumerHandleTest
, DoNotCallOnClearWhenErrored
) {
679 Checkpoint checkpoint
;
680 scoped_refptr
<DestructionTrackingFunction
> on_clear(
681 new StrictMock
<DestructionTrackingFunction
>);
684 EXPECT_CALL(checkpoint
, Call(0));
685 EXPECT_CALL(checkpoint
, Call(1));
686 EXPECT_CALL(*on_clear
, Destruct());
687 EXPECT_CALL(checkpoint
, Call(2));
688 EXPECT_CALL(checkpoint
, Call(3));
689 EXPECT_CALL(checkpoint
, Call(4));
692 handle_
.reset(new SharedMemoryDataConsumerHandle(
694 base::Bind(&DestructionTrackingFunction::Call
, on_clear
), &writer_
));
705 TEST_P(SharedMemoryDataConsumerHandleTest
, TwoPhaseReadWithMultipleData
) {
706 writer_
->AddData(NewFixedData("Once "));
707 writer_
->AddData(NewFixedData("upon "));
710 const void* buffer
= &result
;
713 auto reader
= handle_
->ObtainReader(nullptr);
714 result
= reader
->beginRead(&buffer
, kNone
, &size
);
715 EXPECT_EQ(kOk
, result
);
717 EXPECT_EQ("Once ", ToString(buffer
, 5));
721 result
= reader
->beginRead(&buffer
, kNone
, &size
);
722 EXPECT_EQ(kOk
, result
);
724 EXPECT_EQ("nce ", ToString(buffer
, 4));
728 result
= reader
->beginRead(&buffer
, kNone
, &size
);
729 EXPECT_EQ(kOk
, result
);
731 EXPECT_EQ("upon ", ToString(buffer
, 5));
735 result
= reader
->beginRead(&buffer
, kNone
, &size
);
736 EXPECT_EQ(kShouldWait
, result
);
738 EXPECT_EQ(nullptr, buffer
);
742 result
= reader
->beginRead(&buffer
, kNone
, &size
);
743 EXPECT_EQ(kDone
, result
);
745 EXPECT_EQ(nullptr, buffer
);
748 TEST_P(SharedMemoryDataConsumerHandleTest
, ErrorRead
) {
749 Checkpoint checkpoint
;
751 char buffer
[20] = {};
753 auto reader
= handle_
->ObtainReader(nullptr);
756 result
= reader
->read(buffer
, sizeof(buffer
), kNone
, &read
);
758 EXPECT_EQ(kUnexpectedError
, result
);
762 TEST_P(SharedMemoryDataConsumerHandleTest
, ErrorTwoPhaseRead
) {
764 const void* pointer
= &result
;
766 auto reader
= handle_
->ObtainReader(nullptr);
769 result
= reader
->beginRead(&pointer
, kNone
, &size
);
771 EXPECT_EQ(kUnexpectedError
, result
);
772 EXPECT_EQ(nullptr, pointer
);
776 TEST_P(SharedMemoryDataConsumerHandleTest
, FailWhileTwoPhaseReadIsInProgress
) {
778 const void* pointer
= nullptr;
780 auto reader
= handle_
->ObtainReader(nullptr);
782 writer_
->AddData(NewFixedData("Once "));
783 result
= reader
->beginRead(&pointer
, kNone
, &size
);
784 auto buffer
= static_cast<const char*>(pointer
);
786 ASSERT_EQ(kOk
, result
);
787 ASSERT_NE(nullptr, pointer
);
792 // We can access the buffer after calling |Fail|. I hope ASAN will detect
793 // an error if the region is already freed.
794 EXPECT_EQ('O', buffer
[0]);
795 EXPECT_EQ('n', buffer
[1]);
796 EXPECT_EQ('c', buffer
[2]);
797 EXPECT_EQ('e', buffer
[3]);
798 EXPECT_EQ(' ', buffer
[4]);
800 EXPECT_EQ(kOk
, reader
->endRead(size
));
802 EXPECT_EQ(kUnexpectedError
, reader
->beginRead(&pointer
, kNone
, &size
));
805 TEST_P(SharedMemoryDataConsumerHandleTest
, FailWithClient
) {
806 Checkpoint checkpoint
;
809 EXPECT_CALL(checkpoint
, Call(0));
810 EXPECT_CALL(checkpoint
, Call(1));
811 EXPECT_CALL(checkpoint
, Call(2));
812 EXPECT_CALL(client_
, didGetReadable());
813 EXPECT_CALL(checkpoint
, Call(3));
816 auto reader
= handle_
->ObtainReader(&client_
);
824 TEST_P(SharedMemoryDataConsumerHandleTest
, FailWithClientAndData
) {
825 Checkpoint checkpoint
;
828 EXPECT_CALL(checkpoint
, Call(0));
829 EXPECT_CALL(checkpoint
, Call(1));
830 EXPECT_CALL(client_
, didGetReadable());
831 EXPECT_CALL(checkpoint
, Call(2));
832 EXPECT_CALL(checkpoint
, Call(3));
833 EXPECT_CALL(client_
, didGetReadable());
834 EXPECT_CALL(checkpoint
, Call(4));
837 auto reader
= handle_
->ObtainReader(&client_
);
839 writer_
->AddData(NewFixedData("Once "));
847 TEST_P(SharedMemoryDataConsumerHandleTest
, RecursiveErrorNotification
) {
848 Checkpoint checkpoint
;
851 EXPECT_CALL(checkpoint
, Call(0));
852 EXPECT_CALL(checkpoint
, Call(1));
853 EXPECT_CALL(client_
, didGetReadable())
854 .WillOnce(Invoke(writer_
.get(), &Writer::Fail
));
855 EXPECT_CALL(checkpoint
, Call(2));
856 EXPECT_CALL(client_
, didGetReadable());
857 EXPECT_CALL(checkpoint
, Call(3));
860 auto reader
= handle_
->ObtainReader(&client_
);
862 writer_
->AddData(NewFixedData("Once "));
868 TEST(SharedMemoryDataConsumerHandleBackpressureTest
, Read
) {
869 base::MessageLoop loop
;
874 scoped_ptr
<Writer
> writer
;
875 auto handle
= make_scoped_ptr(
876 new SharedMemoryDataConsumerHandle(kApplyBackpressure
, &writer
));
877 scoped_refptr
<Logger
> logger(new Logger
);
879 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger
)));
881 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger
)));
883 make_scoped_ptr(new LoggingFixedReceivedData("data3", "a ", logger
)));
885 make_scoped_ptr(new LoggingFixedReceivedData("data4", "time ", logger
)));
887 auto reader
= handle
->ObtainReader(nullptr);
889 result
= reader
->read(buffer
, 2, kNone
, &size
);
890 EXPECT_EQ(kOk
, result
);
893 result
= reader
->read(buffer
, 5, kNone
, &size
);
894 EXPECT_EQ(kOk
, result
);
897 result
= reader
->read(buffer
, 6, kNone
, &size
);
898 EXPECT_EQ(kOk
, result
);
905 "data1 is destructed.\n"
907 "data2 is destructed.\n"
908 "data3 is destructed.\n"
913 TEST(SharedMemoryDataConsumerHandleBackpressureTest
, CloseAndReset
) {
914 base::MessageLoop loop
;
919 scoped_ptr
<Writer
> writer
;
920 auto handle
= make_scoped_ptr(
921 new SharedMemoryDataConsumerHandle(kApplyBackpressure
, &writer
));
922 scoped_refptr
<Logger
> logger(new Logger
);
924 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger
)));
926 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger
)));
928 make_scoped_ptr(new LoggingFixedReceivedData("data3", "a ", logger
)));
930 auto reader
= handle
->ObtainReader(nullptr);
932 result
= reader
->read(buffer
, 2, kNone
, &size
);
933 EXPECT_EQ(kOk
, result
);
946 "data1 is destructed.\n"
947 "data2 is destructed.\n"
948 "data3 is destructed.\n"
953 TEST(SharedMemoryDataConsumerHandleWithoutBackpressureTest
, AddData
) {
954 base::MessageLoop loop
;
955 scoped_ptr
<Writer
> writer
;
956 auto handle
= make_scoped_ptr(
957 new SharedMemoryDataConsumerHandle(kDoNotApplyBackpressure
, &writer
));
958 scoped_refptr
<Logger
> logger(new Logger
);
962 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger
)));
965 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger
)));
970 "data1 is destructed.\n"
972 "data2 is destructed.\n"
977 TEST_F(ThreadedSharedMemoryDataConsumerHandleTest
, Read
) {
978 base::RunLoop run_loop
;
979 auto operation
= make_scoped_ptr(
980 new ReadDataOperation(handle_
.Pass(), &loop_
, run_loop
.QuitClosure()));
981 scoped_refptr
<Logger
> logger(new Logger
);
983 base::Thread
t("DataConsumerHandle test thread");
984 ASSERT_TRUE(t
.Start());
986 t
.message_loop()->PostTask(FROM_HERE
,
987 base::Bind(&ReadDataOperation::ReadData
,
988 base::Unretained(operation
.get())));
992 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger
)));
994 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger
)));
995 writer_
->AddData(make_scoped_ptr(
996 new LoggingFixedReceivedData("data3", "a time ", logger
)));
998 make_scoped_ptr(new LoggingFixedReceivedData("data4", "there ", logger
)));
1000 make_scoped_ptr(new LoggingFixedReceivedData("data5", "was ", logger
)));
1007 EXPECT_EQ("Once upon a time there was ", operation
->result());
1011 "data1 is destructed.\n"
1012 "data2 is destructed.\n"
1013 "data3 is destructed.\n"
1014 "data4 is destructed.\n"
1015 "data5 is destructed.\n",
1019 INSTANTIATE_TEST_CASE_P(SharedMemoryDataConsumerHandleTest
,
1020 SharedMemoryDataConsumerHandleTest
,
1021 ::testing::Values(kApplyBackpressure
,
1022 kDoNotApplyBackpressure
));
1025 } // namespace content