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

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());
hiroshige 2016/09/08 08:25:55 Add EXPECT_EQ(Done, dest1->getPublicState());
yhirano 2016/09/08 09:41:35 Done.
109 EXPECT_EQ(Result::Done, result2.first);
110 EXPECT_TRUE(result2.second.isEmpty());
hiroshige 2016/09/08 08:25:55 Add EXPECT_EQ(Done, dest2->getPublicState());
yhirano 2016/09/08 09:41:34 Done.
111 EXPECT_FALSE(src->isCancelled());
hiroshige 2016/09/08 08:25:54 How about adding here or somewhere: dest1->cance
yhirano 2016/09/08 09:41:35 Done.
112 }
113
114 TEST_F(BytesConsumerTeeTest, Read)
115 {
116 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
117
118 src->add(Command(Command::Wait));
119 src->add(Command(Command::Data, "hello, "));
120 src->add(Command(Command::Wait));
121 src->add(Command(Command::Data, "world"));
122 src->add(Command(Command::Wait));
123 src->add(Command(Command::Wait));
124 src->add(Command(Command::Done));
125
126 BytesConsumer* dest1 = nullptr;
127 BytesConsumer* dest2 = nullptr;
128 BytesConsumer::tee(document(), src, &dest1, &dest2);
129
hiroshige 2016/09/08 08:25:54 Add EXPECT_EQ(ReadableOrWaiting, dest1->getPublicS
yhirano 2016/09/08 09:41:34 Done.
130 auto result1 = (new BytesConsumerTestUtil::Reader(dest1))->run();
131 auto result2 = (new BytesConsumerTestUtil::Reader(dest2))->run();
132
133 EXPECT_EQ(Result::Done, result1.first);
134 EXPECT_EQ("hello, world", toString(result1.second));
hiroshige 2016/09/08 08:25:55 Add EXPECT_EQ(Done, dest1->getPublicState());
yhirano 2016/09/08 09:41:34 Done.
135 EXPECT_EQ(Result::Done, result2.first);
136 EXPECT_EQ("hello, world", toString(result2.second));
hiroshige 2016/09/08 08:25:54 Add EXPECT_EQ(Done, dest2->getPublicState());
yhirano 2016/09/08 09:41:35 Done.
137 EXPECT_FALSE(src->isCancelled());
138 }
139
140 TEST_F(BytesConsumerTeeTest, TwoPhaseRead)
141 {
142 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
143
144 src->add(Command(Command::Wait));
145 src->add(Command(Command::Data, "hello, "));
146 src->add(Command(Command::Wait));
147 src->add(Command(Command::Data, "world"));
148 src->add(Command(Command::Wait));
149 src->add(Command(Command::Wait));
150 src->add(Command(Command::Done));
151
152 BytesConsumer* dest1 = nullptr;
153 BytesConsumer* dest2 = nullptr;
154 BytesConsumer::tee(document(), src, &dest1, &dest2);
155
hiroshige 2016/09/08 08:25:54 Add EXPECT_EQ(ReadableOrWaiting, dest1->getPublicS
yhirano 2016/09/08 09:41:35 Done.
156 auto result1 = (new BytesConsumerTestUtil::TwoPhaseReader(dest1))->run();
157 auto result2 = (new BytesConsumerTestUtil::TwoPhaseReader(dest2))->run();
158
159 EXPECT_EQ(Result::Done, result1.first);
160 EXPECT_EQ("hello, world", toString(result1.second));
hiroshige 2016/09/08 08:25:54 Add EXPECT_EQ(Done, dest1->getPublicState());
yhirano 2016/09/08 09:41:34 Done.
161 EXPECT_EQ(Result::Done, result2.first);
162 EXPECT_EQ("hello, world", toString(result2.second));
hiroshige 2016/09/08 08:25:54 Add EXPECT_EQ(Done, dest2->getPublicState());
yhirano 2016/09/08 09:41:35 Done.
163 EXPECT_FALSE(src->isCancelled());
164 }
165
166 TEST_F(BytesConsumerTeeTest, Error)
167 {
168 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
169
170 src->add(Command(Command::Data, "hello, "));
171 src->add(Command(Command::Data, "world"));
172 src->add(Command(Command::Error));
173
174 BytesConsumer* dest1 = nullptr;
175 BytesConsumer* dest2 = nullptr;
176 BytesConsumer::tee(document(), src, &dest1, &dest2);
177
hiroshige 2016/09/08 08:25:55 Add EXPECT_EQ(Errored, dest1->getPublicState()); A
yhirano 2016/09/08 09:41:34 Done.
178 auto result1 = (new BytesConsumerTestUtil::TwoPhaseReader(dest1))->run();
179 auto result2 = (new BytesConsumerTestUtil::TwoPhaseReader(dest2))->run();
180
181 EXPECT_EQ(Result::Error, result1.first);
182 EXPECT_EQ(Result::Error, result2.first);
hiroshige 2016/09/08 08:25:54 Add EXPECT_TRUE(result1.second.isEmpty()); EXPECT_
yhirano 2016/09/08 09:41:35 Done.
183 EXPECT_FALSE(src->isCancelled());
hiroshige 2016/09/08 08:25:55 How about adding dest1->cancel(); dest2->cance
yhirano 2016/09/08 09:41:34 Done.
184 }
185
186 TEST_F(BytesConsumerTeeTest, Cancel)
187 {
188 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
189
190 src->add(Command(Command::Data, "hello, "));
191 src->add(Command(Command::Wait));
192
193 BytesConsumer* dest1 = nullptr;
194 BytesConsumer* dest2 = nullptr;
195 BytesConsumer::tee(document(), src, &dest1, &dest2);
196
197 EXPECT_FALSE(src->isCancelled());
hiroshige 2016/09/08 08:25:54 EXPECT_EQ(ReadableOrWaiting, dest1->getPublicState
yhirano 2016/09/08 09:41:35 Done.
198 dest1->cancel();
hiroshige 2016/09/08 08:25:54 EXPECT_EQ(Closed, dest1->getPublicState()); EXPECT
yhirano 2016/09/08 09:41:34 Done.
199 EXPECT_FALSE(src->isCancelled());
200 dest2->cancel();
hiroshige 2016/09/08 08:25:55 EXPECT_EQ(Closed, dest1->getPublicState()); EXPECT
yhirano 2016/09/08 09:41:35 Done.
201 EXPECT_TRUE(src->isCancelled());
202 }
203
hiroshige 2016/09/08 08:25:55 Please add tests where: - |dest1| is cancelled and
yhirano 2016/09/08 09:41:35 Done.
204 TEST_F(BytesConsumerTeeTest, BlobHandle)
205 {
206 RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::cre ate(), 12345);
207 BytesConsumer* src = new FakeBlobBytesConsumer(blobDataHandle);
208
209 BytesConsumer* dest1 = nullptr;
210 BytesConsumer* dest2 = nullptr;
211 BytesConsumer::tee(document(), src, &dest1, &dest2);
212
213 RefPtr<BlobDataHandle> destBlobDataHandle1 = dest1->drainAsBlobDataHandle(By tesConsumer::BlobSizePolicy::AllowBlobWithInvalidSize);
214 RefPtr<BlobDataHandle> destBlobDataHandle2 = dest2->drainAsBlobDataHandle(By tesConsumer::BlobSizePolicy::DisallowBlobWithInvalidSize);
215 ASSERT_TRUE(destBlobDataHandle1);
216 ASSERT_TRUE(destBlobDataHandle2);
217 EXPECT_EQ(12345u, destBlobDataHandle1->size());
218 EXPECT_EQ(12345u, destBlobDataHandle2->size());
219 }
220
221 TEST_F(BytesConsumerTeeTest, BlobHandleWithInvalidSize)
222 {
223 RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::cre ate(), -1);
224 BytesConsumer* src = new FakeBlobBytesConsumer(blobDataHandle);
225
226 BytesConsumer* dest1 = nullptr;
227 BytesConsumer* dest2 = nullptr;
228 BytesConsumer::tee(document(), src, &dest1, &dest2);
229
230 RefPtr<BlobDataHandle> destBlobDataHandle1 = dest1->drainAsBlobDataHandle(By tesConsumer::BlobSizePolicy::AllowBlobWithInvalidSize);
231 RefPtr<BlobDataHandle> destBlobDataHandle2 = dest2->drainAsBlobDataHandle(By tesConsumer::BlobSizePolicy::DisallowBlobWithInvalidSize);
232 ASSERT_TRUE(destBlobDataHandle1);
233 ASSERT_FALSE(destBlobDataHandle2);
234 EXPECT_EQ(UINT64_MAX, destBlobDataHandle1->size());
235 }
236
237 TEST_F(BytesConsumerTeeTest, ConsumerCanBeErroredInTwoPhaseRead)
238 {
239 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
240 src->add(Command(Command::Data, "a"));
241 src->add(Command(Command::Wait));
242 src->add(Command(Command::Error));
243
244 BytesConsumer* dest1 = nullptr;
245 BytesConsumer* dest2 = nullptr;
246 BytesConsumer::tee(document(), src, &dest1, &dest2);
247 TestClient* client = new TestClient();
248 dest1->setClient(client);
249
250 {
251 const char* buffer = nullptr;
252 size_t available = 0;
253 while (true) {
hiroshige 2016/09/08 08:25:54 Why do we need this while loop? Doesn't dest1->beg
yhirano 2016/09/08 09:41:34 Hmm ok, deleted
254 auto result = dest1->beginRead(&buffer, &available);
255 if (result == Result::Ok)
256 break;
257 ASSERT_EQ(Result::ShouldWait, result);
258 testing::runPendingTasks();
259 }
260 }
261
hiroshige 2016/09/08 08:25:54 ASSERT_EQ(BytesConsumer::PublicState::Errored, des
yhirano 2016/09/08 09:41:34 It's ReadableOrWaiting here.
hiroshige 2016/09/09 06:37:30 Acknowledged.
262 int numOnStateChangeCalled = client->numOnStateChangeCalled();
263 EXPECT_EQ(Result::Error, (new BytesConsumerTestUtil::Reader(dest2))->run().f irst);
264 EXPECT_EQ(BytesConsumer::PublicState::Errored, dest1->getPublicState());
265 EXPECT_EQ(numOnStateChangeCalled + 1, client->numOnStateChangeCalled());
266 EXPECT_EQ(Result::Ok, dest1->endRead(0));
hiroshige 2016/09/08 08:25:54 How about testing that we can read the data (i.e.
yhirano 2016/09/08 09:41:35 Done.
267 }
268
269 TEST_F(BytesConsumerTeeTest, AsyncNotificationShouldBeDispatchedWhenAllDataIsCon sumed)
270 {
271 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
272 src->add(Command(Command::Data, "a"));
273 src->add(Command(Command::Done));
274 TestClient* client = new TestClient();
275
276 BytesConsumer* dest1 = nullptr;
277 BytesConsumer* dest2 = nullptr;
278 BytesConsumer::tee(document(), src, &dest1, &dest2);
279
hiroshige 2016/09/08 08:25:54 In this test, |src->getPublicState()| is Closed he
yhirano 2016/09/08 09:41:35 I think we don't need the former if we have the la
hiroshige 2016/09/09 06:37:30 Acknowledged.
280 dest1->setClient(client);
281
282 const char* buffer = nullptr;
283 size_t available = 0;
284 ASSERT_EQ(Result::Ok, dest1->beginRead(&buffer, &available));
285 ASSERT_EQ(1u, available);
286 EXPECT_EQ('a', buffer[0]);
287
288 testing::runPendingTasks();
hiroshige 2016/09/08 08:25:54 Add EXPECT_EQ('a', buffer[0]); (this might be help
yhirano 2016/09/08 09:41:35 Done.
289 ASSERT_EQ(Result::Ok, dest1->endRead(1));
290
291 EXPECT_EQ(0, client->numOnStateChangeCalled());
292 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest1->getPublicSta te());
293 testing::runPendingTasks();
294 EXPECT_EQ(1, client->numOnStateChangeCalled());
295 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
296 }
297
298 TEST_F(BytesConsumerTeeTest, AsyncCloseNotificationShouldBeCancelledBySubsequent ReadCall)
299 {
300 ReplayingBytesConsumer* src = new ReplayingBytesConsumer(document());
301 src->add(Command(Command::Data, "a"));
302 src->add(Command(Command::Done));
303 TestClient* client = new TestClient();
304
305 BytesConsumer* dest1 = nullptr;
306 BytesConsumer* dest2 = nullptr;
307 BytesConsumer::tee(document(), src, &dest1, &dest2);
308
309 dest1->setClient(client);
310
311 const char* buffer = nullptr;
312 size_t available = 0;
313 ASSERT_EQ(Result::Ok, dest1->beginRead(&buffer, &available));
314 ASSERT_EQ(1u, available);
315 EXPECT_EQ('a', buffer[0]);
316
317 testing::runPendingTasks();
318 ASSERT_EQ(Result::Ok, dest1->endRead(1));
319 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, dest1->getPublicSta te());
320
321 EXPECT_EQ(Result::Done, dest1->beginRead(&buffer, &available));
322 EXPECT_EQ(0, client->numOnStateChangeCalled());
323 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
324 testing::runPendingTasks();
325 EXPECT_EQ(0, client->numOnStateChangeCalled());
326 EXPECT_EQ(BytesConsumer::PublicState::Closed, dest1->getPublicState());
327 }
328
329 } // namespace
330
331 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698