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

Unified Diff: third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp

Issue 1665413004: toBlob: If idle image encoding is postponed for too long, switch to main thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed unnecessary include in unit test Created 4 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8ea339267604b23a3890efac1af160eb074122c5
--- /dev/null
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp
@@ -0,0 +1,195 @@
+// 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 "core/html/canvas/CanvasAsyncBlobCreator.h"
+
+#include "core/html/ImageData.h"
+#include "platform/Task.h"
+#include "platform/testing/UnitTestHelpers.h"
+#include "public/platform/Platform.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "wtf/Functional.h"
+
+namespace blink {
+
+typedef CanvasAsyncBlobCreator::IdleTaskStatus IdleTaskStatus;
+
+class MockCanvasAsyncBlobCreator : public CanvasAsyncBlobCreator {
+public:
+ MockCanvasAsyncBlobCreator(PassRefPtr<DOMUint8ClampedArray> data, const IntSize& size)
+ : CanvasAsyncBlobCreator(data, "image/png", size, nullptr)
+ {
+ }
+
+ CanvasAsyncBlobCreator::IdleTaskStatus idleTaskStatus()
+ {
+ return m_idleTaskStatus;
+ }
+
+ MOCK_METHOD0(signalTaskSwitchInStartTimeoutEventForTesting, void());
+ MOCK_METHOD0(signalTaskSwitchInCompleteTimeoutEventForTesting, void());
+
+protected:
+ void createBlobAndCall() override { };
+ void createNullptrAndCall() override { };
+ void clearAlternativeSelfReference() override;
+ void postDelayedTaskToMainThread(const WebTraceLocation&, Task*, double delayMs) override;
+};
+
+void MockCanvasAsyncBlobCreator::clearAlternativeSelfReference()
+{
+ testing::exitRunLoop();
+}
+
+void MockCanvasAsyncBlobCreator::postDelayedTaskToMainThread(const WebTraceLocation& location, Task* task, double delayMs)
+{
+ Platform::current()->mainThread()->taskRunner()->postTask(location, task);
+}
+
+//==============================================================================
+
+class MockCanvasAsyncBlobCreatorWithoutStart : public MockCanvasAsyncBlobCreator {
+public:
+ MockCanvasAsyncBlobCreatorWithoutStart(PassRefPtr<DOMUint8ClampedArray> data, const IntSize& size)
+ : MockCanvasAsyncBlobCreator(data, size)
+ {
+ }
+
+protected:
+ void scheduleInitiatePngEncoding() override
+ {
+ // Deliberately make scheduleInitiatePngEncoding do nothing so that idle task never starts
+ this->clearSelfReference();
+ }
+};
+
+//==============================================================================
+
+class MockCanvasAsyncBlobCreatorWithoutComplete : public MockCanvasAsyncBlobCreator {
+public:
+ MockCanvasAsyncBlobCreatorWithoutComplete(PassRefPtr<DOMUint8ClampedArray> data, const IntSize& size)
+ : MockCanvasAsyncBlobCreator(data, size)
+ {
+ }
+
+protected:
+ void scheduleInitiatePngEncoding() override
+ {
+ Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE,
+ bind(&MockCanvasAsyncBlobCreatorWithoutComplete::initiatePngEncoding, this, std::numeric_limits<double>::max()));
+ }
+
+ void idleEncodeRowsPng(double deadlineSeconds) override
+ {
+ // Deliberately make idleEncodeRowsPng do nothing so that idle task never completes
+ this->clearSelfReference();
+ }
+};
+
+//==============================================================================
+
+class CanvasAsyncBlobCreatorTest : public ::testing::Test {
+public:
+ void prepareMockCanvasAsyncBlobCreatorWithoutStart();
+ void prepareMockCanvasAsyncBlobCreatorWithoutComplete();
+ void prepareMockCanvasAsyncBlobCreatorFail();
+
+protected:
+ CanvasAsyncBlobCreatorTest();
+ MockCanvasAsyncBlobCreator* asyncBlobCreator() { return m_asyncBlobCreator.get(); }
+ void TearDown() override;
+
+private:
+ RefPtr<MockCanvasAsyncBlobCreator> m_asyncBlobCreator;
+};
+
+CanvasAsyncBlobCreatorTest::CanvasAsyncBlobCreatorTest()
+{
+}
+
+void CanvasAsyncBlobCreatorTest::prepareMockCanvasAsyncBlobCreatorWithoutStart()
+{
+ IntSize testSize(20, 20);
+ ImageData* imageData = ImageData::create(testSize);
+ RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data());
+
+ m_asyncBlobCreator = adoptRef(new MockCanvasAsyncBlobCreatorWithoutStart(imageDataRef.release(), testSize));
+}
+
+void CanvasAsyncBlobCreatorTest::prepareMockCanvasAsyncBlobCreatorWithoutComplete()
+{
+ IntSize testSize(20, 20);
+ ImageData* imageData = ImageData::create(testSize);
+ RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data());
+
+ m_asyncBlobCreator = adoptRef(new MockCanvasAsyncBlobCreatorWithoutComplete(imageDataRef.release(), testSize));
+}
+
+void CanvasAsyncBlobCreatorTest::prepareMockCanvasAsyncBlobCreatorFail()
+{
+ IntSize testSize(0, 0);
+ ImageData* imageData = ImageData::create(testSize);
+ RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data());
+
+ // We reuse the class MockCanvasAsyncBlobCreatorWithoutComplete because this
+ // test case is expected to fail at initialization step before completion.
+ m_asyncBlobCreator = adoptRef(new MockCanvasAsyncBlobCreatorWithoutComplete(imageDataRef.release(), testSize));
+}
+
+void CanvasAsyncBlobCreatorTest::TearDown()
+{
+ ASSERT(!!m_asyncBlobCreator->m_alternativeSelfRef);
+ m_asyncBlobCreator->m_alternativeSelfRef.clear();
+ m_asyncBlobCreator = nullptr;
+}
+
+//==============================================================================
+
+TEST_F(CanvasAsyncBlobCreatorTest, IdleTaskNotStartedWhenStartTimeoutEventHappens)
+{
+ // This test mocks the scenario when idle task is not started when the
+ // StartTimeoutEvent is inspecting the idle task status.
+ // The whole image encoding process (including initialization) will then
+ // become carried out in the alternative code path instead.
+ this->prepareMockCanvasAsyncBlobCreatorWithoutStart();
+ EXPECT_CALL(*(asyncBlobCreator()), signalTaskSwitchInStartTimeoutEventForTesting());
+
+ this->asyncBlobCreator()->scheduleAsyncBlobCreation(true);
+ testing::enterRunLoop();
+
+ ::testing::Mock::VerifyAndClearExpectations(asyncBlobCreator());
+ EXPECT_EQ(IdleTaskStatus::IdleTaskSwitchedToMainThreadTask, this->asyncBlobCreator()->idleTaskStatus());
+}
+
+TEST_F(CanvasAsyncBlobCreatorTest, IdleTaskNotCompletedWhenCompleteTimeoutEventHappens)
+{
+ // This test mocks the scenario when idle task is not completed when the
+ // CompleteTimeoutEvent is inspecting the idle task status.
+ // The remaining image encoding process (excluding initialization) will
+ // then become carried out in the alternative code path instead.
+ this->prepareMockCanvasAsyncBlobCreatorWithoutComplete();
+ EXPECT_CALL(*(asyncBlobCreator()), signalTaskSwitchInCompleteTimeoutEventForTesting());
+
+ this->asyncBlobCreator()->scheduleAsyncBlobCreation(true);
+ testing::enterRunLoop();
+
+ ::testing::Mock::VerifyAndClearExpectations(asyncBlobCreator());
+ EXPECT_EQ(IdleTaskStatus::IdleTaskSwitchedToMainThreadTask, this->asyncBlobCreator()->idleTaskStatus());
+}
+
+TEST_F(CanvasAsyncBlobCreatorTest, IdleTaskFailedWhenStartTimeoutEventHappens)
+{
+ // This test mocks the scenario when idle task is not failed during when
+ // either the StartTimeoutEvent or the CompleteTimeoutEvent is inspecting
+ // the idle task status.
+ this->prepareMockCanvasAsyncBlobCreatorFail();
+
+ this->asyncBlobCreator()->scheduleAsyncBlobCreation(true);
+ testing::enterRunLoop();
+
+ EXPECT_EQ(IdleTaskStatus::IdleTaskFailed, this->asyncBlobCreator()->idleTaskStatus());
+}
+
+}
« no previous file with comments | « third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698