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
, CloseWithDataBeforeZeroRead
) {
335 writer_
->AddData(NewFixedData("hello"));
339 auto reader
= handle_
->ObtainReader(nullptr);
340 Result result
= reader
->read(nullptr, 0, kNone
, &read
);
342 EXPECT_EQ(kOk
, result
);
346 TEST_P(SharedMemoryDataConsumerHandleTest
, CloseWithoutDataBeforeZeroRead
) {
350 auto reader
= handle_
->ObtainReader(nullptr);
351 Result result
= reader
->read(nullptr, 0, kNone
, &read
);
353 EXPECT_EQ(kDone
, result
);
356 TEST_P(SharedMemoryDataConsumerHandleTest
, AddMultipleData
) {
357 writer_
->AddData(NewFixedData("Once "));
358 writer_
->AddData(NewFixedData("upon "));
359 writer_
->AddData(NewFixedData("a "));
360 writer_
->AddData(NewFixedData("time "));
361 writer_
->AddData(NewFixedData("there "));
362 writer_
->AddData(NewFixedData("was "));
363 writer_
->AddData(NewFixedData("a "));
370 auto reader
= handle_
->ObtainReader(nullptr);
371 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
372 result
= reader
->read(buffer
, 6, kNone
, &read
);
373 EXPECT_EQ(kOk
, result
);
375 EXPECT_STREQ("Once u", buffer
);
377 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
378 result
= reader
->read(buffer
, 2, kNone
, &read
);
379 EXPECT_EQ(kOk
, result
);
381 EXPECT_STREQ("po", buffer
);
383 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
384 result
= reader
->read(buffer
, 9, kNone
, &read
);
385 EXPECT_EQ(kOk
, result
);
387 EXPECT_STREQ("n a time ", buffer
);
389 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
390 result
= reader
->read(buffer
, 3, kNone
, &read
);
391 EXPECT_EQ(kOk
, result
);
393 EXPECT_STREQ("the", buffer
);
395 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
396 result
= reader
->read(buffer
, 20, kNone
, &read
);
397 EXPECT_EQ(kOk
, result
);
399 EXPECT_STREQ("re was a ", buffer
);
401 result
= reader
->read(buffer
, sizeof(buffer
), kNone
, &read
);
402 EXPECT_EQ(kDone
, result
);
406 TEST_P(SharedMemoryDataConsumerHandleTest
, AddMultipleDataInteractively
) {
407 writer_
->AddData(NewFixedData("Once "));
408 writer_
->AddData(NewFixedData("upon "));
414 auto reader
= handle_
->ObtainReader(nullptr);
415 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
416 result
= reader
->read(buffer
, 6, kNone
, &read
);
417 EXPECT_EQ(kOk
, result
);
419 EXPECT_STREQ("Once u", buffer
);
421 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
422 result
= reader
->read(buffer
, 2, kNone
, &read
);
423 EXPECT_EQ(kOk
, result
);
425 EXPECT_STREQ("po", buffer
);
427 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
428 result
= reader
->read(buffer
, 9, kNone
, &read
);
429 EXPECT_EQ(kOk
, result
);
431 EXPECT_STREQ("n ", buffer
);
433 writer_
->AddData(NewFixedData("a "));
435 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
436 result
= reader
->read(buffer
, 1, kNone
, &read
);
437 EXPECT_EQ(kOk
, result
);
439 EXPECT_STREQ("a", buffer
);
441 writer_
->AddData(NewFixedData("time "));
442 writer_
->AddData(NewFixedData("there "));
443 writer_
->AddData(NewFixedData("was "));
444 writer_
->AddData(NewFixedData("a "));
447 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
448 result
= reader
->read(buffer
, 9, kNone
, &read
);
449 EXPECT_EQ(kOk
, result
);
451 EXPECT_STREQ(" time the", buffer
);
453 std::fill(&buffer
[0], &buffer
[arraysize(buffer
)], 0);
454 result
= reader
->read(buffer
, 20, kNone
, &read
);
455 EXPECT_EQ(kOk
, result
);
457 EXPECT_STREQ("re was a ", buffer
);
459 result
= reader
->read(buffer
, sizeof(buffer
), kNone
, &read
);
460 EXPECT_EQ(kDone
, result
);
464 TEST_P(SharedMemoryDataConsumerHandleTest
, RegisterClient
) {
465 Checkpoint checkpoint
;
468 EXPECT_CALL(checkpoint
, Call(0));
469 EXPECT_CALL(checkpoint
, Call(1));
470 EXPECT_CALL(checkpoint
, Call(2));
471 EXPECT_CALL(checkpoint
, Call(3));
472 EXPECT_CALL(client_
, didGetReadable());
473 EXPECT_CALL(checkpoint
, Call(4));
476 auto reader
= handle_
->ObtainReader(&client_
);
486 TEST_P(SharedMemoryDataConsumerHandleTest
, RegisterClientWhenDataExists
) {
487 Checkpoint checkpoint
;
490 EXPECT_CALL(checkpoint
, Call(0));
491 EXPECT_CALL(checkpoint
, Call(1));
492 EXPECT_CALL(checkpoint
, Call(2));
493 EXPECT_CALL(client_
, didGetReadable());
494 EXPECT_CALL(checkpoint
, Call(3));
497 writer_
->AddData(NewFixedData("Once "));
499 auto reader
= handle_
->ObtainReader(&client_
);
505 TEST_P(SharedMemoryDataConsumerHandleTest
, AddDataWhenClientIsRegistered
) {
506 Checkpoint checkpoint
;
512 EXPECT_CALL(checkpoint
, Call(0));
513 EXPECT_CALL(checkpoint
, Call(1));
514 EXPECT_CALL(client_
, didGetReadable());
515 EXPECT_CALL(checkpoint
, Call(2));
516 EXPECT_CALL(checkpoint
, Call(3));
517 EXPECT_CALL(checkpoint
, Call(4));
518 EXPECT_CALL(client_
, didGetReadable());
519 EXPECT_CALL(checkpoint
, Call(5));
522 auto reader
= handle_
->ObtainReader(&client_
);
524 writer_
->AddData(NewFixedData("Once "));
526 writer_
->AddData(NewFixedData("upon "));
528 result
= reader
->read(buffer
, sizeof(buffer
), kNone
, &size
);
529 EXPECT_EQ(kOk
, result
);
530 EXPECT_EQ(10u, size
);
532 writer_
->AddData(NewFixedData("a "));
536 TEST_P(SharedMemoryDataConsumerHandleTest
, CloseWithClientAndData
) {
537 Checkpoint checkpoint
;
540 EXPECT_CALL(checkpoint
, Call(0));
541 EXPECT_CALL(checkpoint
, Call(1));
542 EXPECT_CALL(client_
, didGetReadable());
543 EXPECT_CALL(checkpoint
, Call(2));
544 EXPECT_CALL(checkpoint
, Call(3));
547 auto reader
= handle_
->ObtainReader(&client_
);
549 writer_
->AddData(NewFixedData("Once "));
555 TEST_P(SharedMemoryDataConsumerHandleTest
, ReleaseReader
) {
556 Checkpoint checkpoint
;
559 EXPECT_CALL(checkpoint
, Call(0));
560 EXPECT_CALL(checkpoint
, Call(1));
561 EXPECT_CALL(checkpoint
, Call(2));
564 auto reader
= handle_
->ObtainReader(&client_
);
567 writer_
->AddData(NewFixedData("Once "));
571 TEST_P(SharedMemoryDataConsumerHandleTest
, TwoPhaseReadShouldWait
) {
573 const void* buffer
= &result
;
576 auto reader
= handle_
->ObtainReader(nullptr);
577 result
= reader
->beginRead(&buffer
, kNone
, &size
);
578 EXPECT_EQ(kShouldWait
, result
);
579 EXPECT_EQ(nullptr, buffer
);
583 TEST_P(SharedMemoryDataConsumerHandleTest
, TwoPhaseReadSimple
) {
584 writer_
->AddData(NewFixedData("Once "));
587 const void* buffer
= &result
;
590 auto reader
= handle_
->ObtainReader(nullptr);
591 result
= reader
->beginRead(&buffer
, kNone
, &size
);
592 EXPECT_EQ(kOk
, result
);
594 EXPECT_EQ("Once ", ToString(buffer
, 5));
598 result
= reader
->beginRead(&buffer
, kNone
, &size
);
599 EXPECT_EQ(kOk
, result
);
601 EXPECT_EQ("nce ", ToString(buffer
, 4));
605 result
= reader
->beginRead(&buffer
, kNone
, &size
);
606 EXPECT_EQ(kShouldWait
, result
);
608 EXPECT_EQ(nullptr, buffer
);
612 result
= reader
->beginRead(&buffer
, kNone
, &size
);
613 EXPECT_EQ(kDone
, result
);
615 EXPECT_EQ(nullptr, buffer
);
618 TEST_P(SharedMemoryDataConsumerHandleTest
, CallOnClearWhenDestructed1
) {
619 // Call |on_clear| when the handle is gone and if there is no reader.
620 Checkpoint checkpoint
;
621 scoped_refptr
<DestructionTrackingFunction
> on_clear(
622 new StrictMock
<DestructionTrackingFunction
>);
625 EXPECT_CALL(checkpoint
, Call(0));
626 EXPECT_CALL(checkpoint
, Call(1));
627 EXPECT_CALL(*on_clear
, Call());
628 EXPECT_CALL(*on_clear
, Destruct());
629 EXPECT_CALL(checkpoint
, Call(2));
632 handle_
.reset(new SharedMemoryDataConsumerHandle(
634 base::Bind(&DestructionTrackingFunction::Call
, on_clear
), &writer_
));
642 TEST_P(SharedMemoryDataConsumerHandleTest
, CallOnClearWhenDestructed2
) {
643 // Call |on_clear| when the reader is gone if the handle is alredy gone.
644 Checkpoint checkpoint
;
645 scoped_refptr
<DestructionTrackingFunction
> on_clear(
646 new StrictMock
<DestructionTrackingFunction
>);
649 EXPECT_CALL(checkpoint
, Call(0));
650 EXPECT_CALL(checkpoint
, Call(1));
651 EXPECT_CALL(checkpoint
, Call(2));
652 EXPECT_CALL(checkpoint
, Call(3));
653 EXPECT_CALL(*on_clear
, Call());
654 EXPECT_CALL(*on_clear
, Destruct());
655 EXPECT_CALL(checkpoint
, Call(4));
658 handle_
.reset(new SharedMemoryDataConsumerHandle(
660 base::Bind(&DestructionTrackingFunction::Call
, on_clear
), &writer_
));
661 auto reader
= handle_
->ObtainReader(nullptr);
673 TEST_P(SharedMemoryDataConsumerHandleTest
, DoNotCallOnClearWhenDone
) {
674 Checkpoint checkpoint
;
675 scoped_refptr
<DestructionTrackingFunction
> on_clear(
676 new StrictMock
<DestructionTrackingFunction
>);
679 EXPECT_CALL(checkpoint
, Call(0));
680 EXPECT_CALL(checkpoint
, Call(1));
681 EXPECT_CALL(*on_clear
, Destruct());
682 EXPECT_CALL(checkpoint
, Call(2));
683 EXPECT_CALL(checkpoint
, Call(3));
684 EXPECT_CALL(checkpoint
, Call(4));
687 handle_
.reset(new SharedMemoryDataConsumerHandle(
689 base::Bind(&DestructionTrackingFunction::Call
, on_clear
), &writer_
));
700 TEST_P(SharedMemoryDataConsumerHandleTest
, DoNotCallOnClearWhenErrored
) {
701 Checkpoint checkpoint
;
702 scoped_refptr
<DestructionTrackingFunction
> on_clear(
703 new StrictMock
<DestructionTrackingFunction
>);
706 EXPECT_CALL(checkpoint
, Call(0));
707 EXPECT_CALL(checkpoint
, Call(1));
708 EXPECT_CALL(*on_clear
, Destruct());
709 EXPECT_CALL(checkpoint
, Call(2));
710 EXPECT_CALL(checkpoint
, Call(3));
711 EXPECT_CALL(checkpoint
, Call(4));
714 handle_
.reset(new SharedMemoryDataConsumerHandle(
716 base::Bind(&DestructionTrackingFunction::Call
, on_clear
), &writer_
));
727 TEST_P(SharedMemoryDataConsumerHandleTest
, TwoPhaseReadWithMultipleData
) {
728 writer_
->AddData(NewFixedData("Once "));
729 writer_
->AddData(NewFixedData("upon "));
732 const void* buffer
= &result
;
735 auto reader
= handle_
->ObtainReader(nullptr);
736 result
= reader
->beginRead(&buffer
, kNone
, &size
);
737 EXPECT_EQ(kOk
, result
);
739 EXPECT_EQ("Once ", ToString(buffer
, 5));
743 result
= reader
->beginRead(&buffer
, kNone
, &size
);
744 EXPECT_EQ(kOk
, result
);
746 EXPECT_EQ("nce ", ToString(buffer
, 4));
750 result
= reader
->beginRead(&buffer
, kNone
, &size
);
751 EXPECT_EQ(kOk
, result
);
753 EXPECT_EQ("upon ", ToString(buffer
, 5));
757 result
= reader
->beginRead(&buffer
, kNone
, &size
);
758 EXPECT_EQ(kShouldWait
, result
);
760 EXPECT_EQ(nullptr, buffer
);
764 result
= reader
->beginRead(&buffer
, kNone
, &size
);
765 EXPECT_EQ(kDone
, result
);
767 EXPECT_EQ(nullptr, buffer
);
770 TEST_P(SharedMemoryDataConsumerHandleTest
, ErrorRead
) {
771 Checkpoint checkpoint
;
773 char buffer
[20] = {};
775 auto reader
= handle_
->ObtainReader(nullptr);
778 result
= reader
->read(buffer
, sizeof(buffer
), kNone
, &read
);
780 EXPECT_EQ(kUnexpectedError
, result
);
784 TEST_P(SharedMemoryDataConsumerHandleTest
, ErrorTwoPhaseRead
) {
786 const void* pointer
= &result
;
788 auto reader
= handle_
->ObtainReader(nullptr);
791 result
= reader
->beginRead(&pointer
, kNone
, &size
);
793 EXPECT_EQ(kUnexpectedError
, result
);
794 EXPECT_EQ(nullptr, pointer
);
798 TEST_P(SharedMemoryDataConsumerHandleTest
, FailWhileTwoPhaseReadIsInProgress
) {
800 const void* pointer
= nullptr;
802 auto reader
= handle_
->ObtainReader(nullptr);
804 writer_
->AddData(NewFixedData("Once "));
805 result
= reader
->beginRead(&pointer
, kNone
, &size
);
806 auto buffer
= static_cast<const char*>(pointer
);
808 ASSERT_EQ(kOk
, result
);
809 ASSERT_NE(nullptr, pointer
);
814 // We can access the buffer after calling |Fail|. I hope ASAN will detect
815 // an error if the region is already freed.
816 EXPECT_EQ('O', buffer
[0]);
817 EXPECT_EQ('n', buffer
[1]);
818 EXPECT_EQ('c', buffer
[2]);
819 EXPECT_EQ('e', buffer
[3]);
820 EXPECT_EQ(' ', buffer
[4]);
822 EXPECT_EQ(kOk
, reader
->endRead(size
));
824 EXPECT_EQ(kUnexpectedError
, reader
->beginRead(&pointer
, kNone
, &size
));
827 TEST_P(SharedMemoryDataConsumerHandleTest
, FailWithClient
) {
828 Checkpoint checkpoint
;
831 EXPECT_CALL(checkpoint
, Call(0));
832 EXPECT_CALL(checkpoint
, Call(1));
833 EXPECT_CALL(checkpoint
, Call(2));
834 EXPECT_CALL(client_
, didGetReadable());
835 EXPECT_CALL(checkpoint
, Call(3));
838 auto reader
= handle_
->ObtainReader(&client_
);
846 TEST_P(SharedMemoryDataConsumerHandleTest
, FailWithClientAndData
) {
847 Checkpoint checkpoint
;
850 EXPECT_CALL(checkpoint
, Call(0));
851 EXPECT_CALL(checkpoint
, Call(1));
852 EXPECT_CALL(client_
, didGetReadable());
853 EXPECT_CALL(checkpoint
, Call(2));
854 EXPECT_CALL(checkpoint
, Call(3));
855 EXPECT_CALL(client_
, didGetReadable());
856 EXPECT_CALL(checkpoint
, Call(4));
859 auto reader
= handle_
->ObtainReader(&client_
);
861 writer_
->AddData(NewFixedData("Once "));
869 TEST_P(SharedMemoryDataConsumerHandleTest
, RecursiveErrorNotification
) {
870 Checkpoint checkpoint
;
873 EXPECT_CALL(checkpoint
, Call(0));
874 EXPECT_CALL(checkpoint
, Call(1));
875 EXPECT_CALL(client_
, didGetReadable())
876 .WillOnce(Invoke(writer_
.get(), &Writer::Fail
));
877 EXPECT_CALL(checkpoint
, Call(2));
878 EXPECT_CALL(client_
, didGetReadable());
879 EXPECT_CALL(checkpoint
, Call(3));
882 auto reader
= handle_
->ObtainReader(&client_
);
884 writer_
->AddData(NewFixedData("Once "));
890 TEST(SharedMemoryDataConsumerHandleBackpressureTest
, Read
) {
891 base::MessageLoop loop
;
896 scoped_ptr
<Writer
> writer
;
897 auto handle
= make_scoped_ptr(
898 new SharedMemoryDataConsumerHandle(kApplyBackpressure
, &writer
));
899 scoped_refptr
<Logger
> logger(new Logger
);
901 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger
)));
903 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger
)));
905 make_scoped_ptr(new LoggingFixedReceivedData("data3", "a ", logger
)));
907 make_scoped_ptr(new LoggingFixedReceivedData("data4", "time ", logger
)));
909 auto reader
= handle
->ObtainReader(nullptr);
911 result
= reader
->read(buffer
, 2, kNone
, &size
);
912 EXPECT_EQ(kOk
, result
);
915 result
= reader
->read(buffer
, 5, kNone
, &size
);
916 EXPECT_EQ(kOk
, result
);
919 result
= reader
->read(buffer
, 6, kNone
, &size
);
920 EXPECT_EQ(kOk
, result
);
927 "data1 is destructed.\n"
929 "data2 is destructed.\n"
930 "data3 is destructed.\n"
935 TEST(SharedMemoryDataConsumerHandleBackpressureTest
, CloseAndReset
) {
936 base::MessageLoop loop
;
941 scoped_ptr
<Writer
> writer
;
942 auto handle
= make_scoped_ptr(
943 new SharedMemoryDataConsumerHandle(kApplyBackpressure
, &writer
));
944 scoped_refptr
<Logger
> logger(new Logger
);
946 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger
)));
948 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger
)));
950 make_scoped_ptr(new LoggingFixedReceivedData("data3", "a ", logger
)));
952 auto reader
= handle
->ObtainReader(nullptr);
954 result
= reader
->read(buffer
, 2, kNone
, &size
);
955 EXPECT_EQ(kOk
, result
);
968 "data1 is destructed.\n"
969 "data2 is destructed.\n"
970 "data3 is destructed.\n"
975 TEST(SharedMemoryDataConsumerHandleWithoutBackpressureTest
, AddData
) {
976 base::MessageLoop loop
;
977 scoped_ptr
<Writer
> writer
;
978 auto handle
= make_scoped_ptr(
979 new SharedMemoryDataConsumerHandle(kDoNotApplyBackpressure
, &writer
));
980 scoped_refptr
<Logger
> logger(new Logger
);
984 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger
)));
987 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger
)));
992 "data1 is destructed.\n"
994 "data2 is destructed.\n"
999 TEST_F(ThreadedSharedMemoryDataConsumerHandleTest
, Read
) {
1000 base::RunLoop run_loop
;
1001 auto operation
= make_scoped_ptr(
1002 new ReadDataOperation(handle_
.Pass(), &loop_
, run_loop
.QuitClosure()));
1003 scoped_refptr
<Logger
> logger(new Logger
);
1005 base::Thread
t("DataConsumerHandle test thread");
1006 ASSERT_TRUE(t
.Start());
1008 t
.message_loop()->PostTask(FROM_HERE
,
1009 base::Bind(&ReadDataOperation::ReadData
,
1010 base::Unretained(operation
.get())));
1014 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger
)));
1016 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger
)));
1017 writer_
->AddData(make_scoped_ptr(
1018 new LoggingFixedReceivedData("data3", "a time ", logger
)));
1020 make_scoped_ptr(new LoggingFixedReceivedData("data4", "there ", logger
)));
1022 make_scoped_ptr(new LoggingFixedReceivedData("data5", "was ", logger
)));
1029 EXPECT_EQ("Once upon a time there was ", operation
->result());
1033 "data1 is destructed.\n"
1034 "data2 is destructed.\n"
1035 "data3 is destructed.\n"
1036 "data4 is destructed.\n"
1037 "data5 is destructed.\n",
1041 INSTANTIATE_TEST_CASE_P(SharedMemoryDataConsumerHandleTest
,
1042 SharedMemoryDataConsumerHandleTest
,
1043 ::testing::Values(kApplyBackpressure
,
1044 kDoNotApplyBackpressure
));
1047 } // namespace content