Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 | |
| OLD | NEW |