Make USB permissions work in the new permission message system
[chromium-blink-merge.git] / content / child / shared_memory_data_consumer_handle_unittest.cc
blob3e5590c3216bc2178bc4d1ce4f59717bdb63af33
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, CloseWithDataBeforeZeroRead) {
335 writer_->AddData(NewFixedData("hello"));
336 writer_->Close();
338 size_t read = 88;
339 auto reader = handle_->ObtainReader(nullptr);
340 Result result = reader->read(nullptr, 0, kNone, &read);
342 EXPECT_EQ(kOk, result);
343 EXPECT_EQ(0u, read);
346 TEST_P(SharedMemoryDataConsumerHandleTest, CloseWithoutDataBeforeZeroRead) {
347 writer_->Close();
349 size_t read = 88;
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 "));
364 writer_->Close();
366 char buffer[20];
367 size_t read;
368 Result result;
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);
374 EXPECT_EQ(6u, read);
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);
380 EXPECT_EQ(2u, read);
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);
386 EXPECT_EQ(9u, read);
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);
392 EXPECT_EQ(3u, read);
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);
398 EXPECT_EQ(9u, read);
399 EXPECT_STREQ("re was a ", buffer);
401 result = reader->read(buffer, sizeof(buffer), kNone, &read);
402 EXPECT_EQ(kDone, result);
403 EXPECT_EQ(0u, read);
406 TEST_P(SharedMemoryDataConsumerHandleTest, AddMultipleDataInteractively) {
407 writer_->AddData(NewFixedData("Once "));
408 writer_->AddData(NewFixedData("upon "));
410 char buffer[20];
411 size_t read;
412 Result result;
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);
418 EXPECT_EQ(6u, read);
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);
424 EXPECT_EQ(2u, read);
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);
430 EXPECT_EQ(2u, read);
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);
438 EXPECT_EQ(1u, read);
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 "));
445 writer_->Close();
447 std::fill(&buffer[0], &buffer[arraysize(buffer)], 0);
448 result = reader->read(buffer, 9, kNone, &read);
449 EXPECT_EQ(kOk, result);
450 EXPECT_EQ(9u, read);
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);
456 EXPECT_EQ(9u, read);
457 EXPECT_STREQ("re was a ", buffer);
459 result = reader->read(buffer, sizeof(buffer), kNone, &read);
460 EXPECT_EQ(kDone, result);
461 EXPECT_EQ(0u, read);
464 TEST_P(SharedMemoryDataConsumerHandleTest, RegisterClient) {
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(checkpoint, Call(3));
472 EXPECT_CALL(client_, didGetReadable());
473 EXPECT_CALL(checkpoint, Call(4));
475 checkpoint.Call(0);
476 auto reader = handle_->ObtainReader(&client_);
477 checkpoint.Call(1);
478 RunPostedTasks();
479 checkpoint.Call(2);
480 writer_->Close();
481 checkpoint.Call(3);
482 RunPostedTasks();
483 checkpoint.Call(4);
486 TEST_P(SharedMemoryDataConsumerHandleTest, RegisterClientWhenDataExists) {
487 Checkpoint checkpoint;
489 InSequence s;
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));
496 checkpoint.Call(0);
497 writer_->AddData(NewFixedData("Once "));
498 checkpoint.Call(1);
499 auto reader = handle_->ObtainReader(&client_);
500 checkpoint.Call(2);
501 RunPostedTasks();
502 checkpoint.Call(3);
505 TEST_P(SharedMemoryDataConsumerHandleTest, AddDataWhenClientIsRegistered) {
506 Checkpoint checkpoint;
507 char buffer[20];
508 Result result;
509 size_t size;
511 InSequence s;
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));
521 checkpoint.Call(0);
522 auto reader = handle_->ObtainReader(&client_);
523 checkpoint.Call(1);
524 writer_->AddData(NewFixedData("Once "));
525 checkpoint.Call(2);
526 writer_->AddData(NewFixedData("upon "));
527 checkpoint.Call(3);
528 result = reader->read(buffer, sizeof(buffer), kNone, &size);
529 EXPECT_EQ(kOk, result);
530 EXPECT_EQ(10u, size);
531 checkpoint.Call(4);
532 writer_->AddData(NewFixedData("a "));
533 checkpoint.Call(5);
536 TEST_P(SharedMemoryDataConsumerHandleTest, CloseWithClientAndData) {
537 Checkpoint checkpoint;
539 InSequence s;
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));
546 checkpoint.Call(0);
547 auto reader = handle_->ObtainReader(&client_);
548 checkpoint.Call(1);
549 writer_->AddData(NewFixedData("Once "));
550 checkpoint.Call(2);
551 writer_->Close();
552 checkpoint.Call(3);
555 TEST_P(SharedMemoryDataConsumerHandleTest, ReleaseReader) {
556 Checkpoint checkpoint;
558 InSequence s;
559 EXPECT_CALL(checkpoint, Call(0));
560 EXPECT_CALL(checkpoint, Call(1));
561 EXPECT_CALL(checkpoint, Call(2));
563 checkpoint.Call(0);
564 auto reader = handle_->ObtainReader(&client_);
565 checkpoint.Call(1);
566 reader.reset();
567 writer_->AddData(NewFixedData("Once "));
568 checkpoint.Call(2);
571 TEST_P(SharedMemoryDataConsumerHandleTest, TwoPhaseReadShouldWait) {
572 Result result;
573 const void* buffer = &result;
574 size_t size = 99;
576 auto reader = handle_->ObtainReader(nullptr);
577 result = reader->beginRead(&buffer, kNone, &size);
578 EXPECT_EQ(kShouldWait, result);
579 EXPECT_EQ(nullptr, buffer);
580 EXPECT_EQ(0u, size);
583 TEST_P(SharedMemoryDataConsumerHandleTest, TwoPhaseReadSimple) {
584 writer_->AddData(NewFixedData("Once "));
586 Result result;
587 const void* buffer = &result;
588 size_t size = 99;
590 auto reader = handle_->ObtainReader(nullptr);
591 result = reader->beginRead(&buffer, kNone, &size);
592 EXPECT_EQ(kOk, result);
593 EXPECT_EQ(5u, size);
594 EXPECT_EQ("Once ", ToString(buffer, 5));
596 reader->endRead(1);
598 result = reader->beginRead(&buffer, kNone, &size);
599 EXPECT_EQ(kOk, result);
600 EXPECT_EQ(4u, size);
601 EXPECT_EQ("nce ", ToString(buffer, 4));
603 reader->endRead(4);
605 result = reader->beginRead(&buffer, kNone, &size);
606 EXPECT_EQ(kShouldWait, result);
607 EXPECT_EQ(0u, size);
608 EXPECT_EQ(nullptr, buffer);
610 writer_->Close();
612 result = reader->beginRead(&buffer, kNone, &size);
613 EXPECT_EQ(kDone, result);
614 EXPECT_EQ(0u, size);
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>);
624 InSequence s;
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));
631 checkpoint.Call(0);
632 handle_.reset(new SharedMemoryDataConsumerHandle(
633 kApplyBackpressure,
634 base::Bind(&DestructionTrackingFunction::Call, on_clear), &writer_));
635 handle_.reset();
636 on_clear = nullptr;
637 checkpoint.Call(1);
638 RunPostedTasks();
639 checkpoint.Call(2);
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>);
648 InSequence s;
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));
657 checkpoint.Call(0);
658 handle_.reset(new SharedMemoryDataConsumerHandle(
659 kApplyBackpressure,
660 base::Bind(&DestructionTrackingFunction::Call, on_clear), &writer_));
661 auto reader = handle_->ObtainReader(nullptr);
662 handle_.reset();
663 on_clear = nullptr;
664 checkpoint.Call(1);
665 RunPostedTasks();
666 checkpoint.Call(2);
667 reader.reset();
668 checkpoint.Call(3);
669 RunPostedTasks();
670 checkpoint.Call(4);
673 TEST_P(SharedMemoryDataConsumerHandleTest, DoNotCallOnClearWhenDone) {
674 Checkpoint checkpoint;
675 scoped_refptr<DestructionTrackingFunction> on_clear(
676 new StrictMock<DestructionTrackingFunction>);
678 InSequence s;
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));
686 checkpoint.Call(0);
687 handle_.reset(new SharedMemoryDataConsumerHandle(
688 kApplyBackpressure,
689 base::Bind(&DestructionTrackingFunction::Call, on_clear), &writer_));
690 on_clear = nullptr;
691 checkpoint.Call(1);
692 writer_->Close();
693 checkpoint.Call(2);
694 handle_.reset();
695 checkpoint.Call(3);
696 RunPostedTasks();
697 checkpoint.Call(4);
700 TEST_P(SharedMemoryDataConsumerHandleTest, DoNotCallOnClearWhenErrored) {
701 Checkpoint checkpoint;
702 scoped_refptr<DestructionTrackingFunction> on_clear(
703 new StrictMock<DestructionTrackingFunction>);
705 InSequence s;
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));
713 checkpoint.Call(0);
714 handle_.reset(new SharedMemoryDataConsumerHandle(
715 kApplyBackpressure,
716 base::Bind(&DestructionTrackingFunction::Call, on_clear), &writer_));
717 on_clear = nullptr;
718 checkpoint.Call(1);
719 writer_->Fail();
720 checkpoint.Call(2);
721 handle_.reset();
722 checkpoint.Call(3);
723 RunPostedTasks();
724 checkpoint.Call(4);
727 TEST_P(SharedMemoryDataConsumerHandleTest, TwoPhaseReadWithMultipleData) {
728 writer_->AddData(NewFixedData("Once "));
729 writer_->AddData(NewFixedData("upon "));
731 Result result;
732 const void* buffer = &result;
733 size_t size = 99;
735 auto reader = handle_->ObtainReader(nullptr);
736 result = reader->beginRead(&buffer, kNone, &size);
737 EXPECT_EQ(kOk, result);
738 EXPECT_EQ(5u, size);
739 EXPECT_EQ("Once ", ToString(buffer, 5));
741 reader->endRead(1);
743 result = reader->beginRead(&buffer, kNone, &size);
744 EXPECT_EQ(kOk, result);
745 EXPECT_EQ(4u, size);
746 EXPECT_EQ("nce ", ToString(buffer, 4));
748 reader->endRead(4);
750 result = reader->beginRead(&buffer, kNone, &size);
751 EXPECT_EQ(kOk, result);
752 EXPECT_EQ(5u, size);
753 EXPECT_EQ("upon ", ToString(buffer, 5));
755 reader->endRead(5);
757 result = reader->beginRead(&buffer, kNone, &size);
758 EXPECT_EQ(kShouldWait, result);
759 EXPECT_EQ(0u, size);
760 EXPECT_EQ(nullptr, buffer);
762 writer_->Close();
764 result = reader->beginRead(&buffer, kNone, &size);
765 EXPECT_EQ(kDone, result);
766 EXPECT_EQ(0u, size);
767 EXPECT_EQ(nullptr, buffer);
770 TEST_P(SharedMemoryDataConsumerHandleTest, ErrorRead) {
771 Checkpoint checkpoint;
772 Result result;
773 char buffer[20] = {};
774 size_t read = 99;
775 auto reader = handle_->ObtainReader(nullptr);
777 writer_->Fail();
778 result = reader->read(buffer, sizeof(buffer), kNone, &read);
780 EXPECT_EQ(kUnexpectedError, result);
781 EXPECT_EQ(0u, read);
784 TEST_P(SharedMemoryDataConsumerHandleTest, ErrorTwoPhaseRead) {
785 Result result;
786 const void* pointer = &result;
787 size_t size = 99;
788 auto reader = handle_->ObtainReader(nullptr);
790 writer_->Fail();
791 result = reader->beginRead(&pointer, kNone, &size);
793 EXPECT_EQ(kUnexpectedError, result);
794 EXPECT_EQ(nullptr, pointer);
795 EXPECT_EQ(0u, size);
798 TEST_P(SharedMemoryDataConsumerHandleTest, FailWhileTwoPhaseReadIsInProgress) {
799 Result result;
800 const void* pointer = nullptr;
801 size_t size = 0;
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);
810 ASSERT_EQ(size, 5u);
812 writer_->Fail();
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;
830 InSequence s;
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));
837 checkpoint.Call(0);
838 auto reader = handle_->ObtainReader(&client_);
839 checkpoint.Call(1);
840 writer_->Fail();
841 checkpoint.Call(2);
842 RunPostedTasks();
843 checkpoint.Call(3);
846 TEST_P(SharedMemoryDataConsumerHandleTest, FailWithClientAndData) {
847 Checkpoint checkpoint;
849 InSequence s;
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));
858 checkpoint.Call(0);
859 auto reader = handle_->ObtainReader(&client_);
860 checkpoint.Call(1);
861 writer_->AddData(NewFixedData("Once "));
862 checkpoint.Call(2);
863 writer_->Fail();
864 checkpoint.Call(3);
865 RunPostedTasks();
866 checkpoint.Call(4);
869 TEST_P(SharedMemoryDataConsumerHandleTest, RecursiveErrorNotification) {
870 Checkpoint checkpoint;
872 InSequence s;
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));
881 checkpoint.Call(0);
882 auto reader = handle_->ObtainReader(&client_);
883 checkpoint.Call(1);
884 writer_->AddData(NewFixedData("Once "));
885 checkpoint.Call(2);
886 RunPostedTasks();
887 checkpoint.Call(3);
890 TEST(SharedMemoryDataConsumerHandleBackpressureTest, Read) {
891 base::MessageLoop loop;
892 char buffer[20];
893 Result result;
894 size_t size;
896 scoped_ptr<Writer> writer;
897 auto handle = make_scoped_ptr(
898 new SharedMemoryDataConsumerHandle(kApplyBackpressure, &writer));
899 scoped_refptr<Logger> logger(new Logger);
900 writer->AddData(
901 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
902 writer->AddData(
903 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger)));
904 writer->AddData(
905 make_scoped_ptr(new LoggingFixedReceivedData("data3", "a ", logger)));
906 writer->AddData(
907 make_scoped_ptr(new LoggingFixedReceivedData("data4", "time ", logger)));
909 auto reader = handle->ObtainReader(nullptr);
910 logger->Add("1");
911 result = reader->read(buffer, 2, kNone, &size);
912 EXPECT_EQ(kOk, result);
913 EXPECT_EQ(2u, size);
914 logger->Add("2");
915 result = reader->read(buffer, 5, kNone, &size);
916 EXPECT_EQ(kOk, result);
917 EXPECT_EQ(5u, size);
918 logger->Add("3");
919 result = reader->read(buffer, 6, kNone, &size);
920 EXPECT_EQ(kOk, result);
921 EXPECT_EQ(6u, size);
922 logger->Add("4");
924 EXPECT_EQ(
925 "1\n"
926 "2\n"
927 "data1 is destructed.\n"
928 "3\n"
929 "data2 is destructed.\n"
930 "data3 is destructed.\n"
931 "4\n",
932 logger->log());
935 TEST(SharedMemoryDataConsumerHandleBackpressureTest, CloseAndReset) {
936 base::MessageLoop loop;
937 char buffer[20];
938 Result result;
939 size_t size;
941 scoped_ptr<Writer> writer;
942 auto handle = make_scoped_ptr(
943 new SharedMemoryDataConsumerHandle(kApplyBackpressure, &writer));
944 scoped_refptr<Logger> logger(new Logger);
945 writer->AddData(
946 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
947 writer->AddData(
948 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger)));
949 writer->AddData(
950 make_scoped_ptr(new LoggingFixedReceivedData("data3", "a ", logger)));
952 auto reader = handle->ObtainReader(nullptr);
953 logger->Add("1");
954 result = reader->read(buffer, 2, kNone, &size);
955 EXPECT_EQ(kOk, result);
956 EXPECT_EQ(2u, size);
957 logger->Add("2");
958 writer->Close();
959 logger->Add("3");
960 handle.reset();
961 reader.reset();
962 logger->Add("4");
964 EXPECT_EQ(
965 "1\n"
966 "2\n"
967 "3\n"
968 "data1 is destructed.\n"
969 "data2 is destructed.\n"
970 "data3 is destructed.\n"
971 "4\n",
972 logger->log());
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);
982 logger->Add("1");
983 writer->AddData(
984 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
985 logger->Add("2");
986 writer->AddData(
987 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger)));
988 logger->Add("3");
990 EXPECT_EQ(
991 "1\n"
992 "data1 is destructed.\n"
993 "2\n"
994 "data2 is destructed.\n"
995 "3\n",
996 logger->log());
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())));
1012 logger->Add("1");
1013 writer_->AddData(
1014 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
1015 writer_->AddData(
1016 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger)));
1017 writer_->AddData(make_scoped_ptr(
1018 new LoggingFixedReceivedData("data3", "a time ", logger)));
1019 writer_->AddData(
1020 make_scoped_ptr(new LoggingFixedReceivedData("data4", "there ", logger)));
1021 writer_->AddData(
1022 make_scoped_ptr(new LoggingFixedReceivedData("data5", "was ", logger)));
1023 writer_->Close();
1024 logger->Add("2");
1026 run_loop.Run();
1027 t.Stop();
1029 EXPECT_EQ("Once upon a time there was ", operation->result());
1030 EXPECT_EQ(
1031 "1\n"
1032 "2\n"
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",
1038 logger->log());
1041 INSTANTIATE_TEST_CASE_P(SharedMemoryDataConsumerHandleTest,
1042 SharedMemoryDataConsumerHandleTest,
1043 ::testing::Values(kApplyBackpressure,
1044 kDoNotApplyBackpressure));
1045 } // namespace
1047 } // namespace content