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

Side by Side Diff: net/base/prioritized_dispatcher_unittest.cc

Issue 9113022: Adds PriorityQueue and PrioritizedDispatcher. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Removed changes to net/dns/ that don't belong to this CL. Created 8 years, 11 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/prioritized_dispatcher.cc ('k') | net/base/priority_queue.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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
5 #include <ctype.h>
6 #include <string>
7
8 #include "base/compiler_specific.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/memory/scoped_vector.h"
11 #include "net/base/prioritized_dispatcher.h"
12 #include "net/base/request_priority.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace net {
16
17 namespace {
18
19 // We rely on the priority enum values being sequential having starting at 0,
20 // and increasing for lower priorities.
21 COMPILE_ASSERT(HIGHEST == 0u &&
22 LOWEST > HIGHEST &&
23 IDLE > LOWEST &&
24 NUM_PRIORITIES > IDLE,
25 priority_indexes_incompatible);
26
27 class PrioritizedDispatcherTest : public testing::Test {
28 public:
29 typedef PrioritizedDispatcher::Priority Priority;
30 // A job that appends |data| to |log_| when started and '.' when finished.
31 // This is intended to confirm the execution order of a sequence of jobs added
32 // to the dispatcher.
33 class TestJob : public PrioritizedDispatcher::Job {
34 public:
35 TestJob(PrioritizedDispatcherTest* test, char data, Priority priority)
36 : test_(test), data_(data), priority_(priority), running_(false) {}
37
38 // MSVS does not accept EXPECT_EQ(this, ...) so wrap it up.
39 PrioritizedDispatcher::Job* this_job() {
40 return this;
41 }
42
43 void Add() {
44 EXPECT_TRUE(handle_.is_null());
45 EXPECT_FALSE(running_);
46 size_t num_queued = dispatch().num_queued_jobs();
47 size_t num_running = dispatch().num_running_jobs();
48
49 handle_ = dispatch().Add(this, priority_);
50
51 if (handle_.is_null()) {
52 EXPECT_EQ(num_queued, dispatch().num_queued_jobs());
53 EXPECT_TRUE(running_);
54 EXPECT_EQ(num_running + 1, dispatch().num_running_jobs());
55 } else {
56 EXPECT_FALSE(running_);
57 EXPECT_EQ(priority_, handle_.priority());
58 EXPECT_EQ(this_job(), handle_.value());
59 EXPECT_EQ(num_running, dispatch().num_running_jobs());
60 }
61 }
62
63 void ChangePriority(Priority priority) {
64 EXPECT_FALSE(running_);
65 ASSERT_FALSE(handle_.is_null());
66 size_t num_queued = dispatch().num_queued_jobs();
67 size_t num_running = dispatch().num_running_jobs();
68
69 handle_ = dispatch().ChangePriority(handle_, priority);
70
71 if (handle_.is_null()) {
72 EXPECT_TRUE(running_);
73 EXPECT_EQ(num_queued - 1, dispatch().num_queued_jobs());
74 EXPECT_EQ(num_running + 1, dispatch().num_running_jobs());
75 } else {
76 EXPECT_FALSE(running_);
77 EXPECT_EQ(priority, handle_.priority());
78 EXPECT_EQ(this_job(), handle_.value());
79 EXPECT_EQ(num_queued, dispatch().num_queued_jobs());
80 EXPECT_EQ(num_running, dispatch().num_running_jobs());
81 }
82 }
83
84 void Cancel() {
85 EXPECT_FALSE(running_);
86 ASSERT_FALSE(handle_.is_null());
87 size_t num_queued = dispatch().num_queued_jobs();
88
89 dispatch().Cancel(handle_);
90
91 EXPECT_EQ(num_queued - 1, dispatch().num_queued_jobs());
92 handle_ = PrioritizedDispatcher::Handle();
93 }
94
95 void Finish() {
96 EXPECT_TRUE(running_);
97 running_ = false;
98 test_->log_.append(1u, '.');
99
100 dispatch().OnJobFinished();
101 }
102
103 // PriorityDispatch::Job interface
104 virtual void Start() OVERRIDE {
105 EXPECT_FALSE(running_);
106 handle_ = PrioritizedDispatcher::Handle();
107 running_ = true;
108 test_->log_.append(1u, data_);
109 }
110
111 private:
112 PrioritizedDispatcher& dispatch() { return *(test_->dispatch_); }
113
114 PrioritizedDispatcherTest* test_;
115
116 char data_;
117 Priority priority_;
118
119 PrioritizedDispatcher::Handle handle_;
120 bool running_;
121 };
122
123 protected:
124 void Prepare(const PrioritizedDispatcher::Limits& limits) {
125 dispatch_.reset(new PrioritizedDispatcher(limits));
126 }
127
128 TestJob* AddJob(char data, Priority priority) {
129 TestJob* job = new TestJob(this, data, priority);
130 jobs_.push_back(job);
131 job->Add();
132 return job;
133 }
134
135 void Expect(std::string log) {
136 EXPECT_EQ(0u, dispatch_->num_queued_jobs());
137 EXPECT_EQ(0u, dispatch_->num_running_jobs());
138 EXPECT_EQ(log, log_);
139 log_.clear();
140 }
141
142 std::string log_;
143 scoped_ptr<PrioritizedDispatcher> dispatch_;
144 ScopedVector<TestJob> jobs_;
145 };
146
147 TEST_F(PrioritizedDispatcherTest, AddAFIFO) {
148 // Allow only one running job.
149 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
150 Prepare(limits);
151
152 TestJob* job_a = AddJob('a', IDLE);
153 TestJob* job_b = AddJob('b', IDLE);
154 TestJob* job_c = AddJob('c', IDLE);
155 TestJob* job_d = AddJob('d', IDLE);
156
157 job_a->Finish();
158 job_b->Finish();
159 job_c->Finish();
160 job_d->Finish();
161
162 Expect("a.b.c.d.");
163 }
164
165 TEST_F(PrioritizedDispatcherTest, AddPriority) {
166 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
167 Prepare(limits);
168
169 TestJob* job_a = AddJob('a', IDLE);
170 TestJob* job_b = AddJob('b', MEDIUM);
171 TestJob* job_c = AddJob('c', HIGHEST);
172 TestJob* job_d = AddJob('d', HIGHEST);
173 TestJob* job_e = AddJob('e', MEDIUM);
174
175 job_a->Finish();
176 job_c->Finish();
177 job_d->Finish();
178 job_b->Finish();
179 job_e->Finish();
180
181 Expect("a.c.d.b.e.");
182 }
183
184 TEST_F(PrioritizedDispatcherTest, EnforceLimits) {
185 // Reserve 2 for HIGHEST and 1 for LOW or higher.
186 // This leaves 2 for LOWEST or lower.
187 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 5);
188 limits.reserved_slots[HIGHEST] = 2;
189 limits.reserved_slots[LOW] = 1;
190 Prepare(limits);
191
192 TestJob* job_a = AddJob('a', IDLE); // Uses unreserved slot.
193 TestJob* job_b = AddJob('b', IDLE); // Uses unreserved slot.
194 TestJob* job_c = AddJob('c', LOWEST); // Must wait.
195 TestJob* job_d = AddJob('d', LOW); // Uses reserved slot.
196 TestJob* job_e = AddJob('e', MEDIUM); // Must wait.
197 TestJob* job_f = AddJob('f', HIGHEST); // Uses reserved slot.
198 TestJob* job_g = AddJob('g', HIGHEST); // Uses reserved slot.
199 TestJob* job_h = AddJob('h', HIGHEST); // Must wait.
200
201 EXPECT_EQ(5u, dispatch_->num_running_jobs());
202 EXPECT_EQ(3u, dispatch_->num_queued_jobs());
203
204 job_a->Finish(); // Releases h.
205 job_b->Finish();
206 job_d->Finish();
207 job_f->Finish(); // Releases e.
208 job_g->Finish();
209 job_h->Finish(); // Releases c.
210 job_e->Finish();
211 job_c->Finish();
212
213 Expect("abdfg.h...e..c..");
214 }
215
216 TEST_F(PrioritizedDispatcherTest, ChangePriority) {
217 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
218 Prepare(limits);
219
220 TestJob* job_a = AddJob('a', IDLE);
221 TestJob* job_b = AddJob('b', MEDIUM);
222 TestJob* job_c = AddJob('c', HIGHEST);
223 TestJob* job_d = AddJob('d', HIGHEST);
224
225 job_b->ChangePriority(HIGHEST);
226 job_c->ChangePriority(MEDIUM);
227
228 job_a->Finish();
229 job_d->Finish();
230 job_b->Finish();
231 job_c->Finish();
232
233 Expect("a.d.b.c.");
234 }
235
236 TEST_F(PrioritizedDispatcherTest, Cancel) {
237 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
238 Prepare(limits);
239
240 TestJob* job_a = AddJob('a', IDLE);
241 TestJob* job_b = AddJob('b', IDLE);
242 TestJob* job_c = AddJob('c', IDLE);
243 TestJob* job_d = AddJob('d', IDLE);
244 TestJob* job_e = AddJob('e', IDLE);
245
246 job_b->Cancel();
247 job_d->Cancel();
248
249 job_a->Finish();
250 job_c->Finish();
251 job_e->Finish();
252
253 Expect("a.c.e.");
254 }
255
256 TEST_F(PrioritizedDispatcherTest, Evict) {
257 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
258 Prepare(limits);
259
260 TestJob* job_a = AddJob('a', IDLE);
261 TestJob* job_b = AddJob('b', LOW);
262 TestJob* job_c = AddJob('c', HIGHEST);
263 TestJob* job_d = AddJob('d', LOW);
264 TestJob* job_e = AddJob('e', HIGHEST);
265
266 EXPECT_EQ(job_b, dispatch_->EvictOldestLowest());
267 EXPECT_EQ(job_d, dispatch_->EvictOldestLowest());
268
269 job_a->Finish();
270 job_c->Finish();
271 job_e->Finish();
272
273 Expect("a.c.e.");
274 }
275
276 } // namespace
277
278 } // namespace net
279
OLDNEW
« no previous file with comments | « net/base/prioritized_dispatcher.cc ('k') | net/base/priority_queue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698