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

Side by Side Diff: chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc

Issue 2698813005: Prerender: fix flaky page load metrics tests (Closed)
Patch Set: Created 3 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "base/files/scoped_temp_dir.h" 5 #include "base/files/scoped_temp_dir.h"
6 #include "base/macros.h" 6 #include "base/macros.h"
7 #include "base/test/histogram_tester.h" 7 #include "base/test/histogram_tester.h"
8 #include "base/time/time.h" 8 #include "base/time/time.h"
9 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" 9 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
10 #include "chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_ob server.h" 10 #include "chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_ob server.h"
11 #include "chrome/browser/page_load_metrics/observers/core_page_load_metrics_obse rver.h" 11 #include "chrome/browser/page_load_metrics/observers/core_page_load_metrics_obse rver.h"
12 #include "chrome/browser/page_load_metrics/observers/document_write_page_load_me trics_observer.h" 12 #include "chrome/browser/page_load_metrics/observers/document_write_page_load_me trics_observer.h"
13 #include "chrome/browser/page_load_metrics/observers/no_state_prefetch_page_load _metrics_observer.h" 13 #include "chrome/browser/page_load_metrics/observers/no_state_prefetch_page_load _metrics_observer.h"
14 #include "chrome/browser/page_load_metrics/page_load_tracker.h" 14 #include "chrome/browser/page_load_metrics/page_load_tracker.h"
15 #include "chrome/browser/prerender/prerender_histograms.h" 15 #include "chrome/browser/prerender/prerender_histograms.h"
16 #include "chrome/browser/prerender/prerender_origin.h" 16 #include "chrome/browser/prerender/prerender_origin.h"
17 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/browser.h" 18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_navigator_params.h" 19 #include "chrome/browser/ui/browser_navigator_params.h"
20 #include "chrome/browser/ui/tabs/tab_strip_model.h" 20 #include "chrome/browser/ui/tabs/tab_strip_model.h"
21 #include "chrome/common/page_load_metrics/page_load_metrics_messages.h"
21 #include "chrome/common/pref_names.h" 22 #include "chrome/common/pref_names.h"
22 #include "chrome/common/url_constants.h" 23 #include "chrome/common/url_constants.h"
23 #include "chrome/test/base/in_process_browser_test.h" 24 #include "chrome/test/base/in_process_browser_test.h"
24 #include "chrome/test/base/ui_test_utils.h" 25 #include "chrome/test/base/ui_test_utils.h"
25 #include "components/prefs/pref_service.h" 26 #include "components/prefs/pref_service.h"
26 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/render_process_host.h"
29 #include "content/public/browser/render_view_host.h"
27 #include "content/public/test/browser_test_utils.h" 30 #include "content/public/test/browser_test_utils.h"
28 #include "content/public/test/download_test_observer.h" 31 #include "content/public/test/download_test_observer.h"
29 #include "net/http/failing_http_transaction_factory.h" 32 #include "net/http/failing_http_transaction_factory.h"
30 #include "net/http/http_cache.h" 33 #include "net/http/http_cache.h"
31 #include "net/test/embedded_test_server/embedded_test_server.h" 34 #include "net/test/embedded_test_server/embedded_test_server.h"
32 #include "net/test/url_request/url_request_failed_job.h" 35 #include "net/test/url_request/url_request_failed_job.h"
33 #include "net/url_request/url_request_context.h" 36 #include "net/url_request/url_request_context.h"
34 #include "net/url_request/url_request_context_getter.h" 37 #include "net/url_request/url_request_context_getter.h"
35 38
39 namespace {
40
41 // Waits until a PageLoadMetricsMsg_TimingUpdated message IPC is received
42 // matching a PageLoadTiming. See WaitForMatchingIPC for details.
43 class TimingUpdatedObserver : public content::BrowserMessageFilter {
44 public:
45 explicit TimingUpdatedObserver(
46 content::RenderWidgetHost* render_widget_host,
47 const page_load_metrics::PageLoadTiming& template_timing)
48 : content::BrowserMessageFilter(PageLoadMetricsMsgStart),
49 template_timing_(template_timing) {
50 DCHECK(template_timing_.dom_content_loaded_event_start ||
Bryan McQuade 2017/02/16 18:18:14 could you use !template_timing_.IsEmpty() here? I
mattcary 2017/02/17 09:37:47 Thanks, IsEmpty is much better. I don't think the
51 template_timing_.load_event_start || template_timing_.first_layout ||
52 template_timing_.first_paint || template_timing_.first_text_paint ||
53 template_timing_.first_image_paint ||
54 template_timing_.first_contentful_paint ||
55 template_timing_.first_meaningful_paint ||
56 template_timing_.parse_start || template_timing_.parse_stop);
57
58 render_widget_host->GetProcess()->AddFilter(this);
59
60 // Roundtrip to the IO thread, to ensure that the filter is properly
61 // installed.
62 content::BrowserThread::PostTaskAndReply(
63 content::BrowserThread::IO, FROM_HERE, base::Bind(&base::DoNothing),
64 base::Bind(&TimingUpdatedObserver::Quit, this));
65 run_loop_.reset(new base::RunLoop());
66 run_loop_->Run();
67 run_loop_.reset(nullptr);
68 }
69
70 // Waits for a TimingUpdated IPC that matches the template PageLoadTiming
71 // given to the constructor. An IPC matches when its PageLoadTiming contains a
72 // non-zero field that is non-zero in the template.
73 void WaitForMatchingIPC() {
74 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
75 if (matched_timing_update_)
76 return;
77
78 run_loop_.reset(new base::RunLoop());
79 run_loop_->Run();
Bryan McQuade 2017/02/16 18:18:14 can we have this time out and fail after some amou
mattcary 2017/02/17 09:37:47 The test harness will time out tests. It seems bet
80 run_loop_.reset(nullptr);
81 }
82
83 private:
84 bool OnMessageReceived(const IPC::Message& message) override {
85 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
86
87 bool unused;
droger 2017/02/16 16:33:12 Do we really need this variable (since the functio
mattcary 2017/02/16 17:43:28 Probably not, but I didn't know what the conventio
mattcary 2017/02/17 09:37:47 Seems to work without the unhandled case. Hooray!
88 IPC_BEGIN_MESSAGE_MAP(TimingUpdatedObserver, message)
89 IPC_MESSAGE_HANDLER(PageLoadMetricsMsg_TimingUpdated, OnTimingUpdated)
90 IPC_MESSAGE_UNHANDLED(unused = false)
91 IPC_END_MESSAGE_MAP()
92
93 return false;
94 }
95
96 bool OnTimingUpdated(const page_load_metrics::PageLoadTiming& timing,
97 const page_load_metrics::PageLoadMetadata& metadata) {
98 if ((template_timing_.dom_content_loaded_event_start &&
99 timing.dom_content_loaded_event_start) ||
droger 2017/02/16 16:33:12 Not exactly sure what would be the use case for se
mattcary 2017/02/16 17:43:28 Since I'm just checking on the single metric it's
Bryan McQuade 2017/02/16 18:18:14 yeah i think i agree that we should verify that al
mattcary 2017/02/17 09:37:47 Done.
100 (template_timing_.load_event_start && timing.load_event_start) ||
101 (template_timing_.first_layout && timing.first_layout) ||
102 (template_timing_.first_paint && timing.first_paint) ||
103 (template_timing_.first_text_paint && timing.first_text_paint) ||
104 (template_timing_.first_image_paint && timing.first_image_paint) ||
105 (template_timing_.first_contentful_paint &&
106 timing.first_contentful_paint) ||
107 (template_timing_.first_meaningful_paint &&
108 timing.first_meaningful_paint) ||
109 (template_timing_.parse_start && timing.parse_start) ||
110 (template_timing_.parse_stop && timing.parse_stop)) {
111 // Ensure that any other handlers of this message, for example the real
112 // PageLoadMetric observers, get a chance to handle this message before
113 // this waiter unblocks.
114 content::BrowserThread::PostTask(
115 content::BrowserThread::IO, FROM_HERE,
116 base::Bind(&TimingUpdatedObserver::BounceTimingUpdate, this, timing,
117 metadata));
118 }
119 return true;
120 }
121
122 void BounceTimingUpdate(const page_load_metrics::PageLoadTiming& timing,
123 const page_load_metrics::PageLoadMetadata& metadata) {
124 content::BrowserThread::PostTask(
125 content::BrowserThread::UI, FROM_HERE,
126 base::Bind(&TimingUpdatedObserver::SetTimingUpdatedAndQuit, this));
127 }
128
129 void Quit() {
130 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
131 if (run_loop_)
132 run_loop_->Quit();
133 }
134
135 void SetTimingUpdatedAndQuit() {
136 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
137 matched_timing_update_ = true;
138 Quit();
139 }
140
141 ~TimingUpdatedObserver() override {}
142
143 std::unique_ptr<base::RunLoop> run_loop_;
144 page_load_metrics::PageLoadTiming template_timing_;
145 bool matched_timing_update_ = false;
146 };
147
148 } // namespace
149
36 class PageLoadMetricsBrowserTest : public InProcessBrowserTest { 150 class PageLoadMetricsBrowserTest : public InProcessBrowserTest {
37 public: 151 public:
38 PageLoadMetricsBrowserTest() {} 152 PageLoadMetricsBrowserTest() {}
39 ~PageLoadMetricsBrowserTest() override {} 153 ~PageLoadMetricsBrowserTest() override {}
40 154
41 protected: 155 protected:
42 void NavigateToUntrackedUrl() { 156 void NavigateToUntrackedUrl() {
43 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); 157 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
44 } 158 }
45 159
46 bool NoPageLoadMetricsRecorded() { 160 bool NoPageLoadMetricsRecorded() {
47 return histogram_tester_.GetTotalCountsForPrefix("PageLoad.").empty(); 161 return histogram_tester_.GetTotalCountsForPrefix("PageLoad.").empty();
48 } 162 }
49 163
164 scoped_refptr<TimingUpdatedObserver> CreateFCPTimingUpdatedObserver() {
165 content::WebContents* web_contents =
166 browser()->tab_strip_model()->GetActiveWebContents();
167 page_load_metrics::PageLoadTiming template_timing;
168 template_timing.first_contentful_paint =
Bryan McQuade 2017/02/16 18:18:14 maybe add a comment noting that the actual value i
mattcary 2017/02/17 09:37:47 Done.
169 base::TimeDelta::FromInternalValue(1);
170 scoped_refptr<TimingUpdatedObserver> observer(new TimingUpdatedObserver(
171 web_contents->GetRenderViewHost()->GetWidget(), template_timing));
172 return observer;
173 }
174
50 base::HistogramTester histogram_tester_; 175 base::HistogramTester histogram_tester_;
51 176
52 private: 177 private:
53 DISALLOW_COPY_AND_ASSIGN(PageLoadMetricsBrowserTest); 178 DISALLOW_COPY_AND_ASSIGN(PageLoadMetricsBrowserTest);
54 }; 179 };
55 180
56 void FailAllNetworkTransactions(net::URLRequestContextGetter* getter) { 181 void FailAllNetworkTransactions(net::URLRequestContextGetter* getter) {
57 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 182 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
58 net::HttpCache* cache( 183 net::HttpCache* cache(
59 getter->GetURLRequestContext()->http_transaction_factory()->GetCache()); 184 getter->GetURLRequestContext()->http_transaction_factory()->GetCache());
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 633
509 histogram_tester_.ExpectUniqueSample( 634 histogram_tester_.ExpectUniqueSample(
510 internal::kHistogramFirstMeaningfulPaintStatus, 635 internal::kHistogramFirstMeaningfulPaintStatus,
511 internal::FIRST_MEANINGFUL_PAINT_DID_NOT_REACH_NETWORK_STABLE, 1); 636 internal::FIRST_MEANINGFUL_PAINT_DID_NOT_REACH_NETWORK_STABLE, 1);
512 histogram_tester_.ExpectTotalCount( 637 histogram_tester_.ExpectTotalCount(
513 internal::kHistogramFirstMeaningfulPaint, 0); 638 internal::kHistogramFirstMeaningfulPaint, 0);
514 histogram_tester_.ExpectTotalCount( 639 histogram_tester_.ExpectTotalCount(
515 internal::kHistogramParseStartToFirstMeaningfulPaint, 0); 640 internal::kHistogramParseStartToFirstMeaningfulPaint, 0);
516 } 641 }
517 642
518 // Flaky on Linux (timing out or failing in an expectation) crbug.com/657022
519 #if defined(OS_LINUX)
520 #define MAYBE_NoStatePrefetchObserverCacheable \
521 DISABLED_NoStatePrefetchObserverCacheable
522 #else
523 #define MAYBE_NoStatePrefetchObserverCacheable NoStatePrefetchObserverCacheable
524 #endif
525 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, 643 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest,
526 MAYBE_NoStatePrefetchObserverCacheable) { 644 NoStatePrefetchObserverCacheable) {
527 ASSERT_TRUE(embedded_test_server()->Start()); 645 ASSERT_TRUE(embedded_test_server()->Start());
528 646
647 scoped_refptr<TimingUpdatedObserver> fcp_observer =
648 CreateFCPTimingUpdatedObserver();
649
529 ui_test_utils::NavigateToURL(browser(), 650 ui_test_utils::NavigateToURL(browser(),
530 embedded_test_server()->GetURL("/title1.html")); 651 embedded_test_server()->GetURL("/title1.html"));
531 NavigateToUntrackedUrl(); 652
653 fcp_observer->WaitForMatchingIPC();
532 654
533 histogram_tester_.ExpectTotalCount( 655 histogram_tester_.ExpectTotalCount(
534 "Prerender.none_PrefetchTTFCP.Reference.NoStore.Visible", 0); 656 "Prerender.none_PrefetchTTFCP.Reference.NoStore.Visible", 0);
535 histogram_tester_.ExpectTotalCount( 657 histogram_tester_.ExpectTotalCount(
536 "Prerender.none_PrefetchTTFCP.Reference.Cacheable.Visible", 1); 658 "Prerender.none_PrefetchTTFCP.Reference.Cacheable.Visible", 1);
537 } 659 }
538 660
539 // Flaky on Linux (timing out or failing in an expectation) crbug.com/657022
540 #if defined(OS_LINUX)
541 #define MAYBE_NoStatePrefetchObserverNoStore \
542 DISABLED_NoStatePrefetchObserverNoStore
543 #else
544 #define MAYBE_NoStatePrefetchObserverNoStore NoStatePrefetchObserverNoStore
545 #endif
546 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, 661 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest,
547 MAYBE_NoStatePrefetchObserverNoStore) { 662 NoStatePrefetchObserverNoStore) {
548 ASSERT_TRUE(embedded_test_server()->Start()); 663 ASSERT_TRUE(embedded_test_server()->Start());
549 664
665 scoped_refptr<TimingUpdatedObserver> fcp_observer =
666 CreateFCPTimingUpdatedObserver();
667
550 ui_test_utils::NavigateToURL(browser(), 668 ui_test_utils::NavigateToURL(browser(),
551 embedded_test_server()->GetURL("/nostore.html")); 669 embedded_test_server()->GetURL("/nostore.html"));
552 NavigateToUntrackedUrl(); 670
671 fcp_observer->WaitForMatchingIPC();
553 672
554 histogram_tester_.ExpectTotalCount( 673 histogram_tester_.ExpectTotalCount(
555 "Prerender.none_PrefetchTTFCP.Reference.NoStore.Visible", 1); 674 "Prerender.none_PrefetchTTFCP.Reference.NoStore.Visible", 1);
556 histogram_tester_.ExpectTotalCount( 675 histogram_tester_.ExpectTotalCount(
557 "Prerender.none_PrefetchTTFCP.Reference.Cacheable.Visible", 0); 676 "Prerender.none_PrefetchTTFCP.Reference.Cacheable.Visible", 0);
558 } 677 }
559 678
560 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, CSSTiming) { 679 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, CSSTiming) {
561 ASSERT_TRUE(embedded_test_server()->Start()); 680 ASSERT_TRUE(embedded_test_server()->Start());
562 681
(...skipping 21 matching lines...) Expand all
584 ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL( 703 ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL(
585 "/page_load_metrics/large.html")); 704 "/page_load_metrics/large.html"));
586 NavigateToUntrackedUrl(); 705 NavigateToUntrackedUrl();
587 706
588 histogram_tester_.ExpectTotalCount(internal::kHistogramTotalBytes, 1); 707 histogram_tester_.ExpectTotalCount(internal::kHistogramTotalBytes, 1);
589 708
590 // Verify that there is a single sample recorded in the 10kB bucket (the size 709 // Verify that there is a single sample recorded in the 10kB bucket (the size
591 // of the main HTML response). 710 // of the main HTML response).
592 histogram_tester_.ExpectBucketCount(internal::kHistogramTotalBytes, 10, 1); 711 histogram_tester_.ExpectBucketCount(internal::kHistogramTotalBytes, 10, 1);
593 } 712 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698