OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_cache.h" | 5 #include "net/http/http_cache.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/memory/scoped_vector.h" | 11 #include "base/memory/scoped_vector.h" |
12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
13 #include "base/run_loop.h" | |
13 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
15 #include "net/base/cache_type.h" | 16 #include "net/base/cache_type.h" |
16 #include "net/base/host_port_pair.h" | 17 #include "net/base/host_port_pair.h" |
17 #include "net/base/load_flags.h" | 18 #include "net/base/load_flags.h" |
18 #include "net/base/load_timing_info.h" | 19 #include "net/base/load_timing_info.h" |
19 #include "net/base/load_timing_info_test_util.h" | 20 #include "net/base/load_timing_info_test_util.h" |
20 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
21 #include "net/base/net_log_unittest.h" | 22 #include "net/base/net_log_unittest.h" |
22 #include "net/base/upload_bytes_element_reader.h" | 23 #include "net/base/upload_bytes_element_reader.h" |
23 #include "net/base/upload_data_stream.h" | 24 #include "net/base/upload_data_stream.h" |
24 #include "net/cert/cert_status_flags.h" | 25 #include "net/cert/cert_status_flags.h" |
25 #include "net/disk_cache/disk_cache.h" | 26 #include "net/disk_cache/disk_cache.h" |
26 #include "net/http/http_byte_range.h" | 27 #include "net/http/http_byte_range.h" |
27 #include "net/http/http_request_headers.h" | 28 #include "net/http/http_request_headers.h" |
28 #include "net/http/http_request_info.h" | 29 #include "net/http/http_request_info.h" |
29 #include "net/http/http_response_headers.h" | 30 #include "net/http/http_response_headers.h" |
30 #include "net/http/http_response_info.h" | 31 #include "net/http/http_response_info.h" |
31 #include "net/http/http_transaction.h" | 32 #include "net/http/http_transaction.h" |
32 #include "net/http/http_transaction_test_util.h" | 33 #include "net/http/http_transaction_test_util.h" |
33 #include "net/http/http_util.h" | 34 #include "net/http/http_util.h" |
34 #include "net/http/mock_http_cache.h" | 35 #include "net/http/mock_http_cache.h" |
35 #include "net/socket/client_socket_handle.h" | 36 #include "net/socket/client_socket_handle.h" |
36 #include "net/ssl/ssl_cert_request_info.h" | 37 #include "net/ssl/ssl_cert_request_info.h" |
37 #include "net/websockets/websocket_handshake_stream_base.h" | 38 #include "net/websockets/websocket_handshake_stream_base.h" |
38 #include "testing/gtest/include/gtest/gtest.h" | 39 #include "testing/gtest/include/gtest/gtest.h" |
39 | 40 |
40 using base::Time; | 41 using base::Time; |
42 using base::RunLoop; | |
rvargas (doing something else)
2014/09/17 04:32:19
nit: we should probably avoid this and be explicit
Adam Rice
2014/09/30 13:44:50
Done. I originally cleaned up every call to RunUnt
| |
43 using base::MessageLoop; | |
rvargas (doing something else)
2014/09/17 04:32:19
not used
Adam Rice
2014/09/30 13:44:50
Removed.
| |
41 | 44 |
42 namespace { | 45 namespace { |
43 | 46 |
44 // Tests the load timing values of a request that goes through a | 47 // Tests the load timing values of a request that goes through a |
45 // MockNetworkTransaction. | 48 // MockNetworkTransaction. |
46 void TestLoadTimingNetworkRequest(const net::LoadTimingInfo& load_timing_info) { | 49 void TestLoadTimingNetworkRequest(const net::LoadTimingInfo& load_timing_info) { |
47 EXPECT_FALSE(load_timing_info.socket_reused); | 50 EXPECT_FALSE(load_timing_info.socket_reused); |
48 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); | 51 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id); |
49 | 52 |
50 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); | 53 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); |
(...skipping 6667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6718 | 6721 |
6719 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache. | 6722 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache. |
6720 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER; | 6723 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER; |
6721 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; | 6724 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; |
6722 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); | 6725 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction); |
6723 EXPECT_EQ(range_response_size * 2, received_bytes); | 6726 EXPECT_EQ(range_response_size * 2, received_bytes); |
6724 | 6727 |
6725 RemoveMockTransaction(&kRangeGET_TransactionOK); | 6728 RemoveMockTransaction(&kRangeGET_TransactionOK); |
6726 } | 6729 } |
6727 | 6730 |
6731 class HttpCacheStaleWhileRevalidateTest : public ::testing::Test { | |
rvargas (doing something else)
2014/09/17 04:32:19
Add a comment about how to use this class (what ar
Adam Rice
2014/09/30 13:44:50
Done.
| |
6732 protected: | |
6733 HttpCacheStaleWhileRevalidateTest() | |
6734 : transaction_(kSimpleGET_Transaction), | |
6735 age_(3601), | |
6736 stale_while_revalidate_(7200), | |
6737 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") { | |
6738 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(true); | |
6739 } | |
6740 | |
6741 // RunTransactionTest() with the arguments from this fixure. | |
6742 void RunFixtureTransactionTest() { | |
6743 std::string response_headers = base::StringPrintf( | |
6744 "%s\n" | |
6745 "Age: %d\n" | |
6746 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n", | |
6747 validator_.c_str(), | |
6748 age_, | |
6749 stale_while_revalidate_); | |
6750 transaction_.response_headers = response_headers.c_str(); | |
6751 RunTransactionTest(cache_.http_cache(), transaction_); | |
6752 transaction_.response_headers = ""; | |
6753 } | |
6754 | |
6755 int transaction_count() { | |
6756 return cache_.network_layer()->transaction_count(); | |
6757 } | |
6758 | |
6759 int open_count() { return cache_.disk_cache()->open_count(); } | |
6760 | |
6761 MockHttpCache cache_; | |
6762 ScopedMockTransaction transaction_; | |
6763 int age_; | |
6764 int stale_while_revalidate_; | |
6765 std::string validator_; | |
6766 }; | |
6767 | |
6728 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo* request, | 6768 static void CheckResourceFreshnessHeader(const net::HttpRequestInfo* request, |
6729 std::string* response_status, | 6769 std::string* response_status, |
6730 std::string* response_headers, | 6770 std::string* response_headers, |
6731 std::string* response_data) { | 6771 std::string* response_data) { |
6732 std::string value; | 6772 std::string value; |
6733 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value)); | 6773 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value)); |
6734 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value); | 6774 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value); |
6735 } | 6775 } |
6736 | 6776 |
6737 // Verify that the Resource-Freshness header is sent on a revalidation if the | 6777 // Verify that the Resource-Freshness header is sent on a revalidation if the |
6738 // stale-while-revalidate directive was on the response. | 6778 // stale-while-revalidate directive was on the response. |
6739 TEST(HttpCache, ResourceFreshnessHeaderSent) { | 6779 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderSent) { |
6740 MockHttpCache cache; | 6780 age_ = 10801; // Outside the stale-while-revalidate window. |
6741 | |
6742 ScopedMockTransaction stale_while_revalidate_transaction( | |
6743 kSimpleGET_Transaction); | |
6744 stale_while_revalidate_transaction.response_headers = | |
6745 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | |
6746 "Age: 10801\n" | |
6747 "Cache-Control: max-age=3600,stale-while-revalidate=7200\n"; | |
6748 | 6781 |
6749 // Write to the cache. | 6782 // Write to the cache. |
6750 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); | 6783 RunFixtureTransactionTest(); |
6751 | 6784 |
6752 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 6785 EXPECT_EQ(1, transaction_count()); |
6753 | 6786 |
6754 // Send the request again and check that Resource-Freshness header is added. | 6787 // Send the request again and check that Resource-Freshness header is added. |
6755 stale_while_revalidate_transaction.handler = CheckResourceFreshnessHeader; | 6788 transaction_.handler = CheckResourceFreshnessHeader; |
6756 | 6789 |
6757 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); | 6790 RunFixtureTransactionTest(); |
6758 | 6791 |
6759 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 6792 EXPECT_EQ(2, transaction_count()); |
6760 } | 6793 } |
6761 | 6794 |
6762 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo* request, | 6795 static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo* request, |
6763 std::string* response_status, | 6796 std::string* response_status, |
6764 std::string* response_headers, | 6797 std::string* response_headers, |
6765 std::string* response_data) { | 6798 std::string* response_data) { |
6766 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness")); | 6799 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness")); |
6767 } | 6800 } |
6768 | 6801 |
6769 // Verify that the Resource-Freshness header is not sent when | 6802 // Verify that the Resource-Freshness header is not sent when |
6770 // stale-while-revalidate is 0. | 6803 // stale-while-revalidate is 0. |
6771 TEST(HttpCache, ResourceFreshnessHeaderNotSent) { | 6804 TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderNotSent) { |
6772 MockHttpCache cache; | 6805 age_ = 10801; |
6773 | 6806 stale_while_revalidate_ = 0; |
6774 ScopedMockTransaction stale_while_revalidate_transaction( | 6807 |
6775 kSimpleGET_Transaction); | 6808 // Write to the cache. |
6776 stale_while_revalidate_transaction.response_headers = | 6809 RunFixtureTransactionTest(); |
6777 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n" | 6810 |
6778 "Age: 10801\n" | 6811 EXPECT_EQ(1, transaction_count()); |
6779 "Cache-Control: max-age=3600,stale-while-revalidate=0\n"; | |
6780 | |
6781 // Write to the cache. | |
6782 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); | |
6783 | |
6784 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | |
6785 | 6812 |
6786 // Send the request again and check that Resource-Freshness header is absent. | 6813 // Send the request again and check that Resource-Freshness header is absent. |
6787 stale_while_revalidate_transaction.handler = CheckResourceFreshnessAbsent; | 6814 transaction_.handler = CheckResourceFreshnessAbsent; |
6788 | 6815 |
6789 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction); | 6816 RunFixtureTransactionTest(); |
6790 | 6817 |
6791 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 6818 EXPECT_EQ(2, transaction_count()); |
6792 } | 6819 } |
6820 | |
6821 // Verify that when stale-while-revalidate applies the response is read from | |
6822 // cache. | |
6823 TEST_F(HttpCacheStaleWhileRevalidateTest, ReadFromCache) { | |
6824 // Write to the cache. | |
6825 RunFixtureTransactionTest(); | |
6826 | |
6827 EXPECT_EQ(0, open_count()); | |
6828 EXPECT_EQ(1, transaction_count()); | |
6829 | |
6830 // Read back from the cache. | |
6831 RunFixtureTransactionTest(); | |
6832 | |
6833 EXPECT_EQ(1, open_count()); | |
6834 EXPECT_EQ(1, transaction_count()); | |
6835 | |
6836 // Let the async request complete. | |
6837 RunLoop().RunUntilIdle(); | |
rvargas (doing something else)
2014/09/17 04:32:19
What happens if this line is not here? (being the
Adam Rice
2014/09/30 13:44:50
I was concerned about the callbacks interfering wi
| |
6838 } | |
6839 | |
6840 // Verify that when stale-while-revalidate applies an asynchronous request is | |
6841 // sent. | |
6842 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestSent) { | |
6843 // Write to the cache. | |
6844 RunFixtureTransactionTest(); | |
6845 | |
6846 EXPECT_EQ(1, transaction_count()); | |
6847 | |
6848 // Read back from the cache. | |
6849 RunFixtureTransactionTest(); | |
6850 | |
6851 EXPECT_EQ(1, transaction_count()); | |
6852 | |
6853 // Let the async request execute. | |
6854 RunLoop().RunUntilIdle(); | |
6855 EXPECT_EQ(2, transaction_count()); | |
6856 } | |
6857 | |
6858 // Verify that tearing down the HttpCache with an async revalidation in progress | |
6859 // does not break anything (this test is most likely to find problems when run | |
6860 // with a memory checker such as AddressSanitizer). | |
6861 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncTearDown) { | |
6862 // Write to the cache. | |
6863 RunFixtureTransactionTest(); | |
6864 | |
6865 // Read back from the cache. | |
6866 RunFixtureTransactionTest(); | |
6867 } | |
6868 | |
6869 static void CheckIfModifiedSinceHeader(const net::HttpRequestInfo* request, | |
6870 std::string* response_status, | |
6871 std::string* response_headers, | |
6872 std::string* response_data) { | |
6873 std::string value; | |
6874 EXPECT_TRUE(request->extra_headers.GetHeader("If-Modified-Since", &value)); | |
6875 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value); | |
6876 } | |
6877 | |
6878 // Verify that the async revalidation contains an If-Modified-Since header. | |
6879 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfModifiedSince) { | |
6880 // Write to the cache. | |
6881 RunFixtureTransactionTest(); | |
6882 | |
6883 transaction_.handler = CheckIfModifiedSinceHeader; | |
6884 | |
6885 // Read back from the cache. | |
6886 RunFixtureTransactionTest(); | |
6887 | |
6888 RunLoop().RunUntilIdle(); | |
6889 } | |
6890 | |
6891 static void CheckIfNoneMatchHeader(const net::HttpRequestInfo* request, | |
6892 std::string* response_status, | |
6893 std::string* response_headers, | |
6894 std::string* response_data) { | |
6895 std::string value; | |
6896 EXPECT_TRUE(request->extra_headers.GetHeader("If-None-Match", &value)); | |
6897 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value); | |
6898 } | |
6899 | |
6900 // If the response had ETag rather than Last-Modified, then that is used to | |
6901 // conditionalise the response. | |
6902 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfNoneMatch) { | |
6903 validator_ = "Etag: \"40a1-1320-4f6adefa22a40\""; | |
6904 | |
6905 // Write to the cache. | |
6906 RunFixtureTransactionTest(); | |
6907 | |
6908 transaction_.handler = CheckIfNoneMatchHeader; | |
6909 | |
6910 // Read back from the cache. | |
6911 RunFixtureTransactionTest(); | |
6912 | |
6913 RunLoop().RunUntilIdle(); | |
6914 } | |
6915 | |
6916 static void CheckResourceFreshnessHeaderPresent( | |
6917 const net::HttpRequestInfo* request, | |
6918 std::string* response_status, | |
6919 std::string* response_headers, | |
6920 std::string* response_data) { | |
6921 EXPECT_TRUE(request->extra_headers.HasHeader("Resource-Freshness")); | |
6922 } | |
6923 | |
6924 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestHasResourceFreshness) { | |
6925 // Write to the cache. | |
6926 RunFixtureTransactionTest(); | |
6927 | |
6928 transaction_.handler = CheckResourceFreshnessHeaderPresent; | |
6929 | |
6930 // Read back from the cache. | |
6931 RunFixtureTransactionTest(); | |
6932 | |
6933 RunLoop().RunUntilIdle(); | |
6934 } | |
6935 | |
6936 // Verify that when age > max-age + stale-while-revalidate stale results are | |
6937 // not returned. | |
6938 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedIfTooStale) { | |
6939 age_ = 10801; | |
6940 | |
6941 // Write to the cache. | |
6942 RunFixtureTransactionTest(); | |
6943 | |
6944 EXPECT_EQ(0, open_count()); | |
6945 EXPECT_EQ(1, transaction_count()); | |
6946 | |
6947 // Reading back reads from the network. | |
6948 RunFixtureTransactionTest(); | |
6949 | |
6950 EXPECT_EQ(1, open_count()); | |
6951 EXPECT_EQ(2, transaction_count()); | |
6952 } | |
6953 | |
6954 // HEAD requests should be able to take advantage of stale-while-revalidate. | |
6955 TEST_F(HttpCacheStaleWhileRevalidateTest, WorksForHeadMethod) { | |
6956 // Write to the cache. This has to be a GET request; HEAD requests don't | |
6957 // create new cache entries (as of August 2014). | |
rvargas (doing something else)
2014/09/17 04:32:20
nit: remove the date?
Adam Rice
2014/09/30 13:44:50
Done.
| |
6958 RunFixtureTransactionTest(); | |
6959 | |
6960 EXPECT_EQ(0, open_count()); | |
6961 EXPECT_EQ(1, transaction_count()); | |
6962 | |
6963 // Read back from the cache, and trigger an asynchronous HEAD request. | |
6964 transaction_.method = "HEAD"; | |
6965 transaction_.data = ""; | |
6966 | |
6967 RunFixtureTransactionTest(); | |
6968 | |
6969 EXPECT_EQ(1, open_count()); | |
6970 EXPECT_EQ(1, transaction_count()); | |
6971 | |
6972 // Let the network request proceed. | |
6973 RunLoop().RunUntilIdle(); | |
6974 | |
6975 EXPECT_EQ(2, transaction_count()); | |
6976 } | |
6977 | |
6978 // POST requests should not use stale-while-revalidate. | |
6979 TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedToPost) { | |
6980 transaction_ = ScopedMockTransaction(kSimplePOST_Transaction); | |
6981 | |
6982 // Write to the cache. | |
6983 RunFixtureTransactionTest(); | |
6984 | |
6985 EXPECT_EQ(0, open_count()); | |
6986 EXPECT_EQ(1, transaction_count()); | |
6987 | |
6988 // Reading back reads from the network. | |
6989 RunFixtureTransactionTest(); | |
6990 | |
6991 EXPECT_EQ(0, open_count()); | |
6992 EXPECT_EQ(2, transaction_count()); | |
6993 } | |
6994 | |
6995 // Async revalidation is issued to the original URL. | |
6996 TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestUrlMatches) { | |
6997 net::CapturingBoundNetLog log; | |
6998 net::LoadTimingInfo load_timing_info; | |
6999 | |
7000 // Write to the cache. | |
7001 RunFixtureTransactionTest(); | |
7002 | |
7003 // Read back from the cache. | |
7004 RunTransactionTestAndGetTiming( | |
7005 cache_.http_cache(), transaction_, log.bound(), &load_timing_info); | |
7006 | |
7007 // Let the async request execute. | |
7008 RunLoop().RunUntilIdle(); | |
7009 | |
7010 net::CapturingNetLog::CapturedEntryList entries; | |
rvargas (doing something else)
2014/09/17 04:32:19
using a handler seems better to me (ie, looking at
Adam Rice
2014/09/30 13:44:50
Done.
| |
7011 log.GetEntries(&entries); | |
7012 size_t index = | |
7013 net::ExpectLogContainsSomewhere(entries, | |
7014 0, | |
7015 net::NetLog::TYPE_ASYNC_REVALIDATION, | |
7016 net::NetLog::PHASE_BEGIN); | |
7017 ASSERT_LT(index, entries.size()); | |
7018 std::string url_value; | |
7019 EXPECT_TRUE(entries[index].GetStringValue("url", &url_value)); | |
7020 EXPECT_EQ(transaction_.url, url_value); | |
7021 } | |
7022 | |
7023 class SyncLoadFlagTest : public HttpCacheStaleWhileRevalidateTest, | |
7024 public ::testing::WithParamInterface<int> {}; | |
7025 | |
7026 // Flags which should always cause the request to be synchronous. | |
7027 TEST_P(SyncLoadFlagTest, MustBeSynchronous) { | |
7028 transaction_.load_flags |= GetParam(); | |
7029 // Write to the cache. | |
7030 RunFixtureTransactionTest(); | |
7031 | |
7032 EXPECT_EQ(1, transaction_count()); | |
7033 | |
7034 // Reading back reads from the network. | |
7035 RunFixtureTransactionTest(); | |
7036 | |
7037 EXPECT_EQ(2, transaction_count()); | |
7038 } | |
7039 | |
7040 INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate, | |
7041 SyncLoadFlagTest, | |
7042 ::testing::Values(net::LOAD_VALIDATE_CACHE, | |
7043 net::LOAD_BYPASS_CACHE, | |
7044 net::LOAD_DISABLE_CACHE)); | |
7045 | |
7046 TEST_F(HttpCacheStaleWhileRevalidateTest, | |
7047 PreferringCacheDoesNotTriggerAsyncRequest) { | |
7048 transaction_.load_flags |= net::LOAD_PREFERRING_CACHE; | |
7049 // Write to the cache. | |
7050 RunFixtureTransactionTest(); | |
7051 | |
7052 EXPECT_EQ(1, transaction_count()); | |
7053 | |
7054 // Reading back reads from the cache. | |
7055 RunFixtureTransactionTest(); | |
7056 | |
7057 EXPECT_EQ(1, transaction_count()); | |
7058 | |
7059 // If there was an async transaction created, it would run now. | |
7060 RunLoop().RunUntilIdle(); | |
7061 | |
7062 // There was no async transaction. | |
7063 EXPECT_EQ(1, transaction_count()); | |
7064 } | |
7065 | |
7066 TEST_F(HttpCacheStaleWhileRevalidateTest, NotUsedWhenDisabled) { | |
7067 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(false); | |
7068 // Write to the cache. | |
7069 RunFixtureTransactionTest(); | |
7070 | |
7071 EXPECT_EQ(1, transaction_count()); | |
7072 | |
7073 // A synchronous revalidation is performed. | |
7074 RunFixtureTransactionTest(); | |
7075 | |
7076 EXPECT_EQ(2, transaction_count()); | |
7077 } | |
7078 | |
7079 TEST_F(HttpCacheStaleWhileRevalidateTest, | |
7080 OnlyFromCacheDoesNotTriggerAsyncRequest) { | |
7081 transaction_.load_flags |= net::LOAD_ONLY_FROM_CACHE; | |
7082 transaction_.return_code = net::ERR_CACHE_MISS; | |
7083 | |
7084 // Writing to the cache should fail, because we are avoiding the network. | |
7085 RunFixtureTransactionTest(); | |
7086 | |
7087 EXPECT_EQ(0, transaction_count()); | |
7088 | |
7089 RunLoop().RunUntilIdle(); | |
7090 | |
7091 // Still nothing. | |
7092 EXPECT_EQ(0, transaction_count()); | |
7093 } | |
7094 | |
7095 // A certificate error during an asynchronous fetch should cause the next fetch | |
7096 // to proceed synchronously. | |
7097 TEST_F(HttpCacheStaleWhileRevalidateTest, CertificateErrorCausesRefetch) { | |
rvargas (doing something else)
2014/09/17 04:32:19
hmmm. Is this testing for... an incomplete impleme
Adam Rice
2014/09/30 13:44:50
Yes. I am just verifying the current behaviour. I
| |
7098 // Write to the cache. | |
7099 RunFixtureTransactionTest(); | |
7100 | |
7101 EXPECT_EQ(1, transaction_count()); | |
7102 | |
7103 // Now read back. RunTransactionTestBase() expects to receive the network | |
7104 // error back from the HttpCache::Transaction, but since the cache request | |
7105 // will return OK we need to duplicate some of its implementation here. | |
7106 transaction_.return_code = net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED; | |
7107 net::TestCompletionCallback callback; | |
7108 scoped_ptr<net::HttpTransaction> trans; | |
7109 int rv = | |
7110 cache_.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans); | |
7111 EXPECT_EQ(net::OK, rv); | |
7112 ASSERT_TRUE(trans.get()); | |
7113 | |
7114 MockHttpRequest request(transaction_); | |
7115 rv = trans->Start(&request, callback.callback(), net::BoundNetLog()); | |
7116 ASSERT_EQ(net::ERR_IO_PENDING, rv); | |
7117 ASSERT_EQ(net::OK, callback.WaitForResult()); | |
7118 ReadAndVerifyTransaction(trans.get(), transaction_); | |
7119 | |
7120 EXPECT_EQ(1, transaction_count()); | |
7121 | |
7122 // Allow the asynchronous fetch to run. | |
7123 RunLoop().RunUntilIdle(); | |
7124 | |
7125 EXPECT_EQ(2, transaction_count()); | |
7126 | |
7127 // Now run the transaction again. It should run synchronously. | |
7128 transaction_.return_code = net::OK; | |
7129 RunFixtureTransactionTest(); | |
7130 | |
7131 EXPECT_EQ(3, transaction_count()); | |
7132 } | |
7133 | |
7134 // Ensure that the response cached by the asynchronous request is not truncated, | |
7135 // even if the server is slow. | |
7136 TEST_F(HttpCacheStaleWhileRevalidateTest, EntireResponseCached) { | |
7137 transaction_.test_mode = TEST_MODE_SLOW_READ; | |
7138 // Write to the cache. | |
7139 RunFixtureTransactionTest(); | |
7140 | |
7141 // Read back from the cache. | |
7142 RunFixtureTransactionTest(); | |
7143 | |
7144 // Let the async request execute. | |
7145 RunLoop().RunUntilIdle(); | |
7146 | |
7147 // The cache entry should still be complete. | |
7148 transaction_.load_flags = net::LOAD_ONLY_FROM_CACHE; | |
7149 RunFixtureTransactionTest(); | |
7150 } | |
7151 | |
7152 // Verify that there are no race conditions in the completely synchronous case. | |
7153 TEST_F(HttpCacheStaleWhileRevalidateTest, SynchronousCaseWorks) { | |
7154 transaction_.test_mode = TEST_MODE_SYNC_ALL; | |
7155 // Write to the cache. | |
7156 RunFixtureTransactionTest(); | |
7157 | |
7158 EXPECT_EQ(1, transaction_count()); | |
7159 | |
7160 // Read back from the cache. | |
7161 RunFixtureTransactionTest(); | |
7162 | |
7163 EXPECT_EQ(1, transaction_count()); | |
7164 | |
7165 // Let the async request execute. | |
7166 RunLoop().RunUntilIdle(); | |
7167 EXPECT_EQ(2, transaction_count()); | |
7168 } | |
7169 | |
7170 static void CheckLoadFlagsAsyncRevalidation(const net::HttpRequestInfo* request, | |
7171 std::string* response_status, | |
7172 std::string* response_headers, | |
7173 std::string* response_data) { | |
7174 EXPECT_EQ(net::LOAD_ASYNC_REVALIDATION, request->load_flags); | |
7175 } | |
7176 | |
7177 // Check that the load flags on the async request are the same as the load flags | |
7178 // on the original request, plus LOAD_ASYNC_REVALIDATION. | |
7179 TEST_F(HttpCacheStaleWhileRevalidateTest, LoadFlagsAsyncRevalidation) { | |
7180 transaction_.load_flags = net::LOAD_NORMAL; | |
7181 // Write to the cache. | |
7182 RunFixtureTransactionTest(); | |
7183 | |
7184 EXPECT_EQ(1, transaction_count()); | |
7185 | |
7186 // Read back from the cache. | |
7187 RunFixtureTransactionTest(); | |
7188 | |
7189 EXPECT_EQ(1, transaction_count()); | |
7190 | |
7191 transaction_.handler = CheckLoadFlagsAsyncRevalidation; | |
7192 // Let the async request execute. | |
7193 RunLoop().RunUntilIdle(); | |
7194 EXPECT_EQ(2, transaction_count()); | |
7195 } | |
7196 | |
7197 // Cache-Control: must-revalidate directive should override the | |
7198 // stale-while-revalidate directive and cause a synchronous revalidation. | |
7199 TEST_F(HttpCacheStaleWhileRevalidateTest, MustRevalidateOverrides) { | |
rvargas (doing something else)
2014/09/17 04:32:19
This seems like a test that belongs to response he
Adam Rice
2014/09/30 13:44:50
Yes. Thank you. I have moved it there.
| |
7200 transaction_.response_headers = | |
7201 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT" | |
7202 "Age: 3601\n" | |
7203 "Cache-Control: " | |
7204 "max-age=3600,stale-while-revalidate=3600,must-revalidate\n"; | |
7205 | |
7206 // Write to the cache. This test uses custom response headers, so it cannot | |
7207 // use RunFixtureTransactionTest(). | |
7208 RunTransactionTest(cache_.http_cache(), transaction_); | |
7209 | |
7210 EXPECT_EQ(1, transaction_count()); | |
7211 | |
7212 // A synchronous revalidation is performed. | |
7213 RunTransactionTest(cache_.http_cache(), transaction_); | |
7214 | |
7215 EXPECT_EQ(2, transaction_count()); | |
7216 } | |
OLD | NEW |