OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/net/http_pipelining_compatibility_client.h" | 5 #include "chrome/browser/net/http_pipelining_compatibility_client.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/memory/scoped_ptr.h" | |
12 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
13 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
15 #include "base/metrics/histogram_samples.h" | |
14 #include "base/metrics/statistics_recorder.h" | 16 #include "base/metrics/statistics_recorder.h" |
15 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
16 #include "base/stringprintf.h" | 18 #include "base/stringprintf.h" |
17 #include "content/public/test/test_browser_thread.h" | 19 #include "content/public/test/test_browser_thread.h" |
18 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
19 #include "net/base/test_completion_callback.h" | 21 #include "net/base/test_completion_callback.h" |
20 #include "net/url_request/url_request_context_getter.h" | 22 #include "net/url_request/url_request_context_getter.h" |
21 #include "net/url_request/url_request_test_util.h" | 23 #include "net/url_request/url_request_test_util.h" |
22 #include "net/test/test_server.h" | 24 #include "net/test/test_server.h" |
23 #include "testing/gmock/include/gmock/gmock.h" | 25 #include "testing/gmock/include/gmock/gmock.h" |
24 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
25 | 27 |
28 using base::Histogram; | |
29 using base::HistogramSamples; | |
30 | |
26 namespace chrome_browser_net { | 31 namespace chrome_browser_net { |
27 | 32 |
28 namespace { | 33 namespace { |
29 | 34 |
30 static const char* const kHistogramNames[] = { | 35 static const char* const kHistogramNames[] = { |
31 "NetConnectivity.Pipeline.CanarySuccess", | 36 "NetConnectivity.Pipeline.CanarySuccess", |
32 "NetConnectivity.Pipeline.Depth", | 37 "NetConnectivity.Pipeline.Depth", |
33 "NetConnectivity.Pipeline.AllHTTP11", | 38 "NetConnectivity.Pipeline.AllHTTP11", |
34 "NetConnectivity.Pipeline.Success", | 39 "NetConnectivity.Pipeline.Success", |
35 "NetConnectivity.Pipeline.0.NetworkError", | 40 "NetConnectivity.Pipeline.0.NetworkError", |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 // Start up a histogram recorder. | 93 // Start up a histogram recorder. |
89 // TODO(rtenneti): Leaks StatisticsRecorder and will update suppressions. | 94 // TODO(rtenneti): Leaks StatisticsRecorder and will update suppressions. |
90 base::StatisticsRecorder::Initialize(); | 95 base::StatisticsRecorder::Initialize(); |
91 ASSERT_TRUE(test_server_.Start()); | 96 ASSERT_TRUE(test_server_.Start()); |
92 context_ = new TestURLRequestContextGetter( | 97 context_ = new TestURLRequestContextGetter( |
93 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); | 98 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); |
94 context_->AddRef(); | 99 context_->AddRef(); |
95 | 100 |
96 for (size_t i = 0; i < arraysize(kHistogramNames); ++i) { | 101 for (size_t i = 0; i < arraysize(kHistogramNames); ++i) { |
97 const char* name = kHistogramNames[i]; | 102 const char* name = kHistogramNames[i]; |
98 base::Histogram::SampleSet sample = GetHistogram(name); | 103 scoped_ptr<HistogramSamples> samples = GetHistogram(name); |
99 if (sample.TotalCount() > 0) { | 104 if (samples.get() && samples->TotalCount() > 0) { |
100 original_samples_[name] = sample; | 105 original_samples_[name] = samples.release(); |
101 } | 106 } |
102 } | 107 } |
103 } | 108 } |
104 | 109 |
105 virtual void TearDown() OVERRIDE { | 110 virtual void TearDown() OVERRIDE { |
106 BrowserThread::ReleaseSoon(BrowserThread::IO, FROM_HERE, context_); | 111 BrowserThread::ReleaseSoon(BrowserThread::IO, FROM_HERE, context_); |
107 message_loop_.RunAllPending(); | 112 message_loop_.RunAllPending(); |
113 STLDeleteValues(&original_samples_); | |
108 } | 114 } |
109 | 115 |
110 void RunTest( | 116 void RunTest( |
111 std::vector<RequestInfo> requests, | 117 std::vector<RequestInfo> requests, |
112 HttpPipeliningCompatibilityClient::Options options) { | 118 HttpPipeliningCompatibilityClient::Options options) { |
113 HttpPipeliningCompatibilityClient client(NULL); | 119 HttpPipeliningCompatibilityClient client(NULL); |
114 net::TestCompletionCallback callback; | 120 net::TestCompletionCallback callback; |
115 client.Start(test_server_.GetURL("").spec(), | 121 client.Start(test_server_.GetURL("").spec(), |
116 requests, options, callback.callback(), | 122 requests, options, callback.callback(), |
117 context_->GetURLRequestContext()); | 123 context_->GetURLRequestContext()); |
118 callback.WaitForResult(); | 124 callback.WaitForResult(); |
119 } | 125 } |
120 | 126 |
121 void ExpectHistogramCount(int expected_count, int expected_value, | 127 void ExpectHistogramCount(int expected_count, |
128 int expected_value, | |
122 HistogramField field) { | 129 HistogramField field) { |
123 const char* name; | 130 const char* name; |
124 | 131 |
125 switch (field) { | 132 switch (field) { |
126 case FIELD_CANARY: | 133 case FIELD_CANARY: |
127 name = "NetConnectivity.Pipeline.CanarySuccess"; | 134 name = "NetConnectivity.Pipeline.CanarySuccess"; |
128 break; | 135 break; |
129 | 136 |
130 case FIELD_DEPTH: | 137 case FIELD_DEPTH: |
131 name = "NetConnectivity.Pipeline.Depth"; | 138 name = "NetConnectivity.Pipeline.Depth"; |
132 break; | 139 break; |
133 | 140 |
134 case FIELD_HTTP_1_1: | 141 case FIELD_HTTP_1_1: |
135 name = "NetConnectivity.Pipeline.AllHTTP11"; | 142 name = "NetConnectivity.Pipeline.AllHTTP11"; |
136 break; | 143 break; |
137 | 144 |
138 case FIELD_SUCCESS: | 145 case FIELD_SUCCESS: |
139 name = "NetConnectivity.Pipeline.Success"; | 146 name = "NetConnectivity.Pipeline.Success"; |
140 break; | 147 break; |
141 | 148 |
142 default: | 149 default: |
143 FAIL() << "Unexpected field: " << field; | 150 FAIL() << "Unexpected field: " << field; |
144 } | 151 } |
145 | 152 |
146 base::Histogram::SampleSet sample = GetHistogram(name); | 153 scoped_ptr<HistogramSamples> samples = GetHistogram(name); |
154 if (!samples.get()) | |
Ilya Sherman
2012/09/12 03:20:58
Should this be an ASSERT_TRUE(samples.get()), i.e.
kaiwang
2012/09/20 22:54:59
The old GetHistogram function can return an empty
| |
155 return; | |
156 | |
147 if (ContainsKey(original_samples_, name)) { | 157 if (ContainsKey(original_samples_, name)) { |
148 sample.Subtract(original_samples_[name]); | 158 samples->Subtract((*original_samples_[name])); |
149 } | 159 } |
150 | 160 |
151 EXPECT_EQ(expected_count, sample.TotalCount()) << name; | 161 EXPECT_EQ(expected_count, samples->TotalCount()) << name; |
152 if (expected_count > 0) { | 162 if (expected_count > 0) { |
153 EXPECT_EQ(expected_count, sample.counts(expected_value)) << name; | 163 EXPECT_EQ(expected_count, samples->GetCount(expected_value)) << name; |
154 } | 164 } |
155 } | 165 } |
156 | 166 |
157 void ExpectRequestHistogramCount(int expected_count, int expected_value, | 167 void ExpectRequestHistogramCount(int expected_count, |
158 int request_id, HistogramField field) { | 168 int expected_value, |
169 int request_id, | |
170 HistogramField field) { | |
159 const char* field_str = ""; | 171 const char* field_str = ""; |
160 switch (field) { | 172 switch (field) { |
161 case FIELD_STATUS: | 173 case FIELD_STATUS: |
162 field_str = "Status"; | 174 field_str = "Status"; |
163 break; | 175 break; |
164 | 176 |
165 case FIELD_NETWORK_ERROR: | 177 case FIELD_NETWORK_ERROR: |
166 field_str = "NetworkError"; | 178 field_str = "NetworkError"; |
167 break; | 179 break; |
168 | 180 |
169 case FIELD_RESPONSE_CODE: | 181 case FIELD_RESPONSE_CODE: |
170 field_str = "ResponseCode"; | 182 field_str = "ResponseCode"; |
171 break; | 183 break; |
172 | 184 |
173 default: | 185 default: |
174 FAIL() << "Unexpected field: " << field; | 186 FAIL() << "Unexpected field: " << field; |
175 } | 187 } |
176 | 188 |
177 std::string name = base::StringPrintf("NetConnectivity.Pipeline.%d.%s", | 189 std::string name = base::StringPrintf("NetConnectivity.Pipeline.%d.%s", |
178 request_id, field_str); | 190 request_id, field_str); |
179 base::Histogram::SampleSet sample = GetHistogram(name.c_str()); | 191 scoped_ptr<HistogramSamples> samples = GetHistogram(name.c_str()); |
192 if (!samples.get()) | |
193 return; | |
194 | |
180 if (ContainsKey(original_samples_, name)) { | 195 if (ContainsKey(original_samples_, name)) { |
181 sample.Subtract(original_samples_[name]); | 196 samples->Subtract(*(original_samples_[name])); |
182 } | 197 } |
183 | 198 |
184 EXPECT_EQ(expected_count, sample.TotalCount()) << name; | 199 EXPECT_EQ(expected_count, samples->TotalCount()) << name; |
185 if (expected_count > 0) { | 200 if (expected_count > 0) { |
186 EXPECT_EQ(expected_count, sample.counts(expected_value)) << name; | 201 EXPECT_EQ(expected_count, samples->GetCount(expected_value)) << name; |
187 } | 202 } |
188 } | 203 } |
189 | 204 |
190 MessageLoopForIO message_loop_; | 205 MessageLoopForIO message_loop_; |
191 net::TestServer test_server_; | 206 net::TestServer test_server_; |
192 TestURLRequestContextGetter* context_; | 207 TestURLRequestContextGetter* context_; |
193 content::TestBrowserThread io_thread_; | 208 content::TestBrowserThread io_thread_; |
194 | 209 |
195 private: | 210 private: |
196 base::Histogram::SampleSet GetHistogram(const char* name) { | 211 scoped_ptr<HistogramSamples> GetHistogram(const char* name) { |
197 base::Histogram::SampleSet sample; | 212 scoped_ptr<HistogramSamples> samples; |
198 base::Histogram* cached_histogram = NULL; | 213 Histogram* cached_histogram = NULL; |
199 base::Histogram* current_histogram = | 214 Histogram* current_histogram = |
200 base::StatisticsRecorder::FindHistogram(name); | 215 base::StatisticsRecorder::FindHistogram(name); |
201 if (ContainsKey(histograms_, name)) { | 216 if (ContainsKey(histograms_, name)) { |
202 cached_histogram = histograms_[name]; | 217 cached_histogram = histograms_[name]; |
203 } | 218 } |
204 | 219 |
205 // This is to work around the CACHE_HISTOGRAM_* macros caching the last used | 220 // This is to work around the CACHE_HISTOGRAM_* macros caching the last used |
206 // histogram by name. So, even though we throw out the StatisticsRecorder | 221 // histogram by name. So, even though we throw out the StatisticsRecorder |
207 // between tests, the CACHE_HISTOGRAM_* might still write into the old | 222 // between tests, the CACHE_HISTOGRAM_* might still write into the old |
208 // Histogram if it has the same name as the last run. We keep a cache of the | 223 // Histogram if it has the same name as the last run. We keep a cache of the |
209 // last used Histogram and then update the cache if it's different than the | 224 // last used Histogram and then update the cache if it's different than the |
210 // current Histogram. | 225 // current Histogram. |
211 if (cached_histogram && current_histogram) { | 226 if (cached_histogram && current_histogram) { |
212 cached_histogram->SnapshotSample(&sample); | 227 samples = cached_histogram->SnapshotSamples(); |
213 if (cached_histogram != current_histogram) { | 228 if (cached_histogram != current_histogram) { |
214 base::Histogram::SampleSet current_sample; | 229 samples->Add(*(current_histogram->SnapshotSamples())); |
215 current_histogram->SnapshotSample(¤t_sample); | |
216 sample.Add(current_sample); | |
217 histograms_[name] = current_histogram; | 230 histograms_[name] = current_histogram; |
218 } | 231 } |
219 } else if (current_histogram) { | 232 } else if (current_histogram) { |
220 current_histogram->SnapshotSample(&sample); | 233 samples = current_histogram->SnapshotSamples(); |
221 histograms_[name] = current_histogram; | 234 histograms_[name] = current_histogram; |
222 } else if (cached_histogram) { | 235 } else if (cached_histogram) { |
223 cached_histogram->SnapshotSample(&sample); | 236 samples = cached_histogram->SnapshotSamples(); |
224 } | 237 } |
225 return sample; | 238 return samples.Pass(); |
226 } | 239 } |
227 | 240 |
228 static std::map<std::string, base::Histogram*> histograms_; | 241 static std::map<std::string, Histogram*> histograms_; |
229 std::map<std::string, base::Histogram::SampleSet> samples_; | 242 std::map<std::string, HistogramSamples*> original_samples_; |
230 std::map<std::string, base::Histogram::SampleSet> original_samples_; | |
231 }; | 243 }; |
232 | 244 |
233 // static | 245 // static |
234 std::map<std::string, base::Histogram*> | 246 std::map<std::string, Histogram*> |
235 HttpPipeliningCompatibilityClientTest::histograms_; | 247 HttpPipeliningCompatibilityClientTest::histograms_; |
236 | 248 |
237 TEST_F(HttpPipeliningCompatibilityClientTest, Success) { | 249 TEST_F(HttpPipeliningCompatibilityClientTest, Success) { |
238 RequestInfo info; | 250 RequestInfo info; |
239 info.filename = "files/alphabet.txt"; | 251 info.filename = "files/alphabet.txt"; |
240 info.expected_response = "abcdefghijklmnopqrstuvwxyz"; | 252 info.expected_response = "abcdefghijklmnopqrstuvwxyz"; |
241 std::vector<RequestInfo> requests; | 253 std::vector<RequestInfo> requests; |
242 requests.push_back(info); | 254 requests.push_back(info); |
243 | 255 |
244 RunTest(requests, HttpPipeliningCompatibilityClient::PIPE_TEST_DEFAULTS); | 256 RunTest(requests, HttpPipeliningCompatibilityClient::PIPE_TEST_DEFAULTS); |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
556 callback.WaitForResult(); | 568 callback.WaitForResult(); |
557 | 569 |
558 ExpectHistogramCount(1, false, FIELD_CANARY); | 570 ExpectHistogramCount(1, false, FIELD_CANARY); |
559 ExpectHistogramCount(0, false, FIELD_SUCCESS); | 571 ExpectHistogramCount(0, false, FIELD_SUCCESS); |
560 ExpectHistogramCount(0, true, FIELD_SUCCESS); | 572 ExpectHistogramCount(0, true, FIELD_SUCCESS); |
561 } | 573 } |
562 | 574 |
563 } // anonymous namespace | 575 } // anonymous namespace |
564 | 576 |
565 } // namespace chrome_browser_net | 577 } // namespace chrome_browser_net |
OLD | NEW |