Update UnusedResources lint suppressions.
[chromium-blink-merge.git] / content / child / shared_memory_data_consumer_handle_unittest.cc
blob87136639c524dab638fa3913766b7ddb6d24e716
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"
7 #include <string.h>
8 #include <string>
9 #include <vector>
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"
22 namespace content {
24 namespace {
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;
40 using ::testing::_;
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> {
51 public:
52 Logger() {}
53 void Add(const std::string& entry) { log_ += entry + "\n"; }
54 const std::string& log() const { return log_; }
56 private:
57 friend class base::RefCounted<Logger>;
58 ~Logger() {}
59 std::string log_;
61 DISALLOW_COPY_AND_ASSIGN(Logger);
64 class LoggingFixedReceivedData final : public RequestPeer::ReceivedData {
65 public:
66 LoggingFixedReceivedData(const char* name,
67 const char* s,
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()); }
80 private:
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> {
90 public:
91 MOCK_METHOD0(Destruct, void(void));
92 MOCK_METHOD0(Call, void(void));
94 protected:
95 friend class base::RefCountedThreadSafe<DestructionTrackingFunction>;
96 virtual ~DestructionTrackingFunction() { Destruct(); }
99 class MockClient : public WebDataConsumerHandle::Client {
100 public:
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 {
110 protected:
111 class ReadDataOperation;
112 class ClientImpl final : public WebDataConsumerHandle::Client {
113 public:
114 explicit ClientImpl(ReadDataOperation* operation) : operation_(operation) {}
116 void didGetReadable() override { operation_->ReadData(); }
118 private:
119 ReadDataOperation* operation_;
122 class ReadDataOperation final {
123 public:
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),
130 on_done_(on_done) {}
132 const std::string& result() const { return result_; }
134 void ReadData() {
135 if (!client_) {
136 client_.reset(new ClientImpl(this));
137 reader_ = handle_->ObtainReader(client_.get());
140 Result rv = kOk;
141 size_t read_size = 0;
143 while (true) {
144 char buffer[16];
145 rv = reader_->read(&buffer, sizeof(buffer), kNone, &read_size);
146 if (rv != kOk)
147 break;
148 result_.insert(result_.size(), &buffer[0], read_size);
151 if (rv == kShouldWait) {
152 // Wait a while...
153 return;
156 if (rv != kDone) {
157 // Something is wrong.
158 result_ = "error";
161 // The operation is done.
162 reader_.reset();
163 main_message_loop_->PostTask(FROM_HERE, on_done_);
166 private:
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_;
172 std::string result_;
175 void SetUp() override {
176 handle_.reset(
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> {
188 protected:
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());
206 run_loop.Run();
209 TEST_P(SharedMemoryDataConsumerHandleTest, ReadFromEmpty) {
210 char buffer[4];
211 size_t read = 88;
212 auto reader = handle_->ObtainReader(nullptr);
213 Result result = reader->read(buffer, 4, kNone, &read);
215 EXPECT_EQ(kShouldWait, result);
216 EXPECT_EQ(0u, read);
219 TEST_P(SharedMemoryDataConsumerHandleTest, AutoClose) {
220 char buffer[4];
221 size_t read = 88;
223 writer_.reset();
224 auto reader = handle_->ObtainReader(nullptr);
225 Result result = reader->read(buffer, 4, kNone, &read);
227 EXPECT_EQ(kDone, result);
228 EXPECT_EQ(0u, read);
231 TEST_P(SharedMemoryDataConsumerHandleTest, ReadSimple) {
232 writer_->AddData(NewFixedData("hello"));
234 char buffer[4] = {};
235 size_t read = 88;
236 auto reader = handle_->ObtainReader(nullptr);
237 Result result = reader->read(buffer, 3, kNone, &read);
239 EXPECT_EQ(kOk, result);
240 EXPECT_EQ(3u, read);
241 EXPECT_STREQ("hel", buffer);
243 result = reader->read(buffer, 3, kNone, &read);
244 EXPECT_EQ(kOk, result);
245 EXPECT_EQ(2u, read);
246 EXPECT_STREQ("lol", buffer);
248 result = reader->read(buffer, 3, kNone, &read);
249 EXPECT_EQ(kShouldWait, result);
250 EXPECT_EQ(0u, read);
252 writer_->Close();
254 result = reader->read(buffer, 3, kNone, &read);
255 EXPECT_EQ(kDone, result);
256 EXPECT_EQ(0u, read);
259 TEST_P(SharedMemoryDataConsumerHandleTest, ReadAfterHandleIsGone) {
260 writer_->AddData(NewFixedData("hello"));
262 char buffer[8] = {};
263 size_t read = 88;
264 auto reader = handle_->ObtainReader(nullptr);
266 handle_.reset();
268 Result result = reader->read(buffer, sizeof(buffer), kNone, &read);
270 EXPECT_EQ(kOk, result);
271 EXPECT_EQ(5u, read);
272 EXPECT_STREQ("hello", buffer);
274 result = reader->read(buffer, 3, kNone, &read);
275 EXPECT_EQ(kShouldWait, result);
276 EXPECT_EQ(0u, read);
278 writer_->Close();
280 result = reader->read(buffer, 3, kNone, &read);
281 EXPECT_EQ(kDone, result);
282 EXPECT_EQ(0u, read);
285 TEST_P(SharedMemoryDataConsumerHandleTest, ReObtainReader) {
286 writer_->AddData(NewFixedData("hello"));
288 char buffer[4] = {};
289 size_t read = 88;
290 auto reader = handle_->ObtainReader(nullptr);
291 Result result = reader->read(buffer, 3, kNone, &read);
293 EXPECT_EQ(kOk, result);
294 EXPECT_EQ(3u, read);
295 EXPECT_STREQ("hel", buffer);
297 reader.reset();
298 reader = handle_->ObtainReader(nullptr);
300 result = reader->read(buffer, 3, kNone, &read);
301 EXPECT_EQ(kOk, result);
302 EXPECT_EQ(2u, read);
303 EXPECT_STREQ("lol", buffer);
305 result = reader->read(buffer, 3, kNone, &read);
306 EXPECT_EQ(kShouldWait, result);
307 EXPECT_EQ(0u, read);
309 writer_->Close();
311 result = reader->read(buffer, 3, kNone, &read);
312 EXPECT_EQ(kDone, result);
313 EXPECT_EQ(0u, read);
316 TEST_P(SharedMemoryDataConsumerHandleTest, CloseBeforeReading) {
317 writer_->AddData(NewFixedData("hello"));
318 writer_->Close();
320 char buffer[20] = {};
321 size_t read = 88;
322 auto reader = handle_->ObtainReader(nullptr);
323 Result result = reader->read(buffer, sizeof(buffer), kNone, &read);
325 EXPECT_EQ(kOk, result);
326 EXPECT_EQ(5u, read);
327 EXPECT_STREQ("hello", buffer);
329 result = reader->read(buffer, sizeof(buffer), kNone, &read);
330 EXPECT_EQ(kDone, result);
331 EXPECT_EQ(0u, read);
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 "));
342 writer_->Close();
344 char buffer[20];
345 size_t read;
346 Result result;
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);
352 EXPECT_EQ(6u, read);
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);
358 EXPECT_EQ(2u, read);
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);
364 EXPECT_EQ(9u, read);
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);
370 EXPECT_EQ(3u, read);
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);
376 EXPECT_EQ(9u, read);
377 EXPECT_STREQ("re was a ", buffer);
379 result = reader->read(buffer, sizeof(buffer), kNone, &read);
380 EXPECT_EQ(kDone, result);
381 EXPECT_EQ(0u, read);
384 TEST_P(SharedMemoryDataConsumerHandleTest, AddMultipleDataInteractively) {
385 writer_->AddData(NewFixedData("Once "));
386 writer_->AddData(NewFixedData("upon "));
388 char buffer[20];
389 size_t read;
390 Result result;
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);
396 EXPECT_EQ(6u, read);
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);
402 EXPECT_EQ(2u, read);
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);
408 EXPECT_EQ(2u, read);
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);
416 EXPECT_EQ(1u, read);
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 "));
423 writer_->Close();
425 std::fill(&buffer[0], &buffer[arraysize(buffer)], 0);
426 result = reader->read(buffer, 9, kNone, &read);
427 EXPECT_EQ(kOk, result);
428 EXPECT_EQ(9u, read);
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);
434 EXPECT_EQ(9u, read);
435 EXPECT_STREQ("re was a ", buffer);
437 result = reader->read(buffer, sizeof(buffer), kNone, &read);
438 EXPECT_EQ(kDone, result);
439 EXPECT_EQ(0u, read);
442 TEST_P(SharedMemoryDataConsumerHandleTest, RegisterClient) {
443 Checkpoint checkpoint;
445 InSequence s;
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));
453 checkpoint.Call(0);
454 auto reader = handle_->ObtainReader(&client_);
455 checkpoint.Call(1);
456 RunPostedTasks();
457 checkpoint.Call(2);
458 writer_->Close();
459 checkpoint.Call(3);
460 RunPostedTasks();
461 checkpoint.Call(4);
464 TEST_P(SharedMemoryDataConsumerHandleTest, RegisterClientWhenDataExists) {
465 Checkpoint checkpoint;
467 InSequence s;
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));
474 checkpoint.Call(0);
475 writer_->AddData(NewFixedData("Once "));
476 checkpoint.Call(1);
477 auto reader = handle_->ObtainReader(&client_);
478 checkpoint.Call(2);
479 RunPostedTasks();
480 checkpoint.Call(3);
483 TEST_P(SharedMemoryDataConsumerHandleTest, AddDataWhenClientIsRegistered) {
484 Checkpoint checkpoint;
485 char buffer[20];
486 Result result;
487 size_t size;
489 InSequence s;
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));
499 checkpoint.Call(0);
500 auto reader = handle_->ObtainReader(&client_);
501 checkpoint.Call(1);
502 writer_->AddData(NewFixedData("Once "));
503 checkpoint.Call(2);
504 writer_->AddData(NewFixedData("upon "));
505 checkpoint.Call(3);
506 result = reader->read(buffer, sizeof(buffer), kNone, &size);
507 EXPECT_EQ(kOk, result);
508 EXPECT_EQ(10u, size);
509 checkpoint.Call(4);
510 writer_->AddData(NewFixedData("a "));
511 checkpoint.Call(5);
514 TEST_P(SharedMemoryDataConsumerHandleTest, CloseWithClientAndData) {
515 Checkpoint checkpoint;
517 InSequence s;
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));
524 checkpoint.Call(0);
525 auto reader = handle_->ObtainReader(&client_);
526 checkpoint.Call(1);
527 writer_->AddData(NewFixedData("Once "));
528 checkpoint.Call(2);
529 writer_->Close();
530 checkpoint.Call(3);
533 TEST_P(SharedMemoryDataConsumerHandleTest, ReleaseReader) {
534 Checkpoint checkpoint;
536 InSequence s;
537 EXPECT_CALL(checkpoint, Call(0));
538 EXPECT_CALL(checkpoint, Call(1));
539 EXPECT_CALL(checkpoint, Call(2));
541 checkpoint.Call(0);
542 auto reader = handle_->ObtainReader(&client_);
543 checkpoint.Call(1);
544 reader.reset();
545 writer_->AddData(NewFixedData("Once "));
546 checkpoint.Call(2);
549 TEST_P(SharedMemoryDataConsumerHandleTest, TwoPhaseReadShouldWait) {
550 Result result;
551 const void* buffer = &result;
552 size_t size = 99;
554 auto reader = handle_->ObtainReader(nullptr);
555 result = reader->beginRead(&buffer, kNone, &size);
556 EXPECT_EQ(kShouldWait, result);
557 EXPECT_EQ(nullptr, buffer);
558 EXPECT_EQ(0u, size);
561 TEST_P(SharedMemoryDataConsumerHandleTest, TwoPhaseReadSimple) {
562 writer_->AddData(NewFixedData("Once "));
564 Result result;
565 const void* buffer = &result;
566 size_t size = 99;
568 auto reader = handle_->ObtainReader(nullptr);
569 result = reader->beginRead(&buffer, kNone, &size);
570 EXPECT_EQ(kOk, result);
571 EXPECT_EQ(5u, size);
572 EXPECT_EQ("Once ", ToString(buffer, 5));
574 reader->endRead(1);
576 result = reader->beginRead(&buffer, kNone, &size);
577 EXPECT_EQ(kOk, result);
578 EXPECT_EQ(4u, size);
579 EXPECT_EQ("nce ", ToString(buffer, 4));
581 reader->endRead(4);
583 result = reader->beginRead(&buffer, kNone, &size);
584 EXPECT_EQ(kShouldWait, result);
585 EXPECT_EQ(0u, size);
586 EXPECT_EQ(nullptr, buffer);
588 writer_->Close();
590 result = reader->beginRead(&buffer, kNone, &size);
591 EXPECT_EQ(kDone, result);
592 EXPECT_EQ(0u, size);
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>);
602 InSequence s;
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));
609 checkpoint.Call(0);
610 handle_.reset(new SharedMemoryDataConsumerHandle(
611 kApplyBackpressure,
612 base::Bind(&DestructionTrackingFunction::Call, on_clear), &writer_));
613 handle_.reset();
614 on_clear = nullptr;
615 checkpoint.Call(1);
616 RunPostedTasks();
617 checkpoint.Call(2);
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>);
626 InSequence s;
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));
635 checkpoint.Call(0);
636 handle_.reset(new SharedMemoryDataConsumerHandle(
637 kApplyBackpressure,
638 base::Bind(&DestructionTrackingFunction::Call, on_clear), &writer_));
639 auto reader = handle_->ObtainReader(nullptr);
640 handle_.reset();
641 on_clear = nullptr;
642 checkpoint.Call(1);
643 RunPostedTasks();
644 checkpoint.Call(2);
645 reader.reset();
646 checkpoint.Call(3);
647 RunPostedTasks();
648 checkpoint.Call(4);
651 TEST_P(SharedMemoryDataConsumerHandleTest, DoNotCallOnClearWhenDone) {
652 Checkpoint checkpoint;
653 scoped_refptr<DestructionTrackingFunction> on_clear(
654 new StrictMock<DestructionTrackingFunction>);
656 InSequence s;
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));
664 checkpoint.Call(0);
665 handle_.reset(new SharedMemoryDataConsumerHandle(
666 kApplyBackpressure,
667 base::Bind(&DestructionTrackingFunction::Call, on_clear), &writer_));
668 on_clear = nullptr;
669 checkpoint.Call(1);
670 writer_->Close();
671 checkpoint.Call(2);
672 handle_.reset();
673 checkpoint.Call(3);
674 RunPostedTasks();
675 checkpoint.Call(4);
678 TEST_P(SharedMemoryDataConsumerHandleTest, DoNotCallOnClearWhenErrored) {
679 Checkpoint checkpoint;
680 scoped_refptr<DestructionTrackingFunction> on_clear(
681 new StrictMock<DestructionTrackingFunction>);
683 InSequence s;
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));
691 checkpoint.Call(0);
692 handle_.reset(new SharedMemoryDataConsumerHandle(
693 kApplyBackpressure,
694 base::Bind(&DestructionTrackingFunction::Call, on_clear), &writer_));
695 on_clear = nullptr;
696 checkpoint.Call(1);
697 writer_->Fail();
698 checkpoint.Call(2);
699 handle_.reset();
700 checkpoint.Call(3);
701 RunPostedTasks();
702 checkpoint.Call(4);
705 TEST_P(SharedMemoryDataConsumerHandleTest, TwoPhaseReadWithMultipleData) {
706 writer_->AddData(NewFixedData("Once "));
707 writer_->AddData(NewFixedData("upon "));
709 Result result;
710 const void* buffer = &result;
711 size_t size = 99;
713 auto reader = handle_->ObtainReader(nullptr);
714 result = reader->beginRead(&buffer, kNone, &size);
715 EXPECT_EQ(kOk, result);
716 EXPECT_EQ(5u, size);
717 EXPECT_EQ("Once ", ToString(buffer, 5));
719 reader->endRead(1);
721 result = reader->beginRead(&buffer, kNone, &size);
722 EXPECT_EQ(kOk, result);
723 EXPECT_EQ(4u, size);
724 EXPECT_EQ("nce ", ToString(buffer, 4));
726 reader->endRead(4);
728 result = reader->beginRead(&buffer, kNone, &size);
729 EXPECT_EQ(kOk, result);
730 EXPECT_EQ(5u, size);
731 EXPECT_EQ("upon ", ToString(buffer, 5));
733 reader->endRead(5);
735 result = reader->beginRead(&buffer, kNone, &size);
736 EXPECT_EQ(kShouldWait, result);
737 EXPECT_EQ(0u, size);
738 EXPECT_EQ(nullptr, buffer);
740 writer_->Close();
742 result = reader->beginRead(&buffer, kNone, &size);
743 EXPECT_EQ(kDone, result);
744 EXPECT_EQ(0u, size);
745 EXPECT_EQ(nullptr, buffer);
748 TEST_P(SharedMemoryDataConsumerHandleTest, ErrorRead) {
749 Checkpoint checkpoint;
750 Result result;
751 char buffer[20] = {};
752 size_t read = 99;
753 auto reader = handle_->ObtainReader(nullptr);
755 writer_->Fail();
756 result = reader->read(buffer, sizeof(buffer), kNone, &read);
758 EXPECT_EQ(kUnexpectedError, result);
759 EXPECT_EQ(0u, read);
762 TEST_P(SharedMemoryDataConsumerHandleTest, ErrorTwoPhaseRead) {
763 Result result;
764 const void* pointer = &result;
765 size_t size = 99;
766 auto reader = handle_->ObtainReader(nullptr);
768 writer_->Fail();
769 result = reader->beginRead(&pointer, kNone, &size);
771 EXPECT_EQ(kUnexpectedError, result);
772 EXPECT_EQ(nullptr, pointer);
773 EXPECT_EQ(0u, size);
776 TEST_P(SharedMemoryDataConsumerHandleTest, FailWhileTwoPhaseReadIsInProgress) {
777 Result result;
778 const void* pointer = nullptr;
779 size_t size = 0;
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);
788 ASSERT_EQ(size, 5u);
790 writer_->Fail();
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;
808 InSequence s;
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));
815 checkpoint.Call(0);
816 auto reader = handle_->ObtainReader(&client_);
817 checkpoint.Call(1);
818 writer_->Fail();
819 checkpoint.Call(2);
820 RunPostedTasks();
821 checkpoint.Call(3);
824 TEST_P(SharedMemoryDataConsumerHandleTest, FailWithClientAndData) {
825 Checkpoint checkpoint;
827 InSequence s;
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));
836 checkpoint.Call(0);
837 auto reader = handle_->ObtainReader(&client_);
838 checkpoint.Call(1);
839 writer_->AddData(NewFixedData("Once "));
840 checkpoint.Call(2);
841 writer_->Fail();
842 checkpoint.Call(3);
843 RunPostedTasks();
844 checkpoint.Call(4);
847 TEST_P(SharedMemoryDataConsumerHandleTest, RecursiveErrorNotification) {
848 Checkpoint checkpoint;
850 InSequence s;
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));
859 checkpoint.Call(0);
860 auto reader = handle_->ObtainReader(&client_);
861 checkpoint.Call(1);
862 writer_->AddData(NewFixedData("Once "));
863 checkpoint.Call(2);
864 RunPostedTasks();
865 checkpoint.Call(3);
868 TEST(SharedMemoryDataConsumerHandleBackpressureTest, Read) {
869 base::MessageLoop loop;
870 char buffer[20];
871 Result result;
872 size_t size;
874 scoped_ptr<Writer> writer;
875 auto handle = make_scoped_ptr(
876 new SharedMemoryDataConsumerHandle(kApplyBackpressure, &writer));
877 scoped_refptr<Logger> logger(new Logger);
878 writer->AddData(
879 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
880 writer->AddData(
881 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger)));
882 writer->AddData(
883 make_scoped_ptr(new LoggingFixedReceivedData("data3", "a ", logger)));
884 writer->AddData(
885 make_scoped_ptr(new LoggingFixedReceivedData("data4", "time ", logger)));
887 auto reader = handle->ObtainReader(nullptr);
888 logger->Add("1");
889 result = reader->read(buffer, 2, kNone, &size);
890 EXPECT_EQ(kOk, result);
891 EXPECT_EQ(2u, size);
892 logger->Add("2");
893 result = reader->read(buffer, 5, kNone, &size);
894 EXPECT_EQ(kOk, result);
895 EXPECT_EQ(5u, size);
896 logger->Add("3");
897 result = reader->read(buffer, 6, kNone, &size);
898 EXPECT_EQ(kOk, result);
899 EXPECT_EQ(6u, size);
900 logger->Add("4");
902 EXPECT_EQ(
903 "1\n"
904 "2\n"
905 "data1 is destructed.\n"
906 "3\n"
907 "data2 is destructed.\n"
908 "data3 is destructed.\n"
909 "4\n",
910 logger->log());
913 TEST(SharedMemoryDataConsumerHandleBackpressureTest, CloseAndReset) {
914 base::MessageLoop loop;
915 char buffer[20];
916 Result result;
917 size_t size;
919 scoped_ptr<Writer> writer;
920 auto handle = make_scoped_ptr(
921 new SharedMemoryDataConsumerHandle(kApplyBackpressure, &writer));
922 scoped_refptr<Logger> logger(new Logger);
923 writer->AddData(
924 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
925 writer->AddData(
926 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger)));
927 writer->AddData(
928 make_scoped_ptr(new LoggingFixedReceivedData("data3", "a ", logger)));
930 auto reader = handle->ObtainReader(nullptr);
931 logger->Add("1");
932 result = reader->read(buffer, 2, kNone, &size);
933 EXPECT_EQ(kOk, result);
934 EXPECT_EQ(2u, size);
935 logger->Add("2");
936 writer->Close();
937 logger->Add("3");
938 handle.reset();
939 reader.reset();
940 logger->Add("4");
942 EXPECT_EQ(
943 "1\n"
944 "2\n"
945 "3\n"
946 "data1 is destructed.\n"
947 "data2 is destructed.\n"
948 "data3 is destructed.\n"
949 "4\n",
950 logger->log());
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);
960 logger->Add("1");
961 writer->AddData(
962 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
963 logger->Add("2");
964 writer->AddData(
965 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger)));
966 logger->Add("3");
968 EXPECT_EQ(
969 "1\n"
970 "data1 is destructed.\n"
971 "2\n"
972 "data2 is destructed.\n"
973 "3\n",
974 logger->log());
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())));
990 logger->Add("1");
991 writer_->AddData(
992 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
993 writer_->AddData(
994 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger)));
995 writer_->AddData(make_scoped_ptr(
996 new LoggingFixedReceivedData("data3", "a time ", logger)));
997 writer_->AddData(
998 make_scoped_ptr(new LoggingFixedReceivedData("data4", "there ", logger)));
999 writer_->AddData(
1000 make_scoped_ptr(new LoggingFixedReceivedData("data5", "was ", logger)));
1001 writer_->Close();
1002 logger->Add("2");
1004 run_loop.Run();
1005 t.Stop();
1007 EXPECT_EQ("Once upon a time there was ", operation->result());
1008 EXPECT_EQ(
1009 "1\n"
1010 "2\n"
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",
1016 logger->log());
1019 INSTANTIATE_TEST_CASE_P(SharedMemoryDataConsumerHandleTest,
1020 SharedMemoryDataConsumerHandleTest,
1021 ::testing::Values(kApplyBackpressure,
1022 kDoNotApplyBackpressure));
1023 } // namespace
1025 } // namespace content