| OLD | NEW |
| (Empty) | |
| 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. |
| 4 |
| 5 #ifndef DataConsumerHandleTestUtil_h |
| 6 #define DataConsumerHandleTestUtil_h |
| 7 |
| 8 #include "modules/fetch/DataConsumerHandleUtil.h" |
| 9 #include "modules/fetch/FetchDataConsumerHandle.h" |
| 10 #include "platform/Task.h" |
| 11 #include "platform/ThreadSafeFunctional.h" |
| 12 #include "platform/heap/Handle.h" |
| 13 #include "public/platform/Platform.h" |
| 14 #include "public/platform/WebDataConsumerHandle.h" |
| 15 #include "public/platform/WebThread.h" |
| 16 #include "public/platform/WebTraceLocation.h" |
| 17 #include "public/platform/WebWaitableEvent.h" |
| 18 #include "wtf/Locker.h" |
| 19 |
| 20 #include <gmock/gmock.h> |
| 21 #include <gtest/gtest.h> |
| 22 |
| 23 namespace blink { |
| 24 |
| 25 class DataConsumerHandleTestUtil { |
| 26 public: |
| 27 class NoopClient final : public WebDataConsumerHandle::Client { |
| 28 public: |
| 29 void didGetReadable() override { } |
| 30 }; |
| 31 |
| 32 class ThreadingTestBase : public ThreadSafeRefCounted<ThreadingTestBase> { |
| 33 public: |
| 34 class Context : public ThreadSafeRefCounted<Context> { |
| 35 public: |
| 36 static PassRefPtr<Context> create() { return adoptRef(new Context);
} |
| 37 void recordAttach(const String& handle) |
| 38 { |
| 39 MutexLocker locker(m_loggingMutex); |
| 40 m_result.append("A reader is attached to " + handle + " on " + c
urrentThreadName() + ".\n"); |
| 41 } |
| 42 void recordDetach(const String& handle) |
| 43 { |
| 44 MutexLocker locker(m_loggingMutex); |
| 45 m_result.append("A reader is detached from " + handle + " on " +
currentThreadName() + ".\n"); |
| 46 } |
| 47 |
| 48 const String& result() |
| 49 { |
| 50 MutexLocker locker(m_loggingMutex); |
| 51 return m_result; |
| 52 } |
| 53 WebThread* readingThread() { return m_readingThread.get(); } |
| 54 WebThread* updatingThread() { return m_updatingThread.get(); } |
| 55 |
| 56 private: |
| 57 Context() |
| 58 : m_readingThread(adoptPtr(Platform::current()->createThread("re
ading thread"))) |
| 59 , m_updatingThread(adoptPtr(Platform::current()->createThread("u
pdating thread"))) |
| 60 { |
| 61 } |
| 62 String currentThreadName() |
| 63 { |
| 64 if (m_readingThread->isCurrentThread()) |
| 65 return "the reading thread"; |
| 66 if (m_updatingThread->isCurrentThread()) |
| 67 return "the updating thread"; |
| 68 return "an unknown thread"; |
| 69 } |
| 70 |
| 71 OwnPtr<WebThread> m_readingThread; |
| 72 OwnPtr<WebThread> m_updatingThread; |
| 73 Mutex m_loggingMutex; |
| 74 String m_result; |
| 75 }; |
| 76 |
| 77 class ReaderImpl final : public WebDataConsumerHandle::Reader { |
| 78 public: |
| 79 ReaderImpl(const String& name, PassRefPtr<Context> context) : m_name
(name.isolatedCopy()), m_context(context) |
| 80 { |
| 81 m_context->recordAttach(m_name.isolatedCopy()); |
| 82 } |
| 83 ~ReaderImpl() override { m_context->recordDetach(m_name.isolatedCopy
()); } |
| 84 |
| 85 using Result = WebDataConsumerHandle::Result; |
| 86 using Flags = WebDataConsumerHandle::Flags; |
| 87 Result read(void*, size_t, Flags, size_t*) override { return WebData
ConsumerHandle::ShouldWait; } |
| 88 Result beginRead(const void**, Flags, size_t*) override { return Web
DataConsumerHandle::ShouldWait; } |
| 89 Result endRead(size_t) override { return WebDataConsumerHandle::Unex
pectedError; } |
| 90 |
| 91 private: |
| 92 const String m_name; |
| 93 RefPtr<Context> m_context; |
| 94 }; |
| 95 class DataConsumerHandle final : public WebDataConsumerHandle { |
| 96 public: |
| 97 DataConsumerHandle(const String& name, PassRefPtr<Context> context)
: m_name(name.isolatedCopy()), m_context(context) { } |
| 98 |
| 99 private: |
| 100 Reader* obtainReaderInternal(Client*) { return new ReaderImpl(m_name
, m_context); } |
| 101 const String m_name; |
| 102 RefPtr<Context> m_context; |
| 103 }; |
| 104 |
| 105 void resetReader() { m_reader = nullptr; } |
| 106 void signalDone() { m_waitableEvent->signal(); } |
| 107 const String& result() { return m_context->result(); } |
| 108 WebThread* readingThread() { return m_context->readingThread(); } |
| 109 WebThread* updatingThread() { return m_context->updatingThread(); } |
| 110 |
| 111 protected: |
| 112 RefPtr<Context> m_context; |
| 113 OwnPtr<WebDataConsumerHandle::Reader> m_reader; |
| 114 OwnPtr<WebWaitableEvent> m_waitableEvent; |
| 115 NoopClient m_client; |
| 116 }; |
| 117 |
| 118 class ThreadingHandleNotificationTest : public ThreadingTestBase, public Web
DataConsumerHandle::Client { |
| 119 public: |
| 120 using Self = ThreadingHandleNotificationTest; |
| 121 void run(PassOwnPtr<WebDataConsumerHandle> handle) |
| 122 { |
| 123 m_context = Context::create(); |
| 124 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent(
)); |
| 125 m_handle = handle; |
| 126 |
| 127 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
obtainReader, this))); |
| 128 |
| 129 m_waitableEvent->wait(); |
| 130 } |
| 131 |
| 132 private: |
| 133 void obtainReader() |
| 134 { |
| 135 m_reader = m_handle->obtainReader(this); |
| 136 } |
| 137 void didGetReadable() override |
| 138 { |
| 139 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
resetReader, this))); |
| 140 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
signalDone, this))); |
| 141 } |
| 142 |
| 143 OwnPtr<WebDataConsumerHandle> m_handle; |
| 144 }; |
| 145 |
| 146 class ThreadingHandleNoNotificationTest : public ThreadingTestBase, public W
ebDataConsumerHandle::Client { |
| 147 public: |
| 148 using Self = ThreadingHandleNoNotificationTest; |
| 149 void run(PassOwnPtr<WebDataConsumerHandle> handle) |
| 150 { |
| 151 m_context = Context::create(); |
| 152 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent(
)); |
| 153 m_handle = handle; |
| 154 |
| 155 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
obtainReader, this))); |
| 156 |
| 157 m_waitableEvent->wait(); |
| 158 } |
| 159 |
| 160 private: |
| 161 void obtainReader() |
| 162 { |
| 163 m_reader = m_handle->obtainReader(this); |
| 164 m_reader = nullptr; |
| 165 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
signalDone, this))); |
| 166 } |
| 167 void didGetReadable() override |
| 168 { |
| 169 ASSERT_NOT_REACHED(); |
| 170 } |
| 171 |
| 172 OwnPtr<WebDataConsumerHandle> m_handle; |
| 173 }; |
| 174 }; |
| 175 |
| 176 } // namespace blink |
| 177 |
| 178 #endif // DataConsumerHandleTestUtil_h |
| OLD | NEW |