| 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()) |
| 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 |