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

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

Issue 2937623007: predictors: Move more methods from ResourcePrefetchPredictor into LoadingDataCollector. (Closed)
Patch Set: Undo unneeded added mock class. Created 3 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/predictors/loading_data_collector.h" 5 #include "chrome/browser/predictors/loading_data_collector.h"
6 6
7 #include <iostream> 7 #include <iostream>
8 #include <memory> 8 #include <memory>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/run_loop.h" 11 #include "base/run_loop.h"
12 #include "base/test/histogram_tester.h" 12 #include "base/test/histogram_tester.h"
13 #include "chrome/browser/history/history_service_factory.h" 13 #include "chrome/browser/history/history_service_factory.h"
14 #include "chrome/browser/predictors/loading_predictor_config.h"
14 #include "chrome/browser/predictors/loading_test_util.h" 15 #include "chrome/browser/predictors/loading_test_util.h"
15 #include "chrome/test/base/testing_profile.h" 16 #include "chrome/test/base/testing_profile.h"
16 #include "content/public/test/test_browser_thread_bundle.h" 17 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "net/http/http_response_headers.h" 18 #include "net/http/http_response_headers.h"
18 #include "net/url_request/url_request_context.h" 19 #include "net/url_request/url_request_context.h"
19 #include "net/url_request/url_request_job.h" 20 #include "net/url_request/url_request_job.h"
20 #include "testing/gmock/include/gmock/gmock.h" 21 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
22 23
23 using testing::StrictMock; 24 using testing::StrictMock;
24 25
25 namespace predictors { 26 namespace predictors {
26 27
27 class LoadingDataCollectorTest : public testing::Test { 28 class LoadingDataCollectorTest : public testing::Test {
28 public: 29 public:
30 LoadingDataCollectorTest() : profile_(new TestingProfile()) {
31 LoadingPredictorConfig config;
32 PopulateTestConfig(&config);
33 mock_predictor_ =
34 base::MakeUnique<StrictMock<MockResourcePrefetchPredictor>>(
35 config, profile_.get()),
36 collector_ = base::MakeUnique<LoadingDataCollector>(mock_predictor_.get(),
37 nullptr, config);
38 }
39
29 void SetUp() override { 40 void SetUp() override {
41 base::RunLoop loop;
42 loop.RunUntilIdle(); // Runs the DB lookup.
43
30 url_request_job_factory_.Reset(); 44 url_request_job_factory_.Reset();
31 url_request_context_.set_job_factory(&url_request_job_factory_); 45 url_request_context_.set_job_factory(&url_request_job_factory_);
32 } 46 }
33 47
34 protected: 48 protected:
35 content::TestBrowserThreadBundle thread_bundle_; 49 content::TestBrowserThreadBundle thread_bundle_;
50 std::unique_ptr<TestingProfile> profile_;
36 net::TestURLRequestContext url_request_context_; 51 net::TestURLRequestContext url_request_context_;
37 MockURLRequestJobFactory url_request_job_factory_; 52 MockURLRequestJobFactory url_request_job_factory_;
53
54 std::unique_ptr<StrictMock<MockResourcePrefetchPredictor>> mock_predictor_;
55 std::unique_ptr<LoadingDataCollector> collector_;
38 }; 56 };
39 57
40 TEST_F(LoadingDataCollectorTest, HandledResourceTypes) { 58 TEST_F(LoadingDataCollectorTest, HandledResourceTypes) {
41 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( 59 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType(
42 content::RESOURCE_TYPE_STYLESHEET, "bogus/mime-type")); 60 content::RESOURCE_TYPE_STYLESHEET, "bogus/mime-type"));
43 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( 61 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType(
44 content::RESOURCE_TYPE_STYLESHEET, "")); 62 content::RESOURCE_TYPE_STYLESHEET, ""));
45 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( 63 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType(
46 content::RESOURCE_TYPE_WORKER, "text/css")); 64 content::RESOURCE_TYPE_WORKER, "text/css"));
47 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( 65 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType(
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 prefetch_unknown_font_request.get())); 238 prefetch_unknown_font_request.get()));
221 239
222 // Not main frame. 240 // Not main frame.
223 std::unique_ptr<net::URLRequest> font_request_sub_frame = CreateURLRequest( 241 std::unique_ptr<net::URLRequest> font_request_sub_frame = CreateURLRequest(
224 url_request_context_, GURL("http://www.google.com/comic-sans-ms.woff"), 242 url_request_context_, GURL("http://www.google.com/comic-sans-ms.woff"),
225 net::MEDIUM, content::RESOURCE_TYPE_FONT_RESOURCE, false); 243 net::MEDIUM, content::RESOURCE_TYPE_FONT_RESOURCE, false);
226 EXPECT_FALSE( 244 EXPECT_FALSE(
227 LoadingDataCollector::ShouldRecordResponse(font_request_sub_frame.get())); 245 LoadingDataCollector::ShouldRecordResponse(font_request_sub_frame.get()));
228 } 246 }
229 247
248 // Single navigation that will be recorded. Will check for duplicate
249 // resources and also for number of resources saved.
250 TEST_F(LoadingDataCollectorTest, SimpleNavigation) {
251 URLRequestSummary main_frame =
252 CreateURLRequestSummary(1, "http://www.google.com");
253 collector_->RecordURLRequest(main_frame);
254 EXPECT_EQ(1U, collector_->inflight_navigations_.size());
255
256 std::vector<URLRequestSummary> resources;
257 resources.push_back(CreateURLRequestSummary(
258 1, "http://www.google.com", "http://google.com/style1.css",
259 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false));
260 collector_->RecordURLResponse(resources.back());
261 resources.push_back(CreateURLRequestSummary(
262 1, "http://www.google.com", "http://google.com/script1.js",
263 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false));
264 collector_->RecordURLResponse(resources.back());
265 resources.push_back(CreateURLRequestSummary(
266 1, "http://www.google.com", "http://google.com/script2.js",
267 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false));
268 collector_->RecordURLResponse(resources.back());
269 resources.push_back(CreateURLRequestSummary(
270 1, "http://www.google.com", "http://google.com/script1.js",
271 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", true));
272 collector_->RecordURLResponse(resources.back());
273 resources.push_back(CreateURLRequestSummary(
274 1, "http://www.google.com", "http://google.com/image1.png",
275 content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false));
276 collector_->RecordURLResponse(resources.back());
277 resources.push_back(CreateURLRequestSummary(
278 1, "http://www.google.com", "http://google.com/image2.png",
279 content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false));
280 collector_->RecordURLResponse(resources.back());
281 resources.push_back(CreateURLRequestSummary(
282 1, "http://www.google.com", "http://google.com/style2.css",
283 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true));
284 collector_->RecordURLResponse(resources.back());
285
286 auto no_store = CreateURLRequestSummary(
287 1, "http://www.google.com",
288 "http://static.google.com/style2-no-store.css",
289 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true);
290 no_store.is_no_store = true;
291 collector_->RecordURLResponse(no_store);
292
293 auto redirected = CreateURLRequestSummary(
294 1, "http://www.google.com", "http://reader.google.com/style.css",
295 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true);
296 redirected.redirect_url = GURL("http://dev.null.google.com/style.css");
297
298 collector_->RecordURLRedirect(redirected);
299 redirected.is_no_store = true;
300 redirected.request_url = redirected.redirect_url;
301 redirected.redirect_url = GURL();
302
303 collector_->RecordURLResponse(redirected);
304
305 EXPECT_CALL(
306 *mock_predictor_,
307 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary(
308 "http://www.google.com", "http://www.google.com", resources))));
309
310 collector_->RecordMainFrameLoadComplete(main_frame.navigation_id);
311 }
312
313 TEST_F(LoadingDataCollectorTest, SimpleRedirect) {
314 URLRequestSummary fb1 = CreateURLRequestSummary(1, "http://fb.com/google");
315 collector_->RecordURLRequest(fb1);
316 EXPECT_EQ(1U, collector_->inflight_navigations_.size());
317
318 URLRequestSummary fb2 = CreateRedirectRequestSummary(
319 1, "http://fb.com/google", "http://facebook.com/google");
320 collector_->RecordURLRedirect(fb2);
321 URLRequestSummary fb3 = CreateRedirectRequestSummary(
322 1, "http://facebook.com/google", "https://facebook.com/google");
323 collector_->RecordURLRedirect(fb3);
324 NavigationID fb_end = CreateNavigationID(1, "https://facebook.com/google");
325
326 EXPECT_CALL(
327 *mock_predictor_,
328 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary(
329 "https://facebook.com/google", "http://fb.com/google",
330 std::vector<URLRequestSummary>()))));
331
332 collector_->RecordMainFrameLoadComplete(fb_end);
333 }
334
335 TEST_F(LoadingDataCollectorTest, OnMainFrameRequest) {
336 URLRequestSummary summary1 = CreateURLRequestSummary(
337 1, "http://www.google.com", "http://www.google.com",
338 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
339 URLRequestSummary summary2 = CreateURLRequestSummary(
340 2, "http://www.google.com", "http://www.google.com",
341 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
342 URLRequestSummary summary3 = CreateURLRequestSummary(
343 3, "http://www.yahoo.com", "http://www.yahoo.com",
344 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
345
346 collector_->RecordURLRequest(summary1);
347 EXPECT_EQ(1U, collector_->inflight_navigations_.size());
348 collector_->RecordURLRequest(summary2);
349 EXPECT_EQ(2U, collector_->inflight_navigations_.size());
350 collector_->RecordURLRequest(summary3);
351 EXPECT_EQ(3U, collector_->inflight_navigations_.size());
352
353 // Insert another with same navigation id. It should replace.
354 URLRequestSummary summary4 = CreateURLRequestSummary(
355 1, "http://www.nike.com", "http://www.nike.com",
356 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
357 URLRequestSummary summary5 = CreateURLRequestSummary(
358 2, "http://www.google.com", "http://www.google.com",
359 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
360
361 collector_->RecordURLRequest(summary4);
362 EXPECT_EQ(3U, collector_->inflight_navigations_.size());
363
364 // Change this creation time so that it will go away on the next insert.
365 summary5.navigation_id.creation_time =
366 base::TimeTicks::Now() - base::TimeDelta::FromDays(1);
367 collector_->RecordURLRequest(summary5);
368 EXPECT_EQ(3U, collector_->inflight_navigations_.size());
369
370 URLRequestSummary summary6 = CreateURLRequestSummary(
371 4, "http://www.shoes.com", "http://www.shoes.com",
372 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
373 collector_->RecordURLRequest(summary6);
374 EXPECT_EQ(3U, collector_->inflight_navigations_.size());
375
376 EXPECT_TRUE(collector_->inflight_navigations_.find(summary3.navigation_id) !=
377 collector_->inflight_navigations_.end());
378 EXPECT_TRUE(collector_->inflight_navigations_.find(summary4.navigation_id) !=
379 collector_->inflight_navigations_.end());
380 EXPECT_TRUE(collector_->inflight_navigations_.find(summary6.navigation_id) !=
381 collector_->inflight_navigations_.end());
382 }
383
384 TEST_F(LoadingDataCollectorTest, OnMainFrameRedirect) {
385 URLRequestSummary yahoo = CreateURLRequestSummary(1, "http://yahoo.com");
386
387 URLRequestSummary bbc1 = CreateURLRequestSummary(2, "http://bbc.com");
388 URLRequestSummary bbc2 =
389 CreateRedirectRequestSummary(2, "http://bbc.com", "https://www.bbc.com");
390 NavigationID bbc_end = CreateNavigationID(2, "https://www.bbc.com");
391
392 URLRequestSummary youtube1 = CreateURLRequestSummary(3, "http://youtube.com");
393 URLRequestSummary youtube2 = CreateRedirectRequestSummary(
394 3, "http://youtube.com", "https://youtube.com");
395 NavigationID youtube_end = CreateNavigationID(3, "https://youtube.com");
396
397 URLRequestSummary nyt1 = CreateURLRequestSummary(4, "http://nyt.com");
398 URLRequestSummary nyt2 =
399 CreateRedirectRequestSummary(4, "http://nyt.com", "http://nytimes.com");
400 URLRequestSummary nyt3 = CreateRedirectRequestSummary(4, "http://nytimes.com",
401 "http://m.nytimes.com");
402 NavigationID nyt_end = CreateNavigationID(4, "http://m.nytimes.com");
403
404 URLRequestSummary fb1 = CreateURLRequestSummary(5, "http://fb.com");
405 URLRequestSummary fb2 =
406 CreateRedirectRequestSummary(5, "http://fb.com", "http://facebook.com");
407 URLRequestSummary fb3 = CreateRedirectRequestSummary(5, "http://facebook.com",
408 "https://facebook.com");
409 URLRequestSummary fb4 = CreateRedirectRequestSummary(
410 5, "https://facebook.com",
411 "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr");
412 NavigationID fb_end = CreateNavigationID(
413 5,
414 "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr");
415
416 // Redirect with empty redirect_url will be deleted.
417 collector_->RecordURLRequest(yahoo);
418 EXPECT_EQ(1U, collector_->inflight_navigations_.size());
419 collector_->OnMainFrameRedirect(yahoo);
420 EXPECT_TRUE(collector_->inflight_navigations_.empty());
421
422 // Redirect without previous request works fine.
423 // collector_->RecordURLRequest(bbc1) missing.
424 collector_->OnMainFrameRedirect(bbc2);
425 EXPECT_EQ(1U, collector_->inflight_navigations_.size());
426 EXPECT_EQ(bbc1.navigation_id.main_frame_url,
427 collector_->inflight_navigations_[bbc_end]->initial_url);
428
429 // http://youtube.com -> https://youtube.com.
430 collector_->RecordURLRequest(youtube1);
431 EXPECT_EQ(2U, collector_->inflight_navigations_.size());
432 collector_->OnMainFrameRedirect(youtube2);
433 EXPECT_EQ(2U, collector_->inflight_navigations_.size());
434 EXPECT_EQ(youtube1.navigation_id.main_frame_url,
435 collector_->inflight_navigations_[youtube_end]->initial_url);
436
437 // http://nyt.com -> http://nytimes.com -> http://m.nytimes.com.
438 collector_->RecordURLRequest(nyt1);
439 EXPECT_EQ(3U, collector_->inflight_navigations_.size());
440 collector_->OnMainFrameRedirect(nyt2);
441 collector_->OnMainFrameRedirect(nyt3);
442 EXPECT_EQ(3U, collector_->inflight_navigations_.size());
443 EXPECT_EQ(nyt1.navigation_id.main_frame_url,
444 collector_->inflight_navigations_[nyt_end]->initial_url);
445
446 // http://fb.com -> http://facebook.com -> https://facebook.com ->
447 // https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr.
448 collector_->RecordURLRequest(fb1);
449 EXPECT_EQ(4U, collector_->inflight_navigations_.size());
450 collector_->OnMainFrameRedirect(fb2);
451 collector_->OnMainFrameRedirect(fb3);
452 collector_->OnMainFrameRedirect(fb4);
453 EXPECT_EQ(4U, collector_->inflight_navigations_.size());
454 EXPECT_EQ(fb1.navigation_id.main_frame_url,
455 collector_->inflight_navigations_[fb_end]->initial_url);
456 }
457
458 TEST_F(LoadingDataCollectorTest, OnSubresourceResponse) {
459 // If there is no inflight navigation, nothing happens.
460 URLRequestSummary resource1 = CreateURLRequestSummary(
461 1, "http://www.google.com", "http://google.com/style1.css",
462 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false);
463 collector_->RecordURLResponse(resource1);
464 EXPECT_TRUE(collector_->inflight_navigations_.empty());
465
466 // Add an inflight navigation.
467 URLRequestSummary main_frame1 = CreateURLRequestSummary(
468 1, "http://www.google.com", "http://www.google.com",
469 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false);
470 collector_->RecordURLRequest(main_frame1);
471 EXPECT_EQ(1U, collector_->inflight_navigations_.size());
472
473 // Now add a few subresources.
474 URLRequestSummary resource2 = CreateURLRequestSummary(
475 1, "http://www.google.com", "http://google.com/script1.js",
476 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false);
477 URLRequestSummary resource3 = CreateURLRequestSummary(
478 1, "http://www.google.com", "http://google.com/script2.js",
479 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false);
480 collector_->RecordURLResponse(resource1);
481 collector_->RecordURLResponse(resource2);
482 collector_->RecordURLResponse(resource3);
483
484 EXPECT_EQ(1U, collector_->inflight_navigations_.size());
485 EXPECT_EQ(3U, collector_->inflight_navigations_[main_frame1.navigation_id]
486 ->subresource_requests.size());
487 EXPECT_EQ(resource1,
488 collector_->inflight_navigations_[main_frame1.navigation_id]
489 ->subresource_requests[0]);
490 EXPECT_EQ(resource2,
491 collector_->inflight_navigations_[main_frame1.navigation_id]
492 ->subresource_requests[1]);
493 EXPECT_EQ(resource3,
494 collector_->inflight_navigations_[main_frame1.navigation_id]
495 ->subresource_requests[2]);
496 }
497
498 TEST_F(LoadingDataCollectorTest, TestRecordFirstContentfulPaint) {
499 auto res1_time = base::TimeTicks::FromInternalValue(1);
500 auto res2_time = base::TimeTicks::FromInternalValue(2);
501 auto fcp_time = base::TimeTicks::FromInternalValue(3);
502 auto res3_time = base::TimeTicks::FromInternalValue(4);
503
504 URLRequestSummary main_frame =
505 CreateURLRequestSummary(1, "http://www.google.com");
506 collector_->RecordURLRequest(main_frame);
507 EXPECT_EQ(1U, collector_->inflight_navigations_.size());
508
509 URLRequestSummary resource1 = CreateURLRequestSummary(
510 1, "http://www.google.com", "http://google.com/style1.css",
511 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false);
512 resource1.response_time = res1_time;
513 collector_->RecordURLResponse(resource1);
514 URLRequestSummary resource2 = CreateURLRequestSummary(
515 1, "http://www.google.com", "http://google.com/script1.js",
516 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false);
517 resource2.response_time = res2_time;
518 collector_->RecordURLResponse(resource2);
519 URLRequestSummary resource3 = CreateURLRequestSummary(
520 1, "http://www.google.com", "http://google.com/script2.js",
521 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false);
522 resource3.response_time = res3_time;
523 collector_->RecordURLResponse(resource3);
524
525 collector_->RecordFirstContentfulPaint(main_frame.navigation_id, fcp_time);
526
527 // Since res3_time is after fcp_time, we expect this field to have been set to
528 // false before RecordPageRequestSummary is called.
529 resource3.before_first_contentful_paint = false;
530 EXPECT_CALL(
531 *mock_predictor_,
532 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary(
533 "http://www.google.com", "http://www.google.com",
534 {resource1, resource2, resource3}))));
535
536 collector_->RecordMainFrameLoadComplete(main_frame.navigation_id);
537 }
538
230 } // namespace predictors 539 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698