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

Side by Side Diff: third_party/WebKit/Source/modules/fetch/DataConsumerTeeTest.cpp

Issue 2277143002: Use BytesConsumer in BodyStreamBuffer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bytes-consumer-tee
Patch Set: rebase Created 4 years, 3 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 "modules/fetch/DataConsumerTee.h"
6
7 #include "core/testing/DummyPageHolder.h"
8 #include "core/testing/NullExecutionContext.h"
9 #include "modules/fetch/DataConsumerHandleTestUtil.h"
10 #include "platform/CrossThreadFunctional.h"
11 #include "platform/WaitableEvent.h"
12 #include "platform/WebThreadSupportingGC.h"
13 #include "public/platform/Platform.h"
14 #include "public/platform/WebThread.h"
15 #include "public/platform/WebTraceLocation.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "wtf/PassRefPtr.h"
18 #include "wtf/PtrUtil.h"
19 #include "wtf/RefPtr.h"
20 #include <memory>
21 #include <string.h>
22 #include <v8.h>
23
24 namespace blink {
25 namespace {
26
27 using ::testing::ByMove;
28 using ::testing::InSequence;
29 using ::testing::Return;
30 using ::testing::StrictMock;
31 using ::testing::_;
32 using Checkpoint = StrictMock<::testing::MockFunction<void(int)>>;
33
34 using Result = WebDataConsumerHandle::Result;
35 using Thread = DataConsumerHandleTestUtil::Thread;
36 const Result kDone = WebDataConsumerHandle::Done;
37 const Result kUnexpectedError = WebDataConsumerHandle::UnexpectedError;
38 const FetchDataConsumerHandle::Reader::BlobSizePolicy kDisallowBlobWithInvalidSi ze = FetchDataConsumerHandle::Reader::DisallowBlobWithInvalidSize;
39 const FetchDataConsumerHandle::Reader::BlobSizePolicy kAllowBlobWithInvalidSize = FetchDataConsumerHandle::Reader::AllowBlobWithInvalidSize;
40
41 using Command = DataConsumerHandleTestUtil::Command;
42 using Handle = DataConsumerHandleTestUtil::ReplayingHandle;
43 using HandleReader = DataConsumerHandleTestUtil::HandleReader;
44 using HandleTwoPhaseReader = DataConsumerHandleTestUtil::HandleTwoPhaseReader;
45 using HandleReadResult = DataConsumerHandleTestUtil::HandleReadResult;
46 using MockFetchDataConsumerHandle = DataConsumerHandleTestUtil::MockFetchDataCon sumerHandle;
47 using MockFetchDataConsumerReader = DataConsumerHandleTestUtil::MockFetchDataCon sumerReader;
48 template <typename T>
49 using HandleReaderRunner = DataConsumerHandleTestUtil::HandleReaderRunner<T>;
50
51 String toString(const Vector<char>& v)
52 {
53 return String(v.data(), v.size());
54 }
55
56 template<typename Handle>
57 class TeeCreationThread {
58 public:
59 void run(std::unique_ptr<Handle> src, std::unique_ptr<Handle>* dest1, std::u nique_ptr<Handle>* dest2)
60 {
61 m_thread = wrapUnique(new Thread("src thread", Thread::WithExecutionCont ext));
62 m_waitableEvent = wrapUnique(new WaitableEvent());
63 m_thread->thread()->postTask(BLINK_FROM_HERE, crossThreadBind(&TeeCreati onThread<Handle>::runInternal, crossThreadUnretained(this), passed(std::move(src )), crossThreadUnretained(dest1), crossThreadUnretained(dest2)));
64 m_waitableEvent->wait();
65 }
66
67 Thread* getThread() { return m_thread.get(); }
68
69 private:
70 void runInternal(std::unique_ptr<Handle> src, std::unique_ptr<Handle>* dest1 , std::unique_ptr<Handle>* dest2)
71 {
72 DataConsumerTee::create(m_thread->getExecutionContext(), std::move(src), dest1, dest2);
73 m_waitableEvent->signal();
74 }
75
76 std::unique_ptr<Thread> m_thread;
77 std::unique_ptr<WaitableEvent> m_waitableEvent;
78 };
79
80 TEST(DataConsumerTeeTest, CreateDone)
81 {
82 std::unique_ptr<Handle> src(Handle::create());
83 std::unique_ptr<WebDataConsumerHandle> dest1, dest2;
84
85 src->add(Command(Command::Done));
86
87 std::unique_ptr<TeeCreationThread<WebDataConsumerHandle>> t = wrapUnique(new TeeCreationThread<WebDataConsumerHandle>());
88 t->run(std::move(src), &dest1, &dest2);
89
90 ASSERT_TRUE(dest1);
91 ASSERT_TRUE(dest2);
92
93 HandleReaderRunner<HandleReader> r1(std::move(dest1)), r2(std::move(dest2));
94
95 std::unique_ptr<HandleReadResult> res1 = r1.wait();
96 std::unique_ptr<HandleReadResult> res2 = r2.wait();
97
98 EXPECT_EQ(kDone, res1->result());
99 EXPECT_EQ(0u, res1->data().size());
100 EXPECT_EQ(kDone, res2->result());
101 EXPECT_EQ(0u, res2->data().size());
102 }
103
104 TEST(DataConsumerTeeTest, Read)
105 {
106 std::unique_ptr<Handle> src(Handle::create());
107 std::unique_ptr<WebDataConsumerHandle> dest1, dest2;
108
109 src->add(Command(Command::Wait));
110 src->add(Command(Command::Data, "hello, "));
111 src->add(Command(Command::Wait));
112 src->add(Command(Command::Data, "world"));
113 src->add(Command(Command::Wait));
114 src->add(Command(Command::Wait));
115 src->add(Command(Command::Done));
116
117 std::unique_ptr<TeeCreationThread<WebDataConsumerHandle>> t = wrapUnique(new TeeCreationThread<WebDataConsumerHandle>());
118 t->run(std::move(src), &dest1, &dest2);
119
120 ASSERT_TRUE(dest1);
121 ASSERT_TRUE(dest2);
122
123 HandleReaderRunner<HandleReader> r1(std::move(dest1));
124 HandleReaderRunner<HandleReader> r2(std::move(dest2));
125
126 std::unique_ptr<HandleReadResult> res1 = r1.wait();
127 std::unique_ptr<HandleReadResult> res2 = r2.wait();
128
129 EXPECT_EQ(kDone, res1->result());
130 EXPECT_EQ("hello, world", toString(res1->data()));
131
132 EXPECT_EQ(kDone, res2->result());
133 EXPECT_EQ("hello, world", toString(res2->data()));
134 }
135
136 TEST(DataConsumerTeeTest, TwoPhaseRead)
137 {
138 std::unique_ptr<Handle> src(Handle::create());
139 std::unique_ptr<WebDataConsumerHandle> dest1, dest2;
140
141 src->add(Command(Command::Wait));
142 src->add(Command(Command::Data, "hello, "));
143 src->add(Command(Command::Wait));
144 src->add(Command(Command::Wait));
145 src->add(Command(Command::Wait));
146 src->add(Command(Command::Data, "world"));
147 src->add(Command(Command::Wait));
148 src->add(Command(Command::Done));
149
150 std::unique_ptr<TeeCreationThread<WebDataConsumerHandle>> t = wrapUnique(new TeeCreationThread<WebDataConsumerHandle>());
151 t->run(std::move(src), &dest1, &dest2);
152
153 ASSERT_TRUE(dest1);
154 ASSERT_TRUE(dest2);
155
156 HandleReaderRunner<HandleTwoPhaseReader> r1(std::move(dest1));
157 HandleReaderRunner<HandleTwoPhaseReader> r2(std::move(dest2));
158
159 std::unique_ptr<HandleReadResult> res1 = r1.wait();
160 std::unique_ptr<HandleReadResult> res2 = r2.wait();
161
162 EXPECT_EQ(kDone, res1->result());
163 EXPECT_EQ("hello, world", toString(res1->data()));
164
165 EXPECT_EQ(kDone, res2->result());
166 EXPECT_EQ("hello, world", toString(res2->data()));
167 }
168
169 TEST(DataConsumerTeeTest, Error)
170 {
171 std::unique_ptr<Handle> src(Handle::create());
172 std::unique_ptr<WebDataConsumerHandle> dest1, dest2;
173
174 src->add(Command(Command::Data, "hello, "));
175 src->add(Command(Command::Data, "world"));
176 src->add(Command(Command::Error));
177
178 std::unique_ptr<TeeCreationThread<WebDataConsumerHandle>> t = wrapUnique(new TeeCreationThread<WebDataConsumerHandle>());
179 t->run(std::move(src), &dest1, &dest2);
180
181 ASSERT_TRUE(dest1);
182 ASSERT_TRUE(dest2);
183
184 HandleReaderRunner<HandleReader> r1(std::move(dest1));
185 HandleReaderRunner<HandleReader> r2(std::move(dest2));
186
187 std::unique_ptr<HandleReadResult> res1 = r1.wait();
188 std::unique_ptr<HandleReadResult> res2 = r2.wait();
189
190 EXPECT_EQ(kUnexpectedError, res1->result());
191 EXPECT_EQ(kUnexpectedError, res2->result());
192 }
193
194 void postStop(Thread* thread)
195 {
196 thread->getExecutionContext()->stopActiveDOMObjects();
197 }
198
199 TEST(DataConsumerTeeTest, StopSource)
200 {
201 std::unique_ptr<Handle> src(Handle::create());
202 std::unique_ptr<WebDataConsumerHandle> dest1, dest2;
203
204 src->add(Command(Command::Data, "hello, "));
205 src->add(Command(Command::Data, "world"));
206
207 std::unique_ptr<TeeCreationThread<WebDataConsumerHandle>> t = wrapUnique(new TeeCreationThread<WebDataConsumerHandle>());
208 t->run(std::move(src), &dest1, &dest2);
209
210 ASSERT_TRUE(dest1);
211 ASSERT_TRUE(dest2);
212
213 HandleReaderRunner<HandleReader> r1(std::move(dest1));
214 HandleReaderRunner<HandleReader> r2(std::move(dest2));
215
216 // We can pass a raw pointer because the subsequent |wait| calls ensure
217 // t->thread() is alive.
218 t->getThread()->thread()->postTask(BLINK_FROM_HERE, crossThreadBind(postStop , crossThreadUnretained(t->getThread())));
219
220 std::unique_ptr<HandleReadResult> res1 = r1.wait();
221 std::unique_ptr<HandleReadResult> res2 = r2.wait();
222
223 EXPECT_EQ(kUnexpectedError, res1->result());
224 EXPECT_EQ(kUnexpectedError, res2->result());
225 }
226
227 TEST(DataConsumerTeeTest, DetachSource)
228 {
229 std::unique_ptr<Handle> src(Handle::create());
230 std::unique_ptr<WebDataConsumerHandle> dest1, dest2;
231
232 src->add(Command(Command::Data, "hello, "));
233 src->add(Command(Command::Data, "world"));
234
235 std::unique_ptr<TeeCreationThread<WebDataConsumerHandle>> t = wrapUnique(new TeeCreationThread<WebDataConsumerHandle>());
236 t->run(std::move(src), &dest1, &dest2);
237
238 ASSERT_TRUE(dest1);
239 ASSERT_TRUE(dest2);
240
241 HandleReaderRunner<HandleReader> r1(std::move(dest1));
242 HandleReaderRunner<HandleReader> r2(std::move(dest2));
243
244 t = nullptr;
245
246 std::unique_ptr<HandleReadResult> res1 = r1.wait();
247 std::unique_ptr<HandleReadResult> res2 = r2.wait();
248
249 EXPECT_EQ(kUnexpectedError, res1->result());
250 EXPECT_EQ(kUnexpectedError, res2->result());
251 }
252
253 TEST(DataConsumerTeeTest, DetachSourceAfterReadingDone)
254 {
255 std::unique_ptr<Handle> src(Handle::create());
256 std::unique_ptr<WebDataConsumerHandle> dest1, dest2;
257
258 src->add(Command(Command::Data, "hello, "));
259 src->add(Command(Command::Data, "world"));
260 src->add(Command(Command::Done));
261
262 std::unique_ptr<TeeCreationThread<WebDataConsumerHandle>> t = wrapUnique(new TeeCreationThread<WebDataConsumerHandle>());
263 t->run(std::move(src), &dest1, &dest2);
264
265 ASSERT_TRUE(dest1);
266 ASSERT_TRUE(dest2);
267
268 HandleReaderRunner<HandleReader> r1(std::move(dest1));
269 std::unique_ptr<HandleReadResult> res1 = r1.wait();
270
271 EXPECT_EQ(kDone, res1->result());
272 EXPECT_EQ("hello, world", toString(res1->data()));
273
274 t = nullptr;
275
276 HandleReaderRunner<HandleReader> r2(std::move(dest2));
277 std::unique_ptr<HandleReadResult> res2 = r2.wait();
278
279 EXPECT_EQ(kDone, res2->result());
280 EXPECT_EQ("hello, world", toString(res2->data()));
281 }
282
283 TEST(DataConsumerTeeTest, DetachOneDestination)
284 {
285 std::unique_ptr<Handle> src(Handle::create());
286 std::unique_ptr<WebDataConsumerHandle> dest1, dest2;
287
288 src->add(Command(Command::Data, "hello, "));
289 src->add(Command(Command::Data, "world"));
290 src->add(Command(Command::Done));
291
292 std::unique_ptr<TeeCreationThread<WebDataConsumerHandle>> t = wrapUnique(new TeeCreationThread<WebDataConsumerHandle>());
293 t->run(std::move(src), &dest1, &dest2);
294
295 ASSERT_TRUE(dest1);
296 ASSERT_TRUE(dest2);
297
298 dest1 = nullptr;
299
300 HandleReaderRunner<HandleReader> r2(std::move(dest2));
301 std::unique_ptr<HandleReadResult> res2 = r2.wait();
302
303 EXPECT_EQ(kDone, res2->result());
304 EXPECT_EQ("hello, world", toString(res2->data()));
305 }
306
307 TEST(DataConsumerTeeTest, DetachBothDestinationsShouldStopSourceReader)
308 {
309 std::unique_ptr<Handle> src(Handle::create());
310 RefPtr<Handle::Context> context(src->getContext());
311 std::unique_ptr<WebDataConsumerHandle> dest1, dest2;
312
313 src->add(Command(Command::Data, "hello, "));
314 src->add(Command(Command::Data, "world"));
315
316 std::unique_ptr<TeeCreationThread<WebDataConsumerHandle>> t = wrapUnique(new TeeCreationThread<WebDataConsumerHandle>());
317 t->run(std::move(src), &dest1, &dest2);
318
319 ASSERT_TRUE(dest1);
320 ASSERT_TRUE(dest2);
321
322 dest1 = nullptr;
323 dest2 = nullptr;
324
325 // Collect garbage to finalize the source reader.
326 ThreadState::current()-> collectAllGarbage();
327 context->detached()->wait();
328 }
329
330 TEST(FetchDataConsumerTeeTest, Create)
331 {
332 RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create();
333 std::unique_ptr<MockFetchDataConsumerHandle> src(MockFetchDataConsumerHandle ::create());
334
335 // |reader| will be adopted by |obtainFetchDataReader|.
336 MockFetchDataConsumerReader* reader = MockFetchDataConsumerReader::create(). release();
337
338 Checkpoint checkpoint;
339 InSequence s;
340 EXPECT_CALL(checkpoint, Call(1));
341 EXPECT_CALL(*src, obtainFetchDataReader(_)).WillOnce(Return(ByMove(WTF::wrap Unique(reader))));
342 EXPECT_CALL(*reader, drainAsBlobDataHandle(kAllowBlobWithInvalidSize)).WillO nce(Return(blobDataHandle));
343 EXPECT_CALL(*reader, destruct());
344 EXPECT_CALL(checkpoint, Call(2));
345
346 std::unique_ptr<FetchDataConsumerHandle> dest1, dest2;
347 std::unique_ptr<TeeCreationThread<FetchDataConsumerHandle>> t = wrapUnique(n ew TeeCreationThread<FetchDataConsumerHandle>());
348
349 checkpoint.Call(1);
350 t->run(std::move(src), &dest1, &dest2);
351 checkpoint.Call(2);
352
353 ASSERT_TRUE(dest1);
354 ASSERT_TRUE(dest2);
355 EXPECT_EQ(blobDataHandle, dest1->obtainFetchDataReader(nullptr)->drainAsBlob DataHandle(kAllowBlobWithInvalidSize));
356 EXPECT_EQ(blobDataHandle, dest2->obtainFetchDataReader(nullptr)->drainAsBlob DataHandle(kAllowBlobWithInvalidSize));
357 }
358
359 TEST(FetchDataConsumerTeeTest, CreateFromBlobWithInvalidSize)
360 {
361 RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::cre ate(), -1);
362 std::unique_ptr<MockFetchDataConsumerHandle> src(MockFetchDataConsumerHandle ::create());
363
364 // |reader| is adopted by |obtainFetchDataReader|.
365 MockFetchDataConsumerReader* reader = MockFetchDataConsumerReader::create(). release();
366
367 Checkpoint checkpoint;
368 InSequence s;
369 EXPECT_CALL(checkpoint, Call(1));
370 EXPECT_CALL(*src, obtainFetchDataReader(_)).WillOnce(Return(ByMove(WTF::wrap Unique(reader))));
371 EXPECT_CALL(*reader, drainAsBlobDataHandle(kAllowBlobWithInvalidSize)).WillO nce(Return(blobDataHandle));
372 EXPECT_CALL(*reader, destruct());
373 EXPECT_CALL(checkpoint, Call(2));
374
375 std::unique_ptr<FetchDataConsumerHandle> dest1, dest2;
376 std::unique_ptr<TeeCreationThread<FetchDataConsumerHandle>> t = wrapUnique(n ew TeeCreationThread<FetchDataConsumerHandle>());
377
378 checkpoint.Call(1);
379 t->run(std::move(src), &dest1, &dest2);
380 checkpoint.Call(2);
381
382 ASSERT_TRUE(dest1);
383 ASSERT_TRUE(dest2);
384 EXPECT_FALSE(dest1->obtainFetchDataReader(nullptr)->drainAsBlobDataHandle(kD isallowBlobWithInvalidSize));
385 EXPECT_EQ(blobDataHandle, dest1->obtainFetchDataReader(nullptr)->drainAsBlob DataHandle(kAllowBlobWithInvalidSize));
386 EXPECT_FALSE(dest2->obtainFetchDataReader(nullptr)->drainAsBlobDataHandle(kD isallowBlobWithInvalidSize));
387 EXPECT_EQ(blobDataHandle, dest2->obtainFetchDataReader(nullptr)->drainAsBlob DataHandle(kAllowBlobWithInvalidSize));
388 }
389
390 TEST(FetchDataConsumerTeeTest, CreateDone)
391 {
392 std::unique_ptr<Handle> src(Handle::create());
393 std::unique_ptr<FetchDataConsumerHandle> dest1, dest2;
394
395 src->add(Command(Command::Done));
396
397 std::unique_ptr<TeeCreationThread<FetchDataConsumerHandle>> t = wrapUnique(n ew TeeCreationThread<FetchDataConsumerHandle>());
398 t->run(createFetchDataConsumerHandleFromWebHandle(std::move(src)), &dest1, & dest2);
399
400 ASSERT_TRUE(dest1);
401 ASSERT_TRUE(dest2);
402
403 EXPECT_FALSE(dest1->obtainFetchDataReader(nullptr)->drainAsBlobDataHandle(kA llowBlobWithInvalidSize));
404 EXPECT_FALSE(dest2->obtainFetchDataReader(nullptr)->drainAsBlobDataHandle(kA llowBlobWithInvalidSize));
405
406 HandleReaderRunner<HandleReader> r1(std::move(dest1)), r2(std::move(dest2));
407
408 std::unique_ptr<HandleReadResult> res1 = r1.wait();
409 std::unique_ptr<HandleReadResult> res2 = r2.wait();
410
411 EXPECT_EQ(kDone, res1->result());
412 EXPECT_EQ(0u, res1->data().size());
413 EXPECT_EQ(kDone, res2->result());
414 EXPECT_EQ(0u, res2->data().size());
415 }
416
417 } // namespace
418 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698