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

Side by Side Diff: content/browser/download/download_query_unittest.cc

Issue 8601012: DownloadQuery filters and sorts DownloadItems. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: " 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 <string>
6
7 #include "base/bind.h"
8 #include "base/file_path.h"
9 #include "base/logging.h"
10 #include "base/stl_util.h"
11 #include "base/time.h"
12 #include "base/values.h"
13 #include "content/browser/download/download_query.h"
14 #include "content/browser/download/mock_download_item.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 #include "base/utf_string_conversions.h"
19
20 using ::testing::Return;
21 using ::testing::ReturnRef;
22 using ::testing::_;
23 using base::Time;
24 using base::Value;
25 typedef DownloadQuery::DownloadVector DownloadVector;
26
27 namespace {
28
29 bool IdNotEqual(int not_id, const DownloadItem& item) {
30 return item.GetId() != not_id;
31 }
32
33 bool AlwaysReturn(bool result, const DownloadItem& item) {
34 return result;
35 }
36
37 } // anonymous namespace
38
39 class DownloadQueryTest : public testing::Test {
40 public:
41 DownloadQueryTest() {}
42
43 virtual ~DownloadQueryTest() {}
44
45 virtual void TearDown() {
46 STLDeleteElements(&mocks_);
47 }
48
49 void CreateMocks(int count) {
50 for (int i = 0; i < count; ++i) {
51 mocks_.push_back(new MockDownloadItem());
52 }
53 }
54
55 MockDownloadItem& mock(int index) { return *mocks_[index]; }
56
57 DownloadQuery* query() { return &query_; }
58
59 template<typename ValueType> void AddFilter(
60 DownloadQuery::FilterType name, ValueType value);
61
62 void Search() {
63 query_.Search(mocks_.begin(), mocks_.end(), &results_);
64 }
65
66 DownloadVector* results() { return &results_; }
67
68 private:
69 std::vector<MockDownloadItem*> mocks_;
70 DownloadQuery query_;
71 DownloadVector results_;
72
73 DISALLOW_COPY_AND_ASSIGN(DownloadQueryTest);
74 };
75
76 template<> void DownloadQueryTest::AddFilter(
77 DownloadQuery::FilterType name, bool value) {
78 CHECK(query_.AddFilter(name, Value::CreateBooleanValue(value)));
79 }
80
81 template<> void DownloadQueryTest::AddFilter(
82 DownloadQuery::FilterType name, int value) {
83 CHECK(query_.AddFilter(name, Value::CreateIntegerValue(value)));
84 }
85
86 template<> void DownloadQueryTest::AddFilter(
87 DownloadQuery::FilterType name, const char* value) {
88 CHECK(query_.AddFilter(name, Value::CreateStringValue(value)));
89 }
90
91 TEST_F(DownloadQueryTest, DownloadQueryEmptyNoItems) {
92 Search();
93 EXPECT_EQ(0U, results()->size());
94 }
95
96 TEST_F(DownloadQueryTest, DownloadQueryEmptySomeItems) {
97 CreateMocks(3);
98 Search();
99 EXPECT_EQ(3U, results()->size());
100 }
101
102 TEST_F(DownloadQueryTest, DownloadQueryInvalidFilters) {
103 EXPECT_FALSE(query()->AddFilter(
104 DownloadQuery::FILTER_BYTES_RECEIVED, NULL));
105 EXPECT_FALSE(query()->AddFilter(
106 static_cast<DownloadQuery::FilterType>(kint32max),
107 Value::CreateIntegerValue(0)));
108 }
109
110 TEST_F(DownloadQueryTest, DownloadQueryLimit) {
111 CreateMocks(2);
112 query()->Limit(1);
113 Search();
114 EXPECT_EQ(1U, results()->size());
115 }
116
117 #define SWITCH2(_index, _col1, _ret1, _default) \
118 ((_index == (_col1)) ? _ret1 : _default)
119 #define SWITCH3(_index, _col1, _ret1, _col2, _ret2, _default) \
120 SWITCH2(_index, _col1, _ret1, SWITCH2(_index, _col2, _ret2, _default))
121 #define SWITCH4(_index, _col1, _ret1, _col2, _ret2, _col3, _ret3, _default) \
122 SWITCH3(_index, _col1, _ret1, _col2, _ret2, \
123 SWITCH2(_index, _col3, _ret3, _default))
124
125 TEST_F(DownloadQueryTest, DownloadQueryAllFilters) {
126 // Set up mocks such that only mock(0) matches all filters, and every other
127 // mock fails a different filter (or two for GREATER/LESS filters).
128 static const size_t kNumItems = 19;
129 CreateMocks(kNumItems);
130 FilePath refail_filename("z");
131 FilePath fail_filename("fail");
132 FilePath match_filename("match");
133 GURL refail_url("http://z.com/");
134 GURL fail_url("http://example.com/fail");
135 GURL match_url("http://example.com/match");
136 // Picture a 2D matrix. The rows are MockDownloadItems and the columns are
137 // methods. Every cell contains a value that matches the filters, except for
138 // the diagonal. Every item matches all the filters except one filter, which
139 // it fails, except one item, which matches all the filters without exception.
140 for (size_t i = 0; i < kNumItems; ++i) {
141 EXPECT_CALL(mock(i), GetId()).WillRepeatedly(Return(i));
142 EXPECT_CALL(mock(i), GetReceivedBytes()).WillRepeatedly(Return(SWITCH2(i,
143 1, 2,
144 1)));
145 EXPECT_CALL(mock(i), GetSafetyState()).WillRepeatedly(Return(SWITCH2(i,
146 2, DownloadItem::DANGEROUS,
147 DownloadItem::DANGEROUS_BUT_VALIDATED)));
148 EXPECT_CALL(mock(i), GetFullPath()).WillRepeatedly(ReturnRef(SWITCH3(i,
149 3, refail_filename,
150 4, fail_filename,
151 match_filename)));
152 EXPECT_CALL(mock(i), GetMimeType()).WillRepeatedly(Return(SWITCH2(i,
153 5, "image",
154 "text")));
155 EXPECT_CALL(mock(i), IsPaused()).WillRepeatedly(Return(SWITCH2(i,
156 6, false,
157 true)));
158 EXPECT_CALL(mock(i), MatchesQuery(_)).WillRepeatedly(Return(SWITCH2(i,
159 7, false,
160 true)));
161 EXPECT_CALL(mock(i), GetStartTime()).WillRepeatedly(Return(SWITCH4(i,
162 8, base::Time::FromTimeT(1),
163 9, base::Time::FromTimeT(4),
164 10, base::Time::FromTimeT(3),
165 base::Time::FromTimeT(2))));
166 EXPECT_CALL(mock(i), GetTotalBytes()).WillRepeatedly(Return(SWITCH4(i,
167 11, 1,
168 12, 4,
169 13, 3,
170 2)));
171 EXPECT_CALL(mock(i), GetOriginalUrl()).WillRepeatedly(ReturnRef(SWITCH3(i,
172 14, refail_url,
173 15, fail_url,
174 match_url)));
175 EXPECT_CALL(mock(i), GetState()).WillRepeatedly(Return(SWITCH2(i,
176 17, DownloadItem::CANCELLED,
177 DownloadItem::IN_PROGRESS)));
178 EXPECT_CALL(mock(i), GetDangerType()).WillRepeatedly(Return(SWITCH2(i,
179 18, DownloadStateInfo::DANGEROUS_FILE,
180 DownloadStateInfo::NOT_DANGEROUS)));
181 }
182 for (size_t i = 0; i < kNumItems; ++i) {
183 switch (i) {
184 case 0: break;
185 case 1: AddFilter(DownloadQuery::FILTER_BYTES_RECEIVED, 1); break;
186 case 2: AddFilter(DownloadQuery::FILTER_DANGER_ACCEPTED, true);
187 break;
188 case 3: AddFilter(DownloadQuery::FILTER_FILENAME_REGEX, "a"); break;
189 case 4: AddFilter(DownloadQuery::FILTER_FILENAME,
190 match_filename.value().c_str()); break;
191 case 5: AddFilter(DownloadQuery::FILTER_MIME, "text"); break;
192 case 6: AddFilter(DownloadQuery::FILTER_PAUSED, true); break;
193 case 7: AddFilter(DownloadQuery::FILTER_QUERY, ""); break;
194 case 8: AddFilter(DownloadQuery::FILTER_STARTED_AFTER, 1000); break;
195 case 9: AddFilter(DownloadQuery::FILTER_STARTED_BEFORE, 4000);
196 break;
197 case 10: AddFilter(DownloadQuery::FILTER_START_TIME, 2000); break;
198 case 11: AddFilter(DownloadQuery::FILTER_TOTAL_BYTES_GREATER, 1);
199 break;
200 case 12: AddFilter(DownloadQuery::FILTER_TOTAL_BYTES_LESS, 4);
201 break;
202 case 13: AddFilter(DownloadQuery::FILTER_TOTAL_BYTES, 2); break;
203 case 14: AddFilter(DownloadQuery::FILTER_URL_REGEX, "example");
204 break;
205 case 15: AddFilter(DownloadQuery::FILTER_URL,
206 match_url.spec().c_str()); break;
207 case 16: CHECK(query()->AddFilter(base::Bind(&IdNotEqual, 16))); break;
208 case 17: query()->AddFilter(DownloadItem::IN_PROGRESS); break;
209 case 18: query()->AddFilter(DownloadStateInfo::NOT_DANGEROUS); break;
210 default: NOTREACHED(); break;
211 }
212 Search();
213 ASSERT_EQ(kNumItems - i, results()->size())
214 << "Failing filter: " << i;
215 if (i > 0) {
216 ASSERT_EQ(0, results()->at(0)->GetId())
217 << "Failing filter: " << i;
218 for (size_t j = 1; j < kNumItems - i; ++j) {
219 ASSERT_EQ(static_cast<int32>(j + i), results()->at(j)->GetId())
220 << "Failing filter: " << i;
221 }
222 }
223 }
224 }
225
226 TEST_F(DownloadQueryTest, DownloadQuerySortBytesReceived) {
227 CreateMocks(2);
228 EXPECT_CALL(mock(0), GetReceivedBytes()).WillRepeatedly(Return(0));
229 EXPECT_CALL(mock(1), GetReceivedBytes()).WillRepeatedly(Return(1));
230 query()->AddSorter(
231 DownloadQuery::SORT_BYTES_RECEIVED, DownloadQuery::DESCENDING);
232 Search();
233 EXPECT_EQ(1, results()->at(0)->GetReceivedBytes());
234 EXPECT_EQ(0, results()->at(1)->GetReceivedBytes());
235 }
236
237 TEST_F(DownloadQueryTest, DownloadQuerySortDanger) {
238 CreateMocks(2);
239 EXPECT_CALL(mock(0), GetDangerType()).WillRepeatedly(Return(
240 DownloadStateInfo::DANGEROUS_FILE));
241 EXPECT_CALL(mock(1), GetDangerType()).WillRepeatedly(Return(
242 DownloadStateInfo::NOT_DANGEROUS));
243 query()->AddSorter(
244 DownloadQuery::SORT_DANGER, DownloadQuery::ASCENDING);
245 Search();
246 EXPECT_EQ(DownloadStateInfo::NOT_DANGEROUS,
247 results()->at(0)->GetDangerType());
248 EXPECT_EQ(DownloadStateInfo::DANGEROUS_FILE,
249 results()->at(1)->GetDangerType());
250 }
251
252 TEST_F(DownloadQueryTest, DownloadQuerySortDangerAccepted) {
253 CreateMocks(2);
254 EXPECT_CALL(mock(0), GetSafetyState()).WillRepeatedly(Return(
255 DownloadItem::DANGEROUS));
256 EXPECT_CALL(mock(1), GetSafetyState()).WillRepeatedly(Return(
257 DownloadItem::DANGEROUS_BUT_VALIDATED));
258 query()->AddSorter(
259 DownloadQuery::SORT_DANGER_ACCEPTED, DownloadQuery::DESCENDING);
260 Search();
261 EXPECT_EQ(DownloadItem::DANGEROUS_BUT_VALIDATED,
262 results()->at(0)->GetSafetyState());
263 EXPECT_EQ(DownloadItem::DANGEROUS, results()->at(1)->GetSafetyState());
264 }
265
266 TEST_F(DownloadQueryTest, DownloadQuerySortFilename) {
267 CreateMocks(2);
268 FilePath a_filename("a");
269 FilePath b_filename("b");
270 EXPECT_CALL(mock(0), GetFullPath()).WillRepeatedly(ReturnRef(b_filename));
271 EXPECT_CALL(mock(1), GetFullPath()).WillRepeatedly(ReturnRef(a_filename));
272 query()->AddSorter(
273 DownloadQuery::SORT_FILENAME, DownloadQuery::ASCENDING);
274 Search();
275 EXPECT_EQ(a_filename, results()->at(0)->GetFullPath());
276 EXPECT_EQ(b_filename, results()->at(1)->GetFullPath());
277 }
278
279 TEST_F(DownloadQueryTest, DownloadQuerySortMime) {
280 CreateMocks(2);
281 EXPECT_CALL(mock(0), GetMimeType()).WillRepeatedly(Return("a"));
282 EXPECT_CALL(mock(1), GetMimeType()).WillRepeatedly(Return("b"));
283 query()->AddSorter(
284 DownloadQuery::SORT_MIME, DownloadQuery::DESCENDING);
285 Search();
286 EXPECT_EQ("b", results()->at(0)->GetMimeType());
287 EXPECT_EQ("a", results()->at(1)->GetMimeType());
288 }
289
290 TEST_F(DownloadQueryTest, DownloadQuerySortPaused) {
291 CreateMocks(2);
292 EXPECT_CALL(mock(0), IsPaused()).WillRepeatedly(Return(true));
293 EXPECT_CALL(mock(1), IsPaused()).WillRepeatedly(Return(false));
294 query()->AddSorter(
295 DownloadQuery::SORT_PAUSED, DownloadQuery::ASCENDING);
296 Search();
297 EXPECT_EQ(false, results()->at(0)->IsPaused());
298 EXPECT_EQ(true, results()->at(1)->IsPaused());
299 }
300
301 TEST_F(DownloadQueryTest, DownloadQuerySortStartTime) {
302 CreateMocks(2);
303 EXPECT_CALL(mock(0), GetStartTime()).WillRepeatedly(Return(
304 base::Time::FromTimeT(0)));
305 EXPECT_CALL(mock(1), GetStartTime()).WillRepeatedly(Return(
306 base::Time::FromTimeT(1)));
307 query()->AddSorter(
308 DownloadQuery::SORT_START_TIME, DownloadQuery::DESCENDING);
309 Search();
310 EXPECT_EQ(base::Time::FromTimeT(1), results()->at(0)->GetStartTime());
311 EXPECT_EQ(base::Time::FromTimeT(0), results()->at(1)->GetStartTime());
312 }
313
314 TEST_F(DownloadQueryTest, DownloadQuerySortState) {
315 CreateMocks(2);
316 EXPECT_CALL(mock(0), GetState()).WillRepeatedly(Return(
317 DownloadItem::IN_PROGRESS));
318 EXPECT_CALL(mock(1), GetState()).WillRepeatedly(Return(
319 DownloadItem::COMPLETE));
320 query()->AddSorter(
321 DownloadQuery::SORT_STATE, DownloadQuery::ASCENDING);
322 Search();
323 EXPECT_EQ(DownloadItem::IN_PROGRESS, results()->at(0)->GetState());
324 EXPECT_EQ(DownloadItem::COMPLETE, results()->at(1)->GetState());
325 }
326
327 TEST_F(DownloadQueryTest, DownloadQuerySortTotalBytes) {
328 CreateMocks(2);
329 EXPECT_CALL(mock(0), GetTotalBytes()).WillRepeatedly(Return(0));
330 EXPECT_CALL(mock(1), GetTotalBytes()).WillRepeatedly(Return(1));
331 query()->AddSorter(
332 DownloadQuery::SORT_TOTAL_BYTES, DownloadQuery::DESCENDING);
333 Search();
334 EXPECT_EQ(1, results()->at(0)->GetTotalBytes());
335 EXPECT_EQ(0, results()->at(1)->GetTotalBytes());
336 }
337
338 TEST_F(DownloadQueryTest, DownloadQuerySortUrl) {
339 CreateMocks(2);
340 GURL a_url("http://example.com/a");
341 GURL b_url("http://example.com/b");
342 EXPECT_CALL(mock(0), GetOriginalUrl()).WillRepeatedly(ReturnRef(b_url));
343 EXPECT_CALL(mock(1), GetOriginalUrl()).WillRepeatedly(ReturnRef(a_url));
344 query()->AddSorter(
345 DownloadQuery::SORT_URL, DownloadQuery::ASCENDING);
346 Search();
347 EXPECT_EQ(a_url, results()->at(0)->GetOriginalUrl());
348 EXPECT_EQ(b_url, results()->at(1)->GetOriginalUrl());
349 }
350
351 TEST_F(DownloadQueryTest, DownloadQuerySortId) {
352 CreateMocks(2);
353 EXPECT_CALL(mock(0), GetReceivedBytes()).WillRepeatedly(Return(0));
354 EXPECT_CALL(mock(1), GetReceivedBytes()).WillRepeatedly(Return(0));
355 EXPECT_CALL(mock(0), GetId()).WillRepeatedly(Return(1));
356 EXPECT_CALL(mock(1), GetId()).WillRepeatedly(Return(0));
357 query()->AddSorter(
358 DownloadQuery::SORT_BYTES_RECEIVED, DownloadQuery::DESCENDING);
359 Search();
360 EXPECT_EQ(0, results()->at(0)->GetId());
361 EXPECT_EQ(1, results()->at(1)->GetId());
362 }
363
364 TEST_F(DownloadQueryTest, DownloadQuerySortDbHandle) {
365 CreateMocks(2);
366 EXPECT_CALL(mock(0), GetReceivedBytes()).WillRepeatedly(Return(0));
367 EXPECT_CALL(mock(1), GetReceivedBytes()).WillRepeatedly(Return(0));
368 EXPECT_CALL(mock(0), GetId()).WillRepeatedly(Return(0));
369 EXPECT_CALL(mock(1), GetId()).WillRepeatedly(Return(0));
370 EXPECT_CALL(mock(0), GetDbHandle()).WillRepeatedly(Return(1));
371 EXPECT_CALL(mock(1), GetDbHandle()).WillRepeatedly(Return(0));
372 query()->AddSorter(
373 DownloadQuery::SORT_BYTES_RECEIVED, DownloadQuery::DESCENDING);
374 Search();
375 EXPECT_EQ(0, results()->at(0)->GetDbHandle());
376 EXPECT_EQ(1, results()->at(1)->GetDbHandle());
377 }
378
379 TEST_F(DownloadQueryTest, DownloadQueryFilterPerformance) {
380 static const int kNumItems = 10000;
381 static const int kNumFilters = 1000;
382 CreateMocks(kNumItems);
383 for (size_t i = 0; i < (kNumFilters - 1); ++i) {
384 query()->AddFilter(base::Bind(&AlwaysReturn, true));
385 }
386 query()->AddFilter(base::Bind(&AlwaysReturn, false));
387 base::Time start = base::Time::Now();
388 Search();
389 base::Time end = base::Time::Now();
390 double nanos = (end - start).InMillisecondsF() * 1000.0 * 1000.0;
391 double nanos_per_item = nanos / static_cast<double>(kNumItems);
392 double nanos_per_item_per_filter = nanos_per_item
393 / static_cast<double>(kNumFilters);
394 std::cout << "Search took " << nanos_per_item_per_filter
395 << " nanoseconds per item per filter.\n";
396 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698