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

Side by Side Diff: chrome/browser/predictors/resource_prefetch_predictor_unittest.cc

Issue 10416002: Seculative resource prefetching for URLs CL. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Resolving conflicts. Created 8 years, 6 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
OLDNEW
(Empty)
1 // 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
5
6 #include "base/memory/ref_counted.h"
7 #include "base/message_loop.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/time.h"
10 #include "chrome/browser/history/history.h"
11 #include "chrome/browser/history/history_types.h"
12 #include "chrome/browser/history/in_memory_database.h"
13 #include "chrome/browser/history/url_database.h"
14 #include "chrome/browser/predictors/resource_prefetch_predictor.h"
15 #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "content/public/test/test_browser_thread.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20
21 using testing::ContainerEq;
22 using testing::Pointee;
23 using testing::SetArgPointee;
24
25 namespace predictors {
26
27 typedef ResourcePrefetchPredictor::URLRequestSummary URLRequestSummary;
28 typedef ResourcePrefetchPredictorTables::UrlTableRow UrlTableRow;
29 typedef ResourcePrefetchPredictorTables::UrlTableRows UrlTableRows;
30
31 class MockResourcePrefetchPredictorTables
32 : public ResourcePrefetchPredictorTables {
33 public:
34 MockResourcePrefetchPredictorTables() { }
35
36 MOCK_METHOD1(GetAllRows, void(std::vector<UrlTableRow>* url_row_buffer));
37 MOCK_METHOD2(UpdateRowsForUrl, void(const GURL& main_page_url,
38 const UrlTableRows& row_buffer));
39 MOCK_METHOD1(DeleteRowsForUrls, void(const std::vector<GURL>& urls));
40 MOCK_METHOD0(DeleteAllRows, void());
41
42 private:
43 ~MockResourcePrefetchPredictorTables() { }
44 };
45
46 class ResourcePrefetchPredictorTest : public testing::Test {
47 public:
48 ResourcePrefetchPredictorTest();
49 ~ResourcePrefetchPredictorTest();
50 void SetUp() OVERRIDE;
51 void TearDown() OVERRIDE;
52
53 protected:
54 void AddUrlToHistory(const std::string& url,
55 int visit_count,
56 time_t last_visit) {
57 history::URLRow row = history::URLRow(GURL(url));
58 row.set_visit_count(visit_count);
59 row.set_last_visit(base::Time::FromTimeT(last_visit));
60 url_db_->AddURL(row);
61 }
62
63 NavigationID CreateNavigationID(int process_id,
64 int render_view_id,
65 const std::string& main_frame_url) {
66 NavigationID navigation_id;
67 navigation_id.render_process_id = process_id;
68 navigation_id.render_view_id = render_view_id;
69 navigation_id.main_frame_url = GURL(main_frame_url);
70 navigation_id.creation_time = base::TimeTicks::Now();
71 return navigation_id;
72 }
73
74 ResourcePrefetchPredictor::URLRequestSummary CreateURLRequestSummary(
75 int process_id,
76 int render_view_id,
77 const std::string& main_frame_url,
78 const std::string& resource_url,
79 ResourceType::Type resource_type,
80 const std::string& mime_type,
81 bool was_cached) {
82 ResourcePrefetchPredictor::URLRequestSummary summary;
83 summary.navigation_id = CreateNavigationID(process_id, render_view_id,
84 main_frame_url);
85 summary.resource_url = GURL(resource_url);
86 summary.resource_type = resource_type;
87 summary.mime_type = mime_type;
88 summary.was_cached = was_cached;
89 return summary;
90 }
91
92 bool URLRequestSummaryAreEqual(const URLRequestSummary& lhs,
93 const URLRequestSummary& rhs) {
94 return lhs.navigation_id == rhs.navigation_id &&
95 lhs.resource_url == rhs.resource_url &&
96 lhs.resource_type == rhs.resource_type &&
97 lhs.mime_type == rhs.mime_type &&
98 lhs.was_cached == rhs.was_cached;
99 }
100
101 void ResetPredictor() {
102 ResourcePrefetchPredictor::Config config;
103 config.max_urls_to_track = 3;
104 config.min_url_visit_count = 2;
105 config.max_resources_per_entry = 4;
106 config.max_consecutive_misses = 2;
107 predictor_.reset(new ResourcePrefetchPredictor(config, &profile_));
108 predictor_->SetTablesForTesting(mock_tables_);
109 }
110
111 MessageLoop loop_;
112 content::TestBrowserThread ui_thread_;
113 content::TestBrowserThread db_thread_;
114 TestingProfile profile_;
115
116 scoped_ptr<ResourcePrefetchPredictor> predictor_;
117 scoped_refptr<MockResourcePrefetchPredictorTables> mock_tables_;
118 UrlTableRows test_url_rows_;
119 history::URLDatabase* url_db_;
120 };
121
122 ResourcePrefetchPredictorTest::ResourcePrefetchPredictorTest()
123 : loop_(MessageLoop::TYPE_DEFAULT),
124 ui_thread_(content::BrowserThread::UI, &loop_),
125 db_thread_(content::BrowserThread::DB, &loop_),
126 predictor_(NULL),
127 mock_tables_(new MockResourcePrefetchPredictorTables()) {
128 test_url_rows_.push_back(UrlTableRow(
129 "http://www.google.com",
130 "http://google.com/style1.css",
131 ResourceType::STYLESHEET,
132 3, 2, 1, 1.0));
133 test_url_rows_.push_back(UrlTableRow(
134 "http://www.google.com",
135 "http://google.com/script3.js",
136 ResourceType::SCRIPT,
137 4, 0, 1, 2.1));
138 test_url_rows_.push_back(UrlTableRow(
139 "http://www.google.com",
140 "http://google.com/script4.js",
141 ResourceType::SCRIPT,
142 11, 0, 0, 2.1));
143 test_url_rows_.push_back(UrlTableRow(
144 "http://www.google.com",
145 "http://google.com/image1.png",
146 ResourceType::IMAGE,
147 6, 3, 0, 2.2));
148 test_url_rows_.push_back(UrlTableRow(
149 "http://www.google.com",
150 "http://google.com/a.font",
151 ResourceType::LAST_TYPE,
152 2, 0, 0, 5.1));
153
154 test_url_rows_.push_back(UrlTableRow(
155 "http://www.reddit.com",
156 "http://reddit-resource.com/script1.js",
157 ResourceType::SCRIPT,
158 4, 0, 1, 1.0));
159 test_url_rows_.push_back(UrlTableRow(
160 "http://www.reddit.com",
161 "http://reddit-resource.com/script2.js",
162 ResourceType::SCRIPT,
163 2, 0, 0, 2.1));
164
165 test_url_rows_.push_back(UrlTableRow(
166 "http://www.yahoo.com",
167 "http://google.com/image.png",
168 ResourceType::IMAGE,
169 20, 1, 0, 10.0));
170 }
171
172 ResourcePrefetchPredictorTest::~ResourcePrefetchPredictorTest() {
173 }
174
175 void ResourcePrefetchPredictorTest::SetUp() {
176 profile_.CreateHistoryService(true, false);
177 profile_.BlockUntilHistoryProcessesPendingRequests();
178 EXPECT_TRUE(profile_.GetHistoryService(Profile::EXPLICIT_ACCESS));
179 url_db_ = profile_.GetHistoryService(
180 Profile::EXPLICIT_ACCESS)->InMemoryDatabase();
181
182 // Initialize the predictor with empty data.
183 ResetPredictor();
184 EXPECT_EQ(predictor_->initialization_state_,
185 ResourcePrefetchPredictor::NOT_INITIALIZED);
186 EXPECT_CALL(*mock_tables_, GetAllRows(Pointee(ContainerEq(UrlTableRows()))));
187 predictor_->LazilyInitialize();
188 profile_.BlockUntilHistoryProcessesPendingRequests();
189 EXPECT_TRUE(predictor_->inflight_navigations_.empty());
190 EXPECT_EQ(predictor_->initialization_state_,
191 ResourcePrefetchPredictor::INITIALIZED);
192 }
193
194 void ResourcePrefetchPredictorTest::TearDown() {
195 predictor_.reset(NULL);
196 profile_.DestroyHistoryService();
197 }
198
199 TEST_F(ResourcePrefetchPredictorTest, LazilyInitializeEmpty) {
200 // Tests that the predictor initializes correctly without any data.
201 EXPECT_TRUE(predictor_->url_table_cache_.empty());
202 }
203
204 TEST_F(ResourcePrefetchPredictorTest, LazilyInitializeWithData) {
205 // Tests that the history and the db tables data are loaded correctly.
206 AddUrlToHistory("http://www.google.com", 4, 12345);
207 AddUrlToHistory("http://www.yahoo.com", 2, 12346);
208
209 EXPECT_CALL(*mock_tables_, GetAllRows(Pointee(ContainerEq(UrlTableRows()))))
210 .WillOnce(SetArgPointee<0>(test_url_rows_));
211
212 std::vector<GURL> urls_to_delete;
213 urls_to_delete.push_back(GURL("http://www.reddit.com"));
214 EXPECT_CALL(*mock_tables_, DeleteRowsForUrls(ContainerEq(urls_to_delete)));
215
216 ResetPredictor();
217 predictor_->LazilyInitialize();
218 loop_.RunAllPending();
219
220 // Test that the internal variables correctly initialized.
221 EXPECT_EQ(predictor_->initialization_state_,
222 ResourcePrefetchPredictor::INITIALIZED);
223 EXPECT_TRUE(predictor_->inflight_navigations_.empty());
224 EXPECT_EQ(2, static_cast<int>(predictor_->url_table_cache_.size()));
225
226 UrlTableRows google_rows(test_url_rows_.begin(),
227 test_url_rows_.begin() + 5);
228 std::sort(google_rows.begin(), google_rows.end(),
229 ResourcePrefetchPredictorTables::UrlTableRowSorter());
230 EXPECT_EQ(predictor_->url_table_cache_[GURL("http://www.google.com")].rows,
231 google_rows);
232 EXPECT_EQ(
233 predictor_->url_table_cache_[GURL("http://www.google.com")].last_visit,
234 base::Time::FromTimeT(12345));
235
236 UrlTableRows yahoo_rows(test_url_rows_.begin() + 7,
237 test_url_rows_.begin() + 8);
238 EXPECT_EQ(predictor_->url_table_cache_[GURL("http://www.yahoo.com")].rows,
239 yahoo_rows);
240 EXPECT_EQ(
241 predictor_->url_table_cache_[GURL("http://www.yahoo.com")].last_visit,
242 base::Time::FromTimeT(12346));
243 }
244
245 TEST_F(ResourcePrefetchPredictorTest, NavigationNotRecorded) {
246 // Single navigation but history count is low, so should not record.
247 AddUrlToHistory("http://www.google.com", 1, 12345);
248
249 URLRequestSummary main_frame = CreateURLRequestSummary(
250 1, 1, "http://www.google.com", "http://www.google.com",
251 ResourceType::MAIN_FRAME, "", false);
252 predictor_->RecordURLRequest(main_frame);
253 EXPECT_EQ(1, static_cast<int>(predictor_->inflight_navigations_.size()));
254
255 // Now add a few subresources.
256 URLRequestSummary resource1 = CreateURLRequestSummary(
257 1, 1, "http://www.google.com", "http://google.com/style1.css",
258 ResourceType::STYLESHEET, "text/css", false);
259 predictor_->RecordUrlResponse(resource1);
260 URLRequestSummary resource2 = CreateURLRequestSummary(
261 1, 1, "http://www.google.com", "http://google.com/script1.js",
262 ResourceType::SCRIPT, "text/javascript", false);
263 predictor_->RecordUrlResponse(resource2);
264 URLRequestSummary resource3 = CreateURLRequestSummary(
265 1, 1, "http://www.google.com", "http://google.com/script2.js",
266 ResourceType::SCRIPT, "text/javascript", false);
267 predictor_->RecordUrlResponse(resource3);
268 predictor_->OnNavigationComplete(main_frame.navigation_id);
269 }
270
271 TEST_F(ResourcePrefetchPredictorTest, NavigationUrlNotInDB) {
272 // Single navigation that will be recorded. Will check for duplicate
273 // resources and also for number of resources saved.
274 AddUrlToHistory("http://www.google.com", 4, 12345);
275
276 URLRequestSummary main_frame = CreateURLRequestSummary(
277 1, 1, "http://www.google.com", "http://www.google.com",
278 ResourceType::MAIN_FRAME, "", false);
279 predictor_->RecordURLRequest(main_frame);
280 EXPECT_EQ(1, static_cast<int>(predictor_->inflight_navigations_.size()));
281
282 URLRequestSummary resource1 = CreateURLRequestSummary(
283 1, 1, "http://www.google.com", "http://google.com/style1.css",
284 ResourceType::STYLESHEET, "text/css", false);
285 predictor_->RecordUrlResponse(resource1);
286 URLRequestSummary resource2 = CreateURLRequestSummary(
287 1, 1, "http://www.google.com", "http://google.com/script1.js",
288 ResourceType::SCRIPT, "text/javascript", false);
289 predictor_->RecordUrlResponse(resource2);
290 URLRequestSummary resource3 = CreateURLRequestSummary(
291 1, 1, "http://www.google.com", "http://google.com/script2.js",
292 ResourceType::SCRIPT, "text/javascript", false);
293 predictor_->RecordUrlResponse(resource3);
294 URLRequestSummary resource4 = CreateURLRequestSummary(
295 1, 1, "http://www.google.com", "http://google.com/script1.js",
296 ResourceType::SCRIPT, "text/javascript", true);
297 predictor_->RecordUrlResponse(resource4);
298 URLRequestSummary resource5 = CreateURLRequestSummary(
299 1, 1, "http://www.google.com", "http://google.com/image1.png",
300 ResourceType::IMAGE, "image/png", false);
301 predictor_->RecordUrlResponse(resource5);
302 URLRequestSummary resource6 = CreateURLRequestSummary(
303 1, 1, "http://www.google.com", "http://google.com/image2.png",
304 ResourceType::IMAGE, "image/png", false);
305 predictor_->RecordUrlResponse(resource6);
306 URLRequestSummary resource7 = CreateURLRequestSummary(
307 1, 1, "http://www.google.com", "http://google.com/style2.css",
308 ResourceType::STYLESHEET, "text/css", false);
309 predictor_->OnSubresourceLoadedFromMemory(
310 resource7.navigation_id,
311 resource7.resource_url,
312 resource7.mime_type,
313 resource7.resource_type);
314
315 UrlTableRows db_rows;
316 db_rows.push_back(UrlTableRow(
317 "http://www.google.com", "http://google.com/style1.css",
318 ResourceType::STYLESHEET, 1, 0, 0, 1.0));
319 db_rows.push_back(UrlTableRow(
320 "http://www.google.com", "http://google.com/script1.js",
321 ResourceType::SCRIPT, 1, 0, 0, 2.0));
322 db_rows.push_back(UrlTableRow(
323 "http://www.google.com", "http://google.com/script2.js",
324 ResourceType::SCRIPT, 1, 0, 0, 3.0));
325 db_rows.push_back(UrlTableRow(
326 "http://www.google.com", "http://google.com/style2.css",
327 ResourceType::STYLESHEET, 1, 0, 0, 7.0));
328 EXPECT_CALL(*mock_tables_,
329 UpdateRowsForUrl(GURL("http://www.google.com"),
330 ContainerEq(db_rows)));
331
332 predictor_->OnNavigationComplete(main_frame.navigation_id);
333 }
334
335 TEST_F(ResourcePrefetchPredictorTest, NavigationUrlInDB) {
336 // Tests that navigation is recoreded correctly for URL already present in
337 // the database cache.
338 AddUrlToHistory("http://www.google.com", 4, 12345);
339
340 EXPECT_CALL(*mock_tables_, GetAllRows(Pointee(ContainerEq(UrlTableRows()))))
341 .WillOnce(SetArgPointee<0>(test_url_rows_));
342
343 std::vector<GURL> urls_to_delete;
344 urls_to_delete.push_back(GURL("http://www.reddit.com"));
345 urls_to_delete.push_back(GURL("http://www.yahoo.com"));
346 EXPECT_CALL(*mock_tables_, DeleteRowsForUrls(ContainerEq(urls_to_delete)));
347
348 ResetPredictor();
349 predictor_->LazilyInitialize();
350 loop_.RunAllPending();
351
352 URLRequestSummary main_frame = CreateURLRequestSummary(
353 1, 1, "http://www.google.com", "http://www.google.com",
354 ResourceType::MAIN_FRAME, "", false);
355 predictor_->RecordURLRequest(main_frame);
356 EXPECT_EQ(1, static_cast<int>(predictor_->inflight_navigations_.size()));
357
358 URLRequestSummary resource1 = CreateURLRequestSummary(
359 1, 1, "http://www.google.com", "http://google.com/style1.css",
360 ResourceType::STYLESHEET, "text/css", false);
361 predictor_->RecordUrlResponse(resource1);
362 URLRequestSummary resource2 = CreateURLRequestSummary(
363 1, 1, "http://www.google.com", "http://google.com/script1.js",
364 ResourceType::SCRIPT, "text/javascript", false);
365 predictor_->RecordUrlResponse(resource2);
366 URLRequestSummary resource3 = CreateURLRequestSummary(
367 1, 1, "http://www.google.com", "http://google.com/script2.js",
368 ResourceType::SCRIPT, "text/javascript", false);
369 predictor_->RecordUrlResponse(resource3);
370 URLRequestSummary resource4 = CreateURLRequestSummary(
371 1, 1, "http://www.google.com", "http://google.com/script1.js",
372 ResourceType::SCRIPT, "text/javascript", true);
373 predictor_->RecordUrlResponse(resource4);
374 URLRequestSummary resource5 = CreateURLRequestSummary(
375 1, 1, "http://www.google.com", "http://google.com/image1.png",
376 ResourceType::IMAGE, "image/png", false);
377 predictor_->RecordUrlResponse(resource5);
378 URLRequestSummary resource6 = CreateURLRequestSummary(
379 1, 1, "http://www.google.com", "http://google.com/image2.png",
380 ResourceType::IMAGE, "image/png", false);
381 predictor_->RecordUrlResponse(resource6);
382 URLRequestSummary resource7 = CreateURLRequestSummary(
383 1, 1, "http://www.google.com", "http://google.com/style2.css",
384 ResourceType::STYLESHEET, "text/css", false);
385 predictor_->OnSubresourceLoadedFromMemory(
386 resource7.navigation_id,
387 resource7.resource_url,
388 resource7.mime_type,
389 resource7.resource_type);
390
391 UrlTableRows db_rows;
392 db_rows.push_back(UrlTableRow(
393 "http://www.google.com", "http://google.com/style1.css",
394 ResourceType::STYLESHEET, 4, 2, 0, 1.0));
395 db_rows.push_back(UrlTableRow(
396 "http://www.google.com", "http://google.com/script1.js",
397 ResourceType::SCRIPT, 1, 0, 0, 2.0));
398 db_rows.push_back(UrlTableRow(
399 "http://www.google.com", "http://google.com/script4.js",
400 ResourceType::SCRIPT, 11, 1, 1, 2.1));
401 db_rows.push_back(UrlTableRow(
402 "http://www.google.com", "http://google.com/script2.js",
403 ResourceType::SCRIPT, 1, 0, 0, 3.0));
404 EXPECT_CALL(*mock_tables_,
405 UpdateRowsForUrl(GURL("http://www.google.com"),
406 ContainerEq(db_rows)));
407
408 predictor_->OnNavigationComplete(main_frame.navigation_id);
409 }
410
411 TEST_F(ResourcePrefetchPredictorTest, NavigationUrlNotInDBAndDBFull) {
412 // Tests that a URL is deleted before another is added if the cache is full.
413 AddUrlToHistory("http://www.google.com", 4, 12345);
414 AddUrlToHistory("http://www.reddit.com", 4, 12340); // Should be deleted.
415 AddUrlToHistory("http://www.yahoo.com", 4, 12350);
416 AddUrlToHistory("http://www.nike.com", 4, 10000);
417
418 EXPECT_CALL(*mock_tables_, GetAllRows(Pointee(ContainerEq(UrlTableRows()))))
419 .WillOnce(SetArgPointee<0>(test_url_rows_));
420
421 ResetPredictor();
422 predictor_->LazilyInitialize();
423 loop_.RunAllPending();
424 EXPECT_EQ(3, static_cast<int>(predictor_->url_table_cache_.size()));
425
426 URLRequestSummary main_frame = CreateURLRequestSummary(
427 1, 1, "http://www.nike.com", "http://www.nike.com",
428 ResourceType::MAIN_FRAME, "", false);
429 predictor_->RecordURLRequest(main_frame);
430 EXPECT_EQ(1, static_cast<int>(predictor_->inflight_navigations_.size()));
431
432 URLRequestSummary resource1 = CreateURLRequestSummary(
433 1, 1, "http://www.nike.com", "http://nike.com/style1.css",
434 ResourceType::STYLESHEET, "text/css", false);
435 predictor_->RecordUrlResponse(resource1);
436 URLRequestSummary resource2 = CreateURLRequestSummary(
437 1, 1, "http://www.nike.com", "http://nike.com/image2.png",
438 ResourceType::IMAGE, "image/png", false);
439 predictor_->RecordUrlResponse(resource2);
440
441 std::vector<GURL> urls_to_delete;
442 urls_to_delete.push_back(GURL("http://www.reddit.com"));
443 EXPECT_CALL(*mock_tables_, DeleteRowsForUrls(ContainerEq(urls_to_delete)));
444
445 UrlTableRows db_rows;
446 db_rows.push_back(UrlTableRow(
447 "http://www.nike.com", "http://nike.com/style1.css",
448 ResourceType::STYLESHEET, 1, 0, 0, 1.0));
449 db_rows.push_back(UrlTableRow(
450 "http://www.nike.com", "http://nike.com/image2.png",
451 ResourceType::IMAGE, 1, 0, 0, 2.0));
452 EXPECT_CALL(*mock_tables_,
453 UpdateRowsForUrl(GURL("http://www.nike.com"),
454 ContainerEq(db_rows)));
455
456 predictor_->OnNavigationComplete(main_frame.navigation_id);
457 }
458
459 TEST_F(ResourcePrefetchPredictorTest, DeleteUrls) {
460 // Add some dummy entries to cache.
461 predictor_->url_table_cache_[GURL("http://www.google.com")];
462 predictor_->url_table_cache_[GURL("http://www.yahoo.com")];
463 predictor_->url_table_cache_[GURL("http://www.apple.com")];
464 predictor_->url_table_cache_[GURL("http://www.nike.com")];
465 predictor_->url_table_cache_[GURL("http://www.reddit.com")];
466
467 history::URLRows rows;
468 rows.push_back(history::URLRow(GURL("http://www.apple.com")));
469 rows.push_back(history::URLRow(GURL("http://www.yahoo.com")));
470
471 std::vector<GURL> urls_to_delete;
472 urls_to_delete.push_back(GURL("http://www.apple.com"));
473 urls_to_delete.push_back(GURL("http://www.yahoo.com"));
474 EXPECT_CALL(*mock_tables_, DeleteRowsForUrls(ContainerEq(urls_to_delete)));
475 predictor_->DeleteUrls(rows);
476 EXPECT_EQ(3, static_cast<int>(predictor_->url_table_cache_.size()));
477
478 EXPECT_CALL(*mock_tables_, DeleteAllRows());
479
480 predictor_->DeleteAllUrls();
481 EXPECT_TRUE(predictor_->url_table_cache_.empty());
482 }
483
484 TEST_F(ResourcePrefetchPredictorTest, OnMainFrameRequest) {
485 URLRequestSummary summary1 = CreateURLRequestSummary(
486 1, 1, "http://www.google.com", "http://www.google.com",
487 ResourceType::MAIN_FRAME, "", false);
488 URLRequestSummary summary2 = CreateURLRequestSummary(
489 1, 2, "http://www.google.com", "http://www.google.com",
490 ResourceType::MAIN_FRAME, "", false);
491 URLRequestSummary summary3 = CreateURLRequestSummary(
492 2, 1, "http://www.yahoo.com", "http://www.yahoo.com",
493 ResourceType::MAIN_FRAME, "", false);
494
495 predictor_->OnMainFrameRequest(summary1);
496 EXPECT_EQ(1, static_cast<int>(predictor_->inflight_navigations_.size()));
497 predictor_->OnMainFrameRequest(summary2);
498 EXPECT_EQ(2, static_cast<int>(predictor_->inflight_navigations_.size()));
499 predictor_->OnMainFrameRequest(summary3);
500 EXPECT_EQ(3, static_cast<int>(predictor_->inflight_navigations_.size()));
501
502 // Insert anther with same navigation id. It should replace.
503 URLRequestSummary summary4 = CreateURLRequestSummary(
504 1, 1, "http://www.nike.com", "http://www.nike.com",
505 ResourceType::MAIN_FRAME, "", false);
506 URLRequestSummary summary5 = CreateURLRequestSummary(
507 1, 2, "http://www.google.com", "http://www.google.com",
508 ResourceType::MAIN_FRAME, "", false);
509
510 predictor_->OnMainFrameRequest(summary4);
511 EXPECT_EQ(3, static_cast<int>(predictor_->inflight_navigations_.size()));
512
513 // Change this creation time so that it will go away on the next insert.
514 summary5.navigation_id.creation_time = base::TimeTicks::Now() -
515 base::TimeDelta::FromDays(1);
516 predictor_->OnMainFrameRequest(summary5);
517 EXPECT_EQ(3, static_cast<int>(predictor_->inflight_navigations_.size()));
518
519 URLRequestSummary summary6 = CreateURLRequestSummary(
520 3, 1, "http://www.shoes.com", "http://www.shoes.com",
521 ResourceType::MAIN_FRAME, "", false);
522 predictor_->OnMainFrameRequest(summary6);
523 EXPECT_EQ(3, static_cast<int>(predictor_->inflight_navigations_.size()));
524
525 EXPECT_TRUE(predictor_->inflight_navigations_.find(summary3.navigation_id) !=
526 predictor_->inflight_navigations_.end());
527 EXPECT_TRUE(predictor_->inflight_navigations_.find(summary4.navigation_id) !=
528 predictor_->inflight_navigations_.end());
529 EXPECT_TRUE(predictor_->inflight_navigations_.find(summary6.navigation_id) !=
530 predictor_->inflight_navigations_.end());
531 }
532
533 TEST_F(ResourcePrefetchPredictorTest, OnMainFrameRedirect) {
534 URLRequestSummary summary1 = CreateURLRequestSummary(
535 1, 1, "http://www.google.com", "http://www.google.com",
536 ResourceType::MAIN_FRAME, "", false);
537 URLRequestSummary summary2 = CreateURLRequestSummary(
538 1, 2, "http://www.google.com", "http://www.google.com",
539 ResourceType::MAIN_FRAME, "", false);
540 URLRequestSummary summary3 = CreateURLRequestSummary(
541 2, 1, "http://www.yahoo.com", "http://www.yahoo.com",
542 ResourceType::MAIN_FRAME, "", false);
543
544 predictor_->OnMainFrameRedirect(summary1);
545 EXPECT_TRUE(predictor_->inflight_navigations_.empty());
546
547 predictor_->OnMainFrameRequest(summary1);
548 EXPECT_EQ(1, static_cast<int>(predictor_->inflight_navigations_.size()));
549 predictor_->OnMainFrameRequest(summary2);
550 EXPECT_EQ(2, static_cast<int>(predictor_->inflight_navigations_.size()));
551
552 predictor_->OnMainFrameRedirect(summary3);
553 EXPECT_EQ(2, static_cast<int>(predictor_->inflight_navigations_.size()));
554 predictor_->OnMainFrameRedirect(summary1);
555 EXPECT_EQ(1, static_cast<int>(predictor_->inflight_navigations_.size()));
556 predictor_->OnMainFrameRedirect(summary2);
557 EXPECT_TRUE(predictor_->inflight_navigations_.empty());
558 }
559
560 TEST_F(ResourcePrefetchPredictorTest, OnSubresourceResponse) {
561 // If there is no inflight navigation, nothing happens.
562 URLRequestSummary resource1 = CreateURLRequestSummary(
563 1, 1, "http://www.google.com", "http://google.com/style1.css",
564 ResourceType::STYLESHEET, "text/css", false);
565 predictor_->OnSubresourceResponse(resource1);
566 EXPECT_TRUE(predictor_->inflight_navigations_.empty());
567
568 // Add an inflight navigation.
569 URLRequestSummary main_frame1 = CreateURLRequestSummary(
570 1, 1, "http://www.google.com", "http://www.google.com",
571 ResourceType::MAIN_FRAME, "", false);
572 predictor_->OnMainFrameRequest(main_frame1);
573 EXPECT_EQ(1, static_cast<int>(predictor_->inflight_navigations_.size()));
574
575 // Now add a few subresources.
576 URLRequestSummary resource2 = CreateURLRequestSummary(
577 1, 1, "http://www.google.com", "http://google.com/script1.js",
578 ResourceType::SCRIPT, "text/javascript", false);
579 URLRequestSummary resource3 = CreateURLRequestSummary(
580 1, 1, "http://www.google.com", "http://google.com/script2.js",
581 ResourceType::SCRIPT, "text/javascript", false);
582 predictor_->OnSubresourceResponse(resource1);
583 predictor_->OnSubresourceResponse(resource2);
584 predictor_->OnSubresourceResponse(resource3);
585
586 EXPECT_EQ(1, static_cast<int>(predictor_->inflight_navigations_.size()));
587 EXPECT_EQ(3, static_cast<int>(
588 predictor_->inflight_navigations_[main_frame1.navigation_id].size()));
589 EXPECT_TRUE(URLRequestSummaryAreEqual(
590 resource1,
591 predictor_->inflight_navigations_[main_frame1.navigation_id][0]));
592 EXPECT_TRUE(URLRequestSummaryAreEqual(
593 resource2,
594 predictor_->inflight_navigations_[main_frame1.navigation_id][1]));
595 EXPECT_TRUE(URLRequestSummaryAreEqual(
596 resource3,
597 predictor_->inflight_navigations_[main_frame1.navigation_id][2]));
598 }
599
600 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698