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

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

Issue 8965025: Refactoring of job dispatch in HostResolverImpl in preparation for DnsClient. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed PriorityQueue. Created 9 years 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
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/priority_dispatch.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace net {
15
16 namespace {
17
18 class PriorityDispatchTest : public testing::Test {
19 public:
20 // A job that appends |data| to |log| when started, toupper(|data|) when
21 // evicted, and '.' when finished.
mmenke 2011/12/21 16:22:58 nit: log_
mmenke 2011/12/21 16:22:58 I think a bit more of an explanation is in order.
szym 2011/12/28 01:24:10 Done.
22 class TestJob : public PriorityDispatch::Job {
23 public:
24 TestJob(PriorityDispatchTest* test, char data, RequestPriority priority)
25 : test_(test), data_(data), priority_(priority), running_(false) {}
26
27 // win does not accept EXPECT_EQ(this, ...) so wrap it up.
mmenke 2011/12/21 16:22:58 nit: "Windows does not"
szym 2011/12/28 01:24:10 Done.
28 PriorityDispatch::Job* this_job() {
29 return this;
30 }
31
32 void Add() {
33 EXPECT_TRUE(handle_.is_null());
34 EXPECT_FALSE(running_);
35 size_t num_queued = dispatch().num_queued_jobs();
36 size_t num_running = dispatch().num_running_jobs();
37
38 handle_ = dispatch().Add(this, priority_);
39
40 if (handle_.is_null()) {
41 EXPECT_EQ(num_queued, dispatch().num_queued_jobs());
42 if (running_) {
43 EXPECT_EQ(num_running + 1, dispatch().num_running_jobs());
44 } else {
45 // This job got evicted on Add.
46 EXPECT_EQ(num_running, dispatch().num_running_jobs());
47 }
48 } else {
49 EXPECT_FALSE(running_);
50 EXPECT_EQ(priority_, handle_.priority());
51 EXPECT_EQ(this_job(), handle_.value());
52 EXPECT_EQ(num_running, dispatch().num_running_jobs());
53 }
54 }
55
56 void Update(RequestPriority priority) {
57 EXPECT_FALSE(running_);
58 ASSERT_FALSE(handle_.is_null());
59 size_t num_queued = dispatch().num_queued_jobs();
60 size_t num_running = dispatch().num_running_jobs();
61
62 handle_ = dispatch().Update(handle_, priority);
63
64 if (handle_.is_null()) {
65 EXPECT_TRUE(running_);
66 EXPECT_EQ(num_queued - 1, dispatch().num_queued_jobs());
67 EXPECT_EQ(num_running + 1, dispatch().num_running_jobs());
68 } else {
69 EXPECT_FALSE(running_);
70 EXPECT_EQ(priority, handle_.priority());
71 EXPECT_EQ(this_job(), handle_.value());
72 EXPECT_EQ(num_queued, dispatch().num_queued_jobs());
73 EXPECT_EQ(num_running, dispatch().num_running_jobs());
74 }
75 }
76
77 void Cancel() {
78 EXPECT_FALSE(running_);
79 ASSERT_FALSE(handle_.is_null());
80 size_t num_queued = dispatch().num_queued_jobs();
81
82 dispatch().Cancel(handle_);
83
84 EXPECT_EQ(num_queued - 1, dispatch().num_queued_jobs());
85 handle_ = PriorityDispatch::Handle();
86 }
87
88 void Finish() {
89 EXPECT_TRUE(running_);
90 running_ = false;
91 test_->log_.append(1u, '.');
92
93 dispatch().OnJobFinished();
94 }
95
96 // PriorityDispatch::Job interface
97 virtual void Start() OVERRIDE {
98 EXPECT_FALSE(running_);
99 handle_ = PriorityDispatch::Handle();
100 running_ = true;
101 test_->log_.append(1u, data_);
102 }
103
104 virtual void OnEvicted() OVERRIDE {
105 EXPECT_FALSE(running_);
106 handle_ = PriorityDispatch::Handle();
107 test_->log_.append(1u, toupper(data_));
108 }
109
110 private:
111 PriorityDispatch& dispatch() { return *(test_->dispatch_); }
112
113 PriorityDispatchTest* test_;
114
115 char data_;
116 RequestPriority priority_;
117
118 PriorityDispatch::Handle handle_;
119 bool running_;
120 };
121
122 protected:
123 friend class TestJob;
mmenke 2011/12/21 16:22:58 nit: Don't believe this is needed. Inner classes
szym 2011/12/28 01:24:10 Done.
124
125 void Prepare(const PriorityDispatch::Limits& limits, size_t max_queued) {
126 dispatch_.reset(new PriorityDispatch(limits, max_queued));
127 }
128
129 TestJob* AddJob(char data, RequestPriority priority) {
130 TestJob* job = new TestJob(this, data, priority);
131 jobs_.push_back(job);
132 job->Add();
133 return job;
134 }
135
136 void Expect(std::string log) {
137 EXPECT_EQ(0u, dispatch_->num_queued_jobs());
138 EXPECT_EQ(0u, dispatch_->num_running_jobs());
139 EXPECT_EQ(log, log_);
140 log_.clear();
141 }
142
143 std::string log_;
144 scoped_ptr<PriorityDispatch> dispatch_;
145 ScopedVector<TestJob> jobs_;
146 };
147
148 TEST_F(PriorityDispatchTest, AddAFIFO) {
149 // Allow only one running job.
150 PriorityDispatch::Limits limits = {{0, 0, 0, 0, 1}};
151 Prepare(limits, 1000u);
152
153 TestJob* job_a = AddJob('a', IDLE);
154 TestJob* job_b = AddJob('b', IDLE);
155 TestJob* job_c = AddJob('c', IDLE);
156 TestJob* job_d = AddJob('d', IDLE);
157
158 job_a->Finish();
159 job_b->Finish();
160 job_c->Finish();
161 job_d->Finish();
162
163 Expect("a.b.c.d.");
164 }
165
166 TEST_F(PriorityDispatchTest, AddPriority) {
167 PriorityDispatch::Limits limits = {{0, 0, 0, 0, 1}};
168 Prepare(limits, 1000u);
169
170 TestJob* job_a = AddJob('a', IDLE);
171 TestJob* job_b = AddJob('b', MEDIUM);
172 TestJob* job_c = AddJob('c', HIGHEST);
173 TestJob* job_d = AddJob('d', HIGHEST);
174 TestJob* job_e = AddJob('e', MEDIUM);
175
176 job_a->Finish();
177 job_c->Finish();
178 job_d->Finish();
179 job_b->Finish();
180 job_e->Finish();
181
182 Expect("a.c.d.b.e.");
183 }
184
185 TEST_F(PriorityDispatchTest, EnforceLimits) {
186 PriorityDispatch::Limits limits = {{2, 0, 1, 0, 2}};
187 Prepare(limits, 1000u);
188
189 TestJob* job_a = AddJob('a', IDLE);
190 TestJob* job_b = AddJob('b', IDLE);
191 TestJob* job_c = AddJob('c', LOWEST);
192 TestJob* job_d = AddJob('d', LOW);
193 TestJob* job_e = AddJob('e', MEDIUM);
194 TestJob* job_f = AddJob('f', HIGHEST);
195 TestJob* job_g = AddJob('g', HIGHEST);
196 TestJob* job_h = AddJob('h', HIGHEST);
197
198 EXPECT_EQ(5u, dispatch_->num_running_jobs());
199 EXPECT_EQ(3u, dispatch_->num_queued_jobs());
200
201 job_a->Finish(); // Releases h.
202 job_b->Finish();
203 job_d->Finish();
204 job_f->Finish(); // Releases e.
205 job_g->Finish();
206 job_h->Finish(); // Releases c.
207 job_e->Finish();
208 job_c->Finish();
209
210 Expect("abdfg.h...e..c..");
211 }
212
213 TEST_F(PriorityDispatchTest, Update) {
214 PriorityDispatch::Limits limits = {{0, 0, 0, 0, 1}};
215 Prepare(limits, 1000u);
216
217 TestJob* job_a = AddJob('a', IDLE);
218 TestJob* job_b = AddJob('b', MEDIUM);
219 TestJob* job_c = AddJob('c', HIGHEST);
220 TestJob* job_d = AddJob('d', HIGHEST);
221
222 job_b->Update(HIGHEST);
223 job_c->Update(MEDIUM);
224
225 job_a->Finish();
226 job_d->Finish();
227 job_b->Finish();
228 job_c->Finish();
229
230 Expect("a.d.b.c.");
231 }
232
233 TEST_F(PriorityDispatchTest, Cancel) {
234 PriorityDispatch::Limits limits = {{0, 0, 0, 0, 1}};
235 Prepare(limits, 1000u);
236
237 TestJob* job_a = AddJob('a', IDLE);
238 TestJob* job_b = AddJob('b', IDLE);
239 TestJob* job_c = AddJob('c', IDLE);
240 TestJob* job_d = AddJob('d', IDLE);
241 TestJob* job_e = AddJob('e', IDLE);
242
243 job_b->Cancel();
244 job_d->Cancel();
245
246 job_a->Finish();
247 job_c->Finish();
248 job_e->Finish();
249
250 Expect("a.c.e.");
251 }
252
253 TEST_F(PriorityDispatchTest, Evict) {
254 PriorityDispatch::Limits limits = {{0, 0, 0, 0, 1}};
255 Prepare(limits, 2u);
256
257 // Note that the eviction order is by OldestLowest.
258 TestJob* job_a = AddJob('a', LOW);
259 AddJob('b', LOW);
260 AddJob('c', LOW);
261 TestJob* job_d = AddJob('d', LOW); // Evicts b.
262 TestJob* job_e = AddJob('e', HIGHEST); // Evicts c.
263 AddJob('f', IDLE); // Evicts self.
264
265 job_a->Finish();
266 job_e->Finish();
267 job_d->Finish();
268
269 Expect("aBCF.e.d.");
270 }
271
272 } // namespace
273
274 } // namespace net
275
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698