Index: net/base/prioritized_dispatcher_unittest.cc |
diff --git a/net/base/prioritized_dispatcher_unittest.cc b/net/base/prioritized_dispatcher_unittest.cc |
deleted file mode 100644 |
index 44ffb57780c16b8f230f71db22ab767786a0f662..0000000000000000000000000000000000000000 |
--- a/net/base/prioritized_dispatcher_unittest.cc |
+++ /dev/null |
@@ -1,567 +0,0 @@ |
-// Copyright (c) 2012 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 <ctype.h> |
-#include <string> |
- |
-#include "base/compiler_specific.h" |
-#include "base/logging.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/memory/scoped_vector.h" |
-#include "net/base/prioritized_dispatcher.h" |
-#include "net/base/request_priority.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-namespace net { |
- |
-namespace { |
- |
-// We rely on the priority enum values being sequential having starting at 0, |
-// and increasing for higher priorities. |
-static_assert(MINIMUM_PRIORITY == 0u && MINIMUM_PRIORITY == IDLE && |
- IDLE < LOWEST && LOWEST < HIGHEST && |
- HIGHEST <= MAXIMUM_PRIORITY, |
- "priority indexes incompatible"); |
- |
-class PrioritizedDispatcherTest : public testing::Test { |
- public: |
- typedef PrioritizedDispatcher::Priority Priority; |
- // A job that appends |tag| to |log| when started and '.' when finished. |
- // This is intended to confirm the execution order of a sequence of jobs added |
- // to the dispatcher. Note that finishing order of jobs does not matter. |
- class TestJob : public PrioritizedDispatcher::Job { |
- public: |
- TestJob(PrioritizedDispatcher* dispatcher, |
- char tag, |
- Priority priority, |
- std::string* log) |
- : dispatcher_(dispatcher), |
- tag_(tag), |
- priority_(priority), |
- running_(false), |
- log_(log) {} |
- |
- bool running() const { |
- return running_; |
- } |
- |
- const PrioritizedDispatcher::Handle handle() const { |
- return handle_; |
- } |
- |
- void Add(bool at_head) { |
- CHECK(handle_.is_null()); |
- CHECK(!running_); |
- size_t num_queued = dispatcher_->num_queued_jobs(); |
- size_t num_running = dispatcher_->num_running_jobs(); |
- |
- if (!at_head) { |
- handle_ = dispatcher_->Add(this, priority_); |
- } else { |
- handle_ = dispatcher_->AddAtHead(this, priority_); |
- } |
- |
- if (handle_.is_null()) { |
- EXPECT_EQ(num_queued, dispatcher_->num_queued_jobs()); |
- EXPECT_TRUE(running_); |
- EXPECT_EQ(num_running + 1, dispatcher_->num_running_jobs()); |
- } else { |
- EXPECT_FALSE(running_); |
- EXPECT_EQ(priority_, handle_.priority()); |
- EXPECT_EQ(tag_, reinterpret_cast<TestJob*>(handle_.value())->tag_); |
- EXPECT_EQ(num_running, dispatcher_->num_running_jobs()); |
- } |
- } |
- |
- void ChangePriority(Priority priority) { |
- CHECK(!handle_.is_null()); |
- CHECK(!running_); |
- size_t num_queued = dispatcher_->num_queued_jobs(); |
- size_t num_running = dispatcher_->num_running_jobs(); |
- |
- handle_ = dispatcher_->ChangePriority(handle_, priority); |
- |
- if (handle_.is_null()) { |
- EXPECT_TRUE(running_); |
- EXPECT_EQ(num_queued - 1, dispatcher_->num_queued_jobs()); |
- EXPECT_EQ(num_running + 1, dispatcher_->num_running_jobs()); |
- } else { |
- EXPECT_FALSE(running_); |
- EXPECT_EQ(priority, handle_.priority()); |
- EXPECT_EQ(tag_, reinterpret_cast<TestJob*>(handle_.value())->tag_); |
- EXPECT_EQ(num_queued, dispatcher_->num_queued_jobs()); |
- EXPECT_EQ(num_running, dispatcher_->num_running_jobs()); |
- } |
- } |
- |
- void Cancel() { |
- CHECK(!handle_.is_null()); |
- CHECK(!running_); |
- size_t num_queued = dispatcher_->num_queued_jobs(); |
- |
- dispatcher_->Cancel(handle_); |
- |
- EXPECT_EQ(num_queued - 1, dispatcher_->num_queued_jobs()); |
- handle_ = PrioritizedDispatcher::Handle(); |
- } |
- |
- void Finish() { |
- CHECK(running_); |
- running_ = false; |
- log_->append(1u, '.'); |
- |
- dispatcher_->OnJobFinished(); |
- } |
- |
- // PriorityDispatch::Job interface |
- void Start() override { |
- EXPECT_FALSE(running_); |
- handle_ = PrioritizedDispatcher::Handle(); |
- running_ = true; |
- log_->append(1u, tag_); |
- } |
- |
- private: |
- PrioritizedDispatcher* dispatcher_; |
- |
- char tag_; |
- Priority priority_; |
- |
- PrioritizedDispatcher::Handle handle_; |
- bool running_; |
- |
- std::string* log_; |
- }; |
- |
- protected: |
- void Prepare(const PrioritizedDispatcher::Limits& limits) { |
- dispatcher_.reset(new PrioritizedDispatcher(limits)); |
- } |
- |
- TestJob* AddJob(char data, Priority priority) { |
- TestJob* job = new TestJob(dispatcher_.get(), data, priority, &log_); |
- jobs_.push_back(job); |
- job->Add(false); |
- return job; |
- } |
- |
- TestJob* AddJobAtHead(char data, Priority priority) { |
- TestJob* job = new TestJob(dispatcher_.get(), data, priority, &log_); |
- jobs_.push_back(job); |
- job->Add(true); |
- return job; |
- } |
- |
- void Expect(std::string log) { |
- EXPECT_EQ(0u, dispatcher_->num_queued_jobs()); |
- EXPECT_EQ(0u, dispatcher_->num_running_jobs()); |
- EXPECT_EQ(log, log_); |
- log_.clear(); |
- } |
- |
- std::string log_; |
- scoped_ptr<PrioritizedDispatcher> dispatcher_; |
- ScopedVector<TestJob> jobs_; |
-}; |
- |
-TEST_F(PrioritizedDispatcherTest, GetLimits) { |
- // Set non-trivial initial limits. |
- PrioritizedDispatcher::Limits original_limits(NUM_PRIORITIES, 5); |
- original_limits.reserved_slots[HIGHEST] = 1; |
- original_limits.reserved_slots[LOW] = 2; |
- Prepare(original_limits); |
- |
- // Get current limits, make sure the original limits are returned. |
- PrioritizedDispatcher::Limits retrieved_limits = dispatcher_->GetLimits(); |
- ASSERT_EQ(original_limits.total_jobs, retrieved_limits.total_jobs); |
- ASSERT_EQ(NUM_PRIORITIES, retrieved_limits.reserved_slots.size()); |
- for (size_t priority = MINIMUM_PRIORITY; priority <= MAXIMUM_PRIORITY; |
- ++priority) { |
- EXPECT_EQ(original_limits.reserved_slots[priority], |
- retrieved_limits.reserved_slots[priority]); |
- } |
- |
- // Set new limits. |
- PrioritizedDispatcher::Limits new_limits(NUM_PRIORITIES, 6); |
- new_limits.reserved_slots[MEDIUM] = 3; |
- new_limits.reserved_slots[LOWEST] = 1; |
- Prepare(new_limits); |
- |
- // Get current limits, make sure the new limits are returned. |
- retrieved_limits = dispatcher_->GetLimits(); |
- ASSERT_EQ(new_limits.total_jobs, retrieved_limits.total_jobs); |
- ASSERT_EQ(NUM_PRIORITIES, retrieved_limits.reserved_slots.size()); |
- for (size_t priority = MINIMUM_PRIORITY; priority <= MAXIMUM_PRIORITY; |
- ++priority) { |
- EXPECT_EQ(new_limits.reserved_slots[priority], |
- retrieved_limits.reserved_slots[priority]); |
- } |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, AddAFIFO) { |
- // Allow only one running job. |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1); |
- Prepare(limits); |
- |
- TestJob* job_a = AddJob('a', IDLE); |
- TestJob* job_b = AddJob('b', IDLE); |
- TestJob* job_c = AddJob('c', IDLE); |
- TestJob* job_d = AddJob('d', IDLE); |
- |
- ASSERT_TRUE(job_a->running()); |
- job_a->Finish(); |
- ASSERT_TRUE(job_b->running()); |
- job_b->Finish(); |
- ASSERT_TRUE(job_c->running()); |
- job_c->Finish(); |
- ASSERT_TRUE(job_d->running()); |
- job_d->Finish(); |
- |
- Expect("a.b.c.d."); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, AddPriority) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1); |
- Prepare(limits); |
- |
- TestJob* job_a = AddJob('a', IDLE); |
- TestJob* job_b = AddJob('b', MEDIUM); |
- TestJob* job_c = AddJob('c', HIGHEST); |
- TestJob* job_d = AddJob('d', HIGHEST); |
- TestJob* job_e = AddJob('e', MEDIUM); |
- |
- ASSERT_TRUE(job_a->running()); |
- job_a->Finish(); |
- ASSERT_TRUE(job_c->running()); |
- job_c->Finish(); |
- ASSERT_TRUE(job_d->running()); |
- job_d->Finish(); |
- ASSERT_TRUE(job_b->running()); |
- job_b->Finish(); |
- ASSERT_TRUE(job_e->running()); |
- job_e->Finish(); |
- |
- Expect("a.c.d.b.e."); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, AddAtHead) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1); |
- Prepare(limits); |
- |
- TestJob* job_a = AddJob('a', MEDIUM); |
- TestJob* job_b = AddJobAtHead('b', MEDIUM); |
- TestJob* job_c = AddJobAtHead('c', HIGHEST); |
- TestJob* job_d = AddJobAtHead('d', HIGHEST); |
- TestJob* job_e = AddJobAtHead('e', MEDIUM); |
- TestJob* job_f = AddJob('f', MEDIUM); |
- |
- ASSERT_TRUE(job_a->running()); |
- job_a->Finish(); |
- ASSERT_TRUE(job_d->running()); |
- job_d->Finish(); |
- ASSERT_TRUE(job_c->running()); |
- job_c->Finish(); |
- ASSERT_TRUE(job_e->running()); |
- job_e->Finish(); |
- ASSERT_TRUE(job_b->running()); |
- job_b->Finish(); |
- ASSERT_TRUE(job_f->running()); |
- job_f->Finish(); |
- |
- Expect("a.d.c.e.b.f."); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, EnforceLimits) { |
- // Reserve 2 for HIGHEST and 1 for LOW or higher. |
- // This leaves 2 for LOWEST or lower. |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 5); |
- limits.reserved_slots[HIGHEST] = 2; |
- limits.reserved_slots[LOW] = 1; |
- Prepare(limits); |
- |
- TestJob* job_a = AddJob('a', IDLE); // Uses unreserved slot. |
- TestJob* job_b = AddJob('b', IDLE); // Uses unreserved slot. |
- TestJob* job_c = AddJob('c', LOWEST); // Must wait. |
- TestJob* job_d = AddJob('d', LOW); // Uses reserved slot. |
- TestJob* job_e = AddJob('e', MEDIUM); // Must wait. |
- TestJob* job_f = AddJob('f', HIGHEST); // Uses reserved slot. |
- TestJob* job_g = AddJob('g', HIGHEST); // Uses reserved slot. |
- TestJob* job_h = AddJob('h', HIGHEST); // Must wait. |
- |
- EXPECT_EQ(5u, dispatcher_->num_running_jobs()); |
- EXPECT_EQ(3u, dispatcher_->num_queued_jobs()); |
- |
- ASSERT_TRUE(job_a->running()); |
- ASSERT_TRUE(job_b->running()); |
- ASSERT_TRUE(job_d->running()); |
- ASSERT_TRUE(job_f->running()); |
- ASSERT_TRUE(job_g->running()); |
- // a, b, d, f, g are running. Finish them in any order. |
- job_b->Finish(); // Releases h. |
- job_f->Finish(); |
- job_a->Finish(); |
- job_g->Finish(); // Releases e. |
- job_d->Finish(); |
- ASSERT_TRUE(job_e->running()); |
- ASSERT_TRUE(job_h->running()); |
- // h, e are running. |
- job_e->Finish(); // Releases c. |
- ASSERT_TRUE(job_c->running()); |
- job_c->Finish(); |
- job_h->Finish(); |
- |
- Expect("abdfg.h...e..c.."); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, ChangePriority) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 2); |
- // Reserve one slot only for HIGHEST priority requests. |
- limits.reserved_slots[HIGHEST] = 1; |
- Prepare(limits); |
- |
- TestJob* job_a = AddJob('a', IDLE); |
- TestJob* job_b = AddJob('b', LOW); |
- TestJob* job_c = AddJob('c', MEDIUM); |
- TestJob* job_d = AddJob('d', MEDIUM); |
- TestJob* job_e = AddJob('e', IDLE); |
- |
- ASSERT_FALSE(job_b->running()); |
- ASSERT_FALSE(job_c->running()); |
- job_b->ChangePriority(MEDIUM); |
- job_c->ChangePriority(LOW); |
- |
- ASSERT_TRUE(job_a->running()); |
- job_a->Finish(); |
- ASSERT_TRUE(job_d->running()); |
- job_d->Finish(); |
- |
- EXPECT_FALSE(job_e->running()); |
- // Increasing |job_e|'s priority to HIGHEST should result in it being |
- // started immediately. |
- job_e->ChangePriority(HIGHEST); |
- ASSERT_TRUE(job_e->running()); |
- job_e->Finish(); |
- |
- ASSERT_TRUE(job_b->running()); |
- job_b->Finish(); |
- ASSERT_TRUE(job_c->running()); |
- job_c->Finish(); |
- |
- Expect("a.d.be..c."); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, Cancel) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1); |
- Prepare(limits); |
- |
- TestJob* job_a = AddJob('a', IDLE); |
- TestJob* job_b = AddJob('b', IDLE); |
- TestJob* job_c = AddJob('c', IDLE); |
- TestJob* job_d = AddJob('d', IDLE); |
- TestJob* job_e = AddJob('e', IDLE); |
- |
- ASSERT_FALSE(job_b->running()); |
- ASSERT_FALSE(job_d->running()); |
- job_b->Cancel(); |
- job_d->Cancel(); |
- |
- ASSERT_TRUE(job_a->running()); |
- job_a->Finish(); |
- ASSERT_TRUE(job_c->running()); |
- job_c->Finish(); |
- ASSERT_TRUE(job_e->running()); |
- job_e->Finish(); |
- |
- Expect("a.c.e."); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, Evict) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1); |
- Prepare(limits); |
- |
- TestJob* job_a = AddJob('a', IDLE); |
- TestJob* job_b = AddJob('b', LOW); |
- TestJob* job_c = AddJob('c', HIGHEST); |
- TestJob* job_d = AddJob('d', LOW); |
- TestJob* job_e = AddJob('e', HIGHEST); |
- |
- EXPECT_EQ(job_b, dispatcher_->EvictOldestLowest()); |
- EXPECT_EQ(job_d, dispatcher_->EvictOldestLowest()); |
- |
- ASSERT_TRUE(job_a->running()); |
- job_a->Finish(); |
- ASSERT_TRUE(job_c->running()); |
- job_c->Finish(); |
- ASSERT_TRUE(job_e->running()); |
- job_e->Finish(); |
- |
- Expect("a.c.e."); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, EvictFromEmpty) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1); |
- Prepare(limits); |
- EXPECT_TRUE(dispatcher_->EvictOldestLowest() == NULL); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, AddWhileZeroLimits) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 2); |
- Prepare(limits); |
- |
- dispatcher_->SetLimitsToZero(); |
- TestJob* job_a = AddJob('a', LOW); |
- TestJob* job_b = AddJob('b', MEDIUM); |
- TestJob* job_c = AddJobAtHead('c', MEDIUM); |
- |
- EXPECT_EQ(0u, dispatcher_->num_running_jobs()); |
- EXPECT_EQ(3u, dispatcher_->num_queued_jobs()); |
- |
- dispatcher_->SetLimits(limits); |
- EXPECT_EQ(2u, dispatcher_->num_running_jobs()); |
- EXPECT_EQ(1u, dispatcher_->num_queued_jobs()); |
- |
- ASSERT_TRUE(job_b->running()); |
- job_b->Finish(); |
- |
- ASSERT_TRUE(job_c->running()); |
- job_c->Finish(); |
- |
- ASSERT_TRUE(job_a->running()); |
- job_a->Finish(); |
- |
- Expect("cb.a.."); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, ReduceLimitsWhileJobQueued) { |
- PrioritizedDispatcher::Limits initial_limits(NUM_PRIORITIES, 2); |
- Prepare(initial_limits); |
- |
- TestJob* job_a = AddJob('a', MEDIUM); |
- TestJob* job_b = AddJob('b', MEDIUM); |
- TestJob* job_c = AddJob('c', MEDIUM); |
- TestJob* job_d = AddJob('d', MEDIUM); |
- TestJob* job_e = AddJob('e', MEDIUM); |
- |
- EXPECT_EQ(2u, dispatcher_->num_running_jobs()); |
- EXPECT_EQ(3u, dispatcher_->num_queued_jobs()); |
- |
- // Reduce limits to just allow one job at a time. Running jobs should not |
- // be affected. |
- dispatcher_->SetLimits(PrioritizedDispatcher::Limits(NUM_PRIORITIES, 1)); |
- |
- EXPECT_EQ(2u, dispatcher_->num_running_jobs()); |
- EXPECT_EQ(3u, dispatcher_->num_queued_jobs()); |
- |
- // Finishing a job should not result in another job starting. |
- ASSERT_TRUE(job_a->running()); |
- job_a->Finish(); |
- EXPECT_EQ(1u, dispatcher_->num_running_jobs()); |
- EXPECT_EQ(3u, dispatcher_->num_queued_jobs()); |
- |
- ASSERT_TRUE(job_b->running()); |
- job_b->Finish(); |
- EXPECT_EQ(1u, dispatcher_->num_running_jobs()); |
- EXPECT_EQ(2u, dispatcher_->num_queued_jobs()); |
- |
- // Increasing the limits again should let c start. |
- dispatcher_->SetLimits(initial_limits); |
- |
- ASSERT_TRUE(job_c->running()); |
- job_c->Finish(); |
- ASSERT_TRUE(job_d->running()); |
- job_d->Finish(); |
- ASSERT_TRUE(job_e->running()); |
- job_e->Finish(); |
- |
- Expect("ab..cd.e.."); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, ZeroLimitsThenCancel) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1); |
- Prepare(limits); |
- |
- TestJob* job_a = AddJob('a', IDLE); |
- TestJob* job_b = AddJob('b', IDLE); |
- TestJob* job_c = AddJob('c', IDLE); |
- dispatcher_->SetLimitsToZero(); |
- |
- ASSERT_TRUE(job_a->running()); |
- EXPECT_FALSE(job_b->running()); |
- EXPECT_FALSE(job_c->running()); |
- job_a->Finish(); |
- |
- EXPECT_FALSE(job_b->running()); |
- EXPECT_FALSE(job_c->running()); |
- |
- // Cancelling b shouldn't start job c. |
- job_b->Cancel(); |
- EXPECT_FALSE(job_c->running()); |
- |
- // Restoring the limits should start c. |
- dispatcher_->SetLimits(limits); |
- ASSERT_TRUE(job_c->running()); |
- job_c->Finish(); |
- |
- Expect("a.c."); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, ZeroLimitsThenIncreasePriority) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 2); |
- limits.reserved_slots[HIGHEST] = 1; |
- Prepare(limits); |
- |
- TestJob* job_a = AddJob('a', IDLE); |
- TestJob* job_b = AddJob('b', IDLE); |
- EXPECT_TRUE(job_a->running()); |
- EXPECT_FALSE(job_b->running()); |
- dispatcher_->SetLimitsToZero(); |
- |
- job_b->ChangePriority(HIGHEST); |
- EXPECT_FALSE(job_b->running()); |
- job_a->Finish(); |
- EXPECT_FALSE(job_b->running()); |
- |
- job_b->Cancel(); |
- Expect("a."); |
-} |
- |
-#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG) |
-TEST_F(PrioritizedDispatcherTest, CancelNull) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1); |
- Prepare(limits); |
- EXPECT_DEBUG_DEATH(dispatcher_->Cancel(PrioritizedDispatcher::Handle()), ""); |
-} |
- |
-TEST_F(PrioritizedDispatcherTest, CancelMissing) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1); |
- Prepare(limits); |
- AddJob('a', IDLE); |
- TestJob* job_b = AddJob('b', IDLE); |
- PrioritizedDispatcher::Handle handle = job_b->handle(); |
- ASSERT_FALSE(handle.is_null()); |
- dispatcher_->Cancel(handle); |
- EXPECT_DEBUG_DEATH(dispatcher_->Cancel(handle), ""); |
-} |
- |
-// TODO(szym): Fix the PriorityQueue::Pointer check to die here. |
-// http://crbug.com/130846 |
-TEST_F(PrioritizedDispatcherTest, DISABLED_CancelIncompatible) { |
- PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1); |
- Prepare(limits); |
- AddJob('a', IDLE); |
- TestJob* job_b = AddJob('b', IDLE); |
- PrioritizedDispatcher::Handle handle = job_b->handle(); |
- ASSERT_FALSE(handle.is_null()); |
- |
- // New dispatcher. |
- Prepare(limits); |
- AddJob('a', IDLE); |
- AddJob('b', IDLE); |
- EXPECT_DEBUG_DEATH(dispatcher_->Cancel(handle), ""); |
-} |
-#endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG) |
- |
-} // namespace |
- |
-} // namespace net |