Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/net/http_pipelining_compatibility_client.h" | |
| 6 | |
| 7 #include <map> | |
| 8 #include <string> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/basictypes.h" | |
| 12 #include "base/message_loop.h" | |
| 13 #include "base/metrics/histogram.h" | |
| 14 #include "base/stl_util.h" | |
| 15 #include "base/stringprintf.h" | |
| 16 #include "chrome/test/base/test_url_request_context_getter.h" | |
| 17 #include "content/test/test_browser_thread.h" | |
| 18 #include "net/base/net_errors.h" | |
| 19 #include "net/base/test_completion_callback.h" | |
| 20 #include "net/url_request/url_request_context_getter.h" | |
| 21 #include "net/test/test_server.h" | |
| 22 #include "testing/gtest/include/gtest/gtest.h" | |
| 23 | |
| 24 namespace chrome_browser_net { | |
| 25 | |
| 26 namespace { | |
| 27 | |
| 28 static const char* const kHistogramNames[] = { | |
| 29 "NetConnectivity.Pipeline.0.NetworkError", | |
| 30 "NetConnectivity.Pipeline.0.ResponseCode", | |
| 31 "NetConnectivity.Pipeline.0.Status", | |
| 32 "NetConnectivity.Pipeline.1.NetworkError", | |
| 33 "NetConnectivity.Pipeline.1.ResponseCode", | |
| 34 "NetConnectivity.Pipeline.1.Status", | |
| 35 "NetConnectivity.Pipeline.2.NetworkError", | |
| 36 "NetConnectivity.Pipeline.2.ResponseCode", | |
| 37 "NetConnectivity.Pipeline.2.Status", | |
| 38 }; | |
| 39 | |
| 40 enum HistogramField { | |
| 41 FIELD_NETWORK_ERROR, | |
| 42 FIELD_RESPONSE_CODE, | |
| 43 FIELD_STATUS, | |
| 44 }; | |
| 45 | |
| 46 class HttpPipeliningCompatibilityClientTest : public testing::Test { | |
| 47 public: | |
| 48 HttpPipeliningCompatibilityClientTest() | |
| 49 : test_server_( | |
| 50 net::TestServer::TYPE_HTTP, | |
| 51 FilePath(FILE_PATH_LITERAL("chrome/test/data/http_pipelining"))) { | |
| 52 } | |
| 53 | |
| 54 protected: | |
| 55 virtual void SetUp() OVERRIDE { | |
| 56 ASSERT_TRUE(test_server_.Start()); | |
| 57 context_ = new TestURLRequestContextGetter; | |
| 58 context_->AddRef(); | |
| 59 | |
| 60 for (size_t i = 0; i < arraysize(kHistogramNames); ++i) { | |
| 61 const char* name = kHistogramNames[i]; | |
| 62 base::Histogram::SampleSet sample = GetHistogram(name); | |
| 63 if (sample.TotalCount() > 0) { | |
| 64 original_samples_[name] = sample; | |
| 65 } | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 virtual void TearDown() OVERRIDE { | |
| 70 content::BrowserThread::ReleaseSoon(content::BrowserThread::IO, | |
| 71 FROM_HERE, context_); | |
| 72 message_loop_.RunAllPending(); | |
|
szym
2012/02/11 02:01:17
Is |message_loop_| the same loop that ReleaseSoon
mmenke
2012/02/11 02:06:31
I was thinking the issue was we didn't have a:
Br
| |
| 73 } | |
| 74 | |
| 75 void RunTest( | |
| 76 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests) { | |
| 77 HttpPipeliningCompatibilityClient client; | |
| 78 net::TestCompletionCallback callback; | |
| 79 client.Start(test_server_.GetURL("").spec(), | |
| 80 requests, callback.callback(), | |
| 81 context_->GetURLRequestContext()); | |
| 82 callback.WaitForResult(); | |
| 83 | |
| 84 for (size_t i = 0; i < arraysize(kHistogramNames); ++i) { | |
| 85 const char* name = kHistogramNames[i]; | |
| 86 base::Histogram::SampleSet sample = GetHistogram(name); | |
| 87 if (ContainsKey(original_samples_, name)) { | |
| 88 sample.Subtract(original_samples_[name]); | |
| 89 } | |
| 90 samples_[name] = sample; | |
| 91 } | |
| 92 } | |
| 93 | |
| 94 base::Histogram::SampleSet GetHistogramValue(int request_id, | |
| 95 HistogramField field) { | |
| 96 const char* field_str = ""; | |
| 97 switch (field) { | |
| 98 case FIELD_STATUS: | |
| 99 field_str = "Status"; | |
| 100 break; | |
| 101 | |
| 102 case FIELD_NETWORK_ERROR: | |
| 103 field_str = "NetworkError"; | |
| 104 break; | |
| 105 | |
| 106 case FIELD_RESPONSE_CODE: | |
| 107 field_str = "ResponseCode"; | |
| 108 break; | |
| 109 | |
| 110 default: | |
| 111 NOTREACHED(); | |
| 112 break; | |
| 113 } | |
| 114 | |
| 115 std::string name = base::StringPrintf("NetConnectivity.Pipeline.%d.%s", | |
| 116 request_id, field_str); | |
| 117 return samples_[name]; | |
| 118 } | |
| 119 | |
| 120 MessageLoopForIO message_loop_; | |
| 121 net::TestServer test_server_; | |
| 122 TestURLRequestContextGetter* context_; | |
| 123 | |
| 124 private: | |
| 125 base::Histogram::SampleSet GetHistogram(const char* name) { | |
| 126 base::Histogram::SampleSet sample; | |
| 127 base::Histogram* histogram; | |
| 128 if (ContainsKey(histograms_, name)) { | |
| 129 histogram = histograms_[name]; | |
| 130 histogram->SnapshotSample(&sample); | |
| 131 } else if (base::StatisticsRecorder::FindHistogram(name, &histogram)) { | |
| 132 histograms_[name] = histogram; | |
| 133 histogram->SnapshotSample(&sample); | |
| 134 } | |
| 135 return sample; | |
| 136 } | |
| 137 | |
| 138 static std::map<std::string, base::Histogram*> histograms_; | |
| 139 std::map<std::string, base::Histogram::SampleSet> samples_; | |
| 140 std::map<std::string, base::Histogram::SampleSet> original_samples_; | |
| 141 base::StatisticsRecorder recorder_; | |
| 142 }; | |
| 143 | |
| 144 // static | |
| 145 std::map<std::string, base::Histogram*> | |
| 146 HttpPipeliningCompatibilityClientTest::histograms_; | |
| 147 | |
| 148 TEST_F(HttpPipeliningCompatibilityClientTest, Success) { | |
| 149 HttpPipeliningCompatibilityClient::RequestInfo info; | |
| 150 info.filename = "files/alphabet.txt"; | |
| 151 info.expected_response = "abcdefghijklmnopqrstuvwxyz"; | |
| 152 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
| 153 requests.push_back(info); | |
| 154 | |
| 155 RunTest(requests); | |
| 156 | |
| 157 base::Histogram::SampleSet status_sample = | |
| 158 GetHistogramValue(0, FIELD_STATUS); | |
| 159 EXPECT_EQ(1, status_sample.TotalCount()); | |
| 160 EXPECT_EQ(1, status_sample.counts( | |
| 161 HttpPipeliningCompatibilityClient::SUCCESS)); | |
| 162 | |
| 163 base::Histogram::SampleSet network_sample = | |
| 164 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
| 165 EXPECT_EQ(0, network_sample.TotalCount()); | |
| 166 | |
| 167 base::Histogram::SampleSet response_sample = | |
| 168 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
| 169 EXPECT_EQ(1, response_sample.TotalCount()); | |
| 170 EXPECT_EQ(1, response_sample.counts(200)); | |
| 171 } | |
| 172 | |
| 173 TEST_F(HttpPipeliningCompatibilityClientTest, TooSmall) { | |
| 174 HttpPipeliningCompatibilityClient::RequestInfo info; | |
| 175 info.filename = "files/alphabet.txt"; | |
| 176 info.expected_response = "abcdefghijklmnopqrstuvwxyz26"; | |
| 177 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
| 178 requests.push_back(info); | |
| 179 | |
| 180 RunTest(requests); | |
| 181 | |
| 182 base::Histogram::SampleSet status_sample = | |
| 183 GetHistogramValue(0, FIELD_STATUS); | |
| 184 EXPECT_EQ(1, status_sample.TotalCount()); | |
| 185 EXPECT_EQ(1, status_sample.counts( | |
| 186 HttpPipeliningCompatibilityClient::TOO_SMALL)); | |
| 187 | |
| 188 base::Histogram::SampleSet network_sample = | |
| 189 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
| 190 EXPECT_EQ(0, network_sample.TotalCount()); | |
| 191 | |
| 192 base::Histogram::SampleSet response_sample = | |
| 193 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
| 194 EXPECT_EQ(1, response_sample.TotalCount()); | |
| 195 EXPECT_EQ(1, response_sample.counts(200)); | |
| 196 } | |
| 197 | |
| 198 TEST_F(HttpPipeliningCompatibilityClientTest, TooLarge) { | |
| 199 HttpPipeliningCompatibilityClient::RequestInfo info; | |
| 200 info.filename = "files/alphabet.txt"; | |
| 201 info.expected_response = "abc"; | |
| 202 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
| 203 requests.push_back(info); | |
| 204 | |
| 205 RunTest(requests); | |
| 206 | |
| 207 base::Histogram::SampleSet status_sample = | |
| 208 GetHistogramValue(0, FIELD_STATUS); | |
| 209 EXPECT_EQ(1, status_sample.TotalCount()); | |
| 210 EXPECT_EQ(1, status_sample.counts( | |
| 211 HttpPipeliningCompatibilityClient::TOO_LARGE)); | |
| 212 | |
| 213 base::Histogram::SampleSet network_sample = | |
| 214 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
| 215 EXPECT_EQ(0, network_sample.TotalCount()); | |
| 216 | |
| 217 base::Histogram::SampleSet response_sample = | |
| 218 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
| 219 EXPECT_EQ(1, response_sample.TotalCount()); | |
| 220 EXPECT_EQ(1, response_sample.counts(200)); | |
| 221 } | |
| 222 | |
| 223 TEST_F(HttpPipeliningCompatibilityClientTest, Mismatch) { | |
| 224 HttpPipeliningCompatibilityClient::RequestInfo info; | |
| 225 info.filename = "files/alphabet.txt"; | |
| 226 info.expected_response = "zyxwvutsrqponmlkjihgfedcba"; | |
| 227 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
| 228 requests.push_back(info); | |
| 229 | |
| 230 RunTest(requests); | |
| 231 | |
| 232 base::Histogram::SampleSet status_sample = | |
| 233 GetHistogramValue(0, FIELD_STATUS); | |
| 234 EXPECT_EQ(1, status_sample.TotalCount()); | |
| 235 EXPECT_EQ(1, status_sample.counts( | |
| 236 HttpPipeliningCompatibilityClient::CONTENT_MISMATCH)); | |
| 237 | |
| 238 base::Histogram::SampleSet network_sample = | |
| 239 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
| 240 EXPECT_EQ(0, network_sample.TotalCount()); | |
| 241 | |
| 242 base::Histogram::SampleSet response_sample = | |
| 243 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
| 244 EXPECT_EQ(1, response_sample.TotalCount()); | |
| 245 EXPECT_EQ(1, response_sample.counts(200)); | |
| 246 } | |
| 247 | |
| 248 TEST_F(HttpPipeliningCompatibilityClientTest, Redirect) { | |
| 249 HttpPipeliningCompatibilityClient::RequestInfo info; | |
| 250 info.filename = "server-redirect?http://foo.bar/asdf"; | |
| 251 info.expected_response = "shouldn't matter"; | |
| 252 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
| 253 requests.push_back(info); | |
| 254 | |
| 255 RunTest(requests); | |
| 256 | |
| 257 base::Histogram::SampleSet status_sample = | |
| 258 GetHistogramValue(0, FIELD_STATUS); | |
| 259 EXPECT_EQ(1, status_sample.TotalCount()); | |
| 260 EXPECT_EQ(1, status_sample.counts( | |
| 261 HttpPipeliningCompatibilityClient::REDIRECTED)); | |
| 262 | |
| 263 base::Histogram::SampleSet network_sample = | |
| 264 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
| 265 EXPECT_EQ(0, network_sample.TotalCount()); | |
| 266 | |
| 267 base::Histogram::SampleSet response_sample = | |
| 268 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
| 269 EXPECT_EQ(0, response_sample.TotalCount()); | |
| 270 } | |
| 271 | |
| 272 TEST_F(HttpPipeliningCompatibilityClientTest, AuthRequired) { | |
| 273 HttpPipeliningCompatibilityClient::RequestInfo info; | |
| 274 info.filename = "auth-basic"; | |
| 275 info.expected_response = "shouldn't matter"; | |
| 276 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
| 277 requests.push_back(info); | |
| 278 | |
| 279 RunTest(requests); | |
| 280 | |
| 281 base::Histogram::SampleSet status_sample = | |
| 282 GetHistogramValue(0, FIELD_STATUS); | |
| 283 EXPECT_EQ(1, status_sample.TotalCount()); | |
| 284 EXPECT_EQ(1, status_sample.counts( | |
| 285 HttpPipeliningCompatibilityClient::BAD_RESPONSE_CODE)); | |
| 286 | |
| 287 base::Histogram::SampleSet network_sample = | |
| 288 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
| 289 EXPECT_EQ(0, network_sample.TotalCount()); | |
| 290 | |
| 291 base::Histogram::SampleSet response_sample = | |
| 292 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
| 293 EXPECT_EQ(1, response_sample.TotalCount()); | |
| 294 EXPECT_EQ(1, response_sample.counts(401)); | |
| 295 } | |
| 296 | |
| 297 TEST_F(HttpPipeliningCompatibilityClientTest, NoContent) { | |
| 298 HttpPipeliningCompatibilityClient::RequestInfo info; | |
| 299 info.filename = "nocontent"; | |
| 300 info.expected_response = "shouldn't matter"; | |
| 301 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
| 302 requests.push_back(info); | |
| 303 | |
| 304 RunTest(requests); | |
| 305 | |
| 306 base::Histogram::SampleSet status_sample = | |
| 307 GetHistogramValue(0, FIELD_STATUS); | |
| 308 EXPECT_EQ(1, status_sample.TotalCount()); | |
| 309 EXPECT_EQ(1, status_sample.counts( | |
| 310 HttpPipeliningCompatibilityClient::BAD_RESPONSE_CODE)); | |
| 311 | |
| 312 base::Histogram::SampleSet network_sample = | |
| 313 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
| 314 EXPECT_EQ(0, network_sample.TotalCount()); | |
| 315 | |
| 316 base::Histogram::SampleSet response_sample = | |
| 317 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
| 318 EXPECT_EQ(1, response_sample.TotalCount()); | |
| 319 EXPECT_EQ(1, response_sample.counts(204)); | |
| 320 } | |
| 321 | |
| 322 TEST_F(HttpPipeliningCompatibilityClientTest, CloseSocket) { | |
| 323 HttpPipeliningCompatibilityClient::RequestInfo info; | |
| 324 info.filename = "close-socket"; | |
| 325 info.expected_response = "shouldn't matter"; | |
| 326 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
| 327 requests.push_back(info); | |
| 328 | |
| 329 RunTest(requests); | |
| 330 | |
| 331 base::Histogram::SampleSet status_sample = | |
| 332 GetHistogramValue(0, FIELD_STATUS); | |
| 333 EXPECT_EQ(1, status_sample.TotalCount()); | |
| 334 EXPECT_EQ(1, status_sample.counts( | |
| 335 HttpPipeliningCompatibilityClient::NETWORK_ERROR)); | |
| 336 | |
| 337 base::Histogram::SampleSet network_sample = | |
| 338 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
| 339 EXPECT_EQ(1, network_sample.TotalCount()); | |
| 340 EXPECT_EQ(1, network_sample.counts(-net::ERR_EMPTY_RESPONSE)); | |
| 341 | |
| 342 base::Histogram::SampleSet response_sample = | |
| 343 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
| 344 EXPECT_EQ(0, response_sample.TotalCount()); | |
| 345 } | |
| 346 | |
| 347 TEST_F(HttpPipeliningCompatibilityClientTest, OldHttpVersion) { | |
| 348 HttpPipeliningCompatibilityClient::RequestInfo info; | |
| 349 info.filename = "http-1.0"; | |
| 350 info.expected_response = "abcdefghijklmnopqrstuvwxyz"; | |
| 351 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
| 352 requests.push_back(info); | |
| 353 | |
| 354 RunTest(requests); | |
| 355 | |
| 356 base::Histogram::SampleSet status_sample = | |
| 357 GetHistogramValue(0, FIELD_STATUS); | |
| 358 EXPECT_EQ(1, status_sample.TotalCount()); | |
| 359 EXPECT_EQ(1, status_sample.counts( | |
| 360 HttpPipeliningCompatibilityClient::BAD_HTTP_VERSION)); | |
| 361 | |
| 362 base::Histogram::SampleSet network_sample = | |
| 363 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
| 364 EXPECT_EQ(0, network_sample.TotalCount()); | |
| 365 | |
| 366 base::Histogram::SampleSet response_sample = | |
| 367 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
| 368 EXPECT_EQ(1, response_sample.TotalCount()); | |
| 369 EXPECT_EQ(1, response_sample.counts(200)); | |
| 370 } | |
| 371 | |
| 372 TEST_F(HttpPipeliningCompatibilityClientTest, MultipleRequests) { | |
| 373 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
| 374 | |
| 375 HttpPipeliningCompatibilityClient::RequestInfo info1; | |
| 376 info1.filename = "files/alphabet.txt"; | |
| 377 info1.expected_response = "abcdefghijklmnopqrstuvwxyz"; | |
| 378 requests.push_back(info1); | |
| 379 | |
| 380 HttpPipeliningCompatibilityClient::RequestInfo info2; | |
| 381 info2.filename = "close-socket"; | |
| 382 info2.expected_response = "shouldn't matter"; | |
| 383 requests.push_back(info2); | |
| 384 | |
| 385 HttpPipeliningCompatibilityClient::RequestInfo info3; | |
| 386 info3.filename = "auth-basic"; | |
| 387 info3.expected_response = "shouldn't matter"; | |
| 388 requests.push_back(info3); | |
| 389 | |
| 390 RunTest(requests); | |
| 391 | |
| 392 base::Histogram::SampleSet status_sample1 = | |
| 393 GetHistogramValue(0, FIELD_STATUS); | |
| 394 EXPECT_EQ(1, status_sample1.TotalCount()); | |
| 395 EXPECT_EQ(1, status_sample1.counts( | |
| 396 HttpPipeliningCompatibilityClient::SUCCESS)); | |
| 397 | |
| 398 base::Histogram::SampleSet network_sample1 = | |
| 399 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
| 400 EXPECT_EQ(0, network_sample1.TotalCount()); | |
| 401 | |
| 402 base::Histogram::SampleSet response_sample1 = | |
| 403 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
| 404 EXPECT_EQ(1, response_sample1.TotalCount()); | |
| 405 EXPECT_EQ(1, response_sample1.counts(200)); | |
| 406 | |
| 407 base::Histogram::SampleSet status_sample2 = | |
| 408 GetHistogramValue(1, FIELD_STATUS); | |
| 409 EXPECT_EQ(1, status_sample2.TotalCount()); | |
| 410 EXPECT_EQ(1, status_sample2.counts( | |
| 411 HttpPipeliningCompatibilityClient::NETWORK_ERROR)); | |
| 412 | |
| 413 base::Histogram::SampleSet network_sample2 = | |
| 414 GetHistogramValue(1, FIELD_NETWORK_ERROR); | |
| 415 EXPECT_EQ(1, network_sample2.TotalCount()); | |
| 416 EXPECT_EQ(1, network_sample2.counts(-net::ERR_EMPTY_RESPONSE)); | |
| 417 | |
| 418 base::Histogram::SampleSet response_sample2 = | |
| 419 GetHistogramValue(1, FIELD_RESPONSE_CODE); | |
| 420 EXPECT_EQ(0, response_sample2.TotalCount()); | |
| 421 | |
| 422 base::Histogram::SampleSet status_sample3 = | |
| 423 GetHistogramValue(2, FIELD_STATUS); | |
| 424 EXPECT_EQ(1, status_sample3.TotalCount()); | |
| 425 EXPECT_EQ(1, status_sample3.counts( | |
| 426 HttpPipeliningCompatibilityClient::BAD_RESPONSE_CODE)); | |
| 427 | |
| 428 base::Histogram::SampleSet network_sample3 = | |
| 429 GetHistogramValue(2, FIELD_NETWORK_ERROR); | |
| 430 EXPECT_EQ(0, network_sample3.TotalCount()); | |
| 431 | |
| 432 base::Histogram::SampleSet response_sample3 = | |
| 433 GetHistogramValue(2, FIELD_RESPONSE_CODE); | |
| 434 EXPECT_EQ(1, response_sample3.TotalCount()); | |
| 435 EXPECT_EQ(1, response_sample3.counts(401)); | |
| 436 } | |
| 437 | |
| 438 } // anonymous namespace | |
| 439 | |
| 440 } // namespace chrome_browser_net | |
| OLD | NEW |