Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1581)

Unified Diff: Source/modules/fetch/DataConsumerHandleTestUtil.h

Issue 1210693002: Move Handle in TeeTest and MockFetchDataLoaderClient to TestUtil (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/modules/fetch/DataConsumerHandleTestUtil.h
diff --git a/Source/modules/fetch/DataConsumerHandleTestUtil.h b/Source/modules/fetch/DataConsumerHandleTestUtil.h
index b60d2e6c7b22517ddb79f91d901acb83176d9dcd..6acf0677d6a8ca8d1c85869cc81d3e5d00e439dd 100644
--- a/Source/modules/fetch/DataConsumerHandleTestUtil.h
+++ b/Source/modules/fetch/DataConsumerHandleTestUtil.h
@@ -10,6 +10,7 @@
#include "gin/public/isolate_holder.h"
#include "modules/fetch/DataConsumerHandleUtil.h"
#include "modules/fetch/FetchDataConsumerHandle.h"
+#include "modules/fetch/FetchDataLoader.h"
#include "platform/Task.h"
#include "platform/ThreadSafeFunctional.h"
#include "platform/WebThreadSupportingGC.h"
@@ -211,6 +212,226 @@ public:
OwnPtr<WebDataConsumerHandle> m_handle;
};
+
+ class MockFetchDataLoaderClient : public GarbageCollectedFinalized<MockFetchDataLoaderClient>, public FetchDataLoader::Client {
+ USING_GARBAGE_COLLECTED_MIXIN(MockFetchDataLoaderClient);
+ public:
+ static ::testing::StrictMock<MockFetchDataLoaderClient>* create() { return new ::testing::StrictMock<MockFetchDataLoaderClient>; }
+
+ DEFINE_INLINE_VIRTUAL_TRACE()
+ {
+ FetchDataLoader::Client::trace(visitor);
+ }
+
+ MOCK_METHOD1(didFetchDataLoadedBlobHandleMock, void(RefPtr<BlobDataHandle>));
+ MOCK_METHOD1(didFetchDataLoadedArrayBufferMock, void(RefPtr<DOMArrayBuffer>));
+ MOCK_METHOD1(didFetchDataLoadedString, void(const String&));
+ MOCK_METHOD0(didFetchDataLoadFailed, void());
+
+ // In mock methods we use RefPtr<> rather than PassRefPtr<>.
+ void didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer) override
+ {
+ didFetchDataLoadedArrayBufferMock(arrayBuffer);
+ }
+ void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle) override
+ {
+ didFetchDataLoadedBlobHandleMock(blobDataHandle);
+ }
+ };
+
+ class Command final {
+ public:
+ enum Name {
+ Data,
+ Done,
+ Error,
+ Wait,
+ };
+
+ Command(Name name) : m_name(name) { }
+ Command(Name name, const Vector<char>& body) : m_name(name), m_body(body) { }
+ Command(Name name, const char* body, size_t size) : m_name(name)
+ {
+ m_body.append(body, size);
+ }
+ Command(Name name, const char* body) : Command(name, body, strlen(body)) { }
+ Name name() const { return m_name; }
+ const Vector<char>& body() const { return m_body; }
+
+ private:
+ const Name m_name;
+ Vector<char> m_body;
+ };
+
+ // ReplayingHandle stores commands via |add| and replays the stored commends when read.
+ class ReplayingHandle final : public WebDataConsumerHandle {
+ public:
+ static PassOwnPtr<ReplayingHandle> create() { return adoptPtr(new ReplayingHandle()); }
+ ~ReplayingHandle();
+
+ // Add a command to this handle. This function must be called on the
+ // creator thread. This function must be called BEFORE any reader is
+ // obtained.
+ void add(const Command&);
+
+ class Context final : public ThreadSafeRefCounted<Context> {
+ public:
+ static PassRefPtr<Context> create() { return adoptRef(new Context); }
+
+ // This function cannot be called after creating a tee.
+ void add(const Command& command)
yhirano 2015/06/25 04:31:03 Please move function definitions to the cpp file.
hiroshige 2015/06/25 05:33:57 Done.
+ {
+ MutexLocker locker(m_mutex);
+ m_commands.append(command);
+ }
+
+ void attachReader(WebDataConsumerHandle::Client* client)
+ {
+ MutexLocker locker(m_mutex);
+ ASSERT(!m_readerThread);
+ ASSERT(!m_client);
+ m_readerThread = Platform::current()->currentThread();
+ m_client = client;
+
+ if (m_client && !(isEmpty() && m_result == ShouldWait))
+ notify();
+ }
+ void detachReader()
+ {
+ MutexLocker locker(m_mutex);
+ ASSERT(m_readerThread && m_readerThread->isCurrentThread());
+ m_readerThread = nullptr;
+ m_client = nullptr;
+ if (!m_isHandleAttached)
+ m_detached->signal();
+ }
+
+ void detachHandle()
+ {
+ MutexLocker locker(m_mutex);
+ m_isHandleAttached = false;
+ if (!m_readerThread)
+ m_detached->signal();
+ }
+
+ Result beginRead(const void** buffer, Flags, size_t* available)
+ {
+ MutexLocker locker(m_mutex);
+ *buffer = nullptr;
+ *available = 0;
+ if (isEmpty())
+ return m_result;
+
+ const Command& command = top();
+ Result result = Ok;
+ switch (command.name()) {
+ case Command::Data: {
+ auto& body = command.body();
+ *available = body.size() - offset();
+ *buffer = body.data() + offset();
+ result = Ok;
+ break;
+ }
+ case Command::Done:
+ m_result = result = Done;
+ consume(0);
+ break;
+ case Command::Wait:
+ consume(0);
+ result = ShouldWait;
+ notify();
+ break;
+ case Command::Error:
+ m_result = result = UnexpectedError;
+ consume(0);
+ break;
+ }
+ return result;
+ }
+ Result endRead(size_t readSize)
+ {
+ MutexLocker locker(m_mutex);
+ consume(readSize);
+ return Ok;
+ }
+
+ WebWaitableEvent* detached() { return m_detached.get(); }
+
+ private:
+ Context()
+ : m_offset(0)
+ , m_readerThread(nullptr)
+ , m_client(nullptr)
+ , m_result(ShouldWait)
+ , m_isHandleAttached(true)
+ , m_detached(adoptPtr(Platform::current()->createWaitableEvent()))
+ {
+ }
+
+ bool isEmpty() const { return m_commands.isEmpty(); }
+ const Command& top()
+ {
+ ASSERT(!isEmpty());
+ return m_commands.first();
+ }
+
+ void consume(size_t size)
+ {
+ ASSERT(!isEmpty());
+ ASSERT(size + m_offset <= top().body().size());
+ bool fullyConsumed = (size + m_offset >= top().body().size());
+ if (fullyConsumed) {
+ m_offset = 0;
+ m_commands.removeFirst();
+ } else {
+ m_offset += size;
+ }
+ }
+
+ size_t offset() const { return m_offset; }
+
+ void notify()
+ {
+ if (!m_client)
+ return;
+ ASSERT(m_readerThread);
+ m_readerThread->postTask(FROM_HERE, new Task(threadSafeBind(&Context::notifyInternal, this)));
+ }
+
+ void notifyInternal()
+ {
+ {
+ MutexLocker locker(m_mutex);
+ if (!m_client || !m_readerThread->isCurrentThread()) {
+ // There is no client, or a new reader is attached.
+ return;
+ }
+ }
+ // The reading thread is the current thread.
+ m_client->didGetReadable();
+ }
+
+ Deque<Command> m_commands;
+ size_t m_offset;
+ WebThread* m_readerThread;
+ Client* m_client;
+ Result m_result;
+ bool m_isHandleAttached;
+ Mutex m_mutex;
+ OwnPtr<WebWaitableEvent> m_detached;
+ };
+
+ Context* context() { return m_context.get(); }
+
+ private:
+ class ReaderImpl;
+
+ ReplayingHandle();
+ Reader* obtainReaderInternal(Client*) override;
+
+ RefPtr<Context> m_context;
+ };
+
};
} // namespace blink
« no previous file with comments | « no previous file | Source/modules/fetch/DataConsumerHandleTestUtil.cpp » ('j') | Source/modules/fetch/DataConsumerTeeTest.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698