blob: 3970ff4d5dc08e14a2ce55d3469868f66d98df52 [file] [log] [blame]
[email protected]ba79eca2012-01-06 21:03:561// Copyright (c) 2012 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
danakj7f767e62016-04-16 23:20:235#include "net/base/prioritized_dispatcher.h"
6
[email protected]ba79eca2012-01-06 21:03:567#include <ctype.h>
danakj7f767e62016-04-16 23:20:238
9#include <memory>
[email protected]ba79eca2012-01-06 21:03:5610#include <string>
11
12#include "base/compiler_specific.h"
[email protected]043324f42012-06-02 00:18:5313#include "base/logging.h"
[email protected]ba79eca2012-01-06 21:03:5614#include "net/base/request_priority.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17namespace net {
18
19namespace {
20
21// We rely on the priority enum values being sequential having starting at 0,
[email protected]31ae7ab2012-04-24 21:09:0522// and increasing for higher priorities.
rdsmith5eb6fbc2016-10-21 17:36:0823static_assert(MINIMUM_PRIORITY == 0u && MINIMUM_PRIORITY == THROTTLED &&
24 THROTTLED < IDLE &&
25 IDLE < LOWEST &&
26 LOWEST < HIGHEST &&
mostynb91e0da982015-01-20 19:17:2727 HIGHEST <= MAXIMUM_PRIORITY,
28 "priority indexes incompatible");
[email protected]ba79eca2012-01-06 21:03:5629
30class PrioritizedDispatcherTest : public testing::Test {
31 public:
32 typedef PrioritizedDispatcher::Priority Priority;
[email protected]043324f42012-06-02 00:18:5333 // A job that appends |tag| to |log| when started and '.' when finished.
[email protected]ba79eca2012-01-06 21:03:5634 // This is intended to confirm the execution order of a sequence of jobs added
[email protected]043324f42012-06-02 00:18:5335 // to the dispatcher. Note that finishing order of jobs does not matter.
[email protected]ba79eca2012-01-06 21:03:5636 class TestJob : public PrioritizedDispatcher::Job {
37 public:
[email protected]043324f42012-06-02 00:18:5338 TestJob(PrioritizedDispatcher* dispatcher,
39 char tag,
40 Priority priority,
41 std::string* log)
42 : dispatcher_(dispatcher),
43 tag_(tag),
44 priority_(priority),
45 running_(false),
46 log_(log) {}
[email protected]ba79eca2012-01-06 21:03:5647
[email protected]043324f42012-06-02 00:18:5348 bool running() const {
49 return running_;
50 }
51
52 const PrioritizedDispatcher::Handle handle() const {
53 return handle_;
[email protected]ba79eca2012-01-06 21:03:5654 }
55
[email protected]daae1322013-09-05 18:26:5056 void Add(bool at_head) {
[email protected]043324f42012-06-02 00:18:5357 CHECK(handle_.is_null());
58 CHECK(!running_);
59 size_t num_queued = dispatcher_->num_queued_jobs();
60 size_t num_running = dispatcher_->num_running_jobs();
[email protected]ba79eca2012-01-06 21:03:5661
[email protected]daae1322013-09-05 18:26:5062 if (!at_head) {
63 handle_ = dispatcher_->Add(this, priority_);
64 } else {
65 handle_ = dispatcher_->AddAtHead(this, priority_);
66 }
[email protected]ba79eca2012-01-06 21:03:5667
68 if (handle_.is_null()) {
[email protected]043324f42012-06-02 00:18:5369 EXPECT_EQ(num_queued, dispatcher_->num_queued_jobs());
[email protected]ba79eca2012-01-06 21:03:5670 EXPECT_TRUE(running_);
[email protected]043324f42012-06-02 00:18:5371 EXPECT_EQ(num_running + 1, dispatcher_->num_running_jobs());
[email protected]ba79eca2012-01-06 21:03:5672 } else {
73 EXPECT_FALSE(running_);
74 EXPECT_EQ(priority_, handle_.priority());
[email protected]043324f42012-06-02 00:18:5375 EXPECT_EQ(tag_, reinterpret_cast<TestJob*>(handle_.value())->tag_);
76 EXPECT_EQ(num_running, dispatcher_->num_running_jobs());
[email protected]ba79eca2012-01-06 21:03:5677 }
78 }
79
80 void ChangePriority(Priority priority) {
[email protected]043324f42012-06-02 00:18:5381 CHECK(!handle_.is_null());
82 CHECK(!running_);
83 size_t num_queued = dispatcher_->num_queued_jobs();
84 size_t num_running = dispatcher_->num_running_jobs();
[email protected]ba79eca2012-01-06 21:03:5685
[email protected]043324f42012-06-02 00:18:5386 handle_ = dispatcher_->ChangePriority(handle_, priority);
[email protected]ba79eca2012-01-06 21:03:5687
88 if (handle_.is_null()) {
89 EXPECT_TRUE(running_);
[email protected]043324f42012-06-02 00:18:5390 EXPECT_EQ(num_queued - 1, dispatcher_->num_queued_jobs());
91 EXPECT_EQ(num_running + 1, dispatcher_->num_running_jobs());
[email protected]ba79eca2012-01-06 21:03:5692 } else {
93 EXPECT_FALSE(running_);
94 EXPECT_EQ(priority, handle_.priority());
[email protected]043324f42012-06-02 00:18:5395 EXPECT_EQ(tag_, reinterpret_cast<TestJob*>(handle_.value())->tag_);
96 EXPECT_EQ(num_queued, dispatcher_->num_queued_jobs());
97 EXPECT_EQ(num_running, dispatcher_->num_running_jobs());
[email protected]ba79eca2012-01-06 21:03:5698 }
99 }
100
101 void Cancel() {
[email protected]043324f42012-06-02 00:18:53102 CHECK(!handle_.is_null());
103 CHECK(!running_);
104 size_t num_queued = dispatcher_->num_queued_jobs();
[email protected]ba79eca2012-01-06 21:03:56105
[email protected]043324f42012-06-02 00:18:53106 dispatcher_->Cancel(handle_);
[email protected]ba79eca2012-01-06 21:03:56107
[email protected]043324f42012-06-02 00:18:53108 EXPECT_EQ(num_queued - 1, dispatcher_->num_queued_jobs());
[email protected]ba79eca2012-01-06 21:03:56109 handle_ = PrioritizedDispatcher::Handle();
110 }
111
112 void Finish() {
[email protected]043324f42012-06-02 00:18:53113 CHECK(running_);
[email protected]ba79eca2012-01-06 21:03:56114 running_ = false;
[email protected]043324f42012-06-02 00:18:53115 log_->append(1u, '.');
[email protected]ba79eca2012-01-06 21:03:56116
[email protected]043324f42012-06-02 00:18:53117 dispatcher_->OnJobFinished();
[email protected]ba79eca2012-01-06 21:03:56118 }
119
120 // PriorityDispatch::Job interface
dchengb03027d2014-10-21 12:00:20121 void Start() override {
[email protected]ba79eca2012-01-06 21:03:56122 EXPECT_FALSE(running_);
123 handle_ = PrioritizedDispatcher::Handle();
124 running_ = true;
[email protected]043324f42012-06-02 00:18:53125 log_->append(1u, tag_);
[email protected]ba79eca2012-01-06 21:03:56126 }
127
128 private:
[email protected]043324f42012-06-02 00:18:53129 PrioritizedDispatcher* dispatcher_;
[email protected]ba79eca2012-01-06 21:03:56130
[email protected]043324f42012-06-02 00:18:53131 char tag_;
[email protected]ba79eca2012-01-06 21:03:56132 Priority priority_;
133
134 PrioritizedDispatcher::Handle handle_;
135 bool running_;
[email protected]043324f42012-06-02 00:18:53136
137 std::string* log_;
[email protected]ba79eca2012-01-06 21:03:56138 };
139
140 protected:
141 void Prepare(const PrioritizedDispatcher::Limits& limits) {
[email protected]043324f42012-06-02 00:18:53142 dispatcher_.reset(new PrioritizedDispatcher(limits));
[email protected]ba79eca2012-01-06 21:03:56143 }
144
danakj7f767e62016-04-16 23:20:23145 std::unique_ptr<TestJob> AddJob(char data, Priority priority) {
146 std::unique_ptr<TestJob> job(
olli.raulada99b382015-12-17 08:55:12147 new TestJob(dispatcher_.get(), data, priority, &log_));
[email protected]daae1322013-09-05 18:26:50148 job->Add(false);
149 return job;
150 }
151
danakj7f767e62016-04-16 23:20:23152 std::unique_ptr<TestJob> AddJobAtHead(char data, Priority priority) {
153 std::unique_ptr<TestJob> job(
olli.raulada99b382015-12-17 08:55:12154 new TestJob(dispatcher_.get(), data, priority, &log_));
[email protected]daae1322013-09-05 18:26:50155 job->Add(true);
[email protected]ba79eca2012-01-06 21:03:56156 return job;
157 }
158
ki.stfu144dce12015-09-22 01:07:57159 void Expect(const std::string& log) {
[email protected]043324f42012-06-02 00:18:53160 EXPECT_EQ(0u, dispatcher_->num_queued_jobs());
161 EXPECT_EQ(0u, dispatcher_->num_running_jobs());
[email protected]ba79eca2012-01-06 21:03:56162 EXPECT_EQ(log, log_);
163 log_.clear();
164 }
165
166 std::string log_;
danakj7f767e62016-04-16 23:20:23167 std::unique_ptr<PrioritizedDispatcher> dispatcher_;
[email protected]ba79eca2012-01-06 21:03:56168};
169
[email protected]daae1322013-09-05 18:26:50170TEST_F(PrioritizedDispatcherTest, GetLimits) {
171 // Set non-trivial initial limits.
172 PrioritizedDispatcher::Limits original_limits(NUM_PRIORITIES, 5);
173 original_limits.reserved_slots[HIGHEST] = 1;
174 original_limits.reserved_slots[LOW] = 2;
175 Prepare(original_limits);
176
177 // Get current limits, make sure the original limits are returned.
178 PrioritizedDispatcher::Limits retrieved_limits = dispatcher_->GetLimits();
179 ASSERT_EQ(original_limits.total_jobs, retrieved_limits.total_jobs);
Hans Wennborg4b99b0f2017-12-07 17:01:28180 ASSERT_EQ(static_cast<size_t>(NUM_PRIORITIES),
181 retrieved_limits.reserved_slots.size());
[email protected]3d08dd382013-10-19 00:13:11182 for (size_t priority = MINIMUM_PRIORITY; priority <= MAXIMUM_PRIORITY;
183 ++priority) {
[email protected]daae1322013-09-05 18:26:50184 EXPECT_EQ(original_limits.reserved_slots[priority],
185 retrieved_limits.reserved_slots[priority]);
186 }
187
188 // Set new limits.
189 PrioritizedDispatcher::Limits new_limits(NUM_PRIORITIES, 6);
190 new_limits.reserved_slots[MEDIUM] = 3;
191 new_limits.reserved_slots[LOWEST] = 1;
192 Prepare(new_limits);
193
194 // Get current limits, make sure the new limits are returned.
195 retrieved_limits = dispatcher_->GetLimits();
196 ASSERT_EQ(new_limits.total_jobs, retrieved_limits.total_jobs);
Hans Wennborg4b99b0f2017-12-07 17:01:28197 ASSERT_EQ(static_cast<size_t>(NUM_PRIORITIES),
198 retrieved_limits.reserved_slots.size());
[email protected]3d08dd382013-10-19 00:13:11199 for (size_t priority = MINIMUM_PRIORITY; priority <= MAXIMUM_PRIORITY;
200 ++priority) {
[email protected]daae1322013-09-05 18:26:50201 EXPECT_EQ(new_limits.reserved_slots[priority],
202 retrieved_limits.reserved_slots[priority]);
203 }
204}
205
[email protected]ba79eca2012-01-06 21:03:56206TEST_F(PrioritizedDispatcherTest, AddAFIFO) {
207 // Allow only one running job.
208 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
209 Prepare(limits);
210
danakj7f767e62016-04-16 23:20:23211 std::unique_ptr<TestJob> job_a = AddJob('a', IDLE);
212 std::unique_ptr<TestJob> job_b = AddJob('b', IDLE);
213 std::unique_ptr<TestJob> job_c = AddJob('c', IDLE);
214 std::unique_ptr<TestJob> job_d = AddJob('d', IDLE);
[email protected]ba79eca2012-01-06 21:03:56215
[email protected]043324f42012-06-02 00:18:53216 ASSERT_TRUE(job_a->running());
[email protected]ba79eca2012-01-06 21:03:56217 job_a->Finish();
[email protected]043324f42012-06-02 00:18:53218 ASSERT_TRUE(job_b->running());
[email protected]ba79eca2012-01-06 21:03:56219 job_b->Finish();
[email protected]043324f42012-06-02 00:18:53220 ASSERT_TRUE(job_c->running());
[email protected]ba79eca2012-01-06 21:03:56221 job_c->Finish();
[email protected]043324f42012-06-02 00:18:53222 ASSERT_TRUE(job_d->running());
[email protected]ba79eca2012-01-06 21:03:56223 job_d->Finish();
224
225 Expect("a.b.c.d.");
226}
227
228TEST_F(PrioritizedDispatcherTest, AddPriority) {
229 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
230 Prepare(limits);
231
danakj7f767e62016-04-16 23:20:23232 std::unique_ptr<TestJob> job_a = AddJob('a', IDLE);
233 std::unique_ptr<TestJob> job_b = AddJob('b', MEDIUM);
234 std::unique_ptr<TestJob> job_c = AddJob('c', HIGHEST);
235 std::unique_ptr<TestJob> job_d = AddJob('d', HIGHEST);
236 std::unique_ptr<TestJob> job_e = AddJob('e', MEDIUM);
[email protected]ba79eca2012-01-06 21:03:56237
[email protected]043324f42012-06-02 00:18:53238 ASSERT_TRUE(job_a->running());
[email protected]ba79eca2012-01-06 21:03:56239 job_a->Finish();
[email protected]043324f42012-06-02 00:18:53240 ASSERT_TRUE(job_c->running());
[email protected]ba79eca2012-01-06 21:03:56241 job_c->Finish();
[email protected]043324f42012-06-02 00:18:53242 ASSERT_TRUE(job_d->running());
[email protected]ba79eca2012-01-06 21:03:56243 job_d->Finish();
[email protected]043324f42012-06-02 00:18:53244 ASSERT_TRUE(job_b->running());
[email protected]ba79eca2012-01-06 21:03:56245 job_b->Finish();
[email protected]043324f42012-06-02 00:18:53246 ASSERT_TRUE(job_e->running());
[email protected]ba79eca2012-01-06 21:03:56247 job_e->Finish();
248
249 Expect("a.c.d.b.e.");
250}
251
[email protected]daae1322013-09-05 18:26:50252TEST_F(PrioritizedDispatcherTest, AddAtHead) {
253 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
254 Prepare(limits);
255
danakj7f767e62016-04-16 23:20:23256 std::unique_ptr<TestJob> job_a = AddJob('a', MEDIUM);
257 std::unique_ptr<TestJob> job_b = AddJobAtHead('b', MEDIUM);
258 std::unique_ptr<TestJob> job_c = AddJobAtHead('c', HIGHEST);
259 std::unique_ptr<TestJob> job_d = AddJobAtHead('d', HIGHEST);
260 std::unique_ptr<TestJob> job_e = AddJobAtHead('e', MEDIUM);
261 std::unique_ptr<TestJob> job_f = AddJob('f', MEDIUM);
[email protected]daae1322013-09-05 18:26:50262
263 ASSERT_TRUE(job_a->running());
264 job_a->Finish();
265 ASSERT_TRUE(job_d->running());
266 job_d->Finish();
267 ASSERT_TRUE(job_c->running());
268 job_c->Finish();
269 ASSERT_TRUE(job_e->running());
270 job_e->Finish();
271 ASSERT_TRUE(job_b->running());
272 job_b->Finish();
273 ASSERT_TRUE(job_f->running());
274 job_f->Finish();
275
276 Expect("a.d.c.e.b.f.");
277}
278
[email protected]ba79eca2012-01-06 21:03:56279TEST_F(PrioritizedDispatcherTest, EnforceLimits) {
280 // Reserve 2 for HIGHEST and 1 for LOW or higher.
281 // This leaves 2 for LOWEST or lower.
282 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 5);
283 limits.reserved_slots[HIGHEST] = 2;
284 limits.reserved_slots[LOW] = 1;
285 Prepare(limits);
286
danakj7f767e62016-04-16 23:20:23287 std::unique_ptr<TestJob> job_a = AddJob('a', IDLE); // Uses unreserved slot.
288 std::unique_ptr<TestJob> job_b = AddJob('b', IDLE); // Uses unreserved slot.
289 std::unique_ptr<TestJob> job_c = AddJob('c', LOWEST); // Must wait.
290 std::unique_ptr<TestJob> job_d = AddJob('d', LOW); // Uses reserved slot.
291 std::unique_ptr<TestJob> job_e = AddJob('e', MEDIUM); // Must wait.
292 std::unique_ptr<TestJob> job_f = AddJob('f', HIGHEST); // Uses reserved slot.
293 std::unique_ptr<TestJob> job_g = AddJob('g', HIGHEST); // Uses reserved slot.
294 std::unique_ptr<TestJob> job_h = AddJob('h', HIGHEST); // Must wait.
[email protected]ba79eca2012-01-06 21:03:56295
[email protected]043324f42012-06-02 00:18:53296 EXPECT_EQ(5u, dispatcher_->num_running_jobs());
297 EXPECT_EQ(3u, dispatcher_->num_queued_jobs());
[email protected]ba79eca2012-01-06 21:03:56298
[email protected]043324f42012-06-02 00:18:53299 ASSERT_TRUE(job_a->running());
300 ASSERT_TRUE(job_b->running());
301 ASSERT_TRUE(job_d->running());
302 ASSERT_TRUE(job_f->running());
303 ASSERT_TRUE(job_g->running());
304 // a, b, d, f, g are running. Finish them in any order.
305 job_b->Finish(); // Releases h.
306 job_f->Finish();
307 job_a->Finish();
308 job_g->Finish(); // Releases e.
[email protected]ba79eca2012-01-06 21:03:56309 job_d->Finish();
[email protected]043324f42012-06-02 00:18:53310 ASSERT_TRUE(job_e->running());
311 ASSERT_TRUE(job_h->running());
312 // h, e are running.
313 job_e->Finish(); // Releases c.
314 ASSERT_TRUE(job_c->running());
[email protected]ba79eca2012-01-06 21:03:56315 job_c->Finish();
[email protected]043324f42012-06-02 00:18:53316 job_h->Finish();
[email protected]ba79eca2012-01-06 21:03:56317
318 Expect("abdfg.h...e..c..");
319}
320
321TEST_F(PrioritizedDispatcherTest, ChangePriority) {
[email protected]daae1322013-09-05 18:26:50322 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 2);
323 // Reserve one slot only for HIGHEST priority requests.
324 limits.reserved_slots[HIGHEST] = 1;
[email protected]ba79eca2012-01-06 21:03:56325 Prepare(limits);
326
danakj7f767e62016-04-16 23:20:23327 std::unique_ptr<TestJob> job_a = AddJob('a', IDLE);
328 std::unique_ptr<TestJob> job_b = AddJob('b', LOW);
329 std::unique_ptr<TestJob> job_c = AddJob('c', MEDIUM);
330 std::unique_ptr<TestJob> job_d = AddJob('d', MEDIUM);
331 std::unique_ptr<TestJob> job_e = AddJob('e', IDLE);
[email protected]ba79eca2012-01-06 21:03:56332
[email protected]043324f42012-06-02 00:18:53333 ASSERT_FALSE(job_b->running());
334 ASSERT_FALSE(job_c->running());
[email protected]daae1322013-09-05 18:26:50335 job_b->ChangePriority(MEDIUM);
336 job_c->ChangePriority(LOW);
[email protected]ba79eca2012-01-06 21:03:56337
[email protected]043324f42012-06-02 00:18:53338 ASSERT_TRUE(job_a->running());
[email protected]ba79eca2012-01-06 21:03:56339 job_a->Finish();
[email protected]043324f42012-06-02 00:18:53340 ASSERT_TRUE(job_d->running());
[email protected]ba79eca2012-01-06 21:03:56341 job_d->Finish();
[email protected]daae1322013-09-05 18:26:50342
343 EXPECT_FALSE(job_e->running());
344 // Increasing |job_e|'s priority to HIGHEST should result in it being
345 // started immediately.
346 job_e->ChangePriority(HIGHEST);
347 ASSERT_TRUE(job_e->running());
348 job_e->Finish();
349
[email protected]043324f42012-06-02 00:18:53350 ASSERT_TRUE(job_b->running());
[email protected]ba79eca2012-01-06 21:03:56351 job_b->Finish();
[email protected]043324f42012-06-02 00:18:53352 ASSERT_TRUE(job_c->running());
[email protected]ba79eca2012-01-06 21:03:56353 job_c->Finish();
354
[email protected]daae1322013-09-05 18:26:50355 Expect("a.d.be..c.");
[email protected]ba79eca2012-01-06 21:03:56356}
357
358TEST_F(PrioritizedDispatcherTest, Cancel) {
359 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
360 Prepare(limits);
361
danakj7f767e62016-04-16 23:20:23362 std::unique_ptr<TestJob> job_a = AddJob('a', IDLE);
363 std::unique_ptr<TestJob> job_b = AddJob('b', IDLE);
364 std::unique_ptr<TestJob> job_c = AddJob('c', IDLE);
365 std::unique_ptr<TestJob> job_d = AddJob('d', IDLE);
366 std::unique_ptr<TestJob> job_e = AddJob('e', IDLE);
[email protected]ba79eca2012-01-06 21:03:56367
[email protected]043324f42012-06-02 00:18:53368 ASSERT_FALSE(job_b->running());
369 ASSERT_FALSE(job_d->running());
[email protected]ba79eca2012-01-06 21:03:56370 job_b->Cancel();
371 job_d->Cancel();
372
[email protected]043324f42012-06-02 00:18:53373 ASSERT_TRUE(job_a->running());
[email protected]ba79eca2012-01-06 21:03:56374 job_a->Finish();
[email protected]043324f42012-06-02 00:18:53375 ASSERT_TRUE(job_c->running());
[email protected]ba79eca2012-01-06 21:03:56376 job_c->Finish();
[email protected]043324f42012-06-02 00:18:53377 ASSERT_TRUE(job_e->running());
[email protected]ba79eca2012-01-06 21:03:56378 job_e->Finish();
379
380 Expect("a.c.e.");
381}
382
383TEST_F(PrioritizedDispatcherTest, Evict) {
384 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
385 Prepare(limits);
386
danakj7f767e62016-04-16 23:20:23387 std::unique_ptr<TestJob> job_a = AddJob('a', IDLE);
388 std::unique_ptr<TestJob> job_b = AddJob('b', LOW);
389 std::unique_ptr<TestJob> job_c = AddJob('c', HIGHEST);
390 std::unique_ptr<TestJob> job_d = AddJob('d', LOW);
391 std::unique_ptr<TestJob> job_e = AddJob('e', HIGHEST);
[email protected]ba79eca2012-01-06 21:03:56392
olli.raulada99b382015-12-17 08:55:12393 EXPECT_EQ(job_b.get(), dispatcher_->EvictOldestLowest());
394 EXPECT_EQ(job_d.get(), dispatcher_->EvictOldestLowest());
[email protected]ba79eca2012-01-06 21:03:56395
[email protected]043324f42012-06-02 00:18:53396 ASSERT_TRUE(job_a->running());
[email protected]ba79eca2012-01-06 21:03:56397 job_a->Finish();
[email protected]043324f42012-06-02 00:18:53398 ASSERT_TRUE(job_c->running());
[email protected]ba79eca2012-01-06 21:03:56399 job_c->Finish();
[email protected]043324f42012-06-02 00:18:53400 ASSERT_TRUE(job_e->running());
[email protected]ba79eca2012-01-06 21:03:56401 job_e->Finish();
402
403 Expect("a.c.e.");
404}
405
[email protected]043324f42012-06-02 00:18:53406TEST_F(PrioritizedDispatcherTest, EvictFromEmpty) {
407 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
408 Prepare(limits);
409 EXPECT_TRUE(dispatcher_->EvictOldestLowest() == NULL);
410}
411
[email protected]daae1322013-09-05 18:26:50412TEST_F(PrioritizedDispatcherTest, AddWhileZeroLimits) {
413 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 2);
414 Prepare(limits);
415
416 dispatcher_->SetLimitsToZero();
danakj7f767e62016-04-16 23:20:23417 std::unique_ptr<TestJob> job_a = AddJob('a', LOW);
418 std::unique_ptr<TestJob> job_b = AddJob('b', MEDIUM);
419 std::unique_ptr<TestJob> job_c = AddJobAtHead('c', MEDIUM);
[email protected]daae1322013-09-05 18:26:50420
421 EXPECT_EQ(0u, dispatcher_->num_running_jobs());
422 EXPECT_EQ(3u, dispatcher_->num_queued_jobs());
423
424 dispatcher_->SetLimits(limits);
425 EXPECT_EQ(2u, dispatcher_->num_running_jobs());
426 EXPECT_EQ(1u, dispatcher_->num_queued_jobs());
427
428 ASSERT_TRUE(job_b->running());
429 job_b->Finish();
430
431 ASSERT_TRUE(job_c->running());
432 job_c->Finish();
433
434 ASSERT_TRUE(job_a->running());
435 job_a->Finish();
436
437 Expect("cb.a..");
438}
439
440TEST_F(PrioritizedDispatcherTest, ReduceLimitsWhileJobQueued) {
441 PrioritizedDispatcher::Limits initial_limits(NUM_PRIORITIES, 2);
442 Prepare(initial_limits);
443
danakj7f767e62016-04-16 23:20:23444 std::unique_ptr<TestJob> job_a = AddJob('a', MEDIUM);
445 std::unique_ptr<TestJob> job_b = AddJob('b', MEDIUM);
446 std::unique_ptr<TestJob> job_c = AddJob('c', MEDIUM);
447 std::unique_ptr<TestJob> job_d = AddJob('d', MEDIUM);
448 std::unique_ptr<TestJob> job_e = AddJob('e', MEDIUM);
[email protected]daae1322013-09-05 18:26:50449
450 EXPECT_EQ(2u, dispatcher_->num_running_jobs());
451 EXPECT_EQ(3u, dispatcher_->num_queued_jobs());
452
453 // Reduce limits to just allow one job at a time. Running jobs should not
454 // be affected.
455 dispatcher_->SetLimits(PrioritizedDispatcher::Limits(NUM_PRIORITIES, 1));
456
457 EXPECT_EQ(2u, dispatcher_->num_running_jobs());
458 EXPECT_EQ(3u, dispatcher_->num_queued_jobs());
459
460 // Finishing a job should not result in another job starting.
461 ASSERT_TRUE(job_a->running());
462 job_a->Finish();
463 EXPECT_EQ(1u, dispatcher_->num_running_jobs());
464 EXPECT_EQ(3u, dispatcher_->num_queued_jobs());
465
466 ASSERT_TRUE(job_b->running());
467 job_b->Finish();
468 EXPECT_EQ(1u, dispatcher_->num_running_jobs());
469 EXPECT_EQ(2u, dispatcher_->num_queued_jobs());
470
471 // Increasing the limits again should let c start.
472 dispatcher_->SetLimits(initial_limits);
473
474 ASSERT_TRUE(job_c->running());
475 job_c->Finish();
476 ASSERT_TRUE(job_d->running());
477 job_d->Finish();
478 ASSERT_TRUE(job_e->running());
479 job_e->Finish();
480
481 Expect("ab..cd.e..");
482}
483
484TEST_F(PrioritizedDispatcherTest, ZeroLimitsThenCancel) {
485 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
486 Prepare(limits);
487
danakj7f767e62016-04-16 23:20:23488 std::unique_ptr<TestJob> job_a = AddJob('a', IDLE);
489 std::unique_ptr<TestJob> job_b = AddJob('b', IDLE);
490 std::unique_ptr<TestJob> job_c = AddJob('c', IDLE);
[email protected]daae1322013-09-05 18:26:50491 dispatcher_->SetLimitsToZero();
492
493 ASSERT_TRUE(job_a->running());
494 EXPECT_FALSE(job_b->running());
495 EXPECT_FALSE(job_c->running());
496 job_a->Finish();
497
498 EXPECT_FALSE(job_b->running());
499 EXPECT_FALSE(job_c->running());
500
501 // Cancelling b shouldn't start job c.
502 job_b->Cancel();
503 EXPECT_FALSE(job_c->running());
504
505 // Restoring the limits should start c.
506 dispatcher_->SetLimits(limits);
507 ASSERT_TRUE(job_c->running());
508 job_c->Finish();
509
510 Expect("a.c.");
511}
512
513TEST_F(PrioritizedDispatcherTest, ZeroLimitsThenIncreasePriority) {
514 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 2);
515 limits.reserved_slots[HIGHEST] = 1;
516 Prepare(limits);
517
danakj7f767e62016-04-16 23:20:23518 std::unique_ptr<TestJob> job_a = AddJob('a', IDLE);
519 std::unique_ptr<TestJob> job_b = AddJob('b', IDLE);
[email protected]daae1322013-09-05 18:26:50520 EXPECT_TRUE(job_a->running());
521 EXPECT_FALSE(job_b->running());
522 dispatcher_->SetLimitsToZero();
523
524 job_b->ChangePriority(HIGHEST);
525 EXPECT_FALSE(job_b->running());
526 job_a->Finish();
527 EXPECT_FALSE(job_b->running());
528
529 job_b->Cancel();
530 Expect("a.");
531}
532
[email protected]043324f42012-06-02 00:18:53533#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
534TEST_F(PrioritizedDispatcherTest, CancelNull) {
535 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
536 Prepare(limits);
537 EXPECT_DEBUG_DEATH(dispatcher_->Cancel(PrioritizedDispatcher::Handle()), "");
538}
539
540TEST_F(PrioritizedDispatcherTest, CancelMissing) {
541 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
542 Prepare(limits);
543 AddJob('a', IDLE);
danakj7f767e62016-04-16 23:20:23544 std::unique_ptr<TestJob> job_b = AddJob('b', IDLE);
[email protected]043324f42012-06-02 00:18:53545 PrioritizedDispatcher::Handle handle = job_b->handle();
546 ASSERT_FALSE(handle.is_null());
547 dispatcher_->Cancel(handle);
548 EXPECT_DEBUG_DEATH(dispatcher_->Cancel(handle), "");
549}
[email protected]043324f42012-06-02 00:18:53550#endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
551
[email protected]ba79eca2012-01-06 21:03:56552} // namespace
553
554} // namespace net