| 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()); |
| 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 |
| OLD | NEW |