| Index: third_party/WebKit/Source/modules/fetch/BlobBytesConsumerTest.cpp
|
| diff --git a/third_party/WebKit/Source/modules/fetch/BlobBytesConsumerTest.cpp b/third_party/WebKit/Source/modules/fetch/BlobBytesConsumerTest.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f6950fe7e013c9c0bed6215aa3e78dac88d325cf
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Source/modules/fetch/BlobBytesConsumerTest.cpp
|
| @@ -0,0 +1,532 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "modules/fetch/BlobBytesConsumer.h"
|
| +
|
| +#include "core/dom/Document.h"
|
| +#include "core/loader/ThreadableLoader.h"
|
| +#include "core/testing/DummyPageHolder.h"
|
| +#include "modules/fetch/BytesConsumerTestUtil.h"
|
| +#include "modules/fetch/DataConsumerHandleTestUtil.h"
|
| +#include "platform/blob/BlobData.h"
|
| +#include "platform/network/EncodedFormData.h"
|
| +#include "platform/network/ResourceError.h"
|
| +#include "platform/network/ResourceResponse.h"
|
| +#include "platform/testing/UnitTestHelpers.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "wtf/Vector.h"
|
| +#include "wtf/text/WTFString.h"
|
| +
|
| +namespace blink {
|
| +
|
| +namespace {
|
| +
|
| +using Command = DataConsumerHandleTestUtil::Command;
|
| +using PublicState = BytesConsumer::PublicState;
|
| +using ReplayingHandle = DataConsumerHandleTestUtil::ReplayingHandle;
|
| +using Result = BytesConsumer::Result;
|
| +
|
| +String toString(const Vector<char>& v)
|
| +{
|
| + return String(v.data(), v.size());
|
| +}
|
| +
|
| +class TestThreadableLoader : public ThreadableLoader {
|
| +public:
|
| + ~TestThreadableLoader() override
|
| + {
|
| + EXPECT_FALSE(m_shouldBeCancelled && !m_isCancelled) << "The loader should be cancelled but is not cancelled.";
|
| + }
|
| +
|
| + void start(const ResourceRequest& request) override
|
| + {
|
| + m_isStarted = true;
|
| + }
|
| +
|
| + void overrideTimeout(unsigned long timeoutMilliseconds) override
|
| + {
|
| + ADD_FAILURE() << "overrideTimeout should not be called.";
|
| + }
|
| +
|
| + void cancel() override
|
| + {
|
| + m_isCancelled = true;
|
| + }
|
| +
|
| + bool isStarted() const { return m_isStarted; }
|
| + bool isCancelled() const { return m_isCancelled; }
|
| + void setShouldBeCancelled() { m_shouldBeCancelled = true; }
|
| +
|
| +private:
|
| + bool m_isStarted = false;
|
| + bool m_isCancelled = false;
|
| + bool m_shouldBeCancelled = false;
|
| +};
|
| +
|
| +class SyncLoadingTestThreadableLoader : public ThreadableLoader {
|
| +public:
|
| + ~SyncLoadingTestThreadableLoader() override
|
| + {
|
| + DCHECK(!m_handle);
|
| + }
|
| +
|
| + void start(const ResourceRequest& request) override
|
| + {
|
| + m_isStarted = true;
|
| + m_client->didReceiveResponse(0, ResourceResponse(), std::move(m_handle));
|
| + m_client->didFinishLoading(0, 0);
|
| + }
|
| +
|
| + void overrideTimeout(unsigned long timeoutMilliseconds) override
|
| + {
|
| + ADD_FAILURE() << "overrideTimeout should not be called.";
|
| + }
|
| +
|
| + void cancel() override
|
| + {
|
| + m_isCancelled = true;
|
| + }
|
| +
|
| + bool isStarted() const { return m_isStarted; }
|
| + bool isCancelled() const { return m_isCancelled; }
|
| +
|
| + void setClient(ThreadableLoaderClient* client)
|
| + {
|
| + m_client = client;
|
| + }
|
| +
|
| + void setHandle(std::unique_ptr<WebDataConsumerHandle> handle)
|
| + {
|
| + m_handle = std::move(handle);
|
| + }
|
| +
|
| +private:
|
| + bool m_isStarted = false;
|
| + bool m_isCancelled = false;
|
| + ThreadableLoaderClient* m_client = nullptr;
|
| + std::unique_ptr<WebDataConsumerHandle> m_handle;
|
| +};
|
| +
|
| +class SyncErrorTestThreadableLoader : public ThreadableLoader {
|
| +public:
|
| + ~SyncErrorTestThreadableLoader() override {}
|
| +
|
| + void start(const ResourceRequest& request) override
|
| + {
|
| + m_isStarted = true;
|
| + m_client->didFail(ResourceError());
|
| + }
|
| +
|
| + void overrideTimeout(unsigned long timeoutMilliseconds) override
|
| + {
|
| + ADD_FAILURE() << "overrideTimeout should not be called.";
|
| + }
|
| +
|
| + void cancel() override
|
| + {
|
| + m_isCancelled = true;
|
| + }
|
| +
|
| + bool isStarted() const { return m_isStarted; }
|
| + bool isCancelled() const { return m_isCancelled; }
|
| +
|
| + void setClient(ThreadableLoaderClient* client)
|
| + {
|
| + m_client = client;
|
| + }
|
| +
|
| +private:
|
| + bool m_isStarted = false;
|
| + bool m_isCancelled = false;
|
| + ThreadableLoaderClient* m_client = nullptr;
|
| +};
|
| +
|
| +class TestClient final : public GarbageCollectedFinalized<TestClient>, public BytesConsumer::Client {
|
| + USING_GARBAGE_COLLECTED_MIXIN(TestClient);
|
| +public:
|
| + void onStateChange() override { ++m_numOnStateChangeCalled; }
|
| + int numOnStateChangeCalled() const { return m_numOnStateChangeCalled; }
|
| +
|
| +private:
|
| + int m_numOnStateChangeCalled = 0;
|
| +};
|
| +
|
| +class BlobBytesConsumerTest : public ::testing::Test {
|
| +public:
|
| + BlobBytesConsumerTest()
|
| + : m_dummyPageHolder(DummyPageHolder::create(IntSize(1, 1))) {}
|
| +
|
| + Document& document() { return m_dummyPageHolder->document(); }
|
| +
|
| +private:
|
| + std::unique_ptr<DummyPageHolder> m_dummyPageHolder;
|
| +};
|
| +
|
| +TEST_F(BlobBytesConsumerTest, TwoPhaseRead)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| + std::unique_ptr<ReplayingHandle> src = ReplayingHandle::create();
|
| + src->add(Command(Command::Data, "hello, "));
|
| + src->add(Command(Command::Wait));
|
| + src->add(Command(Command::Data, "world"));
|
| + src->add(Command(Command::Done));
|
| +
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| +
|
| + const char* buffer = nullptr;
|
| + size_t available = 0;
|
| + EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
|
| + EXPECT_TRUE(loader->isStarted());
|
| + EXPECT_FALSE(consumer->drainAsBlobDataHandle(BytesConsumer::BlobSizePolicy::AllowBlobWithInvalidSize));
|
| + EXPECT_FALSE(consumer->drainAsFormData());
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| +
|
| + consumer->didReceiveResponse(0, ResourceResponse(), std::move(src));
|
| + consumer->didFinishLoading(0, 0);
|
| +
|
| + auto result = (new BytesConsumerTestUtil::TwoPhaseReader(consumer))->run();
|
| + EXPECT_EQ(Result::Done, result.first);
|
| + EXPECT_EQ("hello, world", toString(result.second));
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, FailLoading)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| + TestClient* client = new TestClient();
|
| + consumer->setClient(client);
|
| +
|
| + const char* buffer = nullptr;
|
| + size_t available = 0;
|
| + EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
|
| + EXPECT_TRUE(loader->isStarted());
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| +
|
| + int numOnStateChangeCalled = client->numOnStateChangeCalled();
|
| + consumer->didFail(ResourceError());
|
| +
|
| + EXPECT_EQ(numOnStateChangeCalled + 1, client->numOnStateChangeCalled());
|
| + EXPECT_EQ(PublicState::Errored, consumer->getPublicState());
|
| + EXPECT_EQ(Result::Error, consumer->beginRead(&buffer, &available));
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, FailLoadingAfterResponseReceived)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| + TestClient* client = new TestClient();
|
| + consumer->setClient(client);
|
| +
|
| + const char* buffer = nullptr;
|
| + size_t available;
|
| + EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
|
| + EXPECT_TRUE(loader->isStarted());
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| +
|
| + int numOnStateChangeCalled = client->numOnStateChangeCalled();
|
| + consumer->didReceiveResponse(0, ResourceResponse(), createWaitingDataConsumerHandle());
|
| + EXPECT_EQ(numOnStateChangeCalled + 1, client->numOnStateChangeCalled());
|
| + EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| +
|
| + consumer->didFail(ResourceError());
|
| + EXPECT_EQ(numOnStateChangeCalled + 2, client->numOnStateChangeCalled());
|
| + EXPECT_EQ(PublicState::Errored, consumer->getPublicState());
|
| + EXPECT_EQ(Result::Error, consumer->beginRead(&buffer, &available));
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, FailAccessControlCheck)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| + TestClient* client = new TestClient();
|
| + consumer->setClient(client);
|
| +
|
| + const char* buffer = nullptr;
|
| + size_t available;
|
| + EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
|
| + EXPECT_TRUE(loader->isStarted());
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| +
|
| + int numOnStateChangeCalled = client->numOnStateChangeCalled();
|
| + consumer->didFailAccessControlCheck(ResourceError());
|
| + EXPECT_EQ(numOnStateChangeCalled + 1, client->numOnStateChangeCalled());
|
| +
|
| + EXPECT_EQ(PublicState::Errored, consumer->getPublicState());
|
| + EXPECT_EQ(Result::Error, consumer->beginRead(&buffer, &available));
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, CancelBeforeStarting)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| + TestClient* client = new TestClient();
|
| + consumer->setClient(client);
|
| +
|
| + consumer->cancel();
|
| + // This should be FALSE in production, but TRUE here because we set the
|
| + // loader before starting loading in tests.
|
| + EXPECT_TRUE(loader->isCancelled());
|
| +
|
| + const char* buffer = nullptr;
|
| + size_t available;
|
| + EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
|
| + EXPECT_EQ(PublicState::Closed, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| + EXPECT_EQ(0, client->numOnStateChangeCalled());
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, CancelAfterStarting)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| + TestClient* client = new TestClient();
|
| + consumer->setClient(client);
|
| +
|
| + const char* buffer = nullptr;
|
| + size_t available;
|
| + EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_TRUE(loader->isStarted());
|
| + EXPECT_EQ(0, client->numOnStateChangeCalled());
|
| +
|
| + consumer->cancel();
|
| + EXPECT_TRUE(loader->isCancelled());
|
| + EXPECT_EQ(PublicState::Closed, consumer->getPublicState());
|
| + EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
|
| + EXPECT_EQ(0, client->numOnStateChangeCalled());
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, ReadLastChunkBeforeDidFinishLoadingArrives)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| + TestClient* client = new TestClient();
|
| + consumer->setClient(client);
|
| + std::unique_ptr<ReplayingHandle> src = ReplayingHandle::create();
|
| + src->add(Command(Command::Data, "hello"));
|
| + src->add(Command(Command::Done));
|
| +
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| +
|
| + const char* buffer = nullptr;
|
| + size_t available;
|
| + EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_TRUE(loader->isStarted());
|
| + EXPECT_EQ(0, client->numOnStateChangeCalled());
|
| +
|
| + consumer->didReceiveResponse(0, ResourceResponse(), std::move(src));
|
| + EXPECT_EQ(1, client->numOnStateChangeCalled());
|
| + testing::runPendingTasks();
|
| + EXPECT_EQ(2, client->numOnStateChangeCalled());
|
| +
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available));
|
| + ASSERT_EQ(5u, available);
|
| + EXPECT_EQ("hello", String(buffer, available));
|
| + ASSERT_EQ(Result::Ok, consumer->endRead(available));
|
| +
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + ASSERT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| +
|
| + consumer->didFinishLoading(0, 0);
|
| + EXPECT_EQ(3, client->numOnStateChangeCalled());
|
| + EXPECT_EQ(PublicState::Closed, consumer->getPublicState());
|
| + ASSERT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, ReadLastChunkAfterDidFinishLoadingArrives)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| + TestClient* client = new TestClient();
|
| + consumer->setClient(client);
|
| + std::unique_ptr<ReplayingHandle> src = ReplayingHandle::create();
|
| + src->add(Command(Command::Data, "hello"));
|
| + src->add(Command(Command::Done));
|
| +
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| +
|
| + const char* buffer = nullptr;
|
| + size_t available;
|
| + EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_TRUE(loader->isStarted());
|
| + EXPECT_EQ(0, client->numOnStateChangeCalled());
|
| +
|
| + consumer->didReceiveResponse(0, ResourceResponse(), std::move(src));
|
| + EXPECT_EQ(1, client->numOnStateChangeCalled());
|
| + testing::runPendingTasks();
|
| + EXPECT_EQ(2, client->numOnStateChangeCalled());
|
| +
|
| + consumer->didFinishLoading(0, 0);
|
| + testing::runPendingTasks();
|
| + EXPECT_EQ(2, client->numOnStateChangeCalled());
|
| +
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available));
|
| + ASSERT_EQ(5u, available);
|
| + EXPECT_EQ("hello", String(buffer, available));
|
| + ASSERT_EQ(Result::Ok, consumer->endRead(available));
|
| +
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
|
| + EXPECT_EQ(2, client->numOnStateChangeCalled());
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, DrainAsBlobDataHandle)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| +
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| +
|
| + RefPtr<BlobDataHandle> result = consumer->drainAsBlobDataHandle(BytesConsumer::BlobSizePolicy::DisallowBlobWithInvalidSize);
|
| + ASSERT_TRUE(result);
|
| + EXPECT_FALSE(consumer->drainAsBlobDataHandle(BytesConsumer::BlobSizePolicy::DisallowBlobWithInvalidSize));
|
| + EXPECT_EQ(12345u, result->size());
|
| + EXPECT_EQ(PublicState::Closed, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| +}
|
| +
|
| +
|
| +TEST_F(BlobBytesConsumerTest, DrainAsBlobDataHandle_2)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), -1);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| +
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| +
|
| + RefPtr<BlobDataHandle> result = consumer->drainAsBlobDataHandle(BytesConsumer::BlobSizePolicy::AllowBlobWithInvalidSize);
|
| + ASSERT_TRUE(result);
|
| + EXPECT_FALSE(consumer->drainAsBlobDataHandle(BytesConsumer::BlobSizePolicy::AllowBlobWithInvalidSize));
|
| + EXPECT_EQ(UINT64_MAX, result->size());
|
| + EXPECT_EQ(PublicState::Closed, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, DrainAsBlobDataHandle_3)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), -1);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| +
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| +
|
| + EXPECT_FALSE(consumer->drainAsBlobDataHandle(BytesConsumer::BlobSizePolicy::DisallowBlobWithInvalidSize));
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, DrainAsFormData)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| +
|
| + EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| +
|
| + RefPtr<EncodedFormData> result = consumer->drainAsFormData();
|
| + ASSERT_TRUE(result);
|
| + ASSERT_EQ(1u, result->elements().size());
|
| + ASSERT_EQ(FormDataElement::encodedBlob, result->elements()[0].m_type);
|
| + ASSERT_TRUE(result->elements()[0].m_optionalBlobDataHandle);
|
| + EXPECT_EQ(12345u, result->elements()[0].m_optionalBlobDataHandle->size());
|
| + EXPECT_EQ(blobDataHandle->uuid(), result->elements()[0].m_blobUUID);
|
| + EXPECT_EQ(PublicState::Closed, consumer->getPublicState());
|
| + EXPECT_FALSE(loader->isStarted());
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, LoaderShouldBeCancelled)
|
| +{
|
| + {
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + TestThreadableLoader* loader = new TestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| +
|
| + const char* buffer = nullptr;
|
| + size_t available;
|
| + EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
|
| + EXPECT_TRUE(loader->isStarted());
|
| + loader->setShouldBeCancelled();
|
| + }
|
| + ThreadState::current()->collectAllGarbage();
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, SyncErrorDispatch)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + SyncErrorTestThreadableLoader* loader = new SyncErrorTestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| + loader->setClient(consumer);
|
| + TestClient* client = new TestClient();
|
| + consumer->setClient(client);
|
| +
|
| + const char* buffer = nullptr;
|
| + size_t available;
|
| + EXPECT_EQ(Result::Error, consumer->beginRead(&buffer, &available));
|
| + EXPECT_TRUE(loader->isStarted());
|
| +
|
| + EXPECT_EQ(0, client->numOnStateChangeCalled());
|
| + EXPECT_EQ(BytesConsumer::PublicState::Errored, consumer->getPublicState());
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, SyncLoading)
|
| +{
|
| + RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::create(), 12345);
|
| + SyncLoadingTestThreadableLoader* loader = new SyncLoadingTestThreadableLoader();
|
| + BlobBytesConsumer* consumer = BlobBytesConsumer::createForTesting(&document(), blobDataHandle, loader);
|
| + std::unique_ptr<ReplayingHandle> src = ReplayingHandle::create();
|
| + src->add(Command(Command::Data, "hello, "));
|
| + src->add(Command(Command::Wait));
|
| + src->add(Command(Command::Data, "world"));
|
| + src->add(Command(Command::Done));
|
| + loader->setClient(consumer);
|
| + loader->setHandle(std::move(src));
|
| + TestClient* client = new TestClient();
|
| + consumer->setClient(client);
|
| +
|
| + const char* buffer = nullptr;
|
| + size_t available;
|
| + ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available));
|
| + EXPECT_TRUE(loader->isStarted());
|
| + ASSERT_EQ(7u, available);
|
| + EXPECT_EQ("hello, ", String(buffer, available));
|
| +
|
| + EXPECT_EQ(0, client->numOnStateChangeCalled());
|
| + EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, consumer->getPublicState());
|
| +}
|
| +
|
| +TEST_F(BlobBytesConsumerTest, ConstructedFromNullHandle)
|
| +{
|
| + BlobBytesConsumer* consumer = new BlobBytesConsumer(&document(), nullptr);
|
| + const char* buffer = nullptr;
|
| + size_t available;
|
| + EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState());
|
| + EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +} // namespace blink
|
|
|