Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: net/http/http_cache_unittest.cc

Issue 1230113012: [net] Better StopCaching() handling for HttpCache::Transaction. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "net/http/http_cache.h" 5 #include "net/http/http_cache.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <list>
8 9
9 #include "base/bind.h" 10 #include "base/bind.h"
10 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/format_macros.h"
11 #include "base/memory/scoped_vector.h" 13 #include "base/memory/scoped_vector.h"
12 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h" 15 #include "base/run_loop.h"
14 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
16 #include "base/test/simple_test_clock.h" 18 #include "base/test/simple_test_clock.h"
17 #include "net/base/cache_type.h" 19 #include "net/base/cache_type.h"
18 #include "net/base/elements_upload_data_stream.h" 20 #include "net/base/elements_upload_data_stream.h"
19 #include "net/base/host_port_pair.h" 21 #include "net/base/host_port_pair.h"
20 #include "net/base/load_flags.h" 22 #include "net/base/load_flags.h"
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 "", 271 "",
270 LOAD_VALIDATE_CACHE, 272 LOAD_VALIDATE_CACHE,
271 "HTTP/1.1 200 OK", 273 "HTTP/1.1 200 OK",
272 "Cache-Control: max-age=10000\n", 274 "Cache-Control: max-age=10000\n",
273 base::Time(), 275 base::Time(),
274 "<html><body>Google Blah Blah</body></html>", 276 "<html><body>Google Blah Blah</body></html>",
275 TEST_MODE_SYNC_NET_START, 277 TEST_MODE_SYNC_NET_START,
276 &FastTransactionServer::FastNoStoreHandler, 278 &FastTransactionServer::FastNoStoreHandler,
277 nullptr, 279 nullptr,
278 0, 280 0,
279 0,
280 OK}; 281 OK};
281 282
282 // This class provides a handler for kRangeGET_TransactionOK so that the range 283 // This class provides a handler for kRangeGET_TransactionOK so that the range
283 // request can be served on demand. 284 // request can be served on demand.
284 class RangeTransactionServer { 285 class RangeTransactionServer {
285 public: 286 public:
286 RangeTransactionServer() { 287 RangeTransactionServer() {
287 not_modified_ = false; 288 not_modified_ = false;
288 modified_ = false; 289 modified_ = false;
289 bad_200_ = false; 290 bad_200_ = false;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 // A dummy extra header that must be preserved on a given request. 329 // A dummy extra header that must be preserved on a given request.
329 330
330 // EXTRA_HEADER_LINE doesn't include a line terminator because it 331 // EXTRA_HEADER_LINE doesn't include a line terminator because it
331 // will be passed to AddHeaderFromString() which doesn't accept them. 332 // will be passed to AddHeaderFromString() which doesn't accept them.
332 #define EXTRA_HEADER_LINE "Extra: header" 333 #define EXTRA_HEADER_LINE "Extra: header"
333 334
334 // EXTRA_HEADER contains a line terminator, as expected by 335 // EXTRA_HEADER contains a line terminator, as expected by
335 // AddHeadersFromString() (_not_ AddHeaderFromString()). 336 // AddHeadersFromString() (_not_ AddHeaderFromString()).
336 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n" 337 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
337 338
338 static const char kExtraHeaderKey[] = "Extra"; 339 #define RETURN_DEFAULT_RANGE_HEADER "X-Return-Default-Range: 1\r\n"
340
341 #define INDICATE_NO_RANGES_HEADER "X-Indicate-No-Ranges: 1\r\n"
342
343 const char kExtraHeaderKey[] = "Extra";
344
345 const char kFullRangeData[] =
346 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
347 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
339 348
340 // Static. 349 // Static.
341 void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request, 350 void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request,
342 std::string* response_status, 351 std::string* response_status,
343 std::string* response_headers, 352 std::string* response_headers,
344 std::string* response_data) { 353 std::string* response_data) {
354 SCOPED_TRACE(testing::Message() << "Request headers: \n"
355 << request->extra_headers.ToString());
345 if (request->extra_headers.IsEmpty()) { 356 if (request->extra_headers.IsEmpty()) {
346 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); 357 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
347 response_data->clear(); 358 response_data->clear();
348 return; 359 return;
349 } 360 }
350 361
351 // We want to make sure we don't delete extra headers. 362 // We want to make sure we don't delete extra headers.
352 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey)); 363 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
353 364
354 bool require_auth = 365 bool require_auth =
(...skipping 13 matching lines...) Expand all
368 } 379 }
369 380
370 std::vector<HttpByteRange> ranges; 381 std::vector<HttpByteRange> ranges;
371 std::string range_header; 382 std::string range_header;
372 if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange, 383 if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange,
373 &range_header) || 384 &range_header) ||
374 !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ || 385 !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
375 ranges.size() != 1) { 386 ranges.size() != 1) {
376 // This is not a byte range request. We return 200. 387 // This is not a byte range request. We return 200.
377 response_status->assign("HTTP/1.1 200 OK"); 388 response_status->assign("HTTP/1.1 200 OK");
378 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT"); 389 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
379 response_data->assign("Not a range"); 390 if (request->extra_headers.HasHeader("X-Indicate-No-Ranges")) {
rvargas (doing something else) 2015/09/15 01:07:38 nit: maybe X-No-Ranges ?
rvargas (doing something else) 2015/09/15 01:07:39 Document new headers at line 311.
asanka 2015/09/17 21:59:41 Done. And documented the header at line 311.
391 response_data->assign("Not a range");
392 return;
393 }
394 response_headers->append(
395 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
396 "ETag: \"foo\"\n"
397 "Accept-Ranges: bytes\n"
398 "Content-Length: 80\n");
399 response_data->assign(kFullRangeData);
rvargas (doing something else) 2015/09/15 01:07:39 I'm worried that returning "correct" data by defau
380 return; 400 return;
381 } 401 }
382 402
383 // We can handle this range request. 403 // We can handle this range request.
384 HttpByteRange byte_range = ranges[0]; 404 HttpByteRange byte_range = ranges[0];
385 405
386 if (request->extra_headers.HasHeader("X-Return-Default-Range")) { 406 if (request->extra_headers.HasHeader("X-Return-Default-Range")) {
387 byte_range.set_first_byte_position(40); 407 byte_range.set_first_byte_position(40);
388 byte_range.set_last_byte_position(49); 408 byte_range.set_last_byte_position(49);
389 } 409 }
390 410
391 if (byte_range.first_byte_position() > 79) { 411 if (byte_range.first_byte_position() > 79) {
392 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); 412 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
393 response_data->clear(); 413 response_data->clear();
394 return; 414 return;
395 } 415 }
416 response_status->assign("HTTP/1.1 206 Partial");
396 417
397 EXPECT_TRUE(byte_range.ComputeBounds(80)); 418 EXPECT_TRUE(byte_range.ComputeBounds(80));
398 int start = static_cast<int>(byte_range.first_byte_position()); 419 int start = static_cast<int>(byte_range.first_byte_position());
399 int end = static_cast<int>(byte_range.last_byte_position()); 420 int end = static_cast<int>(byte_range.last_byte_position());
400 421
401 EXPECT_LT(end, 80); 422 EXPECT_LT(end, 80);
402 423
403 std::string content_range = base::StringPrintf( 424 std::string content_range = base::StringPrintf(
404 "Content-Range: bytes %d-%d/80\n", start, end); 425 "Content-Range: bytes %d-%d/80\n", start, end);
405 response_headers->append(content_range); 426 response_headers->append(content_range);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 463 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
443 "ETag: \"foo\"\n" 464 "ETag: \"foo\"\n"
444 "Accept-Ranges: bytes\n" 465 "Accept-Ranges: bytes\n"
445 "Content-Length: 10\n", 466 "Content-Length: 10\n",
446 base::Time(), 467 base::Time(),
447 "rg: 40-49 ", 468 "rg: 40-49 ",
448 TEST_MODE_NORMAL, 469 TEST_MODE_NORMAL,
449 &RangeTransactionServer::RangeHandler, 470 &RangeTransactionServer::RangeHandler,
450 nullptr, 471 nullptr,
451 0, 472 0,
452 0,
453 OK}; 473 OK};
454 474
455 const char kFullRangeData[] =
456 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
457 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
458
459 // Verifies the response headers (|response|) match a partial content 475 // Verifies the response headers (|response|) match a partial content
460 // response for the range starting at |start| and ending at |end|. 476 // response for the range starting at |start| and ending at |end|.
461 void Verify206Response(std::string response, int start, int end) { 477 void Verify206Response(std::string response, int start, int end) {
462 std::string raw_headers( 478 std::string raw_headers(
463 HttpUtil::AssembleRawHeaders(response.data(), response.size())); 479 HttpUtil::AssembleRawHeaders(response.data(), response.size()));
464 scoped_refptr<HttpResponseHeaders> headers( 480 scoped_refptr<HttpResponseHeaders> headers(
465 new HttpResponseHeaders(raw_headers)); 481 new HttpResponseHeaders(raw_headers));
466 482
467 ASSERT_EQ(206, headers->response_code()); 483 ASSERT_EQ(206, headers->response_code());
468 484
(...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after
2088 // Write to the cache. 2104 // Write to the cache.
2089 MockTransaction transaction(kTypicalGET_Transaction); 2105 MockTransaction transaction(kTypicalGET_Transaction);
2090 transaction.request_headers = "Foo: bar\r\n"; 2106 transaction.request_headers = "Foo: bar\r\n";
2091 transaction.response_headers = 2107 transaction.response_headers =
2092 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n" 2108 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2093 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n" 2109 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2094 "Cache-Control: max-age=0\n" 2110 "Cache-Control: max-age=0\n"
2095 "Vary: Foo\n"; 2111 "Vary: Foo\n";
2096 AddMockTransaction(&transaction); 2112 AddMockTransaction(&transaction);
2097 RunTransactionTest(cache.http_cache(), transaction); 2113 RunTransactionTest(cache.http_cache(), transaction);
2098
rvargas (doing something else) 2015/09/15 01:07:39 nit: keep this line.
asanka 2015/09/17 21:59:41 Done.
2099 // Read from the cache and don't revalidate the entry. 2114 // Read from the cache and don't revalidate the entry.
2100 RevalidationServer server; 2115 RevalidationServer server;
2101 transaction.handler = server.Handler; 2116 transaction.handler = server.Handler;
2102 transaction.request_headers = "Foo: none\r\n"; 2117 transaction.request_headers = "Foo: none\r\n";
2118
2103 BoundTestNetLog log; 2119 BoundTestNetLog log;
2104 LoadTimingInfo load_timing_info; 2120 LoadTimingInfo load_timing_info;
2105 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(), 2121 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2106 &load_timing_info); 2122 &load_timing_info);
2107 2123
2108 EXPECT_FALSE(server.EtagUsed()); 2124 EXPECT_FALSE(server.EtagUsed());
2109 EXPECT_FALSE(server.LastModifiedUsed()); 2125 EXPECT_FALSE(server.LastModifiedUsed());
2110 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2126 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2111 EXPECT_EQ(1, cache.disk_cache()->open_count()); 2127 EXPECT_EQ(1, cache.disk_cache()->open_count());
2112 EXPECT_EQ(1, cache.disk_cache()->create_count()); 2128 EXPECT_EQ(1, cache.disk_cache()->create_count());
(...skipping 1778 matching lines...) Expand 10 before | Expand all | Expand 10 after
3891 3907
3892 Verify206Response(headers, 40, 49); 3908 Verify206Response(headers, 40, 49);
3893 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 3909 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3894 EXPECT_EQ(0, cache.disk_cache()->open_count()); 3910 EXPECT_EQ(0, cache.disk_cache()->open_count());
3895 EXPECT_EQ(1, cache.disk_cache()->create_count()); 3911 EXPECT_EQ(1, cache.disk_cache()->create_count());
3896 3912
3897 // Now verify that the cached data is not used. 3913 // Now verify that the cached data is not used.
3898 // Don't ask for a range. The cache will attempt to use the cached data but 3914 // Don't ask for a range. The cache will attempt to use the cached data but
3899 // should discard it as it cannot be validated. A regular request should go 3915 // should discard it as it cannot be validated. A regular request should go
3900 // to the server and a new entry should be created. 3916 // to the server and a new entry should be created.
3901 transaction.request_headers = EXTRA_HEADER; 3917 transaction.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER;
3902 transaction.data = "Not a range"; 3918 transaction.data = "Not a range";
3903 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 3919 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3904 3920
3905 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); 3921 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3906 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 3922 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3907 EXPECT_EQ(1, cache.disk_cache()->open_count()); 3923 EXPECT_EQ(1, cache.disk_cache()->open_count());
3908 EXPECT_EQ(2, cache.disk_cache()->create_count()); 3924 EXPECT_EQ(2, cache.disk_cache()->create_count());
3909 3925
3910 // The last response was saved. 3926 // The last response was saved.
3911 RunTransactionTest(cache.http_cache(), transaction); 3927 RunTransactionTest(cache.http_cache(), transaction);
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
4359 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER; 4375 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4360 transaction.data = "rg: 70-79 "; 4376 transaction.data = "rg: 70-79 ";
4361 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4377 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4362 Verify206Response(headers, 70, 79); 4378 Verify206Response(headers, 70, 79);
4363 4379
4364 // Don't ask for a range. The cache will ask the server for 0-69. 4380 // Don't ask for a range. The cache will ask the server for 0-69.
4365 // The server returns 40-49. The cache should consider the server confused and 4381 // The server returns 40-49. The cache should consider the server confused and
4366 // abort caching, restarting the request. 4382 // abort caching, restarting the request.
4367 // The second network request should not be a byte range request so the server 4383 // The second network request should not be a byte range request so the server
4368 // should return 200 + "Not a range" 4384 // should return 200 + "Not a range"
4369 transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER; 4385 transaction.request_headers =
4386 RETURN_DEFAULT_RANGE_HEADER INDICATE_NO_RANGES_HEADER EXTRA_HEADER;
rvargas (doing something else) 2015/09/15 01:07:39 nit: do we really need the new #defines? I feel li
asanka 2015/09/17 21:59:41 Hmm. I see what you mean. Should I remove the othe
rvargas (doing something else) 2015/09/19 01:09:34 Do you mean EXTRA_HEADER? I think that was added t
4370 transaction.data = "Not a range"; 4387 transaction.data = "Not a range";
4371 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 4388 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4372 4389
4373 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); 4390 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4374 EXPECT_EQ(3, cache.network_layer()->transaction_count()); 4391 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4375 EXPECT_EQ(1, cache.disk_cache()->open_count()); 4392 EXPECT_EQ(1, cache.disk_cache()->open_count());
4376 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4393 EXPECT_EQ(1, cache.disk_cache()->create_count());
4377 4394
4378 // The entry was deleted. 4395 // The entry was deleted.
4379 RunTransactionTest(cache.http_cache(), transaction); 4396 RunTransactionTest(cache.http_cache(), transaction);
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
4751 Verify206Response(headers, 0, 9); 4768 Verify206Response(headers, 0, 9);
4752 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 4769 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4753 EXPECT_EQ(0, cache.disk_cache()->open_count()); 4770 EXPECT_EQ(0, cache.disk_cache()->open_count());
4754 EXPECT_EQ(1, cache.disk_cache()->create_count()); 4771 EXPECT_EQ(1, cache.disk_cache()->create_count());
4755 4772
4756 // Now we'll issue a request without any range that should result first in a 4773 // Now we'll issue a request without any range that should result first in a
4757 // 206 (when revalidating), and then in a weird standard answer: the test 4774 // 206 (when revalidating), and then in a weird standard answer: the test
4758 // server will not modify the response so we'll get the default range... a 4775 // server will not modify the response so we'll get the default range... a
4759 // real server will answer with 200. 4776 // real server will answer with 200.
4760 MockTransaction transaction2(kRangeGET_TransactionOK); 4777 MockTransaction transaction2(kRangeGET_TransactionOK);
4761 transaction2.request_headers = EXTRA_HEADER; 4778 transaction2.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER;
4762 transaction2.load_flags |= LOAD_VALIDATE_CACHE; 4779 transaction2.load_flags |= LOAD_VALIDATE_CACHE;
4763 transaction2.data = "Not a range"; 4780 transaction2.data = "Not a range";
4764 RangeTransactionServer handler; 4781 RangeTransactionServer handler;
4765 handler.set_modified(true); 4782 handler.set_modified(true);
4766 BoundTestNetLog log; 4783 BoundTestNetLog log;
4767 LoadTimingInfo load_timing_info; 4784 LoadTimingInfo load_timing_info;
4768 RunTransactionTestWithResponseAndGetTiming( 4785 RunTransactionTestWithResponseAndGetTiming(
4769 cache.http_cache(), transaction2, &headers, log.bound(), 4786 cache.http_cache(), transaction2, &headers, log.bound(),
4770 &load_timing_info); 4787 &load_timing_info);
4771 4788
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after
5361 5378
5362 RemoveMockTransaction(&kRangeGET_TransactionOK); 5379 RemoveMockTransaction(&kRangeGET_TransactionOK);
5363 } 5380 }
5364 5381
5365 // Tests that we don't crash when after reading from the cache we issue a 5382 // Tests that we don't crash when after reading from the cache we issue a
5366 // request for the next range and the server gives us a 200 synchronously. 5383 // request for the next range and the server gives us a 200 synchronously.
5367 TEST(HttpCache, RangeGET_FastFlakyServer) { 5384 TEST(HttpCache, RangeGET_FastFlakyServer) {
5368 MockHttpCache cache; 5385 MockHttpCache cache;
5369 5386
5370 ScopedMockTransaction transaction(kRangeGET_TransactionOK); 5387 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
5371 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER; 5388 transaction.request_headers =
5389 "Range: bytes = 40-\r\n" INDICATE_NO_RANGES_HEADER EXTRA_HEADER;
5372 transaction.test_mode = TEST_MODE_SYNC_NET_START; 5390 transaction.test_mode = TEST_MODE_SYNC_NET_START;
5373 transaction.load_flags |= LOAD_VALIDATE_CACHE; 5391 transaction.load_flags |= LOAD_VALIDATE_CACHE;
5374 5392
5375 // Write to the cache. 5393 // Write to the cache.
5376 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); 5394 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5377 5395
5378 // And now read from the cache and the network. 5396 // And now read from the cache and the network.
5379 RangeTransactionServer handler; 5397 RangeTransactionServer handler;
5380 handler.set_bad_200(true); 5398 handler.set_bad_200(true);
5381 transaction.data = "Not a range"; 5399 transaction.data = "Not a range";
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
5889 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 5907 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5890 "ETag: \"foo\"\n" 5908 "ETag: \"foo\"\n"
5891 "Accept-Ranges: bytes\n" 5909 "Accept-Ranges: bytes\n"
5892 "Content-Length: 50\n"); 5910 "Content-Length: 50\n");
5893 CreateTruncatedEntry(raw_headers, &cache); 5911 CreateTruncatedEntry(raw_headers, &cache);
5894 5912
5895 // Now make a regular request. We expect the code to fail the validation and 5913 // Now make a regular request. We expect the code to fail the validation and
5896 // retry the request without using byte ranges. 5914 // retry the request without using byte ranges.
5897 std::string headers; 5915 std::string headers;
5898 MockTransaction transaction(kRangeGET_TransactionOK); 5916 MockTransaction transaction(kRangeGET_TransactionOK);
5899 transaction.request_headers = EXTRA_HEADER; 5917 transaction.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER;
5900 transaction.data = "Not a range"; 5918 transaction.data = "Not a range";
5901 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 5919 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5902 5920
5903 // The server will return 200 instead of a byte range. 5921 // The server will return 200 instead of a byte range.
5904 std::string expected_headers( 5922 std::string expected_headers(
5905 "HTTP/1.1 200 OK\n" 5923 "HTTP/1.1 200 OK\n"
5906 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"); 5924 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5907 5925
5908 EXPECT_EQ(expected_headers, headers); 5926 EXPECT_EQ(expected_headers, headers);
5909 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 5927 EXPECT_EQ(2, cache.network_layer()->transaction_count());
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
6044 std::string raw_headers("HTTP/1.1 200 OK\n" 6062 std::string raw_headers("HTTP/1.1 200 OK\n"
6045 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" 6063 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6046 "ETag: \"foo\"\n" 6064 "ETag: \"foo\"\n"
6047 "Accept-Ranges: bytes\n" 6065 "Accept-Ranges: bytes\n"
6048 "Content-Length: 80\n"); 6066 "Content-Length: 80\n");
6049 CreateTruncatedEntry(raw_headers, &cache); 6067 CreateTruncatedEntry(raw_headers, &cache);
6050 6068
6051 // Now make a regular request. 6069 // Now make a regular request.
6052 std::string headers; 6070 std::string headers;
6053 MockTransaction transaction(kRangeGET_TransactionOK); 6071 MockTransaction transaction(kRangeGET_TransactionOK);
6054 transaction.request_headers = EXTRA_HEADER; 6072 transaction.request_headers = INDICATE_NO_RANGES_HEADER EXTRA_HEADER;
6055 transaction.data = "Not a range"; 6073 transaction.data = "Not a range";
6056 RangeTransactionServer handler; 6074 RangeTransactionServer handler;
6057 handler.set_bad_200(true); 6075 handler.set_bad_200(true);
6058 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); 6076 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
6059 6077
6060 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 6078 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6061 EXPECT_EQ(1, cache.disk_cache()->open_count()); 6079 EXPECT_EQ(1, cache.disk_cache()->open_count());
6062 EXPECT_EQ(1, cache.disk_cache()->create_count()); 6080 EXPECT_EQ(1, cache.disk_cache()->create_count());
6063 6081
6064 // Verify that the disk entry was updated. 6082 // Verify that the disk entry was updated.
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
6217 6235
6218 MockHttpRequest request(kTestTransaction); 6236 MockHttpRequest request(kTestTransaction);
6219 TestCompletionCallback callback; 6237 TestCompletionCallback callback;
6220 6238
6221 // Write to the cache. 6239 // Write to the cache.
6222 { 6240 {
6223 scoped_ptr<HttpTransaction> trans; 6241 scoped_ptr<HttpTransaction> trans;
6224 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); 6242 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6225 6243
6226 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6244 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6227 if (rv == ERR_IO_PENDING) 6245 ASSERT_EQ(OK, callback.GetResult(rv));
6228 rv = callback.WaitForResult();
6229 ASSERT_EQ(OK, rv);
6230 6246
6231 const HttpResponseInfo* info = trans->GetResponseInfo(); 6247 const HttpResponseInfo* info = trans->GetResponseInfo();
6232 ASSERT_TRUE(info); 6248 ASSERT_TRUE(info);
6233 6249
6234 EXPECT_EQ(info->headers->response_code(), 301); 6250 EXPECT_EQ(info->headers->response_code(), 301);
6235 6251
6236 std::string location; 6252 std::string location;
6237 info->headers->EnumerateHeader(NULL, "Location", &location); 6253 info->headers->EnumerateHeader(NULL, "Location", &location);
6238 EXPECT_EQ(location, "http://www.bar.com/"); 6254 EXPECT_EQ(location, "http://www.bar.com/");
6239 6255
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
6739 base::MessageLoop::current()->RunUntilIdle(); 6755 base::MessageLoop::current()->RunUntilIdle();
6740 6756
6741 // Read from the cache. This should not deadlock. 6757 // Read from the cache. This should not deadlock.
6742 RunTransactionTest(cache.http_cache(), transaction); 6758 RunTransactionTest(cache.http_cache(), transaction);
6743 6759
6744 EXPECT_EQ(1, cache.network_layer()->transaction_count()); 6760 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6745 EXPECT_EQ(1, cache.disk_cache()->open_count()); 6761 EXPECT_EQ(1, cache.disk_cache()->open_count());
6746 EXPECT_EQ(1, cache.disk_cache()->create_count()); 6762 EXPECT_EQ(1, cache.disk_cache()->create_count());
6747 } 6763 }
6748 6764
6749 // Tests that we stop caching when told. 6765 // Tests that we stop caching when told, even if DoneReading is called after
6750 TEST(HttpCache, StopCachingDeletesEntry) { 6766 // StopCaching.
rvargas (doing something else) 2015/09/15 01:07:39 I'm curious about what fails with this test now. O
asanka 2015/09/17 21:59:41 It was testing whether StopCaching() deletes non-r
6751 MockHttpCache cache;
6752 TestCompletionCallback callback;
6753 MockHttpRequest request(kSimpleGET_Transaction);
6754
6755 {
6756 scoped_ptr<HttpTransaction> trans;
6757 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6758
6759 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6760 EXPECT_EQ(OK, callback.GetResult(rv));
6761
6762 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
6763 rv = trans->Read(buf.get(), 10, callback.callback());
6764 EXPECT_EQ(10, callback.GetResult(rv));
6765
6766 trans->StopCaching();
6767
6768 // We should be able to keep reading.
6769 rv = trans->Read(buf.get(), 256, callback.callback());
6770 EXPECT_GT(callback.GetResult(rv), 0);
6771 rv = trans->Read(buf.get(), 256, callback.callback());
6772 EXPECT_EQ(0, callback.GetResult(rv));
6773 }
6774
6775 // Make sure that the ActiveEntry is gone.
6776 base::MessageLoop::current()->RunUntilIdle();
6777
6778 // Verify that the entry is gone.
6779 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6780
6781 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6782 EXPECT_EQ(0, cache.disk_cache()->open_count());
6783 EXPECT_EQ(2, cache.disk_cache()->create_count());
6784 }
6785
6786 // Tests that we stop caching when told, even if DoneReading is called
6787 // after StopCaching.
6788 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) { 6767 TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) {
6789 MockHttpCache cache; 6768 MockHttpCache cache;
6790 TestCompletionCallback callback; 6769 TestCompletionCallback callback;
6791 MockHttpRequest request(kSimpleGET_Transaction); 6770 MockHttpRequest request(kSimpleGET_Transaction);
6792 6771
6793 { 6772 {
6794 scoped_ptr<HttpTransaction> trans; 6773 scoped_ptr<HttpTransaction> trans;
6795 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); 6774 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6796 6775
6797 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6776 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
6852 base::MessageLoop::current()->RunUntilIdle(); 6831 base::MessageLoop::current()->RunUntilIdle();
6853 6832
6854 // Verify that the entry is gone. 6833 // Verify that the entry is gone.
6855 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); 6834 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6856 6835
6857 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 6836 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6858 EXPECT_EQ(0, cache.disk_cache()->open_count()); 6837 EXPECT_EQ(0, cache.disk_cache()->open_count());
6859 EXPECT_EQ(2, cache.disk_cache()->create_count()); 6838 EXPECT_EQ(2, cache.disk_cache()->create_count());
6860 } 6839 }
6861 6840
6862 // Tests that when we are told to stop caching we don't throw away valid data. 6841 // Even if the request is resumable, the cache is still going to throw away the
6863 TEST(HttpCache, StopCachingSavesEntry) { 6842 // partial entry if StopCaching() is called. This is done on the assumption that
6843 // such an entry is unlikely to be consumed from the cache again.
6844 TEST(HttpCache, StopCachingDeletesNewEntry) {
6864 MockHttpCache cache; 6845 MockHttpCache cache;
6865 TestCompletionCallback callback; 6846 TestCompletionCallback callback;
6866 MockHttpRequest request(kSimpleGET_Transaction); 6847 MockHttpRequest request(kSimpleGET_Transaction);
6867 6848
6868 { 6849 scoped_ptr<HttpTransaction> transaction;
6869 scoped_ptr<HttpTransaction> trans; 6850 ASSERT_EQ(OK, cache.CreateTransaction(&transaction));
6870 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
6871 6851
6872 // Force a response that can be resumed. 6852 MockTransaction mock_transaction(kSimpleGET_Transaction);
6873 MockTransaction mock_transaction(kSimpleGET_Transaction); 6853 AddMockTransaction(&mock_transaction);
6874 AddMockTransaction(&mock_transaction); 6854 mock_transaction.response_headers =
6875 mock_transaction.response_headers = "Cache-Control: max-age=10000\n" 6855 "Cache-Control: max-age=10000\n"
6876 "Content-Length: 42\n" 6856 "Content-Length: 42\n"
6877 "Etag: \"foo\"\n"; 6857 "Accept-Ranges: bytes\n"
6858 "Etag: \"foo\"\n";
6859 int rv = transaction->Start(&request, callback.callback(), BoundNetLog());
6860 ASSERT_EQ(OK, callback.GetResult(rv));
6878 6861
6879 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6862 const size_t kBufferSize = 256;
6880 EXPECT_EQ(OK, callback.GetResult(rv)); 6863 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufferSize));
6864 rv = transaction->Read(buf.get(), 10, callback.callback());
6865 EXPECT_EQ(callback.GetResult(rv), 10);
6881 6866
6882 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); 6867 transaction->StopCaching();
6883 rv = trans->Read(buf.get(), 10, callback.callback());
6884 EXPECT_EQ(callback.GetResult(rv), 10);
6885 6868
6886 trans->StopCaching(); 6869 // Should still be able to read the remainder of the resource. Data should
6870 // still be coming from the same network request, which as asserted by the
6871 // network_layer()->transaction_count() test below.
6872 rv = transaction->Read(buf.get(), kBufferSize, callback.callback());
6873 EXPECT_EQ(32, callback.GetResult(rv));
6874 rv = transaction->Read(buf.get(), kBufferSize, callback.callback());
6875 EXPECT_EQ(0, callback.GetResult(rv));
6887 6876
6888 // We should be able to keep reading. 6877 RemoveMockTransaction(&mock_transaction);
6889 rv = trans->Read(buf.get(), 256, callback.callback());
6890 EXPECT_GT(callback.GetResult(rv), 0);
6891 rv = trans->Read(buf.get(), 256, callback.callback());
6892 EXPECT_EQ(callback.GetResult(rv), 0);
6893 6878
6894 RemoveMockTransaction(&mock_transaction); 6879 // At this point, the cache entry should be gone. It should've been doomed and
6895 } 6880 // released during the previous Read() cycles.
6881 disk_cache::Entry* cache_entry = nullptr;
6882 ASSERT_FALSE(
6883 cache.OpenBackendEntry(kSimpleGET_Transaction.url, &cache_entry));
6884 EXPECT_EQ(1, cache.disk_cache()->create_count());
6885 EXPECT_EQ(0, cache.disk_cache()->open_count());
6896 6886
6897 // Verify that the entry is marked as incomplete. 6887 // StopCaching shouldn't cause any additional network requests.
6898 disk_cache::Entry* entry; 6888 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6899 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6900 HttpResponseInfo response;
6901 bool truncated = false;
6902 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6903 EXPECT_TRUE(truncated);
6904 entry->Close();
6905 } 6889 }
6906 6890
6907 // Tests that we handle truncated enries when StopCaching is called. 6891 // If the request was being fulfilled via a truncated cache entry, and the
6908 TEST(HttpCache, StopCachingTruncatedEntry) { 6892 // client calls StopCaching(), the transaction should remove the truncated cache
6893 // entry.
6894 TEST(HttpCache, StopCachingRemovesPreviousTruncatedEntry) {
6909 MockHttpCache cache; 6895 MockHttpCache cache;
6910 TestCompletionCallback callback; 6896 TestCompletionCallback callback;
6911 MockHttpRequest request(kRangeGET_TransactionOK); 6897 MockHttpRequest request(kRangeGET_TransactionOK);
6912 request.extra_headers.Clear(); 6898 request.extra_headers.Clear();
6913 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE); 6899 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
6914 AddMockTransaction(&kRangeGET_TransactionOK); 6900 AddMockTransaction(&kRangeGET_TransactionOK);
6915 6901
6916 std::string raw_headers("HTTP/1.1 200 OK\n" 6902 std::string raw_headers("HTTP/1.1 200 OK\n"
6917 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" 6903 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6918 "ETag: \"foo\"\n" 6904 "ETag: \"foo\"\n"
6919 "Accept-Ranges: bytes\n" 6905 "Accept-Ranges: bytes\n"
6920 "Content-Length: 80\n"); 6906 "Content-Length: 80\n");
6921 CreateTruncatedEntry(raw_headers, &cache); 6907 CreateTruncatedEntry(raw_headers, &cache);
6922 6908 cache.ResetCounts();
6923 { 6909
6924 // Now make a regular request. 6910 // Now make a regular request.
6925 scoped_ptr<HttpTransaction> trans; 6911 scoped_ptr<HttpTransaction> transaction;
6926 ASSERT_EQ(OK, cache.CreateTransaction(&trans)); 6912 ASSERT_EQ(OK, cache.CreateTransaction(&transaction));
6927 6913
6928 int rv = trans->Start(&request, callback.callback(), BoundNetLog()); 6914 int rv = transaction->Start(&request, callback.callback(), BoundNetLog());
6929 EXPECT_EQ(OK, callback.GetResult(rv)); 6915 ASSERT_EQ(OK, callback.GetResult(rv));
6930 6916 // Start() should send a single byte range request to validate the truncated
6931 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); 6917 // cache entry.
6932 rv = trans->Read(buf.get(), 10, callback.callback()); 6918 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6933 EXPECT_EQ(callback.GetResult(rv), 10); 6919
6934 6920 const size_t kBufferSize = 256;
6935 // This is actually going to do nothing. 6921 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufferSize));
6936 trans->StopCaching(); 6922
6937 6923 // The size of the resource is 80 bytes. The first 20 should be available in
6938 // We should be able to keep reading. 6924 // the truncated cache entry. Let's read the first 10 bytes which should all
6939 rv = trans->Read(buf.get(), 256, callback.callback()); 6925 // come from the cache.
6940 EXPECT_GT(callback.GetResult(rv), 0); 6926 rv = transaction->Read(buf.get(), 10, callback.callback());
6941 rv = trans->Read(buf.get(), 256, callback.callback()); 6927 EXPECT_EQ(callback.GetResult(rv), 10);
6942 EXPECT_GT(callback.GetResult(rv), 0); 6928
6943 rv = trans->Read(buf.get(), 256, callback.callback()); 6929 transaction->StopCaching();
6944 EXPECT_EQ(callback.GetResult(rv), 0); 6930
6931 // We should be able to keep reading. The previous StopCaching() call switches
6932 // the transaction over to a network read. Hence the next read should slurp in
6933 // the remainder of the resource from the network.
6934 rv = transaction->Read(buf.get(), kBufferSize, callback.callback());
6935 EXPECT_EQ(callback.GetResult(rv), 70);
6936 rv = transaction->Read(buf.get(), kBufferSize, callback.callback());
6937 EXPECT_EQ(callback.GetResult(rv), 0);
6938
6939 // The cache entry should be gone now.
6940 disk_cache::Entry* entry = nullptr;
6941 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6942
6943 // Transaction opens existing entry, but doesn't create any new entries.
6944 EXPECT_EQ(0, cache.disk_cache()->create_count());
6945 EXPECT_EQ(1, cache.disk_cache()->open_count());
6946
6947 // Two network requests:
6948 // - 1 request for validation.
6949 // - 1 request for the range 10-.
6950 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6951 RemoveMockTransaction(&kRangeGET_TransactionOK);
6952 }
6953
6954 TEST(HttpCache, StopCachingKeepsSparseEntry) {
6955 MockHttpCache cache;
6956 TestCompletionCallback callback;
6957
6958 // Create a sparse entry which contains 10 bytes at offset 20 out of an 80
6959 // byte resource.
6960 MockTransaction mock_transaction(kRangeGET_TransactionOK);
6961 mock_transaction.handler = nullptr;
6962 mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
6963 mock_transaction.response_headers =
6964 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6965 "ETag: \"foo\"\n"
6966 "Accept-Ranges: bytes\n"
6967 "Content-Range: bytes 20-29/80\n"
6968 "Content-Length: 10\n";
6969 mock_transaction.data = "rg: 20-29 ";
6970 AddMockTransaction(&mock_transaction);
6971 std::string headers;
6972 RunTransactionTestWithResponse(cache.http_cache(), mock_transaction,
6973 &headers);
6974
6975 // Verify our assumptions. There should be sparse entry here.
6976 disk_cache::Entry* cache_entry;
6977 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry));
6978 EXPECT_TRUE(cache_entry->CouldBeSparse());
6979 cache_entry->Close();
6980 RemoveMockTransaction(&mock_transaction);
6981
6982 cache.ResetCounts();
6983
6984 // Prepare a request to read the entire contents of the resource. This should
6985 // usually hope between network -> cache -> network. But not today.
6986 mock_transaction.request_headers = EXTRA_HEADER;
6987 mock_transaction.handler = kRangeGET_TransactionOK.handler;
6988 mock_transaction.response_headers =
6989 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6990 "ETag: \"foo\"\n"
6991 "Accept-Ranges: bytes\n"
6992 "Content-Length: 80\n";
6993 AddMockTransaction(&mock_transaction);
6994 MockHttpRequest request(mock_transaction);
6995
6996 scoped_ptr<HttpTransaction> transaction;
6997 ASSERT_EQ(OK, cache.CreateTransaction(&transaction));
6998 int rv = transaction->Start(&request, callback.callback(), BoundNetLog());
6999 ASSERT_EQ(OK, callback.GetResult(rv));
7000
7001 const size_t kBufferSize = 256;
7002 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
7003
7004 rv = transaction->Read(buffer.get(), 10, callback.callback());
7005 EXPECT_EQ(10, callback.GetResult(rv));
7006
7007 // This should've caused a network read of 10 bytes.
7008 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7009
7010 // StopCaching() should cause the transaction to switch entirely to the
7011 // network for the remainder of the response. Since the existing network
7012 // transaction doesn't cover the entirety of the resource, the cache creates a
7013 // new network transaction.
7014 transaction->StopCaching();
7015
7016 // Since it's coming from a single network request, we can slurp the remainder
7017 // of the resource in one request.
7018 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback());
7019 EXPECT_EQ(70, callback.GetResult(rv));
7020
7021 // And we hit EOF.
7022 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback());
7023 EXPECT_EQ(0, callback.GetResult(rv));
7024
7025 // Another network transaction is issued for the remainder of the resource
7026 // following the StopCaching call.
7027 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7028
7029 // And the sparse entry is still here.
7030 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry));
7031 cache_entry->Close();
7032 RemoveMockTransaction(&mock_transaction);
7033 }
7034
7035 // If StopCaching() is called while serving the entire request out of cache, the
7036 // transaction is expected to ignore the StopCaching() call and continue serving
7037 // the remainder of the resource out of the cache.
7038 TEST(HttpCache, StopCachingKeepsFullEntry) {
7039 MockHttpCache cache;
7040 TestCompletionCallback callback;
7041
7042 MockTransaction mock_transaction(kRangeGET_TransactionOK);
7043 mock_transaction.handler = nullptr;
7044 mock_transaction.request_headers = EXTRA_HEADER;
7045 mock_transaction.status = "HTTP/1.1 200 OK";
7046 mock_transaction.response_headers =
7047 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7048 "ETag: \"foo\"\n"
7049 "Content-Length: 80\n";
7050 mock_transaction.data = kFullRangeData;
7051 AddMockTransaction(&mock_transaction);
7052 std::string headers;
7053 RunTransactionTestWithResponse(cache.http_cache(), mock_transaction,
7054 &headers);
7055
7056 cache.ResetCounts();
7057
7058 mock_transaction.request_headers = EXTRA_HEADER;
7059 mock_transaction.handler = kRangeGET_TransactionOK.handler;
7060 mock_transaction.response_headers =
7061 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7062 "ETag: \"foo\"\n"
7063 "Accept-Ranges: bytes\n"
7064 "Content-Length: 80\n";
7065 AddMockTransaction(&mock_transaction);
7066 MockHttpRequest request(mock_transaction);
7067
7068 scoped_ptr<HttpTransaction> transaction;
7069 ASSERT_EQ(OK, cache.CreateTransaction(&transaction));
7070 int rv = transaction->Start(&request, callback.callback(), BoundNetLog());
7071 ASSERT_EQ(OK, callback.GetResult(rv));
7072
7073 const size_t kBufferSize = 256;
7074 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
7075
7076 rv = transaction->Read(buffer.get(), 10, callback.callback());
7077 EXPECT_EQ(10, callback.GetResult(rv));
7078
7079 // This should've caused a cache read of 10 bytes. No new network transactions
7080 // are expected.
7081 EXPECT_EQ(0, cache.network_layer()->transaction_count());
7082
7083 // StopCaching() doesn't do anything because the entire resource is cached
7084 // already. We proceed with the cache read.
7085 transaction->StopCaching();
7086
7087 // Since it's all coming from a single network request, we can slurp the
7088 // remainder of the resource in one request.
7089 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback());
7090 EXPECT_EQ(70, callback.GetResult(rv));
7091
7092 // And we hit EOF.
7093 rv = transaction->Read(buffer.get(), kBufferSize, callback.callback());
7094 EXPECT_EQ(0, callback.GetResult(rv));
7095
7096 // We should've only seen one network transactions at this point.
7097 EXPECT_EQ(0, cache.network_layer()->transaction_count());
7098
7099 // And the entry is still here.
7100 EXPECT_EQ(1, cache.disk_cache()->open_count());
7101 EXPECT_EQ(0, cache.disk_cache()->create_count());
7102 disk_cache::Entry* cache_entry;
7103 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry));
7104 cache_entry->Close();
7105
7106 RemoveMockTransaction(&mock_transaction);
7107 }
7108
7109 namespace {
7110
7111 const MockTransaction kResumableGET_Transaction = {
7112 kRangeGET_TransactionOK.url, "GET", base::Time(), EXTRA_HEADER, 0,
rvargas (doing something else) 2015/09/15 01:07:39 nit: can we use one line per member here?
asanka 2015/09/17 21:59:41 git cl format.
7113 "HTTP/1.1 200 OK",
7114 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7115 "Date: Sat, 18 Apr 2015 01:10:43 GMT\n"
7116 "ETag: \"foo\"\n"
7117 "Accept-Ranges: bytes\n"
7118 "Content-Length: 80\n",
7119 base::Time(), kFullRangeData, TEST_MODE_NORMAL,
7120 &RangeTransactionServer::RangeHandler};
rvargas (doing something else) 2015/09/15 01:07:39 declare all members.
7121
7122 } // namespace
7123
7124 TEST(HttpCache, StopCachingReleasesCacheLockForNewCacheEntry) {
7125 MockHttpCache cache;
7126 TestCompletionCallback callback;
7127 ScopedMockTransaction mock_transaction(kResumableGET_Transaction);
7128 MockHttpRequest mock_request(mock_transaction);
7129
7130 scoped_ptr<HttpTransaction> first_transaction;
7131 ASSERT_EQ(OK, cache.CreateTransaction(&first_transaction));
7132
7133 int rv = first_transaction->Start(&mock_request, callback.callback(),
7134 BoundNetLog());
7135 ASSERT_EQ(OK, callback.GetResult(rv));
7136
7137 const size_t kBufferSize = 1024;
7138 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize));
7139 rv = first_transaction->Read(buf.get(), 10, callback.callback());
7140 EXPECT_EQ(10, callback.GetResult(rv));
7141
7142 first_transaction->StopCaching();
7143
7144 rv = first_transaction->Read(buf.get(), 10, callback.callback());
7145 EXPECT_EQ(10, callback.GetResult(rv));
7146
7147 // Since the cache entry is no longer locked by |first_transaction|, we can
7148 // start another transaction without blocking. The test should time out if
7149 // this is not the case (i.e. the Start() call has to wait indefinitely[*]
7150 // for the previous transaction to release the lock).
7151 //
7152 // [*]: The wait isn't really indefinite since the Start() call times out
7153 // (currently after 20 seconds) and proceeds without the cache entry. Failure
7154 // to release the cahe entry is accounted for by the previous
7155 // disk_cache()->GetEntryCount() expectation.
7156 scoped_ptr<HttpTransaction> second_transaction;
7157 ASSERT_EQ(OK, cache.CreateTransaction(&second_transaction));
7158 rv = second_transaction->Start(&mock_request, callback.callback(),
7159 BoundNetLog());
7160 ASSERT_EQ(OK, callback.GetResult(rv));
7161
7162 // The first cache entry was gone by the time second_transaction started.
7163 // Hence each transaction creates a cache entry.
7164 EXPECT_EQ(2, cache.disk_cache()->create_count());
7165 EXPECT_EQ(0, cache.disk_cache()->open_count());
7166
7167 // The cache entry from second_transaction is still around.
7168 disk_cache::Entry* cache_entry = nullptr;
7169 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry));
7170 cache_entry->Close();
7171
7172 // One network request for each cache transaction.
7173 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7174 }
7175
7176 TEST(HttpCache, StopCachingReleasesCacheLockForTruncatedEntry) {
7177 MockHttpCache cache;
7178 TestCompletionCallback callback;
7179 ScopedMockTransaction mock_transaction(kResumableGET_Transaction);
7180 MockHttpRequest mock_request(kResumableGET_Transaction);
7181 std::string raw_headers(
7182 "HTTP/1.1 200 OK\n"
7183 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7184 "Date: Sat, 18 Apr 2015 01:10:43 GMT\n"
7185 "ETag: \"foo\"\n"
7186 "Accept-Ranges: bytes\n"
7187 "Content-Length: 80\n");
7188 CreateTruncatedEntry(raw_headers, &cache);
7189 cache.ResetCounts();
7190
7191 scoped_ptr<HttpTransaction> first_transaction;
7192 int rv = cache.CreateTransaction(&first_transaction);
7193 ASSERT_EQ(OK, rv);
7194 ASSERT_TRUE(first_transaction.get());
7195
7196 rv = first_transaction->Start(&mock_request, callback.callback(),
7197 BoundNetLog());
7198 ASSERT_EQ(OK, callback.GetResult(rv));
7199
7200 first_transaction->StopCaching();
7201
7202 const int kBufferSize = 1024;
7203 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize));
7204 rv = first_transaction->Read(buf.get(), 10, callback.callback());
7205 EXPECT_EQ(10, callback.GetResult(rv));
7206
7207 // Now that the cache lock is released, another transaction can begin. The
7208 // Start() call should complete without delay. The test should timeout if this
7209 // is not the case (i.e. the Start() call has to wait indefinitely[*] for the
7210 // previous transaction to release the lock).
7211 //
7212 // [*]: The wait isn't really indefinite since the Start() call times out
7213 // (currently after 20 seconds) and proceeds without the cache entry. This
7214 // case is accounted for by the network_layer()->transaction_count()
7215 // expectation below.
7216 scoped_ptr<HttpTransaction> second_transaction;
7217 rv = cache.CreateTransaction(&second_transaction);
7218 ASSERT_EQ(OK, rv);
7219 ASSERT_TRUE(second_transaction);
7220 rv = second_transaction->Start(&mock_request, callback.callback(),
7221 BoundNetLog());
7222 ASSERT_EQ(OK, callback.GetResult(rv));
7223
7224 // first_transaction: 1 open cache entry + 2 network fetches.
7225 // second_transaction: 1 create cache entry + 1 network fetch.
7226 EXPECT_EQ(1, cache.disk_cache()->create_count());
7227 EXPECT_EQ(1, cache.disk_cache()->open_count());
7228 EXPECT_EQ(3, cache.network_layer()->transaction_count());
7229 }
7230
7231 TEST(HttpCache, StopCachingReleasesCacheLockForSparseEntry) {
7232 MockHttpCache cache;
7233 TestCompletionCallback callback;
7234
7235 // Create a sparse entry which contains 10 bytes at offset 20 out of an 80
7236 // byte resource.
7237 MockTransaction mock_transaction(kRangeGET_TransactionOK);
7238 mock_transaction.handler = nullptr;
7239 mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
7240 mock_transaction.response_headers =
7241 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7242 "ETag: \"foo\"\n"
7243 "Accept-Ranges: bytes\n"
7244 "Content-Range: bytes 20-29/80\n"
7245 "Content-Length: 10\n";
7246 mock_transaction.data = "rg: 20-29 ";
7247 AddMockTransaction(&mock_transaction);
7248 std::string headers;
7249 RunTransactionTestWithResponse(cache.http_cache(), mock_transaction,
7250 &headers);
7251
7252 // Verify our assumptions. There should be sparse entry here.
7253 disk_cache::Entry* cache_entry;
7254 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry));
7255 EXPECT_TRUE(cache_entry->CouldBeSparse());
7256 cache_entry->Close();
7257 RemoveMockTransaction(&mock_transaction);
7258
7259 cache.ResetCounts();
7260
7261 // Prepare a request to read the entire contents of the resource. This should
7262 // usually hope between network -> cache -> network. But not today.
7263 mock_transaction.request_headers = EXTRA_HEADER;
7264 mock_transaction.handler = kRangeGET_TransactionOK.handler;
7265 mock_transaction.response_headers =
7266 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7267 "ETag: \"foo\"\n"
7268 "Accept-Ranges: bytes\n"
7269 "Content-Length: 10\n";
7270 AddMockTransaction(&mock_transaction);
7271 MockHttpRequest request(mock_transaction);
7272
7273 scoped_ptr<HttpTransaction> first_transaction;
7274 ASSERT_EQ(OK, cache.CreateTransaction(&first_transaction));
7275 int rv =
7276 first_transaction->Start(&request, callback.callback(), BoundNetLog());
7277 ASSERT_EQ(OK, callback.GetResult(rv));
7278
7279 const size_t kBufferSize = 256;
7280 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
7281
7282 rv = first_transaction->Read(buffer.get(), 10, callback.callback());
7283 EXPECT_EQ(10, callback.GetResult(rv));
7284
7285 // Create another cache transaction. This one is blocked on the first
7286 // transaction's cache lock.
7287 scoped_ptr<HttpTransaction> second_transaction;
7288 TestCompletionCallback second_callback;
7289 ASSERT_EQ(OK, cache.CreateTransaction(&second_transaction));
7290 rv = second_transaction->Start(&request, second_callback.callback(),
7291 BoundNetLog());
7292 ASSERT_EQ(ERR_IO_PENDING, rv);
7293
7294 // StopCaching() should cause the transaction to switch entirely to the
7295 // network for the remainder of the response. Since the existing network
7296 // transaction doesn't cover the entirety of the resource, the cache creates a
7297 // new network transaction.
7298 first_transaction->StopCaching();
7299
7300 // Since it's coming from a single network request, we can slurp the remaining
7301 // 70 bytes of the resource in one request. Let's leave a little bit on the
7302 // pipe so that the stream doesn't hit EOF.
7303 rv = first_transaction->Read(buffer.get(), 60, callback.callback());
7304 EXPECT_EQ(60, callback.GetResult(rv));
7305
7306 // The second transaction should become unblocked at this point.
7307 EXPECT_EQ(OK, second_callback.GetResult(ERR_IO_PENDING));
7308
7309 // And it can read the entire resource too, but needs to alternate between
7310 // cache and network..
7311 // 0-9 from cache (due to the first Read() on first_transaction).
7312 EXPECT_EQ(10, second_callback.GetResult(second_transaction->Read(
7313 buffer.get(), kBufferSize, second_callback.callback())));
7314
7315 // 10-19 From network:
7316 EXPECT_EQ(10, second_callback.GetResult(second_transaction->Read(
7317 buffer.get(), kBufferSize, second_callback.callback())));
7318
7319 // 20-29 From cache (due to test setup):
7320 EXPECT_EQ(10, second_callback.GetResult(second_transaction->Read(
7321 buffer.get(), kBufferSize, second_callback.callback())));
7322
7323 // 30-79 From network again:
7324 EXPECT_EQ(50, second_callback.GetResult(second_transaction->Read(
7325 buffer.get(), kBufferSize, second_callback.callback())));
7326 EXPECT_EQ(0, second_callback.GetResult(second_transaction->Read(
7327 buffer.get(), kBufferSize, second_callback.callback())));
7328
7329 // Now drain first_transaction as well.
7330 EXPECT_EQ(10, callback.GetResult(first_transaction->Read(
7331 buffer.get(), kBufferSize, callback.callback())));
7332 EXPECT_EQ(0, callback.GetResult(first_transaction->Read(
7333 buffer.get(), kBufferSize, callback.callback())));
7334
7335 // first_transaction:
7336 // 1 open cache entry + 2 network fetches (0-19 and 10-79).
7337 // second_transaction:
7338 // 1 open cache entry + 2 network fetches (10-19 and 30-79).
7339 EXPECT_EQ(0, cache.disk_cache()->create_count());
7340 EXPECT_EQ(4, cache.network_layer()->transaction_count());
7341
7342 // Even though there are two HttpCache::OpenEntry() calls, there's only one
7343 // DiskCache::OpenEntry call because HttpCache already has an active entry.
7344 EXPECT_EQ(1, cache.disk_cache()->open_count());
7345
7346 // And the sparse entry is still here.
7347 ASSERT_TRUE(cache.OpenBackendEntry(mock_transaction.url, &cache_entry));
7348 cache_entry->Close();
7349 RemoveMockTransaction(&mock_transaction);
7350 }
7351
7352 TEST(HttpCache, StopCachingBeforeStartNoCacheEntry) {
7353 MockHttpCache cache;
7354 TestCompletionCallback callback;
7355 MockTransaction transaction(kSimpleGET_Transaction);
7356 cache.ResetCounts();
7357
7358 AddMockTransaction(&transaction);
7359 scoped_ptr<HttpTransaction> http_transaction;
7360
7361 int rv = cache.CreateTransaction(&http_transaction);
7362 ASSERT_EQ(OK, rv);
7363
7364 MockHttpRequest request(transaction);
7365 http_transaction->StopCaching();
7366 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog());
7367 ASSERT_EQ(OK, callback.GetResult(rv));
7368
7369 ReadAndVerifyTransaction(http_transaction.get(), transaction);
7370 RemoveMockTransaction(&transaction);
7371
7372 // If StopCaching() is called before Start(), then the cache should not try to
7373 // create an entry.
7374 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7375 EXPECT_EQ(0, cache.disk_cache()->open_count());
7376 EXPECT_EQ(0, cache.disk_cache()->create_count());
7377 }
7378
7379 TEST(HttpCache, StopCachingBeforeStartOnlyFromCache) {
7380 MockHttpCache cache;
7381 TestCompletionCallback callback;
7382 MockTransaction transaction(kSimpleGET_Transaction);
7383
7384 AddMockTransaction(&transaction);
7385 RunTransactionTest(cache.http_cache(), transaction);
7386 RemoveMockTransaction(&transaction);
7387 cache.ResetCounts();
7388
7389 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
7390 AddMockTransaction(&transaction);
7391
7392 scoped_ptr<HttpTransaction> http_transaction;
7393
7394 int rv = cache.CreateTransaction(&http_transaction);
7395 ASSERT_EQ(OK, rv);
7396
7397 MockHttpRequest request(transaction);
7398 http_transaction->StopCaching();
7399 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog());
7400 ASSERT_EQ(OK, callback.GetResult(rv));
7401
7402 ReadAndVerifyTransaction(http_transaction.get(), transaction);
7403 RemoveMockTransaction(&transaction);
7404
7405 EXPECT_EQ(0, cache.network_layer()->transaction_count());
7406 EXPECT_EQ(1, cache.disk_cache()->open_count());
7407 EXPECT_EQ(0, cache.disk_cache()->create_count());
7408 }
7409
7410 TEST(HttpCache, StopCachingBeforeStartOnlyNonexistentCacheEntry) {
7411 MockHttpCache cache;
7412 TestCompletionCallback callback;
7413 MockTransaction transaction(kSimpleGET_Transaction);
7414 cache.ResetCounts();
7415
7416 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
7417 AddMockTransaction(&transaction);
7418
7419 scoped_ptr<HttpTransaction> http_transaction;
7420
7421 int rv = cache.CreateTransaction(&http_transaction);
7422 ASSERT_EQ(OK, rv);
7423
7424 MockHttpRequest request(transaction);
7425 http_transaction->StopCaching();
7426 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog());
7427 ASSERT_EQ(ERR_CACHE_MISS, callback.GetResult(rv));
7428 RemoveMockTransaction(&transaction);
7429
7430 EXPECT_EQ(0, cache.network_layer()->transaction_count());
7431 EXPECT_EQ(0, cache.disk_cache()->open_count());
7432 EXPECT_EQ(0, cache.disk_cache()->create_count());
7433 }
7434
7435 TEST(HttpCache, StopCachingBeforeStartPreferringNonexistentCacheEntry) {
7436 MockHttpCache cache;
7437 TestCompletionCallback callback;
7438 MockTransaction transaction(kSimpleGET_Transaction);
7439 cache.ResetCounts();
7440
7441 transaction.load_flags |= LOAD_PREFERRING_CACHE;
7442 AddMockTransaction(&transaction);
7443
7444 scoped_ptr<HttpTransaction> http_transaction;
7445
7446 int rv = cache.CreateTransaction(&http_transaction);
7447 ASSERT_EQ(OK, rv);
7448
7449 MockHttpRequest request(transaction);
7450 http_transaction->StopCaching();
7451 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog());
7452 ASSERT_EQ(OK, callback.GetResult(rv));
7453
7454 ReadAndVerifyTransaction(http_transaction.get(), transaction);
7455 RemoveMockTransaction(&transaction);
7456
7457 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7458 EXPECT_EQ(0, cache.disk_cache()->open_count());
7459 EXPECT_EQ(0, cache.disk_cache()->create_count());
7460 }
7461
7462 TEST(HttpCache, StopCachingBeforeStartPreferringCacheEntry) {
7463 MockHttpCache cache;
7464 TestCompletionCallback callback;
7465 MockTransaction transaction(kSimpleGET_Transaction);
7466
7467 AddMockTransaction(&transaction);
7468 RunTransactionTest(cache.http_cache(), transaction);
7469 RemoveMockTransaction(&transaction);
7470 cache.ResetCounts();
7471
7472 transaction.load_flags |= LOAD_PREFERRING_CACHE;
7473 AddMockTransaction(&transaction);
7474
7475 scoped_ptr<HttpTransaction> http_transaction;
7476
7477 int rv = cache.CreateTransaction(&http_transaction);
7478 ASSERT_EQ(OK, rv);
7479
7480 MockHttpRequest request(transaction);
7481 http_transaction->StopCaching();
7482 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog());
7483 ASSERT_EQ(OK, callback.GetResult(rv));
7484
7485 ReadAndVerifyTransaction(http_transaction.get(), transaction);
7486 RemoveMockTransaction(&transaction);
7487
7488 EXPECT_EQ(0, cache.network_layer()->transaction_count());
7489 EXPECT_EQ(1, cache.disk_cache()->open_count());
7490 EXPECT_EQ(0, cache.disk_cache()->create_count());
7491 }
7492
7493 TEST(HttpCache, StopCachingBeforeStartPreferringTruncatedCacheEntry) {
7494 MockHttpCache cache;
7495 TestCompletionCallback callback;
7496 MockTransaction transaction(kRangeGET_TransactionOK);
7497 transaction.load_flags |= LOAD_PREFERRING_CACHE;
7498 transaction.request_headers = EXTRA_HEADER;
7499 transaction.data = kFullRangeData;
7500 AddMockTransaction(&transaction);
7501
7502 std::string raw_headers(
7503 "HTTP/1.1 200 OK\n"
7504 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7505 "ETag: \"foo\"\n"
7506 "Accept-Ranges: bytes\n"
7507 "Content-Length: 80\n");
7508 CreateTruncatedEntry(raw_headers, &cache);
7509 cache.ResetCounts();
7510
7511 scoped_ptr<HttpTransaction> http_transaction;
7512
7513 int rv = cache.CreateTransaction(&http_transaction);
7514 ASSERT_EQ(OK, rv);
7515
7516 MockHttpRequest request(transaction);
7517 http_transaction->StopCaching();
7518 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog());
7519 ASSERT_EQ(OK, callback.GetResult(rv));
7520
7521 ReadAndVerifyTransaction(http_transaction.get(), transaction);
7522 RemoveMockTransaction(&transaction);
7523
7524 // 1 validation request + 1 request for entire range = 2 network reqeusts.
7525 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7526 EXPECT_EQ(1, cache.disk_cache()->open_count());
7527 EXPECT_EQ(0, cache.disk_cache()->create_count());
7528 }
7529
7530 TEST(HttpCache,
7531 StopCachingBeforeStartForExternallyConditionalizedTruncatedEntry) {
7532 MockHttpCache cache;
7533 TestCompletionCallback callback;
7534 RangeTransactionServer range_transaction_server;
7535 range_transaction_server.set_not_modified(true);
7536 MockTransaction transaction(kRangeGET_TransactionOK);
7537 transaction.request_headers = "If-None-Match: \"foo\"\r\n" EXTRA_HEADER,
7538 transaction.data = "";
7539 transaction.load_flags |= LOAD_PREFERRING_CACHE;
7540 AddMockTransaction(&transaction);
7541
7542 std::string raw_headers(
7543 "HTTP/1.1 200 OK\n"
7544 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7545 "ETag: \"foo\"\n"
7546 "Accept-Ranges: bytes\n"
7547 "Content-Length: 80\n");
7548 CreateTruncatedEntry(raw_headers, &cache);
7549 cache.ResetCounts();
7550
7551 scoped_ptr<HttpTransaction> http_transaction;
7552
7553 int rv = cache.CreateTransaction(&http_transaction);
7554 ASSERT_EQ(OK, rv);
7555
7556 MockHttpRequest request(transaction);
7557 http_transaction->StopCaching();
7558 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog());
7559 ASSERT_EQ(OK, callback.GetResult(rv));
7560
7561 ReadAndVerifyTransaction(http_transaction.get(), transaction);
7562 RemoveMockTransaction(&transaction);
7563
7564 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7565 EXPECT_EQ(1, cache.disk_cache()->open_count());
7566 EXPECT_EQ(0, cache.disk_cache()->create_count());
7567 }
7568
7569 TEST(HttpCache, StopCachingAfterStartForLoadPreferringCacheWithInvalidation) {
7570 MockHttpCache cache;
7571 TestCompletionCallback callback;
7572 MockTransaction transaction(kSimpleGET_Transaction);
7573
7574 AddMockTransaction(&transaction);
7575 RunTransactionTest(cache.http_cache(), transaction);
7576 RemoveMockTransaction(&transaction);
7577 cache.ResetCounts();
7578
7579 transaction.load_flags |= LOAD_PREFERRING_CACHE;
7580 AddMockTransaction(&transaction);
7581
7582 scoped_ptr<HttpTransaction> http_transaction;
7583
7584 int rv = cache.CreateTransaction(&http_transaction);
7585 ASSERT_EQ(OK, rv);
7586
7587 MockHttpRequest request(transaction);
7588 rv = http_transaction->Start(&request, callback.callback(), BoundNetLog());
7589 ASSERT_EQ(OK, callback.GetResult(rv));
7590
7591 http_transaction->StopCaching();
7592
7593 ReadAndVerifyTransaction(http_transaction.get(), transaction);
7594 RemoveMockTransaction(&transaction);
7595
7596 EXPECT_EQ(0, cache.network_layer()->transaction_count());
7597 EXPECT_EQ(1, cache.disk_cache()->open_count());
7598 EXPECT_EQ(0, cache.disk_cache()->create_count());
7599 }
7600
7601 namespace {
7602
7603 enum class TransactionPhase {
7604 BEFORE_FIRST_READ,
7605 AFTER_FIRST_READ,
7606 AFTER_NETWORK_READ
7607 };
7608
7609 using CacheInitializer = void (*)(MockHttpCache*);
7610 using HugeCacheTestConfiguration =
7611 std::pair<TransactionPhase, CacheInitializer>;
7612
7613 class HttpCacheHugeResourceTest
7614 : public ::testing::TestWithParam<HugeCacheTestConfiguration> {
7615 public:
7616 static std::list<HugeCacheTestConfiguration> GetTestModes();
7617 static std::list<HugeCacheTestConfiguration> kTestModes;
7618
7619 // CacheInitializer callbacks. These are used to initialize the cache
7620 // depending on the test run configuration.
7621
7622 // Initializes a cache containing a truncated entry containing the first 20
7623 // bytes of the reponse body.
7624 static void SetupTruncatedCacheEntry(MockHttpCache* cache);
7625
7626 // Initializes a cache containing a sparse entry. The first 10 bytes are
7627 // present in the cache.
7628 static void SetupPrefixSparseCacheEntry(MockHttpCache* cache);
7629
7630 // Initializes a cache containing a sparse entry. The 10 bytes at offset
7631 // 99999990 are present in the cache.
7632 static void SetupInfixSparseCacheEntry(MockHttpCache* cache);
7633
7634 protected:
7635 static void ExpectByteRangeTransactionHandler(
7636 const net::HttpRequestInfo* request,
7637 std::string* response_status,
7638 std::string* response_headers,
7639 std::string* response_data);
7640 static int LargeBufferReader(int64 content_length,
7641 int64 offset,
7642 net::IOBuffer* buf,
7643 int buf_len);
7644
7645 static void SetFlagOnBeforeNetworkStart(bool* started, bool* /* defer */);
7646
7647 // Size of resource to be tested.
7648 static const int64 kTotalSize =
7649 5000000000LL; // Five beeeeeelllliooonn bytes!
7650 };
7651
7652 const int64 HttpCacheHugeResourceTest::kTotalSize;
7653
7654 // static
7655 void HttpCacheHugeResourceTest::ExpectByteRangeTransactionHandler(
7656 const net::HttpRequestInfo* request,
7657 std::string* response_status,
7658 std::string* response_headers,
7659 std::string* response_data) {
7660 std::string if_range;
7661 EXPECT_TRUE(request->extra_headers.GetHeader(
7662 net::HttpRequestHeaders::kIfRange, &if_range));
7663 EXPECT_EQ("\"foo\"", if_range);
7664
7665 std::string range_header;
7666 EXPECT_TRUE(request->extra_headers.GetHeader(net::HttpRequestHeaders::kRange,
7667 &range_header));
7668 std::vector<net::HttpByteRange> ranges;
7669
7670 EXPECT_TRUE(net::HttpUtil::ParseRangeHeader(range_header, &ranges));
7671 ASSERT_EQ(1u, ranges.size());
7672
7673 net::HttpByteRange range = ranges[0];
7674 EXPECT_TRUE(range.HasFirstBytePosition());
7675 int64 last_byte_position =
7676 range.HasLastBytePosition() ? range.last_byte_position() : kTotalSize - 1;
7677
7678 response_status->assign("HTTP/1.1 206 Partial");
7679 response_headers->assign(base::StringPrintf(
7680 "Content-Range: bytes %" PRId64 "-%" PRId64 "/%" PRId64
7681 "\n"
7682 "Content-Length: %" PRId64 "\n",
7683 range.first_byte_position(), last_byte_position, kTotalSize,
7684 last_byte_position - range.first_byte_position() + 1));
7685 }
7686
7687 // static
7688 int HttpCacheHugeResourceTest::LargeBufferReader(int64 content_length,
7689 int64 offset,
7690 net::IOBuffer* buf,
7691 int buf_len) {
7692 // This test involves reading multiple gigabytes of data. To make it run in a
7693 // reasonable amount of time, we are going to skip filling the buffer with
7694 // data. Instead the test relies on verifying that the count of bytes expected
7695 // at the end is correct.
7696 EXPECT_LT(0, content_length);
7697 EXPECT_LE(offset, content_length);
7698 int num = std::min(static_cast<int64>(buf_len), content_length - offset);
7699 return num;
7700 }
7701
7702 // static
7703 void HttpCacheHugeResourceTest::SetFlagOnBeforeNetworkStart(bool* started,
7704 bool* /* defer */) {
7705 *started = true;
7706 }
7707
7708 // static
7709 void HttpCacheHugeResourceTest::SetupTruncatedCacheEntry(MockHttpCache* cache) {
7710 ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
7711 std::string cached_headers = base::StringPrintf(
7712 "HTTP/1.1 200 OK\n"
7713 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7714 "ETag: \"foo\"\n"
7715 "Accept-Ranges: bytes\n"
7716 "Content-Length: %" PRId64 "\n",
7717 kTotalSize);
7718 CreateTruncatedEntry(cached_headers, cache);
7719 }
7720
7721 // static
7722 void HttpCacheHugeResourceTest::SetupPrefixSparseCacheEntry(
7723 MockHttpCache* cache) {
7724 MockTransaction transaction(kRangeGET_TransactionOK);
7725 transaction.handler = nullptr;
7726 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
7727 transaction.response_headers =
7728 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7729 "ETag: \"foo\"\n"
7730 "Accept-Ranges: bytes\n"
7731 "Content-Range: bytes 0-9/5000000000\n"
7732 "Content-Length: 10\n";
7733 AddMockTransaction(&transaction);
7734 std::string headers;
7735 RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers);
7736 RemoveMockTransaction(&transaction);
7737 }
7738
7739 // static
7740 void HttpCacheHugeResourceTest::SetupInfixSparseCacheEntry(
7741 MockHttpCache* cache) {
7742 MockTransaction transaction(kRangeGET_TransactionOK);
7743 transaction.handler = nullptr;
7744 transaction.request_headers =
7745 "Range: bytes = 99999990-99999999\r\n" EXTRA_HEADER;
7746 transaction.response_headers =
7747 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7748 "ETag: \"foo\"\n"
7749 "Accept-Ranges: bytes\n"
7750 "Content-Range: bytes 99999990-99999999/5000000000\n"
7751 "Content-Length: 10\n";
7752 AddMockTransaction(&transaction);
7753 std::string headers;
7754 RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers);
7755 RemoveMockTransaction(&transaction);
7756 }
7757
7758 // static
7759 std::list<HugeCacheTestConfiguration>
7760 HttpCacheHugeResourceTest::GetTestModes() {
7761 std::list<HugeCacheTestConfiguration> test_modes;
7762 const TransactionPhase kTransactionPhases[] = {
7763 TransactionPhase::BEFORE_FIRST_READ, TransactionPhase::AFTER_FIRST_READ,
7764 TransactionPhase::AFTER_NETWORK_READ};
7765 const CacheInitializer kInitializers[] = {&SetupTruncatedCacheEntry,
7766 &SetupPrefixSparseCacheEntry,
7767 &SetupInfixSparseCacheEntry};
7768
7769 for (const auto phase : kTransactionPhases)
7770 for (const auto initializer : kInitializers)
7771 test_modes.push_back(std::make_pair(phase, initializer));
7772
7773 return test_modes;
7774 }
7775
7776 // static
7777 std::list<HugeCacheTestConfiguration> HttpCacheHugeResourceTest::kTestModes =
7778 HttpCacheHugeResourceTest::GetTestModes();
7779
7780 INSTANTIATE_TEST_CASE_P(
7781 _,
7782 HttpCacheHugeResourceTest,
7783 ::testing::ValuesIn(HttpCacheHugeResourceTest::kTestModes));
7784
7785 } // namespace
7786
7787 // Test what happens when StopCaching() is called while reading a huge resource
7788 // fetched via GET. Various combinations of cache state and when StopCaching()
7789 // is called is controlled by the parameter passed into the test via the
7790 // INSTANTIATE_TEST_CASE_P invocation above.
7791 TEST_P(HttpCacheHugeResourceTest,
7792 StopCachingFollowedByReadForHugeTruncatedResource) {
7793 // This test is going to be repeated for all combinations of TransactionPhase
7794 // and CacheInitializers returned by GetTestModes().
7795 const TransactionPhase stop_caching_phase = GetParam().first;
7796 const CacheInitializer cache_initializer = GetParam().second;
7797
7798 MockHttpCache cache;
7799 (*cache_initializer)(&cache);
7800
7801 MockTransaction transaction(kSimpleGET_Transaction);
7802 transaction.url = kRangeGET_TransactionOK.url;
7803 transaction.handler = &ExpectByteRangeTransactionHandler;
7804 transaction.read_handler = &LargeBufferReader;
7805 ScopedMockTransaction scoped_transaction(transaction);
7806
7807 MockHttpRequest request(transaction);
7808 net::TestCompletionCallback callback;
7809 scoped_ptr<net::HttpTransaction> http_transaction;
7810 int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY,
7811 &http_transaction);
7812 ASSERT_EQ(net::OK, rv);
7813 ASSERT_TRUE(http_transaction.get());
7814
7815 bool network_transaction_started = false;
7816 if (stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) {
7817 http_transaction->SetBeforeNetworkStartCallback(
7818 base::Bind(&SetFlagOnBeforeNetworkStart, &network_transaction_started));
6945 } 7819 }
6946 7820
6947 // Verify that the disk entry was updated. 7821 rv = http_transaction->Start(&request, callback.callback(),
6948 disk_cache::Entry* entry; 7822 net::BoundNetLog());
6949 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); 7823 rv = callback.GetResult(rv);
6950 EXPECT_EQ(80, entry->GetDataSize(1)); 7824 ASSERT_EQ(net::OK, rv);
6951 bool truncated = true; 7825
6952 HttpResponseInfo response; 7826 if (stop_caching_phase == TransactionPhase::BEFORE_FIRST_READ)
6953 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); 7827 http_transaction->StopCaching();
6954 EXPECT_FALSE(truncated); 7828
6955 entry->Close(); 7829 int64 total_bytes_received = 0;
6956 7830
6957 RemoveMockTransaction(&kRangeGET_TransactionOK); 7831 EXPECT_EQ(kTotalSize,
7832 http_transaction->GetResponseInfo()->headers->GetContentLength());
7833 do {
7834 // This test simulates reading Gigabytes of data. Buffer size is set to 1MB
7835 // to reduce the number of reads and speedup the test.
7836 const int kBufferSize = 1024 * 1024;
7837 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufferSize));
7838 rv = http_transaction->Read(buf.get(), kBufferSize, callback.callback());
7839 rv = callback.GetResult(rv);
7840
7841 if (stop_caching_phase == TransactionPhase::AFTER_FIRST_READ &&
7842 total_bytes_received == 0) {
7843 http_transaction->StopCaching();
7844 }
7845
7846 if (rv > 0)
7847 total_bytes_received += rv;
7848
7849 if (network_transaction_started &&
7850 stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) {
7851 http_transaction->StopCaching();
7852 network_transaction_started = false;
7853 }
7854 } while (rv > 0);
7855
7856 // The only verification we are going to do is that the received resource has
7857 // the correct size. This is sufficient to verify that the state machine
7858 // didn't terminate abruptly due to the StopCaching() call.
7859 EXPECT_EQ(kTotalSize, total_bytes_received);
6958 } 7860 }
6959 7861
6960 // Tests that we detect truncated resources from the net when there is 7862 // Tests that we detect truncated resources from the net when there is
6961 // a Content-Length header. 7863 // a Content-Length header.
6962 TEST(HttpCache, TruncatedByContentLength) { 7864 TEST(HttpCache, TruncatedByContentLength) {
6963 MockHttpCache cache; 7865 MockHttpCache cache;
6964 TestCompletionCallback callback; 7866 TestCompletionCallback callback;
6965 7867
6966 MockTransaction transaction(kSimpleGET_Transaction); 7868 MockTransaction transaction(kSimpleGET_Transaction);
6967 AddMockTransaction(&transaction); 7869 AddMockTransaction(&transaction);
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
7631 EXPECT_EQ(1, cache.disk_cache()->open_count()); 8533 EXPECT_EQ(1, cache.disk_cache()->open_count());
7632 EXPECT_EQ(1, cache.disk_cache()->create_count()); 8534 EXPECT_EQ(1, cache.disk_cache()->create_count());
7633 EXPECT_TRUE(response_info.was_cached); 8535 EXPECT_TRUE(response_info.was_cached);
7634 8536
7635 // The new SSL state is reported. 8537 // The new SSL state is reported.
7636 EXPECT_EQ(status2, response_info.ssl_info.connection_status); 8538 EXPECT_EQ(status2, response_info.ssl_info.connection_status);
7637 EXPECT_TRUE(cert2->Equals(response_info.ssl_info.cert.get())); 8539 EXPECT_TRUE(cert2->Equals(response_info.ssl_info.cert.get()));
7638 } 8540 }
7639 8541
7640 } // namespace net 8542 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698