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

Side by Side Diff: chrome/browser/net/load_timing_browsertest.cc

Issue 12094085: LoadTiming in net part 7: Hooking it all up (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: sync Created 7 years, 9 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
« no previous file with comments | « chrome/browser/net/chrome_net_log.cc ('k') | chrome/browser/net/load_timing_observer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2013 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/basictypes.h"
8 #include "base/bind.h"
9 #include "base/compiler_specific.h"
10 #include "base/files/file_path.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop.h"
14 #include "base/path_service.h"
15 #include "base/stringprintf.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/common/chrome_paths.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/ui_test_utils.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/test/browser_test_utils.h"
23 #include "googleurl/src/gurl.h"
24 #include "net/base/load_timing_info.h"
25 #include "net/test/test_server.h"
26 #include "net/url_request/url_request_file_job.h"
27 #include "net/url_request/url_request_filter.h"
28 #include "net/url_request/url_request_job_factory.h"
29
30 // This file tests that net::LoadTimingInfo is correctly hooked up to the
31 // NavigationTiming API. It depends on behavior in a large number of files
32 // spread across multiple projects, so is somewhat arbitrarily put in
33 // chrome/browser/net.
34
35 using content::BrowserThread;
36
37 namespace {
38
39 const char kTestDomain[] = "test.com";
40 const char kTestUrl[] = "http://test.com/";
41
42 // Relative times need to be used because:
43 // 1) ExecuteScriptAndExtractInt does not support 64-bit integers.
44 // 2) Times for tests are set before the request has been started, but need to
45 // be set relative to the start time.
46 //
47 // Since some tests need to test negative time deltas (preconnected sockets)
48 // and others need to test NULL times (events that don't apply), this class has
49 // to be able to handle all cases: positive deltas, negative deltas, no
50 // delta, and null times.
51 class RelativeTime {
52 public:
53 // Constructor for null RelativeTimes.
54 RelativeTime() : is_null_(true) {
55 }
56
57 // Constructor for non-null RelativeTimes.
58 explicit RelativeTime(int delta_ms)
59 : is_null_(false),
60 delta_(base::TimeDelta::FromMilliseconds(delta_ms)) {
61 }
62
63 // Given a base time, returns the TimeTicks |this| identifies.
64 base::TimeTicks ToTimeTicks(base::TimeTicks base_time) const {
65 if (is_null_)
66 return base::TimeTicks();
67 return base_time + delta_;
68 }
69
70 bool is_null() const { return is_null_; }
71
72 base::TimeDelta GetDelta() const {
73 // This allows tests to compare times that shouldn't be null without
74 // explicitly null-testing them all first.
75 EXPECT_FALSE(is_null_);
76 return delta_;
77 }
78
79 private:
80 bool is_null_;
81
82 // Must be 0 when |is_null| is true.
83 base::TimeDelta delta_;
84
85 // This class is copyable and assignable.
86 };
87
88 // Structure used for both setting the LoadTimingInfo used by mock requests
89 // and for times retrieved from the renderer process.
90 //
91 // Times used for mock requests are all expressed as TimeDeltas relative to
92 // request_start. Null RelativeTimes correspond to null TimeTicks().
93 //
94 // Times read from the renderer are expressed relative to fetchStart (Which is
95 // not the same as request_start). Null RelativeTimes correspond to times that
96 // either cannot be retrieved (proxy times, send end) or times that are 0 (SSL
97 // time when no new SSL connection was established).
98 struct TimingDeltas {
99 RelativeTime proxy_resolve_start;
100 RelativeTime proxy_resolve_end;
101 RelativeTime dns_start;
102 RelativeTime dns_end;
103 RelativeTime connect_start;
104 RelativeTime ssl_start;
105 RelativeTime connect_end;
106 RelativeTime send_start;
107 RelativeTime send_end;
108
109 // Must be non-negative and greater than all other times. May only be null if
110 // all other times are as well.
111 RelativeTime receive_headers_end;
112 };
113
114 // Mock UrlRequestJob that returns the contents of a specified file and
115 // provides the specified load timing information when queried.
116 class MockUrlRequestJobWithTiming : public net::URLRequestFileJob {
117 public:
118 MockUrlRequestJobWithTiming(net::URLRequest* request,
119 net::NetworkDelegate* network_delegate,
120 const base::FilePath& path,
121 const TimingDeltas& load_timing_deltas)
122 : net::URLRequestFileJob(request, network_delegate, path),
123 load_timing_deltas_(load_timing_deltas),
124 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
125 }
126
127 // net::URLRequestFileJob implementation:
128 virtual void Start() OVERRIDE {
129 base::TimeDelta time_to_wait;
130 if (!load_timing_deltas_.receive_headers_end.is_null()) {
131 // Need to delay starting until the largest of the times has elapsed.
132 // Wait a little longer than necessary, to be on the safe side.
133 time_to_wait = load_timing_deltas_.receive_headers_end.GetDelta() +
134 base::TimeDelta::FromMilliseconds(100);
135 }
136
137 MessageLoop::current()->PostDelayedTask(
138 FROM_HERE,
139 base::Bind(&MockUrlRequestJobWithTiming::DelayedStart,
140 weak_factory_.GetWeakPtr()),
141 time_to_wait);
142 }
143
144 virtual void GetLoadTimingInfo(
145 net::LoadTimingInfo* load_timing_info) const OVERRIDE {
146 // This should have been set by the URLRequest.
147 base::TimeTicks request_start = load_timing_info->request_start;
148 ASSERT_FALSE(request_start.is_null());
149
150 // Make sure enough time has elapsed since start was called. If this
151 // fails, the test fixture itself is flaky.
152 if (!load_timing_deltas_.receive_headers_end.is_null()) {
153 EXPECT_LE(
154 request_start + load_timing_deltas_.receive_headers_end.GetDelta(),
155 base::TimeTicks::Now());
156 }
157
158 // If there are no connect times, but there is a receive headers end time,
159 // then assume the socket is reused. This shouldn't affect the load timing
160 // information the test checks, just done for completeness.
161 load_timing_info->socket_reused = false;
162 if (load_timing_deltas_.connect_start.is_null() &&
163 !load_timing_deltas_.receive_headers_end.is_null()) {
164 load_timing_info->socket_reused = true;
165 }
166
167 load_timing_info->proxy_resolve_start =
168 load_timing_deltas_.proxy_resolve_start.ToTimeTicks(request_start);
169 load_timing_info->proxy_resolve_end =
170 load_timing_deltas_.proxy_resolve_end.ToTimeTicks(request_start);
171
172 load_timing_info->connect_timing.dns_start =
173 load_timing_deltas_.dns_start.ToTimeTicks(request_start);
174 load_timing_info->connect_timing.dns_end =
175 load_timing_deltas_.dns_end.ToTimeTicks(request_start);
176 load_timing_info->connect_timing.connect_start =
177 load_timing_deltas_.connect_start.ToTimeTicks(request_start);
178 load_timing_info->connect_timing.ssl_start =
179 load_timing_deltas_.ssl_start.ToTimeTicks(request_start);
180 load_timing_info->connect_timing.connect_end =
181 load_timing_deltas_.connect_end.ToTimeTicks(request_start);
182
183 // If there's an SSL start time, use connect end as the SSL end time.
184 // The NavigationTiming API does not have a corresponding field, and there's
185 // no need to test the case when the values are both non-NULL and different.
186 if (!load_timing_deltas_.ssl_start.is_null()) {
187 load_timing_info->connect_timing.ssl_end =
188 load_timing_info->connect_timing.connect_end;
189 }
190
191 load_timing_info->send_start =
192 load_timing_deltas_.send_start.ToTimeTicks(request_start);
193 load_timing_info->send_end=
194 load_timing_deltas_.send_end.ToTimeTicks(request_start);
195 load_timing_info->receive_headers_end =
196 load_timing_deltas_.receive_headers_end.ToTimeTicks(request_start);
197 }
198
199 private:
200 // Parent class is reference counted, so need to have a private destructor.
201 virtual ~MockUrlRequestJobWithTiming() {}
202
203 void DelayedStart() {
204 net::URLRequestFileJob::Start();
205 }
206
207 // Load times to use, relative to request_start from the URLRequest.
208 const TimingDeltas load_timing_deltas_;
209
210 base::WeakPtrFactory<MockUrlRequestJobWithTiming> weak_factory_;
211
212 DISALLOW_COPY_AND_ASSIGN(MockUrlRequestJobWithTiming);
213 };
214
215 // A protocol handler that returns mock URLRequestJobs that return the specified
216 // file with the given timings. Constructed on the UI thread, but after that,
217 // lives and is destroyed on the IO thread.
218 class TestProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
219 public:
220 TestProtocolHandler(const base::FilePath& path,
221 const TimingDeltas& load_timing_deltas)
222 : path_(path), load_timing_deltas_(load_timing_deltas) {
223 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
224 }
225
226 virtual ~TestProtocolHandler() {
227 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
228 }
229
230 // Registers |this| with the URLRequestFilter, which takes ownership of it.
231 void Register() {
232 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
233 net::URLRequestFilter::GetInstance()->AddHostnameProtocolHandler(
234 "http", kTestDomain,
235 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(this));
236 }
237
238 // Unregisters |this| with the URLRequestFilter, which should then delete
239 // |this|.
240 void Unregister() {
241 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
242 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(
243 "http", kTestDomain);
244 }
245
246 // net::URLRequestJobFactory::ProtocolHandler implementation:
247 virtual net::URLRequestJob* MaybeCreateJob(
248 net::URLRequest* request,
249 net::NetworkDelegate* network_delegate) const OVERRIDE {
250 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
251
252 return new MockUrlRequestJobWithTiming(request, network_delegate, path_,
253 load_timing_deltas_);
254 }
255
256 private:
257 // Path of the file to use as the response body.
258 const base::FilePath path_;
259
260 // Load times for each request to use, relative to their request_start times.
261 const TimingDeltas load_timing_deltas_;
262
263 DISALLOW_COPY_AND_ASSIGN(TestProtocolHandler);
264 };
265
266 class LoadTimingBrowserTest : public InProcessBrowserTest {
267 public:
268 LoadTimingBrowserTest() {
269 }
270
271 virtual ~LoadTimingBrowserTest() {
272 }
273
274 // Navigates to |url| and writes the resulting navigation timings to
275 // |navigation_deltas|.
276 void RunTestWithUrl(const GURL& url, TimingDeltas* navigation_deltas) {
277 ui_test_utils::NavigateToURL(browser(), url);
278 GetResultDeltas(navigation_deltas);
279 }
280
281 // Navigates to a url that returns the timings indicated by
282 // |load_timing_deltas| and writes the resulting navigation timings to
283 // |navigation_deltas|. Uses a generic test page.
284 void RunTest(const TimingDeltas& load_timing_deltas,
285 TimingDeltas* navigation_deltas) {
286 // None of the tests care about the contents of the test page. Just do
287 // this here because PathService has thread restrictions on some platforms.
288 base::FilePath path;
289 PathService::Get(chrome::DIR_TEST_DATA, &path);
290 path = path.AppendASCII("title1.html");
291
292 // Create and register protocol handler.
293 TestProtocolHandler* protocol_handler =
294 new TestProtocolHandler(path, load_timing_deltas);
295 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
296 base::Bind(&TestProtocolHandler::Register,
297 base::Unretained(protocol_handler)));
298
299 // Navigate to the page.
300 RunTestWithUrl(GURL(kTestUrl), navigation_deltas);
301
302 // Once navigation is complete, unregister the protocol handler.
303 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
304 base::Bind(&TestProtocolHandler::Unregister,
305 base::Unretained(protocol_handler)));
306 }
307
308 private:
309 // Reads applicable times from performance.timing and writes them to
310 // |navigation_deltas|. Proxy times and send end cannot be read from the
311 // Navigation Timing API, so those are all left as null.
312 void GetResultDeltas(TimingDeltas* navigation_deltas) {
313 *navigation_deltas = TimingDeltas();
314
315 navigation_deltas->dns_start = GetResultDelta("domainLookupStart");
316 navigation_deltas->dns_end = GetResultDelta("domainLookupEnd");
317 navigation_deltas->connect_start = GetResultDelta("connectStart");
318 navigation_deltas->connect_end = GetResultDelta("connectEnd");
319 navigation_deltas->send_start = GetResultDelta("requestStart");
320 navigation_deltas->receive_headers_end = GetResultDelta("responseStart");
321
322 // Unlike the above times, secureConnectionStart will be zero when not
323 // applicable. In that case, leave ssl_start as null.
324 bool ssl_start_zero = false;
325 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
326 browser()->tab_strip_model()->GetActiveWebContents(),
327 "window.domAutomationController.send("
328 "performance.timing.secureConnectionStart == 0);",
329 &ssl_start_zero));
330 if (!ssl_start_zero)
331 navigation_deltas->ssl_start = GetResultDelta("secureConnectionStart");
332
333 // Simple sanity checks. Make sure times that correspond to LoadTimingInfo
334 // occur between fetchStart and loadEventEnd. Relationships between
335 // intervening times are handled by the test bodies.
336
337 RelativeTime fetch_start = GetResultDelta("fetchStart");
338 // While the input dns_start is sometimes null, when read from the
339 // NavigationTiming API, it's always non-null.
340 EXPECT_LE(fetch_start.GetDelta(), navigation_deltas->dns_start.GetDelta());
341
342 RelativeTime load_event_end = GetResultDelta("loadEventEnd");
343 EXPECT_LE(navigation_deltas->receive_headers_end.GetDelta(),
344 load_event_end.GetDelta());
345 }
346
347 // Returns the time between performance.timing.fetchStart and the time with
348 // the specified name. This time must be non-negative.
349 RelativeTime GetResultDelta(const std::string& name) {
350 int time_ms = 0;
351 std::string command(base::StringPrintf(
352 "window.domAutomationController.send("
353 "performance.timing.%s - performance.timing.fetchStart);",
354 name.c_str()));
355 EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
356 browser()->tab_strip_model()->GetActiveWebContents(),
357 command.c_str(),
358 &time_ms));
359
360 // Basic sanity check.
361 EXPECT_GE(time_ms, 0);
362
363 return RelativeTime(time_ms);
364 }
365 };
366
367 // Test case when no times are given, except the request start times. This
368 // happens with FTP, cached responses, responses handled by something other than
369 // the network stack, RedirectJobs, HSTs, etc.
370 IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, NoTimes) {
371 TimingDeltas load_timing_deltas;
372 TimingDeltas navigation_deltas;
373 RunTest(load_timing_deltas, &navigation_deltas);
374
375 // When there are no times, all read times should be the same as fetchStart,
376 // except SSL start, which should be 0.
377 EXPECT_EQ(base::TimeDelta(), navigation_deltas.dns_start.GetDelta());
378 EXPECT_EQ(base::TimeDelta(), navigation_deltas.dns_end.GetDelta());
379 EXPECT_EQ(base::TimeDelta(), navigation_deltas.connect_start.GetDelta());
380 EXPECT_EQ(base::TimeDelta(), navigation_deltas.connect_end.GetDelta());
381 EXPECT_EQ(base::TimeDelta(), navigation_deltas.send_start.GetDelta());
382 EXPECT_EQ(base::TimeDelta(),
383 navigation_deltas.receive_headers_end.GetDelta());
384
385 EXPECT_TRUE(navigation_deltas.ssl_start.is_null());
386 }
387
388 // Standard case - new socket, no PAC, no preconnect, no SSL.
389 IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, Basic) {
390 TimingDeltas load_timing_deltas;
391 load_timing_deltas.dns_start = RelativeTime(0);
392 load_timing_deltas.dns_end = RelativeTime(100);
393 load_timing_deltas.connect_start = RelativeTime(200);
394 load_timing_deltas.connect_end = RelativeTime(300);
395 load_timing_deltas.send_start = RelativeTime(400);
396 load_timing_deltas.send_end = RelativeTime(500);
397 load_timing_deltas.receive_headers_end = RelativeTime(600);
398
399 TimingDeltas navigation_deltas;
400 RunTest(load_timing_deltas, &navigation_deltas);
401
402 // Due to potential roundoff issues, never check exact differences.
403 EXPECT_LT(navigation_deltas.dns_start.GetDelta(),
404 navigation_deltas.dns_end.GetDelta());
405 EXPECT_LT(navigation_deltas.dns_end.GetDelta(),
406 navigation_deltas.connect_start.GetDelta());
407 EXPECT_LT(navigation_deltas.connect_start.GetDelta(),
408 navigation_deltas.connect_end.GetDelta());
409 EXPECT_LT(navigation_deltas.connect_end.GetDelta(),
410 navigation_deltas.send_start.GetDelta());
411 EXPECT_LT(navigation_deltas.send_start.GetDelta(),
412 navigation_deltas.receive_headers_end.GetDelta());
413
414 EXPECT_TRUE(navigation_deltas.ssl_start.is_null());
415 }
416
417 // Basic SSL case.
418 IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, Ssl) {
419 TimingDeltas load_timing_deltas;
420 load_timing_deltas.dns_start = RelativeTime(0);
421 load_timing_deltas.dns_end = RelativeTime(100);
422 load_timing_deltas.connect_start = RelativeTime(200);
423 load_timing_deltas.ssl_start = RelativeTime(300);
424 load_timing_deltas.connect_end = RelativeTime(400);
425 load_timing_deltas.send_start = RelativeTime(500);
426 load_timing_deltas.send_end = RelativeTime(600);
427 load_timing_deltas.receive_headers_end = RelativeTime(700);
428
429 TimingDeltas navigation_deltas;
430 RunTest(load_timing_deltas, &navigation_deltas);
431
432 // Due to potential roundoff issues, never check exact differences.
433 EXPECT_LT(navigation_deltas.dns_start.GetDelta(),
434 navigation_deltas.dns_end.GetDelta());
435 EXPECT_LT(navigation_deltas.dns_end.GetDelta(),
436 navigation_deltas.connect_start.GetDelta());
437 EXPECT_LT(navigation_deltas.connect_start.GetDelta(),
438 navigation_deltas.ssl_start.GetDelta());
439 EXPECT_LT(navigation_deltas.ssl_start.GetDelta(),
440 navigation_deltas.connect_end.GetDelta());
441 EXPECT_LT(navigation_deltas.connect_end.GetDelta(),
442 navigation_deltas.send_start.GetDelta());
443 EXPECT_LT(navigation_deltas.send_start.GetDelta(),
444 navigation_deltas.receive_headers_end.GetDelta());
445 }
446
447 // All times are the same.
448 IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, EverythingAtOnce) {
449 TimingDeltas load_timing_deltas;
450 load_timing_deltas.dns_start = RelativeTime(100);
451 load_timing_deltas.dns_end = RelativeTime(100);
452 load_timing_deltas.connect_start = RelativeTime(100);
453 load_timing_deltas.ssl_start = RelativeTime(100);
454 load_timing_deltas.connect_end = RelativeTime(100);
455 load_timing_deltas.send_start = RelativeTime(100);
456 load_timing_deltas.send_end = RelativeTime(100);
457 load_timing_deltas.receive_headers_end = RelativeTime(100);
458
459 TimingDeltas navigation_deltas;
460 RunTest(load_timing_deltas, &navigation_deltas);
461
462 EXPECT_EQ(navigation_deltas.dns_start.GetDelta(),
463 navigation_deltas.dns_end.GetDelta());
464 EXPECT_EQ(navigation_deltas.dns_end.GetDelta(),
465 navigation_deltas.connect_start.GetDelta());
466 EXPECT_EQ(navigation_deltas.connect_start.GetDelta(),
467 navigation_deltas.ssl_start.GetDelta());
468 EXPECT_EQ(navigation_deltas.ssl_start.GetDelta(),
469 navigation_deltas.connect_end.GetDelta());
470 EXPECT_EQ(navigation_deltas.connect_end.GetDelta(),
471 navigation_deltas.send_start.GetDelta());
472 EXPECT_EQ(navigation_deltas.send_start.GetDelta(),
473 navigation_deltas.receive_headers_end.GetDelta());
474 }
475
476 // Reuse case.
477 IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, ReuseSocket) {
478 TimingDeltas load_timing_deltas;
479 load_timing_deltas.send_start = RelativeTime(0);
480 load_timing_deltas.send_end = RelativeTime(100);
481 load_timing_deltas.receive_headers_end = RelativeTime(200);
482
483 TimingDeltas navigation_deltas;
484 RunTest(load_timing_deltas, &navigation_deltas);
485
486 // Connect times should all be the same as fetchStart.
487 EXPECT_EQ(base::TimeDelta(), navigation_deltas.dns_start.GetDelta());
488 EXPECT_EQ(base::TimeDelta(), navigation_deltas.dns_end.GetDelta());
489 EXPECT_EQ(base::TimeDelta(), navigation_deltas.connect_start.GetDelta());
490 EXPECT_EQ(base::TimeDelta(), navigation_deltas.connect_end.GetDelta());
491
492 // Connect end may be less than send start, since connect end defaults to
493 // fetchStart, which is often less than request_start.
494 EXPECT_LE(navigation_deltas.connect_end.GetDelta(),
495 navigation_deltas.send_start.GetDelta());
496
497 EXPECT_LT(navigation_deltas.send_start.GetDelta(),
498 navigation_deltas.receive_headers_end.GetDelta());
499
500 EXPECT_TRUE(navigation_deltas.ssl_start.is_null());
501 }
502
503 // Preconnect case. Connect times are all before the request was started.
504 IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, Preconnect) {
505 TimingDeltas load_timing_deltas;
506 load_timing_deltas.dns_start = RelativeTime(-100300);
507 load_timing_deltas.dns_end = RelativeTime(-100200);
508 load_timing_deltas.connect_start = RelativeTime(-100100);
509 load_timing_deltas.connect_end = RelativeTime(-100000);
510 load_timing_deltas.send_start = RelativeTime(0);
511 load_timing_deltas.send_end = RelativeTime(100);
512 load_timing_deltas.receive_headers_end = RelativeTime(200);
513
514 TimingDeltas navigation_deltas;
515 RunTest(load_timing_deltas, &navigation_deltas);
516
517 // Connect times should all be the same as request_start, which is also the
518 // same as send_start (Since send_start is 0).
519 EXPECT_EQ(navigation_deltas.dns_start.GetDelta(),
520 navigation_deltas.dns_end.GetDelta());
521 EXPECT_EQ(navigation_deltas.dns_start.GetDelta(),
522 navigation_deltas.connect_start.GetDelta());
523 EXPECT_EQ(navigation_deltas.dns_start.GetDelta(),
524 navigation_deltas.connect_end.GetDelta());
525 EXPECT_EQ(navigation_deltas.dns_start.GetDelta(),
526 navigation_deltas.send_start.GetDelta());
527
528 EXPECT_LT(navigation_deltas.send_start.GetDelta(),
529 navigation_deltas.receive_headers_end.GetDelta());
530 EXPECT_LT(navigation_deltas.send_start.GetDelta(),
531 navigation_deltas.receive_headers_end.GetDelta());
532
533 EXPECT_TRUE(navigation_deltas.ssl_start.is_null());
534 }
535
536 // Preconnect case with a proxy. Connect times are all before the proxy lookup
537 // finished (Or at the same time).
538 IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, PreconnectProxySsl) {
539 TimingDeltas load_timing_deltas;
540 load_timing_deltas.proxy_resolve_start = RelativeTime(0);
541 load_timing_deltas.proxy_resolve_end = RelativeTime(100);
542 load_timing_deltas.dns_start = RelativeTime(-300);
543 load_timing_deltas.dns_end = RelativeTime(-200);
544 load_timing_deltas.connect_start = RelativeTime(-100);
545 load_timing_deltas.ssl_start = RelativeTime(0);
546 load_timing_deltas.connect_end = RelativeTime(100);
547 load_timing_deltas.send_start = RelativeTime(100);
548 load_timing_deltas.send_end = RelativeTime(200);
549 load_timing_deltas.receive_headers_end = RelativeTime(300);
550
551 TimingDeltas navigation_deltas;
552 RunTest(load_timing_deltas, &navigation_deltas);
553
554 // Connect times should all be the same as proxy_end, which is also the
555 // same as send_start.
556 EXPECT_EQ(navigation_deltas.dns_start.GetDelta(),
557 navigation_deltas.dns_end.GetDelta());
558 EXPECT_EQ(navigation_deltas.dns_start.GetDelta(),
559 navigation_deltas.connect_start.GetDelta());
560 EXPECT_EQ(navigation_deltas.dns_start.GetDelta(),
561 navigation_deltas.ssl_start.GetDelta());
562 EXPECT_EQ(navigation_deltas.dns_start.GetDelta(),
563 navigation_deltas.connect_end.GetDelta());
564 EXPECT_EQ(navigation_deltas.dns_start.GetDelta(),
565 navigation_deltas.send_start.GetDelta());
566
567 EXPECT_LT(navigation_deltas.send_start.GetDelta(),
568 navigation_deltas.receive_headers_end.GetDelta());
569 EXPECT_LT(navigation_deltas.send_start.GetDelta(),
570 navigation_deltas.receive_headers_end.GetDelta());
571 }
572
573 // Integration test with a real network response.
574 IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, Integration) {
575 ASSERT_TRUE(test_server()->Start());
576 TimingDeltas navigation_deltas;
577 RunTestWithUrl(test_server()->GetURL("chunked?waitBeforeHeaders=100"),
578 &navigation_deltas);
579
580 // Due to potential roundoff issues, never check exact differences.
581 EXPECT_LE(navigation_deltas.dns_start.GetDelta(),
582 navigation_deltas.dns_end.GetDelta());
583 EXPECT_LE(navigation_deltas.dns_end.GetDelta(),
584 navigation_deltas.connect_start.GetDelta());
585 EXPECT_LE(navigation_deltas.connect_start.GetDelta(),
586 navigation_deltas.connect_end.GetDelta());
587 EXPECT_LE(navigation_deltas.connect_end.GetDelta(),
588 navigation_deltas.send_start.GetDelta());
589 // The only times that are guaranteed to be distinct are send_start and
590 // received_headers end.
591 EXPECT_LT(navigation_deltas.send_start.GetDelta(),
592 navigation_deltas.receive_headers_end.GetDelta());
593
594 EXPECT_TRUE(navigation_deltas.ssl_start.is_null());
595 }
596
597 } // namespace
OLDNEW
« no previous file with comments | « chrome/browser/net/chrome_net_log.cc ('k') | chrome/browser/net/load_timing_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698