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

Side by Side Diff: Source/modules/fetch/CompositeDataConsumerHandleTest.cpp

Issue 1162043007: Introduce CompositeDataConsumerHandle. (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 unified diff | Download patch
OLDNEW
(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 #include "config.h"
6 #include "modules/fetch/CompositeDataConsumerHandle.h"
7
8 #include "platform/Task.h"
9 #include "platform/ThreadSafeFunctional.h"
10 #include "platform/heap/Handle.h"
11 #include "public/platform/Platform.h"
12 #include "public/platform/WebThread.h"
13 #include "public/platform/WebTraceLocation.h"
14 #include "public/platform/WebWaitableEvent.h"
15 #include "wtf/Locker.h"
16
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19
20 namespace blink {
21
22 namespace {
23
24 using Result = WebDataConsumerHandle::Result;
25 using Flags = WebDataConsumerHandle::Flags;
26 using ::testing::InSequence;
27 using ::testing::Return;
28 using ::testing::StrictMock;
29 using Checkpoint = StrictMock<::testing::MockFunction<void(int)>>;
30
31 const Result kShouldWait = WebDataConsumerHandle::ShouldWait;
32 const Result kDone = WebDataConsumerHandle::Done;
33 const Result kOk = WebDataConsumerHandle::Ok;
34 const Result kUnexpectedError = WebDataConsumerHandle::UnexpectedError;
35 const Flags kNone = WebDataConsumerHandle::FlagNone;
36
37 class NoopClient final : public WebDataConsumerHandle::Client {
38 public:
39 void didGetReadable() override { }
40 };
41
42 class MockHandle : public WebDataConsumerHandle {
43 public:
44 static PassOwnPtr<StrictMock<MockHandle>> create() { return adoptPtr(new Str ictMock<MockHandle>); }
45
46 MOCK_METHOD4(read, Result(void*, size_t, Flags, size_t*));
47 MOCK_METHOD3(beginRead, Result(const void**, Flags, size_t*));
48 MOCK_METHOD1(endRead, Result(size_t));
49 MOCK_METHOD1(registerClient, void(Client*));
50 MOCK_METHOD0(unregisterClient, void());
51 };
52
53 class ThreadingTestBase {
54 public:
55 class DataConsumerHandle final : public WebDataConsumerHandle {
56 public:
57 DataConsumerHandle(const String& name, ThreadingTestBase* test) : m_name (name.isolatedCopy()), m_test(test) { }
58 Result read(void*, size_t, Flags, size_t*) override { return ShouldWait; }
59 Result beginRead(const void**, Flags, size_t*) override { return ShouldW ait; }
60 Result endRead(size_t) override { return ShouldWait; }
61 void registerClient(Client*) override
62 {
63 m_test->record(m_name, "registerClient");
64 }
65 void unregisterClient() override
66 {
67 m_test->record(m_name, "unregisterClient");
68 }
69 private:
70 const String m_name;
71 ThreadingTestBase* m_test;
72 };
73
74 void record(const String& instanceName, const String& functionName)
75 {
76 String threadName;
77 if (m_readingThread->isCurrentThread()) {
78 threadName = "the reading thread";
79 } else if (m_updatingThread->isCurrentThread()) {
80 threadName = "the updating thread";
81 } else {
82 threadName = "an unknown thread";
83 }
84 MutexLocker locker(m_loggingMutex);
85 m_result.append(instanceName.isolatedCopy() + "->" + functionName.isolat edCopy() + " is called on " + threadName + ".\n");
86 }
87 const String& result()
88 {
89 MutexLocker locker(m_loggingMutex);
90 return m_result;
91 }
92
93 static void signalDone(ThreadingTestBase* test)
94 {
95 test->m_waitableEvent->signal();
96 }
97
98 protected:
99 OwnPtr<WebThread> m_readingThread;
100 OwnPtr<WebThread> m_updatingThread;
101 OwnPtr<CompositeDataConsumerHandle> m_handle;
102 NoopClient m_client;
103 OwnPtr<WebWaitableEvent> m_waitableEvent;
104 Mutex m_loggingMutex;
105 String m_result;
106 };
107
108 class ThreadingRegistrationTest : public ThreadingTestBase {
109 public:
110 void run()
111 {
112 m_readingThread = adoptPtr(Platform::current()->createThread("reading th read"));
113 m_updatingThread = adoptPtr(Platform::current()->createThread("updating thread"));
114 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent());
115 m_handle = CompositeDataConsumerHandle::create(adoptPtr(new DataConsumer Handle("handle1", this)));
116
117 m_readingThread->postTask(FROM_HERE, new Task(threadSafeBind(&registerCl ient, AllowCrossThreadAccess(this))));
118
119 m_waitableEvent->wait();
120 }
121
122 private:
123 static void registerClient(ThreadingRegistrationTest* test)
124 {
125 test->m_handle->registerClient(&test->m_client);
126 test->m_updatingThread->postTask(FROM_HERE, new Task(threadSafeBind(&upd ate, AllowCrossThreadAccess(test))));
127 }
128 static void update(ThreadingRegistrationTest* test)
129 {
130 test->m_handle->update(adoptPtr(new DataConsumerHandle("handle2", test)) );
131 test->m_readingThread->postTask(FROM_HERE, new Task(threadSafeBind(&sign alDone, AllowCrossThreadAccess(test))));
132 }
133 };
134
135 class ThreadingRegistrationDeleteTest : public ThreadingTestBase {
136 public:
137 void run()
138 {
139 m_readingThread = adoptPtr(Platform::current()->createThread("reading th read"));
140 m_updatingThread = adoptPtr(Platform::current()->createThread("updating thread"));
141 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent());
142 m_handle = CompositeDataConsumerHandle::create(adoptPtr(new DataConsumer Handle("handle1", this)));
143
144 m_readingThread->postTask(FROM_HERE, new Task(threadSafeBind(&registerCl ient, AllowCrossThreadAccess(this))));
145
146 m_waitableEvent->wait();
147 }
148
149 private:
150 static void registerClient(ThreadingRegistrationDeleteTest* test)
151 {
152 test->m_handle->registerClient(&test->m_client);
153 test->m_updatingThread->postTask(FROM_HERE, new Task(threadSafeBind(&upd ate, AllowCrossThreadAccess(test))));
154 }
155 static void update(ThreadingRegistrationDeleteTest* test)
156 {
157 test->m_handle->update(adoptPtr(new DataConsumerHandle("handle2", test)) );
158 test->m_handle.clear();
159 test->m_readingThread->postTask(FROM_HERE, new Task(threadSafeBind(&sign alDone, AllowCrossThreadAccess(test))));
160 }
161 };
162
163 TEST(CompositeDataConsumerHandleTest, CreateWaitingHandle)
164 {
165 char buffer[20];
166 const void* p = nullptr;
167 size_t size = 0;
168 OwnPtr<WebDataConsumerHandle> handle = CompositeDataConsumerHandle::createWa itingHandle();
169
170 EXPECT_EQ(kShouldWait, handle->read(buffer, sizeof(buffer), kNone, &size));
171 EXPECT_EQ(kShouldWait, handle->beginRead(&p, kNone, &size));
172 EXPECT_EQ(kUnexpectedError, handle->endRead(99));
173 }
174
175 TEST(CompositeDataConsumerHandleTest, CreateDoneHandle)
176 {
177 char buffer[20];
178 const void* p = nullptr;
179 size_t size = 0;
180 OwnPtr<WebDataConsumerHandle> handle = CompositeDataConsumerHandle::createDo neHandle();
181
182 EXPECT_EQ(kDone, handle->read(buffer, sizeof(buffer), kNone, &size));
183 EXPECT_EQ(kDone, handle->beginRead(&p, kNone, &size));
184 EXPECT_EQ(kUnexpectedError, handle->endRead(99));
185 }
186
187 TEST(CompositeDataConsumerHandleTest, Read)
188 {
189 char buffer[20];
190 size_t size = 0;
191 Checkpoint checkpoint;
192
193 OwnPtr<MockHandle> handle1 = MockHandle::create();
194 OwnPtr<MockHandle> handle2 = MockHandle::create();
195
196 InSequence s;
197 EXPECT_CALL(checkpoint, Call(0));
198 EXPECT_CALL(*handle1, read(buffer, sizeof(buffer), kNone, &size)).WillOnce(R eturn(kOk));
199 EXPECT_CALL(checkpoint, Call(1));
200 EXPECT_CALL(checkpoint, Call(2));
201 EXPECT_CALL(*handle2, read(buffer, sizeof(buffer), kNone, &size)).WillOnce(R eturn(kOk));
202 EXPECT_CALL(checkpoint, Call(3));
203
204 OwnPtr<CompositeDataConsumerHandle> handle = CompositeDataConsumerHandle::cr eate(handle1.release());
205 checkpoint.Call(0);
206 EXPECT_EQ(kOk, handle->read(buffer, sizeof(buffer), kNone, &size));
207 checkpoint.Call(1);
208 handle->update(handle2.release());
209 checkpoint.Call(2);
210 EXPECT_EQ(kOk, handle->read(buffer, sizeof(buffer), kNone, &size));
211 checkpoint.Call(3);
212 }
213
214 TEST(CompositeDataConsumerHandleTest, TwoPhaseRead)
215 {
216 const void* p = nullptr;
217 size_t size = 0;
218 Checkpoint checkpoint;
219
220 OwnPtr<MockHandle> handle1 = MockHandle::create();
221 OwnPtr<MockHandle> handle2 = MockHandle::create();
222
223 InSequence s;
224 EXPECT_CALL(checkpoint, Call(0));
225 EXPECT_CALL(*handle1, beginRead(&p, kNone, &size)).WillOnce(Return(kOk));
226 EXPECT_CALL(checkpoint, Call(1));
227 EXPECT_CALL(*handle1, endRead(0)).WillOnce(Return(kOk));
228 EXPECT_CALL(checkpoint, Call(2));
229 EXPECT_CALL(checkpoint, Call(3));
230 EXPECT_CALL(*handle2, beginRead(&p, kNone, &size)).WillOnce(Return(kOk));
231 EXPECT_CALL(checkpoint, Call(4));
232 EXPECT_CALL(*handle2, endRead(0)).WillOnce(Return(kOk));
233 EXPECT_CALL(checkpoint, Call(5));
234
235 OwnPtr<CompositeDataConsumerHandle> handle = CompositeDataConsumerHandle::cr eate(handle1.release());
236 checkpoint.Call(0);
237 EXPECT_EQ(kOk, handle->beginRead(&p, kNone, &size));
238 checkpoint.Call(1);
239 EXPECT_EQ(kOk, handle->endRead(0));
240 checkpoint.Call(2);
241 handle->update(handle2.release());
242 checkpoint.Call(3);
243 EXPECT_EQ(kOk, handle->beginRead(&p, kNone, &size));
244 checkpoint.Call(4);
245 EXPECT_EQ(kOk, handle->endRead(0));
246 checkpoint.Call(5);
247 }
248
249 TEST(CompositeDataConsumerHandleTest, ClientRegistration)
250 {
251 Checkpoint checkpoint;
252
253 OwnPtr<MockHandle> handle1 = MockHandle::create();
254 OwnPtr<MockHandle> handle2 = MockHandle::create();
255 OwnPtr<MockHandle> handle3 = MockHandle::create();
256 NoopClient client;
257
258 InSequence s;
259 EXPECT_CALL(checkpoint, Call(0));
260 EXPECT_CALL(*handle1, registerClient(&client));
261 EXPECT_CALL(checkpoint, Call(1));
262 EXPECT_CALL(*handle1, unregisterClient());
263 EXPECT_CALL(checkpoint, Call(2));
264 EXPECT_CALL(*handle1, registerClient(&client));
265 EXPECT_CALL(checkpoint, Call(3));
266 EXPECT_CALL(*handle1, unregisterClient());
267 EXPECT_CALL(*handle2, registerClient(&client));
268 EXPECT_CALL(checkpoint, Call(4));
269 EXPECT_CALL(*handle2, unregisterClient());
270 EXPECT_CALL(checkpoint, Call(5));
271 EXPECT_CALL(checkpoint, Call(6));
272
273 OwnPtr<CompositeDataConsumerHandle> handle = CompositeDataConsumerHandle::cr eate(handle1.release());
274 checkpoint.Call(0);
275 handle->registerClient(&client);
276 checkpoint.Call(1);
277 handle->unregisterClient();
278 checkpoint.Call(2);
279 handle->registerClient(&client);
280 checkpoint.Call(3);
281 handle->update(handle2.release());
282 checkpoint.Call(4);
283 handle->unregisterClient();
284 checkpoint.Call(5);
285 handle->update(handle3.release());
286 checkpoint.Call(6);
287 }
288
289 TEST(CompositeDataConsumerHandleTest, RegisterClientOnDifferentThreads)
290 {
291 ThreadingRegistrationTest test;
292 test.run();
293
294 EXPECT_EQ(
295 "handle1->registerClient is called on the reading thread.\n"
296 "handle1->unregisterClient is called on the reading thread.\n"
297 "handle2->registerClient is called on the reading thread.\n",
298 test.result());
299 }
300
301 TEST(CompositeDataConsumerHandleTest, DeleteHandleWhileUpdating)
302 {
303 ThreadingRegistrationDeleteTest test;
304 test.run();
305
306 EXPECT_EQ(
307 "handle1->registerClient is called on the reading thread.\n",
308 test.result());
309 }
310
311 } // namespace
312
313 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698