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

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

Powered by Google App Engine
This is Rietveld 408576698