1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/load_timing_observer.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/compiler_specific.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/format_macros.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/load_flags.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_netlog_params.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing net::NetLog;
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Serves to Identify the current thread as the IO thread.
2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass LoadTimingObserverTest : public testing::Test {
2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen public:
2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  LoadTimingObserverTest() : io_thread_(BrowserThread::IO, &message_loop_) {
2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen private:
2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MessageLoop message_loop_;
2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  BrowserThread io_thread_;
3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbase::TimeTicks current_time;
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddStartEntry(LoadTimingObserver& observer,
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   const NetLog::Source& source,
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NetLog::EventType type,
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NetLog::EventParameters* params) {
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observer.OnAddEntry(type, current_time, source, NetLog::PHASE_BEGIN, params);
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddEndEntry(LoadTimingObserver& observer,
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 const NetLog::Source& source,
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NetLog::EventType type,
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NetLog::EventParameters* params) {
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observer.OnAddEntry(type, current_time, source, NetLog::PHASE_END, params);
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddStartURLRequestEntries(LoadTimingObserver& observer,
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               uint32 id,
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               bool request_timing) {
5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  scoped_refptr<net::URLRequestStartEventParameters> params(
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      new net::URLRequestStartEventParameters(
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          GURL(StringPrintf("http://req%d", id)),
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          "GET",
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          request_timing ? net::LOAD_ENABLE_LOAD_TIMING : 0,
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          net::LOW));
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_URL_REQUEST, id);
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartEntry(observer, source, NetLog::TYPE_REQUEST_ALIVE, NULL);
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartEntry(observer,
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                source,
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                NetLog::TYPE_URL_REQUEST_START_JOB,
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                params.get());
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddEndURLRequestEntries(LoadTimingObserver& observer, uint32 id) {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_URL_REQUEST, id);
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndEntry(observer, source, NetLog::TYPE_REQUEST_ALIVE, NULL);
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndEntry(observer,
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              source,
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              NetLog::TYPE_URL_REQUEST_START_JOB,
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              NULL);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AddStartHTTPStreamJobEntries(LoadTimingObserver& observer, uint32 id) {
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NetLog::Source source(NetLog::SOURCE_HTTP_STREAM_JOB, id);
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddStartEntry(observer, source, NetLog::TYPE_HTTP_STREAM_JOB, NULL);
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AddEndHTTPStreamJobEntries(LoadTimingObserver& observer, uint32 id) {
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NetLog::Source source(NetLog::SOURCE_HTTP_STREAM_JOB, id);
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddEndEntry(observer, source, NetLog::TYPE_HTTP_STREAM_JOB, NULL);
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddStartConnectJobEntries(LoadTimingObserver& observer, uint32 id) {
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_CONNECT_JOB, id);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartEntry(observer, source, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, NULL);
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddEndConnectJobEntries(LoadTimingObserver& observer, uint32 id) {
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_CONNECT_JOB, id);
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndEntry(observer, source, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, NULL);
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddStartSocketEntries(LoadTimingObserver& observer, uint32 id) {
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_SOCKET, id);
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartEntry(observer, source, NetLog::TYPE_SOCKET_ALIVE, NULL);
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddEndSocketEntries(LoadTimingObserver& observer, uint32 id) {
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_SOCKET, id);
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndEntry(observer, source, NetLog::TYPE_SOCKET_ALIVE, NULL);
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BindURLRequestToHTTPStreamJob(LoadTimingObserver& observer,
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                   NetLog::Source url_request_source,
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                   NetLog::Source http_stream_job_source) {
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::NetLogSourceParameter> params(
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new net::NetLogSourceParameter("source_dependency",
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                     http_stream_job_source));
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddStartEntry(observer,
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                url_request_source,
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                NetLog::TYPE_HTTP_STREAM_REQUEST_BOUND_TO_JOB,
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                params.get());
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BindHTTPStreamJobToConnectJob(LoadTimingObserver& observer,
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                   NetLog::Source& http_stream_job_source,
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                   NetLog::Source& connect_source) {
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::NetLogSourceParameter> params(
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new net::NetLogSourceParameter("source_dependency", connect_source));
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddStartEntry(observer,
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                http_stream_job_source,
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                params.get());
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BindHTTPStreamJobToSocket(LoadTimingObserver& observer,
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               NetLog::Source& http_stream_job_source,
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               NetLog::Source& socket_source) {
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::NetLogSourceParameter> params(
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new net::NetLogSourceParameter("source_dependency", socket_source));
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddStartEntry(observer,
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                http_stream_job_source,
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                params.get());
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Test that net::URLRequest with no load timing flag is not processed.
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(LoadTimingObserverTest, NoLoadTimingEnabled) {
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver observer;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartURLRequestEntries(observer, 0, false);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver::URLRequestRecord* record =
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer.GetURLRequestRecord(0);
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(record == NULL);
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that URLRequestRecord is created, deleted and is not growing unbound.
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(LoadTimingObserverTest, URLRequestRecord) {
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver observer;
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create record.
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartURLRequestEntries(observer, 0, true);
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver::URLRequestRecord* record =
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer.GetURLRequestRecord(0);
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(record == NULL);
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Collect record.
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndURLRequestEntries(observer, 0);
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  record = observer.GetURLRequestRecord(0);
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(record == NULL);
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check unbound growth.
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 1; i < 1100; ++i)
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddStartURLRequestEntries(observer, i, true);
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  record = observer.GetURLRequestRecord(1);
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(record == NULL);
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test that HTTPStreamJobRecord is created, deleted and is not growing unbound.
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(LoadTimingObserverTest, HTTPStreamJobRecord) {
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  LoadTimingObserver observer;
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create record.
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddStartHTTPStreamJobEntries(observer, 0);
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(observer.http_stream_job_to_record_.find(0) ==
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   observer.http_stream_job_to_record_.end());
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Collect record.
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddEndHTTPStreamJobEntries(observer, 0);
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(observer.http_stream_job_to_record_.find(0) ==
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   observer.http_stream_job_to_record_.end());
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Check unbound growth.
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 1; i < 1100; ++i)
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    AddStartHTTPStreamJobEntries(observer, i);
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(observer.http_stream_job_to_record_.find(1) ==
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  observer.http_stream_job_to_record_.end());
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that ConnectJobRecord is created, deleted and is not growing unbound.
19421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(LoadTimingObserverTest, ConnectJobRecord) {
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver observer;
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create record.
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartConnectJobEntries(observer, 0);
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(observer.connect_job_to_record_.find(0) ==
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   observer.connect_job_to_record_.end());
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Collect record.
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndConnectJobEntries(observer, 0);
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(observer.connect_job_to_record_.find(0) ==
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   observer.connect_job_to_record_.end());
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check unbound growth.
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 1; i < 1100; ++i)
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddStartConnectJobEntries(observer, i);
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(observer.connect_job_to_record_.find(1) ==
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  observer.connect_job_to_record_.end());
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that SocketRecord is created, deleted and is not growing unbound.
21521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(LoadTimingObserverTest, SocketRecord) {
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver observer;
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create record.
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartSocketEntries(observer, 0);
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(observer.socket_to_record_.find(0) ==
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   observer.socket_to_record_.end());
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Collect record.
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndSocketEntries(observer, 0);
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(observer.socket_to_record_.find(0) ==
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   observer.socket_to_record_.end());
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check unbound growth.
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 1; i < 1100; ++i)
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddStartSocketEntries(observer, i);
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(observer.socket_to_record_.find(1) ==
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  observer.socket_to_record_.end());
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that basic time is set to the request.
23721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(LoadTimingObserverTest, BaseTicks) {
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver observer;
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(1);
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartURLRequestEntries(observer, 0, true);
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver::URLRequestRecord* record =
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer.GetURLRequestRecord(0);
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1000000, record->base_ticks.ToInternalValue());
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test proxy time detection.
24821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(LoadTimingObserverTest, ProxyTime) {
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver observer;
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(1);
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartURLRequestEntries(observer, 0, true);
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_URL_REQUEST, 0);
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(2);
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartEntry(observer, source, NetLog::TYPE_PROXY_SERVICE, NULL);
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(3);
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndEntry(observer, source, NetLog::TYPE_PROXY_SERVICE, NULL);
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver::URLRequestRecord* record =
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer.GetURLRequestRecord(0);
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(2000, record->timing.proxy_start);
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(5000, record->timing.proxy_end);
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test connect time detection.
26721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(LoadTimingObserverTest, ConnectTime) {
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver observer;
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(1);
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartURLRequestEntries(observer, 0, true);
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_URL_REQUEST, 0);
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NetLog::Source http_stream_job_source(NetLog::SOURCE_HTTP_STREAM_JOB, 1);
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddStartHTTPStreamJobEntries(observer, 1);
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(2);
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddStartEntry(observer, http_stream_job_source, NetLog::TYPE_SOCKET_POOL,
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                NULL);
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(3);
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddEndEntry(observer, http_stream_job_source, NetLog::TYPE_SOCKET_POOL, NULL);
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BindURLRequestToHTTPStreamJob(observer, source, http_stream_job_source);
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver::URLRequestRecord* record =
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer.GetURLRequestRecord(0);
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(2000, record->timing.connect_start);
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(5000, record->timing.connect_end);
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test dns time detection.
29221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(LoadTimingObserverTest, DnsTime) {
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver observer;
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start request.
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_URL_REQUEST, 0);
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartURLRequestEntries(observer, 0, true);
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(1);
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add resolver entry.
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartConnectJobEntries(observer, 1);
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source connect_source(NetLog::SOURCE_CONNECT_JOB, 1);
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartEntry(observer,
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                connect_source,
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                NetLog::TYPE_HOST_RESOLVER_IMPL,
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                NULL);
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(2);
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndEntry(observer, connect_source, NetLog::TYPE_HOST_RESOLVER_IMPL, NULL);
3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AddEndConnectJobEntries(observer, 1);
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NetLog::Source http_stream_job_source(NetLog::SOURCE_HTTP_STREAM_JOB, 2);
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddStartHTTPStreamJobEntries(observer, 2);
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BindHTTPStreamJobToConnectJob(observer, http_stream_job_source,
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                connect_source);
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BindURLRequestToHTTPStreamJob(observer, source, http_stream_job_source);
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver::URLRequestRecord* record =
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer.GetURLRequestRecord(0);
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1000, record->timing.dns_start);
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(3000, record->timing.dns_end);
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test send time detection.
32521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(LoadTimingObserverTest, SendTime) {
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver observer;
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start request.
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_URL_REQUEST, 0);
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartURLRequestEntries(observer, 0, true);
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(2);
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add send request entry.
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartEntry(observer,
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                source,
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                NULL);
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(5);
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndEntry(observer,
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              source,
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST,
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              NULL);
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver::URLRequestRecord* record =
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer.GetURLRequestRecord(0);
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(2000, record->timing.send_start);
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(7000, record->timing.send_end);
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test receive time detection.
35121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(LoadTimingObserverTest, ReceiveTime) {
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver observer;
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start request.
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_URL_REQUEST, 0);
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartURLRequestEntries(observer, 0, true);
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(2);
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add send request entry.
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartEntry(observer,
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                source,
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                NULL);
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(5);
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndEntry(observer,
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              source,
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS,
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              NULL);
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver::URLRequestRecord* record =
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer.GetURLRequestRecord(0);
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(2000, record->timing.receive_headers_start);
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(7000, record->timing.receive_headers_end);
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test ssl time detection.
37721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(LoadTimingObserverTest, SslTime) {
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver observer;
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start request.
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source source(NetLog::SOURCE_URL_REQUEST, 0);
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartURLRequestEntries(observer, 0, true);
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(1);
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add resolver entry.
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartSocketEntries(observer, 1);
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source socket_source(NetLog::SOURCE_SOCKET, 1);
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddStartEntry(observer, socket_source, NetLog::TYPE_SSL_CONNECT, NULL);
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_time += TimeDelta::FromSeconds(2);
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddEndEntry(observer, socket_source, NetLog::TYPE_SSL_CONNECT, NULL);
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NetLog::Source http_stream_job_source(NetLog::SOURCE_HTTP_STREAM_JOB, 2);
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddStartHTTPStreamJobEntries(observer, 2);
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BindHTTPStreamJobToSocket(observer, http_stream_job_source, socket_source);
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BindURLRequestToHTTPStreamJob(observer, source, http_stream_job_source);
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadTimingObserver::URLRequestRecord* record =
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer.GetURLRequestRecord(0);
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1000, record->timing.ssl_start);
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(3000, record->timing.ssl_end);
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
403