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

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

Issue 2269953004: Implment BytesConsumer::tee (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix 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 2016 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/BytesConsumer.h"
6
7 #include "core/testing/DummyPageHolder.h"
8 #include "modules/fetch/BytesConsumerTestUtil.h"
9 #include "platform/blob/BlobData.h"
10 #include "platform/testing/UnitTestHelpers.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "wtf/RefPtr.h"
13
14 namespace blink {
15
16 namespace {
17
18 using Command = BytesConsumerTestUtil::Command;
19 using Result = BytesConsumer::Result;
20 using ReplayingBytesConsumer = BytesConsumerTestUtil::ReplayingBytesConsumer;
21
22 String toString(const Vector<char>& v)
23 {
24 return String(v.data(), v.size());
25 }
26
27 class TestClient final : public GarbageCollectedFinalized<TestClient>, public By tesConsumer::Client {
28 USING_GARBAGE_COLLECTED_MIXIN(TestClient);
29 public:
30 void onStateChange() override { ++m_numOnStateChangeCalled; }
31 int numOnStateChangeCalled() const { return m_numOnStateChangeCalled; }
32
33 private:
34 int m_numOnStateChangeCalled = 0;
35 };
36
37 class BytesConsumerTeeTest : public ::testing::Test {
38 public:
39 BytesConsumerTeeTest()
40 : m_page(DummyPageHolder::create())
41 {
42 }
43
44 Document* document() { return &m_page->document(); }
45
46 private:
47 std::unique_ptr<DummyPageHolder> m_page;
48 };
49
50 class FakeBlobBytesConsumer : public BytesConsumer {
51 public:
52 explicit FakeBlobBytesConsumer(PassRefPtr<BlobDataHandle> handle) : m_blobHa ndle(handle) {}
53 ~FakeBlobBytesConsumer() override {}
54
55 Result beginRead(const char** buffer, size_t* available) override
56 {
57 if (m_state == PublicState::Closed)
58 return Result::Done;
59 m_blobHandle = nullptr;
60 m_state = PublicState::Errored;
61 return Result::Error;
62 }
63 Result endRead(size_t readSize) override
64 {
65 if (m_state == PublicState::Closed)
66 return Result::Error;
67 m_blobHandle = nullptr;
68 m_state = PublicState::Errored;
69 return Result::Error;
70 }
71 PassRefPtr<BlobDataHandle> drainAsBlobDataHandle(BlobSizePolicy policy)
72 {
73 if (m_state != PublicState::ReadableOrWaiting)
74 return nullptr;
75 DCHECK(m_blobHandle);
76 if (policy == BlobSizePolicy::DisallowBlobWithInvalidSize && m_blobHandl e->size() == UINT64_MAX)
77 return nullptr;
78 m_state = PublicState::Closed;
79 return m_blobHandle.release();
80 }
81
82 void setClient(Client*) override {}
83 void clearClient() override {}
84 void cancel() override {}
85 PublicState getPublicState() const override { return m_state; }
86 Error getError() const override { return Error(); }
87 String debugName() const override { return "FakeBlobBytesConsumer"; }
88
89 private:
90 PublicState m_state = PublicState::ReadableOrWaiting;
91 RefPtr<BlobDataHandle> m_blobHandle;
92 };
93
94 TEST_F(BytesConsumerTeeTest, CreateDone)
95 {
96 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
97 src->add(Command(Command::Done));
98 EXPECT_FALSE(src->isCancelled());
99
100 BytesConsumer* dest1 = nullptr;
101 BytesConsumer* dest2 = nullptr;
102 BytesConsumer::tee(document(), src, &dest1, &dest2);
103
104 auto result1 = (new BytesConsumerTestUtil::Reader(dest1))->run();
105 auto result2 = (new BytesConsumerTestUtil::Reader(dest2))->run();
106
107 EXPECT_EQ(Result::Done, result1.first);
108 EXPECT_TRUE(result1.second.isEmpty());
109 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
110 EXPECT_EQ(Result::Done, result2.first);
111 EXPECT_TRUE(result2.second.isEmpty());
112 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest2->getPublicState());
113 EXPECT_FALSE(src->isCancelled());
114
115 // Cancelling does nothing when closed.
116 dest1->cancel();
117 dest2->cancel();
118 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
119 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest2->getPublicState());
120 EXPECT_FALSE(src->isCancelled());
121 }
122
123 TEST_F(BytesConsumerTeeTest, Read)
124 {
125 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
126
127 src->add(Command(Command::Wait));
128 src->add(Command(Command::Data, "hello, "));
129 src->add(Command(Command::Wait));
130 src->add(Command(Command::Data, "world"));
131 src->add(Command(Command::Wait));
132 src->add(Command(Command::Wait));
133 src->add(Command(Command::Done));
134
135 BytesConsumer* dest1 = nullptr;
136 BytesConsumer* dest2 = nullptr;
137 BytesConsumer::tee(document(), src, &dest1, &dest2);
138
139 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest1->getPublicSta te());
140 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest2->getPublicSta te());
141
142 auto result1 = (new BytesConsumerTestUtil::Reader(dest1))->run();
143 auto result2 = (new BytesConsumerTestUtil::Reader(dest2))->run();
144
145 EXPECT_EQ(Result::Done, result1.first);
146 EXPECT_EQ("hello, world", toString(result1.second));
147 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
148 EXPECT_EQ(Result::Done, result2.first);
149 EXPECT_EQ("hello, world", toString(result2.second));
150 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest2->getPublicState());
151 EXPECT_FALSE(src->isCancelled());
152 }
153
154 TEST_F(BytesConsumerTeeTest, TwoPhaseRead)
155 {
156 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
157
158 src->add(Command(Command::Wait));
159 src->add(Command(Command::Data, "hello, "));
160 src->add(Command(Command::Wait));
161 src->add(Command(Command::Data, "world"));
162 src->add(Command(Command::Wait));
163 src->add(Command(Command::Wait));
164 src->add(Command(Command::Done));
165
166 BytesConsumer* dest1 = nullptr;
167 BytesConsumer* dest2 = nullptr;
168 BytesConsumer::tee(document(), src, &dest1, &dest2);
169
170 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest1->getPublicSta te());
171 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest2->getPublicSta te());
172
173 auto result1 = (new BytesConsumerTestUtil::TwoPhaseReader(dest1))->run();
174 auto result2 = (new BytesConsumerTestUtil::TwoPhaseReader(dest2))->run();
175
176 EXPECT_EQ(Result::Done, result1.first);
177 EXPECT_EQ("hello, world", toString(result1.second));
178 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
179 EXPECT_EQ(Result::Done, result2.first);
180 EXPECT_EQ("hello, world", toString(result2.second));
181 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest2->getPublicState());
182 EXPECT_FALSE(src->isCancelled());
183 }
184
185 TEST_F(BytesConsumerTeeTest, Error)
186 {
187 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
188
189 src->add(Command(Command::Data, "hello, "));
190 src->add(Command(Command::Data, "world"));
191 src->add(Command(Command::Error));
192
193 BytesConsumer* dest1 = nullptr;
194 BytesConsumer* dest2 = nullptr;
195 BytesConsumer::tee(document(), src, &dest1, &dest2);
196
197 EXPECT_EQ(BytesConsumer::PublicState::Errored, dest1->getPublicState());
198 EXPECT_EQ(BytesConsumer::PublicState::Errored, dest2->getPublicState());
199
200 auto result1 = (new BytesConsumerTestUtil::TwoPhaseReader(dest1))->run();
201 auto result2 = (new BytesConsumerTestUtil::TwoPhaseReader(dest2))->run();
202
203 EXPECT_EQ(Result::Error, result1.first);
204 EXPECT_TRUE(result1.second.isEmpty());
205 EXPECT_EQ(BytesConsumer::PublicState::Errored, dest1->getPublicState());
206 EXPECT_EQ(Result::Error, result2.first);
207 EXPECT_TRUE(result2.second.isEmpty());
208 EXPECT_EQ(BytesConsumer::PublicState::Errored, dest2->getPublicState());
209 EXPECT_FALSE(src->isCancelled());
210
211 // Cancelling does nothing when errored.
212 dest1->cancel();
213 dest2->cancel();
214 EXPECT_EQ(BytesConsumer::PublicState::Errored, dest1->getPublicState());
215 EXPECT_EQ(BytesConsumer::PublicState::Errored, dest2->getPublicState());
216 EXPECT_FALSE(src->isCancelled());
217 }
218
219 TEST_F(BytesConsumerTeeTest, Cancel)
220 {
221 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
222
223 src->add(Command(Command::Data, "hello, "));
224 src->add(Command(Command::Wait));
225
226 BytesConsumer* dest1 = nullptr;
227 BytesConsumer* dest2 = nullptr;
228 BytesConsumer::tee(document(), src, &dest1, &dest2);
229
230 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest1->getPublicSta te());
231 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest2->getPublicSta te());
232
233 EXPECT_FALSE(src->isCancelled());
234 dest1->cancel();
235 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
236 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest2->getPublicSta te());
237 EXPECT_FALSE(src->isCancelled());
238 dest2->cancel();
239 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
240 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest2->getPublicState());
241 EXPECT_TRUE(src->isCancelled());
242 }
243
244 TEST_F(BytesConsumerTeeTest, CancelShouldNotAffectTheOtherDestination)
245 {
246 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
247
248 src->add(Command(Command::Data, "hello, "));
249 src->add(Command(Command::Wait));
250 src->add(Command(Command::Data, "world"));
251 src->add(Command(Command::Done));
252
253 BytesConsumer* dest1 = nullptr;
254 BytesConsumer* dest2 = nullptr;
255 BytesConsumer::tee(document(), src, &dest1, &dest2);
256
257 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest1->getPublicSta te());
258 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest2->getPublicSta te());
259
260 EXPECT_FALSE(src->isCancelled());
261 dest1->cancel();
262 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
263 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest2->getPublicSta te());
264 EXPECT_FALSE(src->isCancelled());
265
266 auto result2 = (new BytesConsumerTestUtil::TwoPhaseReader(dest2))->run();
267
268 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
269 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest2->getPublicState());
270 EXPECT_EQ(Result::Done, result2.first);
271 EXPECT_EQ("hello, world", toString(result2.second));
272 EXPECT_FALSE(src->isCancelled());
273 }
274
275 TEST_F(BytesConsumerTeeTest, CancelShouldNotAffectTheOtherDestination2)
276 {
277 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
278
279 src->add(Command(Command::Data, "hello, "));
280 src->add(Command(Command::Wait));
281 src->add(Command(Command::Data, "world"));
282 src->add(Command(Command::Error));
283
284 BytesConsumer* dest1 = nullptr;
285 BytesConsumer* dest2 = nullptr;
286 BytesConsumer::tee(document(), src, &dest1, &dest2);
287
288 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest1->getPublicSta te());
289 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest2->getPublicSta te());
290
291 EXPECT_FALSE(src->isCancelled());
292 dest1->cancel();
293 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
294 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest2->getPublicSta te());
295 EXPECT_FALSE(src->isCancelled());
296
297 auto result2 = (new BytesConsumerTestUtil::TwoPhaseReader(dest2))->run();
298
299 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
300 EXPECT_EQ(BytesConsumer::PublicState::Errored, dest2->getPublicState());
301 EXPECT_EQ(Result::Error, result2.first);
302 EXPECT_FALSE(src->isCancelled());
303 }
304
305 TEST_F(BytesConsumerTeeTest, BlobHandle)
306 {
307 RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::cre ate(), 12345);
308 BytesConsumer* src = new FakeBlobBytesConsumer(blobDataHandle);
309
310 BytesConsumer* dest1 = nullptr;
311 BytesConsumer* dest2 = nullptr;
312 BytesConsumer::tee(document(), src, &dest1, &dest2);
313
314 RefPtr<BlobDataHandle> destBlobDataHandle1 = dest1->drainAsBlobDataHandle(By tesConsumer::BlobSizePolicy::AllowBlobWithInvalidSize);
315 RefPtr<BlobDataHandle> destBlobDataHandle2 = dest2->drainAsBlobDataHandle(By tesConsumer::BlobSizePolicy::DisallowBlobWithInvalidSize);
316 ASSERT_TRUE(destBlobDataHandle1);
317 ASSERT_TRUE(destBlobDataHandle2);
318 EXPECT_EQ(12345u, destBlobDataHandle1->size());
319 EXPECT_EQ(12345u, destBlobDataHandle2->size());
320 }
321
322 TEST_F(BytesConsumerTeeTest, BlobHandleWithInvalidSize)
323 {
324 RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::cre ate(), -1);
325 BytesConsumer* src = new FakeBlobBytesConsumer(blobDataHandle);
326
327 BytesConsumer* dest1 = nullptr;
328 BytesConsumer* dest2 = nullptr;
329 BytesConsumer::tee(document(), src, &dest1, &dest2);
330
331 RefPtr<BlobDataHandle> destBlobDataHandle1 = dest1->drainAsBlobDataHandle(By tesConsumer::BlobSizePolicy::AllowBlobWithInvalidSize);
332 RefPtr<BlobDataHandle> destBlobDataHandle2 = dest2->drainAsBlobDataHandle(By tesConsumer::BlobSizePolicy::DisallowBlobWithInvalidSize);
333 ASSERT_TRUE(destBlobDataHandle1);
334 ASSERT_FALSE(destBlobDataHandle2);
335 EXPECT_EQ(UINT64_MAX, destBlobDataHandle1->size());
336 }
337
338 TEST_F(BytesConsumerTeeTest, ConsumerCanBeErroredInTwoPhaseRead)
339 {
340 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
341 src->add(Command(Command::Data, "a"));
342 src->add(Command(Command::Wait));
343 src->add(Command(Command::Error));
344
345 BytesConsumer* dest1 = nullptr;
346 BytesConsumer* dest2 = nullptr;
347 BytesConsumer::tee(document(), src, &dest1, &dest2);
348 TestClient* client = new TestClient();
349 dest1->setClient(client);
350
351 const char* buffer = nullptr;
352 size_t available = 0;
353 ASSERT_EQ(Result::Ok, dest1->beginRead(&buffer, &available));
354 ASSERT_EQ(1u, available);
355
356 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest1->getPublicSta te());
357 int numOnStateChangeCalled = client->numOnStateChangeCalled();
358 EXPECT_EQ(Result::Error, (new BytesConsumerTestUtil::Reader(dest2))->run().f irst);
359 EXPECT_EQ(BytesConsumer::PublicState::Errored, dest1->getPublicState());
360 EXPECT_EQ(numOnStateChangeCalled + 1, client->numOnStateChangeCalled());
361 EXPECT_EQ('a', buffer[0]);
362 EXPECT_EQ(Result::Ok, dest1->endRead(available));
363 }
364
365 TEST_F(BytesConsumerTeeTest, AsyncNotificationShouldBeDispatchedWhenAllDataIsCon sumed)
366 {
367 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
368 src->add(Command(Command::Data, "a"));
369 src->add(Command(Command::Wait));
370 src->add(Command(Command::Done));
371 TestClient* client = new TestClient();
372
373 BytesConsumer* dest1 = nullptr;
374 BytesConsumer* dest2 = nullptr;
375 BytesConsumer::tee(document(), src, &dest1, &dest2);
376
377 dest1->setClient(client);
378
379 const char* buffer = nullptr;
380 size_t available = 0;
381 ASSERT_EQ(Result::Ok, dest1->beginRead(&buffer, &available));
382 ASSERT_EQ(1u, available);
383 EXPECT_EQ('a', buffer[0]);
384
385 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, src->getPublicState ());
386 testing::runPendingTasks();
387 EXPECT_EQ(BytesConsumer::PublicState::Closed, src->getPublicState());
388 // Just for checking UAF.
389 EXPECT_EQ('a', buffer[0]);
390 ASSERT_EQ(Result::Ok, dest1->endRead(1));
391
392 EXPECT_EQ(0, client->numOnStateChangeCalled());
393 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest1->getPublicSta te());
394 testing::runPendingTasks();
395 EXPECT_EQ(1, client->numOnStateChangeCalled());
396 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
397 }
398
399 TEST_F(BytesConsumerTeeTest, AsyncCloseNotificationShouldBeCancelledBySubsequent ReadCall)
400 {
401 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
402 src->add(Command(Command::Data, "a"));
403 src->add(Command(Command::Done));
404 TestClient* client = new TestClient();
405
406 BytesConsumer* dest1 = nullptr;
407 BytesConsumer* dest2 = nullptr;
408 BytesConsumer::tee(document(), src, &dest1, &dest2);
409
410 dest1->setClient(client);
411
412 const char* buffer = nullptr;
413 size_t available = 0;
414 ASSERT_EQ(Result::Ok, dest1->beginRead(&buffer, &available));
415 ASSERT_EQ(1u, available);
416 EXPECT_EQ('a', buffer[0]);
417
418 testing::runPendingTasks();
419 // Just for checking UAF.
420 EXPECT_EQ('a', buffer[0]);
421 ASSERT_EQ(Result::Ok, dest1->endRead(1));
422 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest1->getPublicSta te());
423
424 EXPECT_EQ(Result::Done, dest1->beginRead(&buffer, &available));
425 EXPECT_EQ(0, client->numOnStateChangeCalled());
426 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
427 testing::runPendingTasks();
428 EXPECT_EQ(0, client->numOnStateChangeCalled());
429 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
430 }
431
432 } // namespace
433
434 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698