| Index: third_party/WebKit/Source/platform/scheduler/base/work_queue_unittest.cc
|
| diff --git a/third_party/WebKit/Source/platform/scheduler/base/work_queue_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/work_queue_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8ccf587392223e0537dc617abc41f1067ba97977
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Source/platform/scheduler/base/work_queue_unittest.cc
|
| @@ -0,0 +1,362 @@
|
| +// Copyright 2015 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 "platform/scheduler/base/work_queue.h"
|
| +
|
| +#include <stddef.h>
|
| +
|
| +#include "base/memory/ptr_util.h"
|
| +#include "platform/scheduler/base/real_time_domain.h"
|
| +#include "platform/scheduler/base/task_queue_impl.h"
|
| +#include "platform/scheduler/base/work_queue_sets.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +
|
| +namespace blink {
|
| +namespace scheduler {
|
| +namespace internal {
|
| +
|
| +class WorkQueueTest : public testing::Test {
|
| + public:
|
| + void SetUp() override {
|
| + time_domain_.reset(new RealTimeDomain(""));
|
| + task_queue_ = make_scoped_refptr(new TaskQueueImpl(
|
| + nullptr, time_domain_.get(), TaskQueue::Spec("fake"), "", ""));
|
| +
|
| + work_queue_.reset(
|
| + new WorkQueue(task_queue_.get(), "test",
|
| + TaskQueueImpl::Task::EnqueueOrderComparatorFn));
|
| + work_queue_sets_.reset(new WorkQueueSets(1, "test"));
|
| + work_queue_sets_->AddQueue(work_queue_.get(), 0);
|
| +
|
| + incoming_queue_.reset(new TaskQueueImpl::ComparatorQueue(
|
| + TaskQueueImpl::Task::EnqueueOrderComparatorFn));
|
| + }
|
| +
|
| + void TearDown() override { work_queue_sets_->RemoveQueue(work_queue_.get()); }
|
| +
|
| + protected:
|
| + TaskQueueImpl::Task FakeTaskWithEnqueueOrder(int enqueue_order) {
|
| + TaskQueueImpl::Task fake_task(FROM_HERE, base::Closure(), base::TimeTicks(),
|
| + 0, true);
|
| + fake_task.set_enqueue_order(enqueue_order);
|
| + return fake_task;
|
| + }
|
| +
|
| + std::unique_ptr<RealTimeDomain> time_domain_;
|
| + scoped_refptr<TaskQueueImpl> task_queue_;
|
| + std::unique_ptr<WorkQueue> work_queue_;
|
| + std::unique_ptr<WorkQueueSets> work_queue_sets_;
|
| + std::unique_ptr<TaskQueueImpl::ComparatorQueue> incoming_queue_;
|
| +};
|
| +
|
| +TEST_F(WorkQueueTest, Empty) {
|
| + EXPECT_TRUE(work_queue_->Empty());
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(1));
|
| + EXPECT_FALSE(work_queue_->Empty());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, Empty_IgnoresFences) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(1));
|
| + work_queue_->InsertFence(1);
|
| + EXPECT_FALSE(work_queue_->Empty());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, GetFrontTaskEnqueueOrderQueueEmpty) {
|
| + EnqueueOrder enqueue_order;
|
| + EXPECT_FALSE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, GetFrontTaskEnqueueOrder) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(3));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(4));
|
| +
|
| + EnqueueOrder enqueue_order;
|
| + EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
|
| + EXPECT_EQ(2ull, enqueue_order);
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, GetFrontTaskQueueEmpty) {
|
| + EXPECT_EQ(nullptr, work_queue_->GetFrontTask());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, GetFrontTask) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(3));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(4));
|
| +
|
| + ASSERT_NE(nullptr, work_queue_->GetFrontTask());
|
| + EXPECT_EQ(2ull, work_queue_->GetFrontTask()->enqueue_order());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, GetBackTask_Empty) {
|
| + EXPECT_EQ(nullptr, work_queue_->GetBackTask());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, GetBackTask) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(3));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(4));
|
| +
|
| + ASSERT_NE(nullptr, work_queue_->GetBackTask());
|
| + EXPECT_EQ(4ull, work_queue_->GetBackTask()->enqueue_order());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, Push) {
|
| + WorkQueue* work_queue;
|
| + EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| +
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_EQ(work_queue_.get(), work_queue);
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, PushAfterFenceHit) {
|
| + work_queue_->InsertFence(1);
|
| + WorkQueue* work_queue;
|
| + EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| +
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, SwapLocked) {
|
| + incoming_queue_->insert(FakeTaskWithEnqueueOrder(2));
|
| + incoming_queue_->insert(FakeTaskWithEnqueueOrder(3));
|
| + incoming_queue_->insert(FakeTaskWithEnqueueOrder(4));
|
| +
|
| + WorkQueue* work_queue;
|
| + EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_TRUE(work_queue_->Empty());
|
| + work_queue_->SwapLocked(*incoming_queue_.get());
|
| +
|
| + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_FALSE(work_queue_->Empty());
|
| + EXPECT_TRUE(incoming_queue_->empty());
|
| +
|
| + ASSERT_NE(nullptr, work_queue_->GetFrontTask());
|
| + EXPECT_EQ(2ull, work_queue_->GetFrontTask()->enqueue_order());
|
| +
|
| + ASSERT_NE(nullptr, work_queue_->GetBackTask());
|
| + EXPECT_EQ(4ull, work_queue_->GetBackTask()->enqueue_order());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, SwapLockedAfterFenceHit) {
|
| + work_queue_->InsertFence(1);
|
| + incoming_queue_->insert(FakeTaskWithEnqueueOrder(2));
|
| + incoming_queue_->insert(FakeTaskWithEnqueueOrder(3));
|
| + incoming_queue_->insert(FakeTaskWithEnqueueOrder(4));
|
| +
|
| + WorkQueue* work_queue;
|
| + EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_TRUE(work_queue_->Empty());
|
| + work_queue_->SwapLocked(*incoming_queue_.get());
|
| +
|
| + EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_FALSE(work_queue_->Empty());
|
| + EXPECT_TRUE(incoming_queue_->empty());
|
| +
|
| + ASSERT_NE(nullptr, work_queue_->GetFrontTask());
|
| + EXPECT_EQ(2ull, work_queue_->GetFrontTask()->enqueue_order());
|
| +
|
| + ASSERT_NE(nullptr, work_queue_->GetBackTask());
|
| + EXPECT_EQ(4ull, work_queue_->GetBackTask()->enqueue_order());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, TakeTaskFromWorkQueue) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(3));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(4));
|
| +
|
| + WorkQueue* work_queue;
|
| + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_FALSE(work_queue_->Empty());
|
| +
|
| + EXPECT_EQ(2ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| + EXPECT_EQ(3ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| + EXPECT_EQ(4ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| +
|
| + EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_TRUE(work_queue_->Empty());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, TakeTaskFromWorkQueue_HitFence) {
|
| + work_queue_->InsertFence(3);
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(4));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +
|
| + WorkQueue* work_queue;
|
| + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_FALSE(work_queue_->Empty());
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +
|
| + EXPECT_EQ(2ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| + EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_FALSE(work_queue_->Empty());
|
| + EXPECT_TRUE(work_queue_->BlockedByFence());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, InsertFenceBeforeEnqueueing) {
|
| + EXPECT_FALSE(work_queue_->InsertFence(1));
|
| + EXPECT_TRUE(work_queue_->BlockedByFence());
|
| +
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(3));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(4));
|
| +
|
| + EnqueueOrder enqueue_order;
|
| + EXPECT_FALSE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, InsertFenceAfterEnqueueingNonBlocking) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(3));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(4));
|
| +
|
| + EXPECT_FALSE(work_queue_->InsertFence(5));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +
|
| + EnqueueOrder enqueue_order;
|
| + EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
|
| + EXPECT_EQ(2ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, InsertFenceAfterEnqueueing) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(3));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(4));
|
| +
|
| + // NB in reality a fence will always be greater than any currently enqueued
|
| + // tasks.
|
| + EXPECT_FALSE(work_queue_->InsertFence(1));
|
| + EXPECT_TRUE(work_queue_->BlockedByFence());
|
| +
|
| + EnqueueOrder enqueue_order;
|
| + EXPECT_FALSE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, InsertNewFence) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(4));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(5));
|
| +
|
| + EXPECT_FALSE(work_queue_->InsertFence(3));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +
|
| + // Note until TakeTaskFromWorkQueue() is called we don't hit the fence.
|
| + EnqueueOrder enqueue_order;
|
| + EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
|
| + EXPECT_EQ(2ull, enqueue_order);
|
| +
|
| + EXPECT_EQ(2ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| + EXPECT_FALSE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
|
| + EXPECT_TRUE(work_queue_->BlockedByFence());
|
| +
|
| + // Inserting the new fence should temporarily unblock the queue until the new
|
| + // one is hit.
|
| + EXPECT_TRUE(work_queue_->InsertFence(6));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +
|
| + EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
|
| + EXPECT_EQ(4ull, enqueue_order);
|
| + EXPECT_EQ(4ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| + EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, PushWithNonEmptyQueueDoesNotHitFence) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(1));
|
| + EXPECT_FALSE(work_queue_->InsertFence(2));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(3));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, RemoveFence) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(4));
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(5));
|
| + work_queue_->InsertFence(3);
|
| +
|
| + WorkQueue* work_queue;
|
| + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_FALSE(work_queue_->Empty());
|
| +
|
| + EXPECT_EQ(2ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| + EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_FALSE(work_queue_->Empty());
|
| + EXPECT_TRUE(work_queue_->BlockedByFence());
|
| +
|
| + EXPECT_TRUE(work_queue_->RemoveFence());
|
| + EXPECT_EQ(4ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, RemoveFenceButNoFence) {
|
| + EXPECT_FALSE(work_queue_->RemoveFence());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, RemoveFenceNothingUnblocked) {
|
| + EXPECT_FALSE(work_queue_->InsertFence(1));
|
| + EXPECT_TRUE(work_queue_->BlockedByFence());
|
| +
|
| + EXPECT_FALSE(work_queue_->RemoveFence());
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, BlockedByFence) {
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| + EXPECT_FALSE(work_queue_->InsertFence(1));
|
| + EXPECT_TRUE(work_queue_->BlockedByFence());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, BlockedByFencePopBecomesEmpty) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(1));
|
| + EXPECT_FALSE(work_queue_->InsertFence(2));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +
|
| + EXPECT_EQ(1ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| + EXPECT_TRUE(work_queue_->BlockedByFence());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, BlockedByFencePop) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(1));
|
| + EXPECT_FALSE(work_queue_->InsertFence(2));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(3));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +
|
| + EXPECT_EQ(1ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| + EXPECT_TRUE(work_queue_->BlockedByFence());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, InitiallyEmptyBlockedByFenceNewFenceUnblocks) {
|
| + EXPECT_FALSE(work_queue_->InsertFence(1));
|
| + EXPECT_TRUE(work_queue_->BlockedByFence());
|
| +
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(2));
|
| + EXPECT_TRUE(work_queue_->InsertFence(3));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +}
|
| +
|
| +TEST_F(WorkQueueTest, BlockedByFenceNewFenceUnblocks) {
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(1));
|
| + EXPECT_FALSE(work_queue_->InsertFence(2));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +
|
| + work_queue_->Push(FakeTaskWithEnqueueOrder(3));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +
|
| + EXPECT_EQ(1ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
|
| + EXPECT_TRUE(work_queue_->BlockedByFence());
|
| +
|
| + EXPECT_TRUE(work_queue_->InsertFence(4));
|
| + EXPECT_FALSE(work_queue_->BlockedByFence());
|
| +}
|
| +
|
| +} // namespace internal
|
| +} // namespace scheduler
|
| +} // namespace blink
|
|
|