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