xref: /aosp_15_r20/external/cronet/net/http/http_cache_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/http/http_cache.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <algorithm>
10*6777b538SAndroid Build Coastguard Worker #include <memory>
11*6777b538SAndroid Build Coastguard Worker #include <optional>
12*6777b538SAndroid Build Coastguard Worker #include <set>
13*6777b538SAndroid Build Coastguard Worker #include <utility>
14*6777b538SAndroid Build Coastguard Worker #include <vector>
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker #include "base/files/scoped_temp_dir.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/format_macros.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/strings/strcat.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/test/metrics/histogram_tester.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/test/simple_test_clock.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/memory_allocator_dump.h"
33*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/memory_dump_request_args.h"
34*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/process_memory_dump.h"
35*6777b538SAndroid Build Coastguard Worker #include "net/base/cache_type.h"
36*6777b538SAndroid Build Coastguard Worker #include "net/base/completion_repeating_callback.h"
37*6777b538SAndroid Build Coastguard Worker #include "net/base/elements_upload_data_stream.h"
38*6777b538SAndroid Build Coastguard Worker #include "net/base/features.h"
39*6777b538SAndroid Build Coastguard Worker #include "net/base/host_port_pair.h"
40*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_address.h"
41*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_endpoint.h"
42*6777b538SAndroid Build Coastguard Worker #include "net/base/load_flags.h"
43*6777b538SAndroid Build Coastguard Worker #include "net/base/load_timing_info.h"
44*6777b538SAndroid Build Coastguard Worker #include "net/base/load_timing_info_test_util.h"
45*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
46*6777b538SAndroid Build Coastguard Worker #include "net/base/schemeful_site.h"
47*6777b538SAndroid Build Coastguard Worker #include "net/base/tracing.h"
48*6777b538SAndroid Build Coastguard Worker #include "net/base/upload_bytes_element_reader.h"
49*6777b538SAndroid Build Coastguard Worker #include "net/cert/cert_status_flags.h"
50*6777b538SAndroid Build Coastguard Worker #include "net/cert/x509_certificate.h"
51*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/disk_cache.h"
52*6777b538SAndroid Build Coastguard Worker #include "net/http/http_byte_range.h"
53*6777b538SAndroid Build Coastguard Worker #include "net/http/http_cache_transaction.h"
54*6777b538SAndroid Build Coastguard Worker #include "net/http/http_request_headers.h"
55*6777b538SAndroid Build Coastguard Worker #include "net/http/http_request_info.h"
56*6777b538SAndroid Build Coastguard Worker #include "net/http/http_response_headers.h"
57*6777b538SAndroid Build Coastguard Worker #include "net/http/http_response_headers_test_util.h"
58*6777b538SAndroid Build Coastguard Worker #include "net/http/http_response_info.h"
59*6777b538SAndroid Build Coastguard Worker #include "net/http/http_transaction.h"
60*6777b538SAndroid Build Coastguard Worker #include "net/http/http_transaction_test_util.h"
61*6777b538SAndroid Build Coastguard Worker #include "net/http/http_util.h"
62*6777b538SAndroid Build Coastguard Worker #include "net/http/mock_http_cache.h"
63*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_event_type.h"
64*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_source.h"
65*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_with_source.h"
66*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log.h"
67*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log_util.h"
68*6777b538SAndroid Build Coastguard Worker #include "net/socket/client_socket_handle.h"
69*6777b538SAndroid Build Coastguard Worker #include "net/ssl/ssl_cert_request_info.h"
70*6777b538SAndroid Build Coastguard Worker #include "net/ssl/ssl_connection_status_flags.h"
71*6777b538SAndroid Build Coastguard Worker #include "net/test/cert_test_util.h"
72*6777b538SAndroid Build Coastguard Worker #include "net/test/gtest_util.h"
73*6777b538SAndroid Build Coastguard Worker #include "net/test/test_data_directory.h"
74*6777b538SAndroid Build Coastguard Worker #include "net/test/test_with_task_environment.h"
75*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_handshake_stream_base.h"
76*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
77*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
78*6777b538SAndroid Build Coastguard Worker #include "url/origin.h"
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker using net::test::IsError;
81*6777b538SAndroid Build Coastguard Worker using net::test::IsOk;
82*6777b538SAndroid Build Coastguard Worker using testing::AllOf;
83*6777b538SAndroid Build Coastguard Worker using testing::ByRef;
84*6777b538SAndroid Build Coastguard Worker using testing::Contains;
85*6777b538SAndroid Build Coastguard Worker using testing::ElementsAre;
86*6777b538SAndroid Build Coastguard Worker using testing::Eq;
87*6777b538SAndroid Build Coastguard Worker using testing::Field;
88*6777b538SAndroid Build Coastguard Worker using testing::Gt;
89*6777b538SAndroid Build Coastguard Worker using testing::IsEmpty;
90*6777b538SAndroid Build Coastguard Worker using testing::NotNull;
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker using base::Time;
93*6777b538SAndroid Build Coastguard Worker 
94*6777b538SAndroid Build Coastguard Worker namespace net {
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker using CacheEntryStatus = HttpResponseInfo::CacheEntryStatus;
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker class WebSocketEndpointLockManager;
99*6777b538SAndroid Build Coastguard Worker 
100*6777b538SAndroid Build Coastguard Worker namespace {
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker constexpr auto ToSimpleString = test::HttpResponseHeadersToSimpleString;
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker // Tests the load timing values of a request that goes through a
105*6777b538SAndroid Build Coastguard Worker // MockNetworkTransaction.
TestLoadTimingNetworkRequest(const LoadTimingInfo & load_timing_info)106*6777b538SAndroid Build Coastguard Worker void TestLoadTimingNetworkRequest(const LoadTimingInfo& load_timing_info) {
107*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(load_timing_info.socket_reused);
108*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
111*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker   ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
114*6777b538SAndroid Build Coastguard Worker                               CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
115*6777b538SAndroid Build Coastguard Worker   EXPECT_LE(load_timing_info.connect_timing.connect_end,
116*6777b538SAndroid Build Coastguard Worker             load_timing_info.send_start);
117*6777b538SAndroid Build Coastguard Worker 
118*6777b538SAndroid Build Coastguard Worker   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker   // Set by URLRequest / URLRequestHttpJob, at a higher level.
121*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
122*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(load_timing_info.request_start.is_null());
123*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
124*6777b538SAndroid Build Coastguard Worker }
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker // Tests the load timing values of a request that receives a cached response.
TestLoadTimingCachedResponse(const LoadTimingInfo & load_timing_info)127*6777b538SAndroid Build Coastguard Worker void TestLoadTimingCachedResponse(const LoadTimingInfo& load_timing_info) {
128*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(load_timing_info.socket_reused);
129*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
132*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker   ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker   // Only the send start / end times should be sent, and they should have the
137*6777b538SAndroid Build Coastguard Worker   // same value.
138*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(load_timing_info.send_start.is_null());
139*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
140*6777b538SAndroid Build Coastguard Worker 
141*6777b538SAndroid Build Coastguard Worker   // Set by URLRequest / URLRequestHttpJob, at a higher level.
142*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
143*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(load_timing_info.request_start.is_null());
144*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
145*6777b538SAndroid Build Coastguard Worker }
146*6777b538SAndroid Build Coastguard Worker 
DeferCallback(bool * defer)147*6777b538SAndroid Build Coastguard Worker void DeferCallback(bool* defer) {
148*6777b538SAndroid Build Coastguard Worker   *defer = true;
149*6777b538SAndroid Build Coastguard Worker }
150*6777b538SAndroid Build Coastguard Worker 
151*6777b538SAndroid Build Coastguard Worker class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
152*6777b538SAndroid Build Coastguard Worker  public:
DeleteCacheCompletionCallback(std::unique_ptr<MockHttpCache> cache)153*6777b538SAndroid Build Coastguard Worker   explicit DeleteCacheCompletionCallback(std::unique_ptr<MockHttpCache> cache)
154*6777b538SAndroid Build Coastguard Worker       : cache_(std::move(cache)) {}
155*6777b538SAndroid Build Coastguard Worker 
156*6777b538SAndroid Build Coastguard Worker   DeleteCacheCompletionCallback(const DeleteCacheCompletionCallback&) = delete;
157*6777b538SAndroid Build Coastguard Worker   DeleteCacheCompletionCallback& operator=(
158*6777b538SAndroid Build Coastguard Worker       const DeleteCacheCompletionCallback&) = delete;
159*6777b538SAndroid Build Coastguard Worker 
callback()160*6777b538SAndroid Build Coastguard Worker   CompletionOnceCallback callback() {
161*6777b538SAndroid Build Coastguard Worker     return base::BindOnce(&DeleteCacheCompletionCallback::OnComplete,
162*6777b538SAndroid Build Coastguard Worker                           base::Unretained(this));
163*6777b538SAndroid Build Coastguard Worker   }
164*6777b538SAndroid Build Coastguard Worker 
165*6777b538SAndroid Build Coastguard Worker  private:
OnComplete(int result)166*6777b538SAndroid Build Coastguard Worker   void OnComplete(int result) {
167*6777b538SAndroid Build Coastguard Worker     cache_.reset();
168*6777b538SAndroid Build Coastguard Worker     SetResult(result);
169*6777b538SAndroid Build Coastguard Worker   }
170*6777b538SAndroid Build Coastguard Worker 
171*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<MockHttpCache> cache_;
172*6777b538SAndroid Build Coastguard Worker };
173*6777b538SAndroid Build Coastguard Worker 
174*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
175*6777b538SAndroid Build Coastguard Worker // helpers
176*6777b538SAndroid Build Coastguard Worker 
ReadAndVerifyTransaction(HttpTransaction * trans,const MockTransaction & trans_info)177*6777b538SAndroid Build Coastguard Worker void ReadAndVerifyTransaction(HttpTransaction* trans,
178*6777b538SAndroid Build Coastguard Worker                               const MockTransaction& trans_info) {
179*6777b538SAndroid Build Coastguard Worker   std::string content;
180*6777b538SAndroid Build Coastguard Worker   int rv = ReadTransaction(trans, &content);
181*6777b538SAndroid Build Coastguard Worker 
182*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsOk());
183*6777b538SAndroid Build Coastguard Worker   std::string expected(trans_info.data);
184*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected, content);
185*6777b538SAndroid Build Coastguard Worker }
186*6777b538SAndroid Build Coastguard Worker 
ReadRemainingAndVerifyTransaction(HttpTransaction * trans,const std::string & already_read,const MockTransaction & trans_info)187*6777b538SAndroid Build Coastguard Worker void ReadRemainingAndVerifyTransaction(HttpTransaction* trans,
188*6777b538SAndroid Build Coastguard Worker                                        const std::string& already_read,
189*6777b538SAndroid Build Coastguard Worker                                        const MockTransaction& trans_info) {
190*6777b538SAndroid Build Coastguard Worker   std::string content;
191*6777b538SAndroid Build Coastguard Worker   int rv = ReadTransaction(trans, &content);
192*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsOk());
193*6777b538SAndroid Build Coastguard Worker 
194*6777b538SAndroid Build Coastguard Worker   std::string expected(trans_info.data);
195*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected, already_read + content);
196*6777b538SAndroid Build Coastguard Worker }
197*6777b538SAndroid Build Coastguard Worker 
RunTransactionTestBase(HttpCache * cache,const MockTransaction & trans_info,const MockHttpRequest & request,HttpResponseInfo * response_info,const NetLogWithSource & net_log,LoadTimingInfo * load_timing_info,int64_t * sent_bytes,int64_t * received_bytes,IPEndPoint * remote_endpoint)198*6777b538SAndroid Build Coastguard Worker void RunTransactionTestBase(HttpCache* cache,
199*6777b538SAndroid Build Coastguard Worker                             const MockTransaction& trans_info,
200*6777b538SAndroid Build Coastguard Worker                             const MockHttpRequest& request,
201*6777b538SAndroid Build Coastguard Worker                             HttpResponseInfo* response_info,
202*6777b538SAndroid Build Coastguard Worker                             const NetLogWithSource& net_log,
203*6777b538SAndroid Build Coastguard Worker                             LoadTimingInfo* load_timing_info,
204*6777b538SAndroid Build Coastguard Worker                             int64_t* sent_bytes,
205*6777b538SAndroid Build Coastguard Worker                             int64_t* received_bytes,
206*6777b538SAndroid Build Coastguard Worker                             IPEndPoint* remote_endpoint) {
207*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
208*6777b538SAndroid Build Coastguard Worker 
209*6777b538SAndroid Build Coastguard Worker   // write to the cache
210*6777b538SAndroid Build Coastguard Worker 
211*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
212*6777b538SAndroid Build Coastguard Worker   int rv = cache->CreateTransaction(DEFAULT_PRIORITY, &trans);
213*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsOk());
214*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(trans.get());
215*6777b538SAndroid Build Coastguard Worker 
216*6777b538SAndroid Build Coastguard Worker   rv = trans->Start(&request, callback.callback(), net_log);
217*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
218*6777b538SAndroid Build Coastguard Worker     rv = callback.WaitForResult();
219*6777b538SAndroid Build Coastguard Worker   }
220*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(trans_info.start_return_code, rv);
221*6777b538SAndroid Build Coastguard Worker 
222*6777b538SAndroid Build Coastguard Worker   if (OK != rv) {
223*6777b538SAndroid Build Coastguard Worker     return;
224*6777b538SAndroid Build Coastguard Worker   }
225*6777b538SAndroid Build Coastguard Worker 
226*6777b538SAndroid Build Coastguard Worker   const HttpResponseInfo* response = trans->GetResponseInfo();
227*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(response);
228*6777b538SAndroid Build Coastguard Worker 
229*6777b538SAndroid Build Coastguard Worker   if (response_info) {
230*6777b538SAndroid Build Coastguard Worker     *response_info = *response;
231*6777b538SAndroid Build Coastguard Worker   }
232*6777b538SAndroid Build Coastguard Worker 
233*6777b538SAndroid Build Coastguard Worker   if (load_timing_info) {
234*6777b538SAndroid Build Coastguard Worker     // If a fake network connection is used, need a NetLog to get a fake socket
235*6777b538SAndroid Build Coastguard Worker     // ID.
236*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(net_log.net_log());
237*6777b538SAndroid Build Coastguard Worker     *load_timing_info = LoadTimingInfo();
238*6777b538SAndroid Build Coastguard Worker     trans->GetLoadTimingInfo(load_timing_info);
239*6777b538SAndroid Build Coastguard Worker   }
240*6777b538SAndroid Build Coastguard Worker 
241*6777b538SAndroid Build Coastguard Worker   if (remote_endpoint) {
242*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(trans->GetRemoteEndpoint(remote_endpoint));
243*6777b538SAndroid Build Coastguard Worker   }
244*6777b538SAndroid Build Coastguard Worker 
245*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(trans.get(), trans_info);
246*6777b538SAndroid Build Coastguard Worker 
247*6777b538SAndroid Build Coastguard Worker   if (sent_bytes) {
248*6777b538SAndroid Build Coastguard Worker     *sent_bytes = trans->GetTotalSentBytes();
249*6777b538SAndroid Build Coastguard Worker   }
250*6777b538SAndroid Build Coastguard Worker   if (received_bytes) {
251*6777b538SAndroid Build Coastguard Worker     *received_bytes = trans->GetTotalReceivedBytes();
252*6777b538SAndroid Build Coastguard Worker   }
253*6777b538SAndroid Build Coastguard Worker }
254*6777b538SAndroid Build Coastguard Worker 
RunTransactionTestWithRequest(HttpCache * cache,const MockTransaction & trans_info,const MockHttpRequest & request,HttpResponseInfo * response_info)255*6777b538SAndroid Build Coastguard Worker void RunTransactionTestWithRequest(HttpCache* cache,
256*6777b538SAndroid Build Coastguard Worker                                    const MockTransaction& trans_info,
257*6777b538SAndroid Build Coastguard Worker                                    const MockHttpRequest& request,
258*6777b538SAndroid Build Coastguard Worker                                    HttpResponseInfo* response_info) {
259*6777b538SAndroid Build Coastguard Worker   RunTransactionTestBase(cache, trans_info, request, response_info,
260*6777b538SAndroid Build Coastguard Worker                          NetLogWithSource(), nullptr, nullptr, nullptr,
261*6777b538SAndroid Build Coastguard Worker                          nullptr);
262*6777b538SAndroid Build Coastguard Worker }
263*6777b538SAndroid Build Coastguard Worker 
RunTransactionTestAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)264*6777b538SAndroid Build Coastguard Worker void RunTransactionTestAndGetTiming(HttpCache* cache,
265*6777b538SAndroid Build Coastguard Worker                                     const MockTransaction& trans_info,
266*6777b538SAndroid Build Coastguard Worker                                     const NetLogWithSource& log,
267*6777b538SAndroid Build Coastguard Worker                                     LoadTimingInfo* load_timing_info) {
268*6777b538SAndroid Build Coastguard Worker   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
269*6777b538SAndroid Build Coastguard Worker                          nullptr, log, load_timing_info, nullptr, nullptr,
270*6777b538SAndroid Build Coastguard Worker                          nullptr);
271*6777b538SAndroid Build Coastguard Worker }
272*6777b538SAndroid Build Coastguard Worker 
RunTransactionTestAndGetTimingAndConnectedSocketAddress(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log,LoadTimingInfo * load_timing_info,IPEndPoint * remote_endpoint)273*6777b538SAndroid Build Coastguard Worker void RunTransactionTestAndGetTimingAndConnectedSocketAddress(
274*6777b538SAndroid Build Coastguard Worker     HttpCache* cache,
275*6777b538SAndroid Build Coastguard Worker     const MockTransaction& trans_info,
276*6777b538SAndroid Build Coastguard Worker     const NetLogWithSource& log,
277*6777b538SAndroid Build Coastguard Worker     LoadTimingInfo* load_timing_info,
278*6777b538SAndroid Build Coastguard Worker     IPEndPoint* remote_endpoint) {
279*6777b538SAndroid Build Coastguard Worker   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
280*6777b538SAndroid Build Coastguard Worker                          nullptr, log, load_timing_info, nullptr, nullptr,
281*6777b538SAndroid Build Coastguard Worker                          remote_endpoint);
282*6777b538SAndroid Build Coastguard Worker }
283*6777b538SAndroid Build Coastguard Worker 
RunTransactionTest(HttpCache * cache,const MockTransaction & trans_info)284*6777b538SAndroid Build Coastguard Worker void RunTransactionTest(HttpCache* cache, const MockTransaction& trans_info) {
285*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache, trans_info, NetLogWithSource(),
286*6777b538SAndroid Build Coastguard Worker                                  nullptr);
287*6777b538SAndroid Build Coastguard Worker }
288*6777b538SAndroid Build Coastguard Worker 
RunTransactionTestWithLog(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log)289*6777b538SAndroid Build Coastguard Worker void RunTransactionTestWithLog(HttpCache* cache,
290*6777b538SAndroid Build Coastguard Worker                                const MockTransaction& trans_info,
291*6777b538SAndroid Build Coastguard Worker                                const NetLogWithSource& log) {
292*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache, trans_info, log, nullptr);
293*6777b538SAndroid Build Coastguard Worker }
294*6777b538SAndroid Build Coastguard Worker 
RunTransactionTestWithResponseInfo(HttpCache * cache,const MockTransaction & trans_info,HttpResponseInfo * response)295*6777b538SAndroid Build Coastguard Worker void RunTransactionTestWithResponseInfo(HttpCache* cache,
296*6777b538SAndroid Build Coastguard Worker                                         const MockTransaction& trans_info,
297*6777b538SAndroid Build Coastguard Worker                                         HttpResponseInfo* response) {
298*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache, trans_info, MockHttpRequest(trans_info),
299*6777b538SAndroid Build Coastguard Worker                                 response);
300*6777b538SAndroid Build Coastguard Worker }
301*6777b538SAndroid Build Coastguard Worker 
RunTransactionTestWithResponseInfoAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,HttpResponseInfo * response,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)302*6777b538SAndroid Build Coastguard Worker void RunTransactionTestWithResponseInfoAndGetTiming(
303*6777b538SAndroid Build Coastguard Worker     HttpCache* cache,
304*6777b538SAndroid Build Coastguard Worker     const MockTransaction& trans_info,
305*6777b538SAndroid Build Coastguard Worker     HttpResponseInfo* response,
306*6777b538SAndroid Build Coastguard Worker     const NetLogWithSource& log,
307*6777b538SAndroid Build Coastguard Worker     LoadTimingInfo* load_timing_info) {
308*6777b538SAndroid Build Coastguard Worker   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
309*6777b538SAndroid Build Coastguard Worker                          response, log, load_timing_info, nullptr, nullptr,
310*6777b538SAndroid Build Coastguard Worker                          nullptr);
311*6777b538SAndroid Build Coastguard Worker }
312*6777b538SAndroid Build Coastguard Worker 
RunTransactionTestWithResponse(HttpCache * cache,const MockTransaction & trans_info,std::string * response_headers)313*6777b538SAndroid Build Coastguard Worker void RunTransactionTestWithResponse(HttpCache* cache,
314*6777b538SAndroid Build Coastguard Worker                                     const MockTransaction& trans_info,
315*6777b538SAndroid Build Coastguard Worker                                     std::string* response_headers) {
316*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
317*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache, trans_info, &response);
318*6777b538SAndroid Build Coastguard Worker   *response_headers = ToSimpleString(response.headers);
319*6777b538SAndroid Build Coastguard Worker }
320*6777b538SAndroid Build Coastguard Worker 
RunTransactionTestWithResponseAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,std::string * response_headers,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)321*6777b538SAndroid Build Coastguard Worker void RunTransactionTestWithResponseAndGetTiming(
322*6777b538SAndroid Build Coastguard Worker     HttpCache* cache,
323*6777b538SAndroid Build Coastguard Worker     const MockTransaction& trans_info,
324*6777b538SAndroid Build Coastguard Worker     std::string* response_headers,
325*6777b538SAndroid Build Coastguard Worker     const NetLogWithSource& log,
326*6777b538SAndroid Build Coastguard Worker     LoadTimingInfo* load_timing_info) {
327*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
328*6777b538SAndroid Build Coastguard Worker   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
329*6777b538SAndroid Build Coastguard Worker                          &response, log, load_timing_info, nullptr, nullptr,
330*6777b538SAndroid Build Coastguard Worker                          nullptr);
331*6777b538SAndroid Build Coastguard Worker   *response_headers = ToSimpleString(response.headers);
332*6777b538SAndroid Build Coastguard Worker }
333*6777b538SAndroid Build Coastguard Worker 
334*6777b538SAndroid Build Coastguard Worker // This class provides a handler for kFastNoStoreGET_Transaction so that the
335*6777b538SAndroid Build Coastguard Worker // no-store header can be included on demand.
336*6777b538SAndroid Build Coastguard Worker class FastTransactionServer {
337*6777b538SAndroid Build Coastguard Worker  public:
FastTransactionServer()338*6777b538SAndroid Build Coastguard Worker   FastTransactionServer() { no_store = false; }
339*6777b538SAndroid Build Coastguard Worker 
340*6777b538SAndroid Build Coastguard Worker   FastTransactionServer(const FastTransactionServer&) = delete;
341*6777b538SAndroid Build Coastguard Worker   FastTransactionServer& operator=(const FastTransactionServer&) = delete;
342*6777b538SAndroid Build Coastguard Worker 
343*6777b538SAndroid Build Coastguard Worker   ~FastTransactionServer() = default;
344*6777b538SAndroid Build Coastguard Worker 
set_no_store(bool value)345*6777b538SAndroid Build Coastguard Worker   void set_no_store(bool value) { no_store = value; }
346*6777b538SAndroid Build Coastguard Worker 
FastNoStoreHandler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)347*6777b538SAndroid Build Coastguard Worker   static void FastNoStoreHandler(const HttpRequestInfo* request,
348*6777b538SAndroid Build Coastguard Worker                                  std::string* response_status,
349*6777b538SAndroid Build Coastguard Worker                                  std::string* response_headers,
350*6777b538SAndroid Build Coastguard Worker                                  std::string* response_data) {
351*6777b538SAndroid Build Coastguard Worker     if (no_store) {
352*6777b538SAndroid Build Coastguard Worker       *response_headers = "Cache-Control: no-store\n";
353*6777b538SAndroid Build Coastguard Worker     }
354*6777b538SAndroid Build Coastguard Worker   }
355*6777b538SAndroid Build Coastguard Worker 
356*6777b538SAndroid Build Coastguard Worker  private:
357*6777b538SAndroid Build Coastguard Worker   static bool no_store;
358*6777b538SAndroid Build Coastguard Worker };
359*6777b538SAndroid Build Coastguard Worker bool FastTransactionServer::no_store;
360*6777b538SAndroid Build Coastguard Worker 
361*6777b538SAndroid Build Coastguard Worker const MockTransaction kFastNoStoreGET_Transaction = {
362*6777b538SAndroid Build Coastguard Worker     "http://www.google.com/nostore",
363*6777b538SAndroid Build Coastguard Worker     "GET",
364*6777b538SAndroid Build Coastguard Worker     base::Time(),
365*6777b538SAndroid Build Coastguard Worker     "",
366*6777b538SAndroid Build Coastguard Worker     LOAD_VALIDATE_CACHE,
367*6777b538SAndroid Build Coastguard Worker     DefaultTransportInfo(),
368*6777b538SAndroid Build Coastguard Worker     "HTTP/1.1 200 OK",
369*6777b538SAndroid Build Coastguard Worker     "Cache-Control: max-age=10000\n",
370*6777b538SAndroid Build Coastguard Worker     base::Time(),
371*6777b538SAndroid Build Coastguard Worker     "<html><body>Google Blah Blah</body></html>",
372*6777b538SAndroid Build Coastguard Worker     {},
373*6777b538SAndroid Build Coastguard Worker     std::nullopt,
374*6777b538SAndroid Build Coastguard Worker     std::nullopt,
375*6777b538SAndroid Build Coastguard Worker     TEST_MODE_SYNC_NET_START,
376*6777b538SAndroid Build Coastguard Worker     base::BindRepeating(&FastTransactionServer::FastNoStoreHandler),
377*6777b538SAndroid Build Coastguard Worker     MockTransactionReadHandler(),
378*6777b538SAndroid Build Coastguard Worker     nullptr,
379*6777b538SAndroid Build Coastguard Worker     0,
380*6777b538SAndroid Build Coastguard Worker     0,
381*6777b538SAndroid Build Coastguard Worker     OK,
382*6777b538SAndroid Build Coastguard Worker };
383*6777b538SAndroid Build Coastguard Worker 
384*6777b538SAndroid Build Coastguard Worker // This class provides a handler for kRangeGET_TransactionOK so that the range
385*6777b538SAndroid Build Coastguard Worker // request can be served on demand.
386*6777b538SAndroid Build Coastguard Worker class RangeTransactionServer {
387*6777b538SAndroid Build Coastguard Worker  public:
RangeTransactionServer()388*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer() {
389*6777b538SAndroid Build Coastguard Worker     not_modified_ = false;
390*6777b538SAndroid Build Coastguard Worker     modified_ = false;
391*6777b538SAndroid Build Coastguard Worker     bad_200_ = false;
392*6777b538SAndroid Build Coastguard Worker     redirect_ = false;
393*6777b538SAndroid Build Coastguard Worker     length_ = 80;
394*6777b538SAndroid Build Coastguard Worker   }
395*6777b538SAndroid Build Coastguard Worker 
396*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer(const RangeTransactionServer&) = delete;
397*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer& operator=(const RangeTransactionServer&) = delete;
398*6777b538SAndroid Build Coastguard Worker 
~RangeTransactionServer()399*6777b538SAndroid Build Coastguard Worker   ~RangeTransactionServer() {
400*6777b538SAndroid Build Coastguard Worker     not_modified_ = false;
401*6777b538SAndroid Build Coastguard Worker     modified_ = false;
402*6777b538SAndroid Build Coastguard Worker     bad_200_ = false;
403*6777b538SAndroid Build Coastguard Worker     redirect_ = false;
404*6777b538SAndroid Build Coastguard Worker     length_ = 80;
405*6777b538SAndroid Build Coastguard Worker   }
406*6777b538SAndroid Build Coastguard Worker 
407*6777b538SAndroid Build Coastguard Worker   // Returns only 416 or 304 when set.
set_not_modified(bool value)408*6777b538SAndroid Build Coastguard Worker   void set_not_modified(bool value) { not_modified_ = value; }
409*6777b538SAndroid Build Coastguard Worker 
410*6777b538SAndroid Build Coastguard Worker   // Returns 206 when revalidating a range (instead of 304).
set_modified(bool value)411*6777b538SAndroid Build Coastguard Worker   void set_modified(bool value) { modified_ = value; }
412*6777b538SAndroid Build Coastguard Worker 
413*6777b538SAndroid Build Coastguard Worker   // Returns 200 instead of 206 (a malformed response overall).
set_bad_200(bool value)414*6777b538SAndroid Build Coastguard Worker   void set_bad_200(bool value) { bad_200_ = value; }
415*6777b538SAndroid Build Coastguard Worker 
416*6777b538SAndroid Build Coastguard Worker   // Sets how long the resource is. (Default is 80)
set_length(int64_t length)417*6777b538SAndroid Build Coastguard Worker   void set_length(int64_t length) { length_ = length; }
418*6777b538SAndroid Build Coastguard Worker 
419*6777b538SAndroid Build Coastguard Worker   // Sets whether to return a 301 instead of normal return.
set_redirect(bool redirect)420*6777b538SAndroid Build Coastguard Worker   void set_redirect(bool redirect) { redirect_ = redirect; }
421*6777b538SAndroid Build Coastguard Worker 
422*6777b538SAndroid Build Coastguard Worker   // Other than regular range related behavior (and the flags mentioned above),
423*6777b538SAndroid Build Coastguard Worker   // the server reacts to requests headers like so:
424*6777b538SAndroid Build Coastguard Worker   //   X-Require-Mock-Auth -> return 401.
425*6777b538SAndroid Build Coastguard Worker   //   X-Require-Mock-Auth-Alt -> return 401.
426*6777b538SAndroid Build Coastguard Worker   //   X-Return-Default-Range -> assume 40-49 was requested.
427*6777b538SAndroid Build Coastguard Worker   // The -Alt variant doesn't cause the MockNetworkTransaction to
428*6777b538SAndroid Build Coastguard Worker   // report that it IsReadyToRestartForAuth().
429*6777b538SAndroid Build Coastguard Worker   static void RangeHandler(const HttpRequestInfo* request,
430*6777b538SAndroid Build Coastguard Worker                            std::string* response_status,
431*6777b538SAndroid Build Coastguard Worker                            std::string* response_headers,
432*6777b538SAndroid Build Coastguard Worker                            std::string* response_data);
433*6777b538SAndroid Build Coastguard Worker 
434*6777b538SAndroid Build Coastguard Worker  private:
435*6777b538SAndroid Build Coastguard Worker   static bool not_modified_;
436*6777b538SAndroid Build Coastguard Worker   static bool modified_;
437*6777b538SAndroid Build Coastguard Worker   static bool bad_200_;
438*6777b538SAndroid Build Coastguard Worker   static bool redirect_;
439*6777b538SAndroid Build Coastguard Worker   static int64_t length_;
440*6777b538SAndroid Build Coastguard Worker };
441*6777b538SAndroid Build Coastguard Worker bool RangeTransactionServer::not_modified_ = false;
442*6777b538SAndroid Build Coastguard Worker bool RangeTransactionServer::modified_ = false;
443*6777b538SAndroid Build Coastguard Worker bool RangeTransactionServer::bad_200_ = false;
444*6777b538SAndroid Build Coastguard Worker bool RangeTransactionServer::redirect_ = false;
445*6777b538SAndroid Build Coastguard Worker int64_t RangeTransactionServer::length_ = 80;
446*6777b538SAndroid Build Coastguard Worker 
447*6777b538SAndroid Build Coastguard Worker // A dummy extra header that must be preserved on a given request.
448*6777b538SAndroid Build Coastguard Worker 
449*6777b538SAndroid Build Coastguard Worker // EXTRA_HEADER_LINE doesn't include a line terminator because it
450*6777b538SAndroid Build Coastguard Worker // will be passed to AddHeaderFromString() which doesn't accept them.
451*6777b538SAndroid Build Coastguard Worker #define EXTRA_HEADER_LINE "Extra: header"
452*6777b538SAndroid Build Coastguard Worker 
453*6777b538SAndroid Build Coastguard Worker // EXTRA_HEADER contains a line terminator, as expected by
454*6777b538SAndroid Build Coastguard Worker // AddHeadersFromString() (_not_ AddHeaderFromString()).
455*6777b538SAndroid Build Coastguard Worker #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
456*6777b538SAndroid Build Coastguard Worker 
457*6777b538SAndroid Build Coastguard Worker static const char kExtraHeaderKey[] = "Extra";
458*6777b538SAndroid Build Coastguard Worker 
459*6777b538SAndroid Build Coastguard Worker // Static.
RangeHandler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)460*6777b538SAndroid Build Coastguard Worker void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request,
461*6777b538SAndroid Build Coastguard Worker                                           std::string* response_status,
462*6777b538SAndroid Build Coastguard Worker                                           std::string* response_headers,
463*6777b538SAndroid Build Coastguard Worker                                           std::string* response_data) {
464*6777b538SAndroid Build Coastguard Worker   if (request->extra_headers.IsEmpty()) {
465*6777b538SAndroid Build Coastguard Worker     response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
466*6777b538SAndroid Build Coastguard Worker     response_data->clear();
467*6777b538SAndroid Build Coastguard Worker     return;
468*6777b538SAndroid Build Coastguard Worker   }
469*6777b538SAndroid Build Coastguard Worker 
470*6777b538SAndroid Build Coastguard Worker   // We want to make sure we don't delete extra headers.
471*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
472*6777b538SAndroid Build Coastguard Worker 
473*6777b538SAndroid Build Coastguard Worker   bool require_auth =
474*6777b538SAndroid Build Coastguard Worker       request->extra_headers.HasHeader("X-Require-Mock-Auth") ||
475*6777b538SAndroid Build Coastguard Worker       request->extra_headers.HasHeader("X-Require-Mock-Auth-Alt");
476*6777b538SAndroid Build Coastguard Worker 
477*6777b538SAndroid Build Coastguard Worker   if (require_auth && !request->extra_headers.HasHeader("Authorization")) {
478*6777b538SAndroid Build Coastguard Worker     response_status->assign("HTTP/1.1 401 Unauthorized");
479*6777b538SAndroid Build Coastguard Worker     response_data->assign("WWW-Authenticate: Foo\n");
480*6777b538SAndroid Build Coastguard Worker     return;
481*6777b538SAndroid Build Coastguard Worker   }
482*6777b538SAndroid Build Coastguard Worker 
483*6777b538SAndroid Build Coastguard Worker   if (redirect_) {
484*6777b538SAndroid Build Coastguard Worker     response_status->assign("HTTP/1.1 301 Moved Permanently");
485*6777b538SAndroid Build Coastguard Worker     response_headers->assign("Location: /elsewhere\nContent-Length: 5");
486*6777b538SAndroid Build Coastguard Worker     response_data->assign("12345");
487*6777b538SAndroid Build Coastguard Worker     return;
488*6777b538SAndroid Build Coastguard Worker   }
489*6777b538SAndroid Build Coastguard Worker 
490*6777b538SAndroid Build Coastguard Worker   if (not_modified_) {
491*6777b538SAndroid Build Coastguard Worker     response_status->assign("HTTP/1.1 304 Not Modified");
492*6777b538SAndroid Build Coastguard Worker     response_data->clear();
493*6777b538SAndroid Build Coastguard Worker     return;
494*6777b538SAndroid Build Coastguard Worker   }
495*6777b538SAndroid Build Coastguard Worker 
496*6777b538SAndroid Build Coastguard Worker   std::vector<HttpByteRange> ranges;
497*6777b538SAndroid Build Coastguard Worker   std::string range_header;
498*6777b538SAndroid Build Coastguard Worker   if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange,
499*6777b538SAndroid Build Coastguard Worker                                         &range_header) ||
500*6777b538SAndroid Build Coastguard Worker       !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
501*6777b538SAndroid Build Coastguard Worker       ranges.size() != 1 ||
502*6777b538SAndroid Build Coastguard Worker       (modified_ && request->extra_headers.HasHeader("If-Range"))) {
503*6777b538SAndroid Build Coastguard Worker     // This is not a byte range request, or a failed If-Range. We return 200.
504*6777b538SAndroid Build Coastguard Worker     response_status->assign("HTTP/1.1 200 OK");
505*6777b538SAndroid Build Coastguard Worker     response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
506*6777b538SAndroid Build Coastguard Worker     response_data->assign("Not a range");
507*6777b538SAndroid Build Coastguard Worker     return;
508*6777b538SAndroid Build Coastguard Worker   }
509*6777b538SAndroid Build Coastguard Worker 
510*6777b538SAndroid Build Coastguard Worker   // We can handle this range request.
511*6777b538SAndroid Build Coastguard Worker   HttpByteRange byte_range = ranges[0];
512*6777b538SAndroid Build Coastguard Worker 
513*6777b538SAndroid Build Coastguard Worker   if (request->extra_headers.HasHeader("X-Return-Default-Range")) {
514*6777b538SAndroid Build Coastguard Worker     byte_range.set_first_byte_position(40);
515*6777b538SAndroid Build Coastguard Worker     byte_range.set_last_byte_position(49);
516*6777b538SAndroid Build Coastguard Worker   }
517*6777b538SAndroid Build Coastguard Worker 
518*6777b538SAndroid Build Coastguard Worker   if (byte_range.first_byte_position() >= length_) {
519*6777b538SAndroid Build Coastguard Worker     response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
520*6777b538SAndroid Build Coastguard Worker     response_data->clear();
521*6777b538SAndroid Build Coastguard Worker     return;
522*6777b538SAndroid Build Coastguard Worker   }
523*6777b538SAndroid Build Coastguard Worker 
524*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(byte_range.ComputeBounds(length_));
525*6777b538SAndroid Build Coastguard Worker   int64_t start = byte_range.first_byte_position();
526*6777b538SAndroid Build Coastguard Worker   int64_t end = byte_range.last_byte_position();
527*6777b538SAndroid Build Coastguard Worker 
528*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(end, length_);
529*6777b538SAndroid Build Coastguard Worker 
530*6777b538SAndroid Build Coastguard Worker   std::string content_range = base::StringPrintf("Content-Range: bytes %" PRId64
531*6777b538SAndroid Build Coastguard Worker                                                  "-%" PRId64 "/%" PRId64 "\n",
532*6777b538SAndroid Build Coastguard Worker                                                  start, end, length_);
533*6777b538SAndroid Build Coastguard Worker   response_headers->append(content_range);
534*6777b538SAndroid Build Coastguard Worker 
535*6777b538SAndroid Build Coastguard Worker   if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
536*6777b538SAndroid Build Coastguard Worker     std::string data;
537*6777b538SAndroid Build Coastguard Worker     if (end == start) {
538*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(0, end % 10);
539*6777b538SAndroid Build Coastguard Worker       data = "r";
540*6777b538SAndroid Build Coastguard Worker     } else {
541*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(9, (end - start) % 10);
542*6777b538SAndroid Build Coastguard Worker       for (int64_t block_start = start; block_start < end; block_start += 10) {
543*6777b538SAndroid Build Coastguard Worker         base::StringAppendF(&data, "rg: %02" PRId64 "-%02" PRId64 " ",
544*6777b538SAndroid Build Coastguard Worker                             block_start % 100, (block_start + 9) % 100);
545*6777b538SAndroid Build Coastguard Worker       }
546*6777b538SAndroid Build Coastguard Worker     }
547*6777b538SAndroid Build Coastguard Worker     *response_data = data;
548*6777b538SAndroid Build Coastguard Worker 
549*6777b538SAndroid Build Coastguard Worker     if (end - start != 9) {
550*6777b538SAndroid Build Coastguard Worker       // We also have to fix content-length.
551*6777b538SAndroid Build Coastguard Worker       int64_t len = end - start + 1;
552*6777b538SAndroid Build Coastguard Worker       std::string content_length =
553*6777b538SAndroid Build Coastguard Worker           base::StringPrintf("Content-Length: %" PRId64 "\n", len);
554*6777b538SAndroid Build Coastguard Worker       response_headers->replace(response_headers->find("Content-Length:"),
555*6777b538SAndroid Build Coastguard Worker                                 content_length.size(), content_length);
556*6777b538SAndroid Build Coastguard Worker     }
557*6777b538SAndroid Build Coastguard Worker   } else {
558*6777b538SAndroid Build Coastguard Worker     response_status->assign("HTTP/1.1 304 Not Modified");
559*6777b538SAndroid Build Coastguard Worker     response_data->clear();
560*6777b538SAndroid Build Coastguard Worker   }
561*6777b538SAndroid Build Coastguard Worker }
562*6777b538SAndroid Build Coastguard Worker 
563*6777b538SAndroid Build Coastguard Worker const MockTransaction kRangeGET_TransactionOK = {
564*6777b538SAndroid Build Coastguard Worker     "http://www.google.com/range",
565*6777b538SAndroid Build Coastguard Worker     "GET",
566*6777b538SAndroid Build Coastguard Worker     base::Time(),
567*6777b538SAndroid Build Coastguard Worker     "Range: bytes = 40-49\r\n" EXTRA_HEADER,
568*6777b538SAndroid Build Coastguard Worker     LOAD_NORMAL,
569*6777b538SAndroid Build Coastguard Worker     DefaultTransportInfo(),
570*6777b538SAndroid Build Coastguard Worker     "HTTP/1.1 206 Partial Content",
571*6777b538SAndroid Build Coastguard Worker     "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
572*6777b538SAndroid Build Coastguard Worker     "ETag: \"foo\"\n"
573*6777b538SAndroid Build Coastguard Worker     "Accept-Ranges: bytes\n"
574*6777b538SAndroid Build Coastguard Worker     "Content-Length: 10\n",
575*6777b538SAndroid Build Coastguard Worker     base::Time(),
576*6777b538SAndroid Build Coastguard Worker     "rg: 40-49 ",
577*6777b538SAndroid Build Coastguard Worker     {},
578*6777b538SAndroid Build Coastguard Worker     std::nullopt,
579*6777b538SAndroid Build Coastguard Worker     std::nullopt,
580*6777b538SAndroid Build Coastguard Worker     TEST_MODE_NORMAL,
581*6777b538SAndroid Build Coastguard Worker     base::BindRepeating(&RangeTransactionServer::RangeHandler),
582*6777b538SAndroid Build Coastguard Worker     MockTransactionReadHandler(),
583*6777b538SAndroid Build Coastguard Worker     nullptr,
584*6777b538SAndroid Build Coastguard Worker     0,
585*6777b538SAndroid Build Coastguard Worker     0,
586*6777b538SAndroid Build Coastguard Worker     OK,
587*6777b538SAndroid Build Coastguard Worker };
588*6777b538SAndroid Build Coastguard Worker 
589*6777b538SAndroid Build Coastguard Worker const char kFullRangeData[] =
590*6777b538SAndroid Build Coastguard Worker     "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
591*6777b538SAndroid Build Coastguard Worker     "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
592*6777b538SAndroid Build Coastguard Worker 
593*6777b538SAndroid Build Coastguard Worker // Verifies the response headers (|response|) match a partial content
594*6777b538SAndroid Build Coastguard Worker // response for the range starting at |start| and ending at |end|.
Verify206Response(const std::string & response,int start,int end)595*6777b538SAndroid Build Coastguard Worker void Verify206Response(const std::string& response, int start, int end) {
596*6777b538SAndroid Build Coastguard Worker   auto headers = base::MakeRefCounted<HttpResponseHeaders>(
597*6777b538SAndroid Build Coastguard Worker       HttpUtil::AssembleRawHeaders(response));
598*6777b538SAndroid Build Coastguard Worker 
599*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(206, headers->response_code());
600*6777b538SAndroid Build Coastguard Worker 
601*6777b538SAndroid Build Coastguard Worker   int64_t range_start, range_end, object_size;
602*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(
603*6777b538SAndroid Build Coastguard Worker       headers->GetContentRangeFor206(&range_start, &range_end, &object_size));
604*6777b538SAndroid Build Coastguard Worker   int64_t content_length = headers->GetContentLength();
605*6777b538SAndroid Build Coastguard Worker 
606*6777b538SAndroid Build Coastguard Worker   int length = end - start + 1;
607*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(length, content_length);
608*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(start, range_start);
609*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(end, range_end);
610*6777b538SAndroid Build Coastguard Worker }
611*6777b538SAndroid Build Coastguard Worker 
612*6777b538SAndroid Build Coastguard Worker // Creates a truncated entry that can be resumed using byte ranges.
CreateTruncatedEntry(std::string raw_headers,MockHttpCache * cache)613*6777b538SAndroid Build Coastguard Worker void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
614*6777b538SAndroid Build Coastguard Worker   // Create a disk cache entry that stores an incomplete resource.
615*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
616*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kRangeGET_TransactionOK);
617*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache->CreateBackendEntry(request.CacheKey(), &entry, nullptr));
618*6777b538SAndroid Build Coastguard Worker 
619*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
620*6777b538SAndroid Build Coastguard Worker   response.response_time = base::Time::Now();
621*6777b538SAndroid Build Coastguard Worker   response.request_time = base::Time::Now();
622*6777b538SAndroid Build Coastguard Worker   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
623*6777b538SAndroid Build Coastguard Worker       HttpUtil::AssembleRawHeaders(raw_headers));
624*6777b538SAndroid Build Coastguard Worker   // Set the last argument for this to be an incomplete request.
625*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
626*6777b538SAndroid Build Coastguard Worker 
627*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<IOBufferWithSize>(100);
628*6777b538SAndroid Build Coastguard Worker   int len =
629*6777b538SAndroid Build Coastguard Worker       static_cast<int>(base::strlcpy(buf->data(), "rg: 00-09 rg: 10-19 ", 100));
630*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback cb;
631*6777b538SAndroid Build Coastguard Worker   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
632*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(len, cb.GetResult(rv));
633*6777b538SAndroid Build Coastguard Worker   entry->Close();
634*6777b538SAndroid Build Coastguard Worker }
635*6777b538SAndroid Build Coastguard Worker 
636*6777b538SAndroid Build Coastguard Worker // Verifies that there's an entry with this |key| with the truncated flag set to
637*6777b538SAndroid Build Coastguard Worker // |flag_value|, and with an optional |data_size| (if not zero).
VerifyTruncatedFlag(MockHttpCache * cache,const std::string & key,bool flag_value,int data_size)638*6777b538SAndroid Build Coastguard Worker void VerifyTruncatedFlag(MockHttpCache* cache,
639*6777b538SAndroid Build Coastguard Worker                          const std::string& key,
640*6777b538SAndroid Build Coastguard Worker                          bool flag_value,
641*6777b538SAndroid Build Coastguard Worker                          int data_size) {
642*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
643*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache->OpenBackendEntry(key, &entry));
644*6777b538SAndroid Build Coastguard Worker   disk_cache::ScopedEntryPtr closer(entry);
645*6777b538SAndroid Build Coastguard Worker 
646*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
647*6777b538SAndroid Build Coastguard Worker   bool truncated = !flag_value;
648*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
649*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(flag_value, truncated);
650*6777b538SAndroid Build Coastguard Worker   if (data_size) {
651*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(data_size, entry->GetDataSize(1));
652*6777b538SAndroid Build Coastguard Worker   }
653*6777b538SAndroid Build Coastguard Worker }
654*6777b538SAndroid Build Coastguard Worker 
655*6777b538SAndroid Build Coastguard Worker // Helper to represent a network HTTP response.
656*6777b538SAndroid Build Coastguard Worker struct Response {
657*6777b538SAndroid Build Coastguard Worker   // Set this response into |trans|.
AssignTonet::__anone6acdaec0111::Response658*6777b538SAndroid Build Coastguard Worker   void AssignTo(MockTransaction* trans) const {
659*6777b538SAndroid Build Coastguard Worker     trans->status = status;
660*6777b538SAndroid Build Coastguard Worker     trans->response_headers = headers;
661*6777b538SAndroid Build Coastguard Worker     trans->data = body;
662*6777b538SAndroid Build Coastguard Worker   }
663*6777b538SAndroid Build Coastguard Worker 
status_and_headersnet::__anone6acdaec0111::Response664*6777b538SAndroid Build Coastguard Worker   std::string status_and_headers() const {
665*6777b538SAndroid Build Coastguard Worker     return std::string(status) + "\n" + std::string(headers);
666*6777b538SAndroid Build Coastguard Worker   }
667*6777b538SAndroid Build Coastguard Worker 
668*6777b538SAndroid Build Coastguard Worker   const char* status;
669*6777b538SAndroid Build Coastguard Worker   const char* headers;
670*6777b538SAndroid Build Coastguard Worker   const char* body;
671*6777b538SAndroid Build Coastguard Worker };
672*6777b538SAndroid Build Coastguard Worker 
673*6777b538SAndroid Build Coastguard Worker struct Context {
674*6777b538SAndroid Build Coastguard Worker   Context() = default;
675*6777b538SAndroid Build Coastguard Worker 
676*6777b538SAndroid Build Coastguard Worker   int result = ERR_IO_PENDING;
677*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
678*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
679*6777b538SAndroid Build Coastguard Worker };
680*6777b538SAndroid Build Coastguard Worker 
681*6777b538SAndroid Build Coastguard Worker class FakeWebSocketHandshakeStreamCreateHelper
682*6777b538SAndroid Build Coastguard Worker     : public WebSocketHandshakeStreamBase::CreateHelper {
683*6777b538SAndroid Build Coastguard Worker  public:
684*6777b538SAndroid Build Coastguard Worker   ~FakeWebSocketHandshakeStreamCreateHelper() override = default;
CreateBasicStream(std::unique_ptr<ClientSocketHandle> connect,bool using_proxy,WebSocketEndpointLockManager * websocket_endpoint_lock_manager)685*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
686*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<ClientSocketHandle> connect,
687*6777b538SAndroid Build Coastguard Worker       bool using_proxy,
688*6777b538SAndroid Build Coastguard Worker       WebSocketEndpointLockManager* websocket_endpoint_lock_manager) override {
689*6777b538SAndroid Build Coastguard Worker     return nullptr;
690*6777b538SAndroid Build Coastguard Worker   }
CreateHttp2Stream(base::WeakPtr<SpdySession> session,std::set<std::string> dns_aliases)691*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
692*6777b538SAndroid Build Coastguard Worker       base::WeakPtr<SpdySession> session,
693*6777b538SAndroid Build Coastguard Worker       std::set<std::string> dns_aliases) override {
694*6777b538SAndroid Build Coastguard Worker     NOTREACHED();
695*6777b538SAndroid Build Coastguard Worker     return nullptr;
696*6777b538SAndroid Build Coastguard Worker   }
CreateHttp3Stream(std::unique_ptr<QuicChromiumClientSession::Handle> session,std::set<std::string> dns_aliases)697*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp3Stream(
698*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<QuicChromiumClientSession::Handle> session,
699*6777b538SAndroid Build Coastguard Worker       std::set<std::string> dns_aliases) override {
700*6777b538SAndroid Build Coastguard Worker     NOTREACHED();
701*6777b538SAndroid Build Coastguard Worker     return nullptr;
702*6777b538SAndroid Build Coastguard Worker   }
703*6777b538SAndroid Build Coastguard Worker };
704*6777b538SAndroid Build Coastguard Worker 
705*6777b538SAndroid Build Coastguard Worker // Returns true if |entry| is not one of the log types paid attention to in this
706*6777b538SAndroid Build Coastguard Worker // test. Note that HTTP_CACHE_WRITE_INFO and HTTP_CACHE_*_DATA are
707*6777b538SAndroid Build Coastguard Worker // ignored.
ShouldIgnoreLogEntry(const NetLogEntry & entry)708*6777b538SAndroid Build Coastguard Worker bool ShouldIgnoreLogEntry(const NetLogEntry& entry) {
709*6777b538SAndroid Build Coastguard Worker   switch (entry.type) {
710*6777b538SAndroid Build Coastguard Worker     case NetLogEventType::HTTP_CACHE_GET_BACKEND:
711*6777b538SAndroid Build Coastguard Worker     case NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY:
712*6777b538SAndroid Build Coastguard Worker     case NetLogEventType::HTTP_CACHE_OPEN_ENTRY:
713*6777b538SAndroid Build Coastguard Worker     case NetLogEventType::HTTP_CACHE_CREATE_ENTRY:
714*6777b538SAndroid Build Coastguard Worker     case NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY:
715*6777b538SAndroid Build Coastguard Worker     case NetLogEventType::HTTP_CACHE_DOOM_ENTRY:
716*6777b538SAndroid Build Coastguard Worker     case NetLogEventType::HTTP_CACHE_READ_INFO:
717*6777b538SAndroid Build Coastguard Worker       return false;
718*6777b538SAndroid Build Coastguard Worker     default:
719*6777b538SAndroid Build Coastguard Worker       return true;
720*6777b538SAndroid Build Coastguard Worker   }
721*6777b538SAndroid Build Coastguard Worker }
722*6777b538SAndroid Build Coastguard Worker 
723*6777b538SAndroid Build Coastguard Worker // Gets the entries from |net_log| created by the cache layer and asserted on in
724*6777b538SAndroid Build Coastguard Worker // these tests.
GetFilteredNetLogEntries(const RecordingNetLogObserver & net_log_observer)725*6777b538SAndroid Build Coastguard Worker std::vector<NetLogEntry> GetFilteredNetLogEntries(
726*6777b538SAndroid Build Coastguard Worker     const RecordingNetLogObserver& net_log_observer) {
727*6777b538SAndroid Build Coastguard Worker   auto entries = net_log_observer.GetEntries();
728*6777b538SAndroid Build Coastguard Worker   std::erase_if(entries, ShouldIgnoreLogEntry);
729*6777b538SAndroid Build Coastguard Worker   return entries;
730*6777b538SAndroid Build Coastguard Worker }
731*6777b538SAndroid Build Coastguard Worker 
LogContainsEventType(const RecordingNetLogObserver & net_log_observer,NetLogEventType expected)732*6777b538SAndroid Build Coastguard Worker bool LogContainsEventType(const RecordingNetLogObserver& net_log_observer,
733*6777b538SAndroid Build Coastguard Worker                           NetLogEventType expected) {
734*6777b538SAndroid Build Coastguard Worker   return !net_log_observer.GetEntriesWithType(expected).empty();
735*6777b538SAndroid Build Coastguard Worker }
736*6777b538SAndroid Build Coastguard Worker 
737*6777b538SAndroid Build Coastguard Worker // Returns a TransportInfo distinct from the default for mock transactions,
738*6777b538SAndroid Build Coastguard Worker // with the given port number.
TestTransportInfoWithPort(uint16_t port)739*6777b538SAndroid Build Coastguard Worker TransportInfo TestTransportInfoWithPort(uint16_t port) {
740*6777b538SAndroid Build Coastguard Worker   TransportInfo result;
741*6777b538SAndroid Build Coastguard Worker   result.endpoint = IPEndPoint(IPAddress(42, 0, 1, 2), port);
742*6777b538SAndroid Build Coastguard Worker   return result;
743*6777b538SAndroid Build Coastguard Worker }
744*6777b538SAndroid Build Coastguard Worker 
745*6777b538SAndroid Build Coastguard Worker // Returns a TransportInfo distinct from the default for mock transactions.
TestTransportInfo()746*6777b538SAndroid Build Coastguard Worker TransportInfo TestTransportInfo() {
747*6777b538SAndroid Build Coastguard Worker   return TestTransportInfoWithPort(1337);
748*6777b538SAndroid Build Coastguard Worker }
749*6777b538SAndroid Build Coastguard Worker 
CachedTestTransportInfo()750*6777b538SAndroid Build Coastguard Worker TransportInfo CachedTestTransportInfo() {
751*6777b538SAndroid Build Coastguard Worker   TransportInfo result = TestTransportInfo();
752*6777b538SAndroid Build Coastguard Worker   result.type = TransportType::kCached;
753*6777b538SAndroid Build Coastguard Worker   return result;
754*6777b538SAndroid Build Coastguard Worker }
755*6777b538SAndroid Build Coastguard Worker 
756*6777b538SAndroid Build Coastguard Worker // Helper function, generating valid HTTP cache key from `url`.
757*6777b538SAndroid Build Coastguard Worker // See also: HttpCache::GenerateCacheKey(..)
GenerateCacheKey(const std::string & url)758*6777b538SAndroid Build Coastguard Worker std::string GenerateCacheKey(const std::string& url) {
759*6777b538SAndroid Build Coastguard Worker   return "1/0/" + url;
760*6777b538SAndroid Build Coastguard Worker }
761*6777b538SAndroid Build Coastguard Worker 
762*6777b538SAndroid Build Coastguard Worker }  // namespace
763*6777b538SAndroid Build Coastguard Worker 
764*6777b538SAndroid Build Coastguard Worker using HttpCacheTest = TestWithTaskEnvironment;
765*6777b538SAndroid Build Coastguard Worker 
766*6777b538SAndroid Build Coastguard Worker class HttpCacheIOCallbackTest : public HttpCacheTest {
767*6777b538SAndroid Build Coastguard Worker  public:
768*6777b538SAndroid Build Coastguard Worker   HttpCacheIOCallbackTest() = default;
769*6777b538SAndroid Build Coastguard Worker   ~HttpCacheIOCallbackTest() override = default;
770*6777b538SAndroid Build Coastguard Worker 
771*6777b538SAndroid Build Coastguard Worker   // HttpCache::ActiveEntry is private, doing this allows tests to use it
772*6777b538SAndroid Build Coastguard Worker   using ActiveEntry = HttpCache::ActiveEntry;
773*6777b538SAndroid Build Coastguard Worker   using Transaction = HttpCache::Transaction;
774*6777b538SAndroid Build Coastguard Worker 
775*6777b538SAndroid Build Coastguard Worker   // The below functions are forwarding calls to the HttpCache class.
OpenEntry(HttpCache * cache,const std::string & url,scoped_refptr<ActiveEntry> * entry,HttpCache::Transaction * trans)776*6777b538SAndroid Build Coastguard Worker   int OpenEntry(HttpCache* cache,
777*6777b538SAndroid Build Coastguard Worker                 const std::string& url,
778*6777b538SAndroid Build Coastguard Worker                 scoped_refptr<ActiveEntry>* entry,
779*6777b538SAndroid Build Coastguard Worker                 HttpCache::Transaction* trans) {
780*6777b538SAndroid Build Coastguard Worker     return cache->OpenEntry(GenerateCacheKey(url), entry, trans);
781*6777b538SAndroid Build Coastguard Worker   }
782*6777b538SAndroid Build Coastguard Worker 
OpenOrCreateEntry(HttpCache * cache,const std::string & url,scoped_refptr<ActiveEntry> * entry,HttpCache::Transaction * trans)783*6777b538SAndroid Build Coastguard Worker   int OpenOrCreateEntry(HttpCache* cache,
784*6777b538SAndroid Build Coastguard Worker                         const std::string& url,
785*6777b538SAndroid Build Coastguard Worker                         scoped_refptr<ActiveEntry>* entry,
786*6777b538SAndroid Build Coastguard Worker                         HttpCache::Transaction* trans) {
787*6777b538SAndroid Build Coastguard Worker     return cache->OpenOrCreateEntry(GenerateCacheKey(url), entry, trans);
788*6777b538SAndroid Build Coastguard Worker   }
789*6777b538SAndroid Build Coastguard Worker 
CreateEntry(HttpCache * cache,const std::string & url,scoped_refptr<ActiveEntry> * entry,HttpCache::Transaction * trans)790*6777b538SAndroid Build Coastguard Worker   int CreateEntry(HttpCache* cache,
791*6777b538SAndroid Build Coastguard Worker                   const std::string& url,
792*6777b538SAndroid Build Coastguard Worker                   scoped_refptr<ActiveEntry>* entry,
793*6777b538SAndroid Build Coastguard Worker                   HttpCache::Transaction* trans) {
794*6777b538SAndroid Build Coastguard Worker     return cache->CreateEntry(GenerateCacheKey(url), entry, trans);
795*6777b538SAndroid Build Coastguard Worker   }
796*6777b538SAndroid Build Coastguard Worker 
DoomEntry(HttpCache * cache,const std::string & url,HttpCache::Transaction * trans)797*6777b538SAndroid Build Coastguard Worker   int DoomEntry(HttpCache* cache,
798*6777b538SAndroid Build Coastguard Worker                 const std::string& url,
799*6777b538SAndroid Build Coastguard Worker                 HttpCache::Transaction* trans) {
800*6777b538SAndroid Build Coastguard Worker     return cache->DoomEntry(GenerateCacheKey(url), trans);
801*6777b538SAndroid Build Coastguard Worker   }
802*6777b538SAndroid Build Coastguard Worker };
803*6777b538SAndroid Build Coastguard Worker 
804*6777b538SAndroid Build Coastguard Worker class HttpSplitCacheKeyTest : public HttpCacheTest {
805*6777b538SAndroid Build Coastguard Worker  public:
806*6777b538SAndroid Build Coastguard Worker   HttpSplitCacheKeyTest() = default;
807*6777b538SAndroid Build Coastguard Worker   ~HttpSplitCacheKeyTest() override = default;
808*6777b538SAndroid Build Coastguard Worker 
ComputeCacheKey(const std::string & url_string)809*6777b538SAndroid Build Coastguard Worker   std::string ComputeCacheKey(const std::string& url_string) {
810*6777b538SAndroid Build Coastguard Worker     GURL url(url_string);
811*6777b538SAndroid Build Coastguard Worker     SchemefulSite site(url);
812*6777b538SAndroid Build Coastguard Worker     net::HttpRequestInfo request_info;
813*6777b538SAndroid Build Coastguard Worker     request_info.url = url;
814*6777b538SAndroid Build Coastguard Worker     request_info.method = "GET";
815*6777b538SAndroid Build Coastguard Worker     request_info.network_isolation_key = net::NetworkIsolationKey(site, site);
816*6777b538SAndroid Build Coastguard Worker     request_info.network_anonymization_key =
817*6777b538SAndroid Build Coastguard Worker         net::NetworkAnonymizationKey::CreateSameSite(site);
818*6777b538SAndroid Build Coastguard Worker     MockHttpCache cache;
819*6777b538SAndroid Build Coastguard Worker     return *cache.http_cache()->GenerateCacheKeyForRequest(&request_info);
820*6777b538SAndroid Build Coastguard Worker   }
821*6777b538SAndroid Build Coastguard Worker };
822*6777b538SAndroid Build Coastguard Worker 
823*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
824*6777b538SAndroid Build Coastguard Worker // Tests.
825*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,CreateThenDestroy)826*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CreateThenDestroy) {
827*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
828*6777b538SAndroid Build Coastguard Worker 
829*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
830*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cache.CreateTransaction(&trans), IsOk());
831*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(trans.get());
832*6777b538SAndroid Build Coastguard Worker }
833*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,GetBackend)834*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GetBackend) {
835*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(0));
836*6777b538SAndroid Build Coastguard Worker 
837*6777b538SAndroid Build Coastguard Worker   disk_cache::Backend* backend;
838*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback cb;
839*6777b538SAndroid Build Coastguard Worker   // This will lazily initialize the backend.
840*6777b538SAndroid Build Coastguard Worker   int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
841*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cb.GetResult(rv), IsOk());
842*6777b538SAndroid Build Coastguard Worker }
843*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET)844*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET) {
845*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
846*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
847*6777b538SAndroid Build Coastguard Worker 
848*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
849*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
850*6777b538SAndroid Build Coastguard Worker                                  NetLogWithSource::Make(NetLogSourceType::NONE),
851*6777b538SAndroid Build Coastguard Worker                                  &load_timing_info);
852*6777b538SAndroid Build Coastguard Worker 
853*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
854*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
855*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
856*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
857*6777b538SAndroid Build Coastguard Worker }
858*6777b538SAndroid Build Coastguard Worker 
859*6777b538SAndroid Build Coastguard Worker // This test verifies that the callback passed to SetConnectedCallback() is
860*6777b538SAndroid Build Coastguard Worker // called once for simple GET calls that traverse the cache.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallback)861*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ConnectedCallback) {
862*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
863*6777b538SAndroid Build Coastguard Worker 
864*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
865*6777b538SAndroid Build Coastguard Worker   mock_transaction.transport_info = TestTransportInfo();
866*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(mock_transaction);
867*6777b538SAndroid Build Coastguard Worker 
868*6777b538SAndroid Build Coastguard Worker   ConnectedHandler connected_handler;
869*6777b538SAndroid Build Coastguard Worker 
870*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> transaction;
871*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
872*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(transaction, NotNull());
873*6777b538SAndroid Build Coastguard Worker 
874*6777b538SAndroid Build Coastguard Worker   transaction->SetConnectedCallback(connected_handler.Callback());
875*6777b538SAndroid Build Coastguard Worker 
876*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
877*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(
878*6777b538SAndroid Build Coastguard Worker       transaction->Start(&request, callback.callback(), NetLogWithSource()),
879*6777b538SAndroid Build Coastguard Worker       IsError(ERR_IO_PENDING));
880*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
881*6777b538SAndroid Build Coastguard Worker 
882*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(connected_handler.transports(), ElementsAre(TestTransportInfo()));
883*6777b538SAndroid Build Coastguard Worker }
884*6777b538SAndroid Build Coastguard Worker 
885*6777b538SAndroid Build Coastguard Worker // This test verifies that when the callback passed to SetConnectedCallback()
886*6777b538SAndroid Build Coastguard Worker // returns an error, the transaction fails with that error.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackReturnError)887*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackReturnError) {
888*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
889*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
890*6777b538SAndroid Build Coastguard Worker   ConnectedHandler connected_handler;
891*6777b538SAndroid Build Coastguard Worker 
892*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> transaction;
893*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
894*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(transaction, NotNull());
895*6777b538SAndroid Build Coastguard Worker 
896*6777b538SAndroid Build Coastguard Worker   // The exact error code does not matter. We only care that it is passed to
897*6777b538SAndroid Build Coastguard Worker   // the transaction's completion callback unmodified.
898*6777b538SAndroid Build Coastguard Worker   connected_handler.set_result(ERR_NOT_IMPLEMENTED);
899*6777b538SAndroid Build Coastguard Worker   transaction->SetConnectedCallback(connected_handler.Callback());
900*6777b538SAndroid Build Coastguard Worker 
901*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
902*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(
903*6777b538SAndroid Build Coastguard Worker       transaction->Start(&request, callback.callback(), NetLogWithSource()),
904*6777b538SAndroid Build Coastguard Worker       IsError(ERR_IO_PENDING));
905*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NOT_IMPLEMENTED));
906*6777b538SAndroid Build Coastguard Worker }
907*6777b538SAndroid Build Coastguard Worker 
908*6777b538SAndroid Build Coastguard Worker // This test verifies that the callback passed to SetConnectedCallback() is
909*6777b538SAndroid Build Coastguard Worker // called once for requests that hit the cache.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHit)910*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHit) {
911*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
912*6777b538SAndroid Build Coastguard Worker 
913*6777b538SAndroid Build Coastguard Worker   {
914*6777b538SAndroid Build Coastguard Worker     // Populate the cache.
915*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
916*6777b538SAndroid Build Coastguard Worker     mock_transaction.transport_info = TestTransportInfo();
917*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
918*6777b538SAndroid Build Coastguard Worker   }
919*6777b538SAndroid Build Coastguard Worker 
920*6777b538SAndroid Build Coastguard Worker   // Establish a baseline.
921*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
922*6777b538SAndroid Build Coastguard Worker 
923*6777b538SAndroid Build Coastguard Worker   // Load from the cache (only), observe the callback being called.
924*6777b538SAndroid Build Coastguard Worker 
925*6777b538SAndroid Build Coastguard Worker   ConnectedHandler connected_handler;
926*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
927*6777b538SAndroid Build Coastguard Worker 
928*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> transaction;
929*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
930*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(transaction, NotNull());
931*6777b538SAndroid Build Coastguard Worker 
932*6777b538SAndroid Build Coastguard Worker   transaction->SetConnectedCallback(connected_handler.Callback());
933*6777b538SAndroid Build Coastguard Worker 
934*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
935*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(
936*6777b538SAndroid Build Coastguard Worker       transaction->Start(&request, callback.callback(), NetLogWithSource()),
937*6777b538SAndroid Build Coastguard Worker       IsError(ERR_IO_PENDING));
938*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
939*6777b538SAndroid Build Coastguard Worker 
940*6777b538SAndroid Build Coastguard Worker   // Still only 1 transaction for the previous request. The connected callback
941*6777b538SAndroid Build Coastguard Worker   // was not called by a second network transaction.
942*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
943*6777b538SAndroid Build Coastguard Worker 
944*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(connected_handler.transports(),
945*6777b538SAndroid Build Coastguard Worker               ElementsAre(CachedTestTransportInfo()));
946*6777b538SAndroid Build Coastguard Worker }
947*6777b538SAndroid Build Coastguard Worker 
948*6777b538SAndroid Build Coastguard Worker // This test verifies that when the callback passed to SetConnectedCallback()
949*6777b538SAndroid Build Coastguard Worker // is called for a request that hit the cache and returns an error, the cache
950*6777b538SAndroid Build Coastguard Worker // entry is reusable.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnError)951*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHitReturnError) {
952*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
953*6777b538SAndroid Build Coastguard Worker 
954*6777b538SAndroid Build Coastguard Worker   {
955*6777b538SAndroid Build Coastguard Worker     // Populate the cache.
956*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
957*6777b538SAndroid Build Coastguard Worker     mock_transaction.transport_info = TestTransportInfo();
958*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
959*6777b538SAndroid Build Coastguard Worker   }
960*6777b538SAndroid Build Coastguard Worker 
961*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
962*6777b538SAndroid Build Coastguard Worker 
963*6777b538SAndroid Build Coastguard Worker   {
964*6777b538SAndroid Build Coastguard Worker     // Attempt to read from cache entry, but abort transaction due to a
965*6777b538SAndroid Build Coastguard Worker     // connected callback error.
966*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
967*6777b538SAndroid Build Coastguard Worker     connected_handler.set_result(ERR_FAILED);
968*6777b538SAndroid Build Coastguard Worker 
969*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
970*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
971*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
972*6777b538SAndroid Build Coastguard Worker 
973*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
974*6777b538SAndroid Build Coastguard Worker 
975*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
976*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
977*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
978*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
979*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FAILED));
980*6777b538SAndroid Build Coastguard Worker 
981*6777b538SAndroid Build Coastguard Worker     // Used the cache entry only.
982*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
983*6777b538SAndroid Build Coastguard Worker                 ElementsAre(CachedTestTransportInfo()));
984*6777b538SAndroid Build Coastguard Worker   }
985*6777b538SAndroid Build Coastguard Worker 
986*6777b538SAndroid Build Coastguard Worker   {
987*6777b538SAndroid Build Coastguard Worker     // Request the same resource once more, observe that it is read from cache.
988*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
989*6777b538SAndroid Build Coastguard Worker 
990*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
991*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
992*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
993*6777b538SAndroid Build Coastguard Worker 
994*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
995*6777b538SAndroid Build Coastguard Worker 
996*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
997*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
998*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
999*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
1000*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsOk());
1001*6777b538SAndroid Build Coastguard Worker 
1002*6777b538SAndroid Build Coastguard Worker     // Used the cache entry only.
1003*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
1004*6777b538SAndroid Build Coastguard Worker                 ElementsAre(CachedTestTransportInfo()));
1005*6777b538SAndroid Build Coastguard Worker   }
1006*6777b538SAndroid Build Coastguard Worker }
1007*6777b538SAndroid Build Coastguard Worker 
1008*6777b538SAndroid Build Coastguard Worker // This test verifies that when the callback passed to SetConnectedCallback()
1009*6777b538SAndroid Build Coastguard Worker // returns `ERR_INCONSISTENT_IP_ADDRESS_SPACE`, the cache entry is invalidated.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnInconsistentIpError)1010*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest,
1011*6777b538SAndroid Build Coastguard Worker        SimpleGET_ConnectedCallbackOnCacheHitReturnInconsistentIpError) {
1012*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1013*6777b538SAndroid Build Coastguard Worker 
1014*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1015*6777b538SAndroid Build Coastguard Worker   mock_transaction.transport_info = TestTransportInfo();
1016*6777b538SAndroid Build Coastguard Worker 
1017*6777b538SAndroid Build Coastguard Worker   // Populate the cache.
1018*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), mock_transaction);
1019*6777b538SAndroid Build Coastguard Worker 
1020*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
1021*6777b538SAndroid Build Coastguard Worker 
1022*6777b538SAndroid Build Coastguard Worker   {
1023*6777b538SAndroid Build Coastguard Worker     // Attempt to read from cache entry, but abort transaction due to a
1024*6777b538SAndroid Build Coastguard Worker     // connected callback error.
1025*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
1026*6777b538SAndroid Build Coastguard Worker     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
1027*6777b538SAndroid Build Coastguard Worker 
1028*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
1029*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1030*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
1031*6777b538SAndroid Build Coastguard Worker 
1032*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
1033*6777b538SAndroid Build Coastguard Worker 
1034*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
1035*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
1036*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1037*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
1038*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(),
1039*6777b538SAndroid Build Coastguard Worker                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
1040*6777b538SAndroid Build Coastguard Worker 
1041*6777b538SAndroid Build Coastguard Worker     // Used the cache entry only.
1042*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
1043*6777b538SAndroid Build Coastguard Worker                 ElementsAre(CachedTestTransportInfo()));
1044*6777b538SAndroid Build Coastguard Worker   }
1045*6777b538SAndroid Build Coastguard Worker 
1046*6777b538SAndroid Build Coastguard Worker   {
1047*6777b538SAndroid Build Coastguard Worker     // Request the same resource once more, observe that it is not read from
1048*6777b538SAndroid Build Coastguard Worker     // cache.
1049*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
1050*6777b538SAndroid Build Coastguard Worker 
1051*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
1052*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1053*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
1054*6777b538SAndroid Build Coastguard Worker 
1055*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
1056*6777b538SAndroid Build Coastguard Worker 
1057*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
1058*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
1059*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1060*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
1061*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsOk());
1062*6777b538SAndroid Build Coastguard Worker 
1063*6777b538SAndroid Build Coastguard Worker     // Used the network only.
1064*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
1065*6777b538SAndroid Build Coastguard Worker                 ElementsAre(TestTransportInfo()));
1066*6777b538SAndroid Build Coastguard Worker   }
1067*6777b538SAndroid Build Coastguard Worker }
1068*6777b538SAndroid Build Coastguard Worker 
1069*6777b538SAndroid Build Coastguard Worker // This test verifies that when the callback passed to SetConnectedCallback()
1070*6777b538SAndroid Build Coastguard Worker // returns
1071*6777b538SAndroid Build Coastguard Worker // `ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY`, the
1072*6777b538SAndroid Build Coastguard Worker // cache entry is invalidated, and we'll retry the connection from the network.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnPrivateNetworkAccessBlockedError)1073*6777b538SAndroid Build Coastguard Worker TEST_F(
1074*6777b538SAndroid Build Coastguard Worker     HttpCacheTest,
1075*6777b538SAndroid Build Coastguard Worker     SimpleGET_ConnectedCallbackOnCacheHitReturnPrivateNetworkAccessBlockedError) {
1076*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1077*6777b538SAndroid Build Coastguard Worker 
1078*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1079*6777b538SAndroid Build Coastguard Worker   mock_transaction.transport_info = TestTransportInfo();
1080*6777b538SAndroid Build Coastguard Worker 
1081*6777b538SAndroid Build Coastguard Worker   // Populate the cache.
1082*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), mock_transaction);
1083*6777b538SAndroid Build Coastguard Worker 
1084*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
1085*6777b538SAndroid Build Coastguard Worker 
1086*6777b538SAndroid Build Coastguard Worker   {
1087*6777b538SAndroid Build Coastguard Worker     // Attempt to read from cache entry, but abort transaction due to a
1088*6777b538SAndroid Build Coastguard Worker     // connected callback error.
1089*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
1090*6777b538SAndroid Build Coastguard Worker     connected_handler.set_result(
1091*6777b538SAndroid Build Coastguard Worker         ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY);
1092*6777b538SAndroid Build Coastguard Worker 
1093*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
1094*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1095*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
1096*6777b538SAndroid Build Coastguard Worker 
1097*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
1098*6777b538SAndroid Build Coastguard Worker 
1099*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
1100*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
1101*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1102*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
1103*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(
1104*6777b538SAndroid Build Coastguard Worker         callback.WaitForResult(),
1105*6777b538SAndroid Build Coastguard Worker         IsError(
1106*6777b538SAndroid Build Coastguard Worker             ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY));
1107*6777b538SAndroid Build Coastguard Worker 
1108*6777b538SAndroid Build Coastguard Worker     // Used the cache entry only.
1109*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
1110*6777b538SAndroid Build Coastguard Worker                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
1111*6777b538SAndroid Build Coastguard Worker   }
1112*6777b538SAndroid Build Coastguard Worker 
1113*6777b538SAndroid Build Coastguard Worker   {
1114*6777b538SAndroid Build Coastguard Worker     // Request the same resource once more, observe that it is not read from
1115*6777b538SAndroid Build Coastguard Worker     // cache.
1116*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
1117*6777b538SAndroid Build Coastguard Worker 
1118*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
1119*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1120*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
1121*6777b538SAndroid Build Coastguard Worker 
1122*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
1123*6777b538SAndroid Build Coastguard Worker 
1124*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
1125*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
1126*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1127*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
1128*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsOk());
1129*6777b538SAndroid Build Coastguard Worker 
1130*6777b538SAndroid Build Coastguard Worker     // Used the network only.
1131*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
1132*6777b538SAndroid Build Coastguard Worker                 ElementsAre(TestTransportInfo()));
1133*6777b538SAndroid Build Coastguard Worker   }
1134*6777b538SAndroid Build Coastguard Worker }
1135*6777b538SAndroid Build Coastguard Worker 
1136*6777b538SAndroid Build Coastguard Worker // This test verifies that the callback passed to SetConnectedCallback() is
1137*6777b538SAndroid Build Coastguard Worker // called with the right transport type when the cached entry was originally
1138*6777b538SAndroid Build Coastguard Worker // fetched via proxy.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitFromProxy)1139*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHitFromProxy) {
1140*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1141*6777b538SAndroid Build Coastguard Worker 
1142*6777b538SAndroid Build Coastguard Worker   TransportInfo proxied_transport_info = TestTransportInfo();
1143*6777b538SAndroid Build Coastguard Worker   proxied_transport_info.type = TransportType::kProxied;
1144*6777b538SAndroid Build Coastguard Worker 
1145*6777b538SAndroid Build Coastguard Worker   {
1146*6777b538SAndroid Build Coastguard Worker     // Populate the cache.
1147*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1148*6777b538SAndroid Build Coastguard Worker     mock_transaction.transport_info = proxied_transport_info;
1149*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1150*6777b538SAndroid Build Coastguard Worker   }
1151*6777b538SAndroid Build Coastguard Worker 
1152*6777b538SAndroid Build Coastguard Worker   // Establish a baseline.
1153*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1154*6777b538SAndroid Build Coastguard Worker 
1155*6777b538SAndroid Build Coastguard Worker   // Load from the cache (only), observe the callback being called.
1156*6777b538SAndroid Build Coastguard Worker 
1157*6777b538SAndroid Build Coastguard Worker   ConnectedHandler connected_handler;
1158*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
1159*6777b538SAndroid Build Coastguard Worker 
1160*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> transaction;
1161*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1162*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(transaction, NotNull());
1163*6777b538SAndroid Build Coastguard Worker 
1164*6777b538SAndroid Build Coastguard Worker   transaction->SetConnectedCallback(connected_handler.Callback());
1165*6777b538SAndroid Build Coastguard Worker 
1166*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
1167*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(
1168*6777b538SAndroid Build Coastguard Worker       transaction->Start(&request, callback.callback(), NetLogWithSource()),
1169*6777b538SAndroid Build Coastguard Worker       IsError(ERR_IO_PENDING));
1170*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
1171*6777b538SAndroid Build Coastguard Worker 
1172*6777b538SAndroid Build Coastguard Worker   // Still only 1 transaction for the previous request. The connected callback
1173*6777b538SAndroid Build Coastguard Worker   // was not called by a second network transaction.
1174*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1175*6777b538SAndroid Build Coastguard Worker 
1176*6777b538SAndroid Build Coastguard Worker   // The transport info mentions both the cache and the original proxy.
1177*6777b538SAndroid Build Coastguard Worker   TransportInfo expected_transport_info = TestTransportInfo();
1178*6777b538SAndroid Build Coastguard Worker   expected_transport_info.type = TransportType::kCachedFromProxy;
1179*6777b538SAndroid Build Coastguard Worker 
1180*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(connected_handler.transports(),
1181*6777b538SAndroid Build Coastguard Worker               ElementsAre(expected_transport_info));
1182*6777b538SAndroid Build Coastguard Worker }
1183*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_DelayedCacheLock)1184*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_DelayedCacheLock) {
1185*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1186*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
1187*6777b538SAndroid Build Coastguard Worker 
1188*6777b538SAndroid Build Coastguard Worker   // Configure the cache to delay the response for AddTransactionToEntry so it
1189*6777b538SAndroid Build Coastguard Worker   // gets sequenced behind any other tasks that get generated when starting the
1190*6777b538SAndroid Build Coastguard Worker   // transaction (i.e. network activity when run in parallel with the cache
1191*6777b538SAndroid Build Coastguard Worker   // lock).
1192*6777b538SAndroid Build Coastguard Worker   cache.http_cache()->DelayAddTransactionToEntryForTesting();
1193*6777b538SAndroid Build Coastguard Worker 
1194*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
1195*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
1196*6777b538SAndroid Build Coastguard Worker                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1197*6777b538SAndroid Build Coastguard Worker                                  &load_timing_info);
1198*6777b538SAndroid Build Coastguard Worker 
1199*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1200*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
1201*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1202*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
1203*6777b538SAndroid Build Coastguard Worker }
1204*6777b538SAndroid Build Coastguard Worker 
1205*6777b538SAndroid Build Coastguard Worker enum class SplitCacheTestCase {
1206*6777b538SAndroid Build Coastguard Worker   kSplitCacheDisabled,
1207*6777b538SAndroid Build Coastguard Worker   kSplitCacheNikFrameSiteEnabled,
1208*6777b538SAndroid Build Coastguard Worker   kSplitCacheNikCrossSiteFlagEnabled,
1209*6777b538SAndroid Build Coastguard Worker   kSplitCacheNikFrameSiteSharedOpaqueEnabled,
1210*6777b538SAndroid Build Coastguard Worker };
1211*6777b538SAndroid Build Coastguard Worker 
InitializeSplitCacheScopedFeatureList(base::test::ScopedFeatureList & scoped_feature_list,SplitCacheTestCase test_case)1212*6777b538SAndroid Build Coastguard Worker void InitializeSplitCacheScopedFeatureList(
1213*6777b538SAndroid Build Coastguard Worker     base::test::ScopedFeatureList& scoped_feature_list,
1214*6777b538SAndroid Build Coastguard Worker     SplitCacheTestCase test_case) {
1215*6777b538SAndroid Build Coastguard Worker   std::vector<base::test::FeatureRef> enabled_features;
1216*6777b538SAndroid Build Coastguard Worker   std::vector<base::test::FeatureRef> disabled_features;
1217*6777b538SAndroid Build Coastguard Worker 
1218*6777b538SAndroid Build Coastguard Worker   if (test_case == SplitCacheTestCase::kSplitCacheDisabled) {
1219*6777b538SAndroid Build Coastguard Worker     disabled_features.push_back(
1220*6777b538SAndroid Build Coastguard Worker         net::features::kSplitCacheByNetworkIsolationKey);
1221*6777b538SAndroid Build Coastguard Worker   } else {
1222*6777b538SAndroid Build Coastguard Worker     enabled_features.push_back(net::features::kSplitCacheByNetworkIsolationKey);
1223*6777b538SAndroid Build Coastguard Worker   }
1224*6777b538SAndroid Build Coastguard Worker 
1225*6777b538SAndroid Build Coastguard Worker   if (test_case == SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled) {
1226*6777b538SAndroid Build Coastguard Worker     enabled_features.push_back(
1227*6777b538SAndroid Build Coastguard Worker         net::features::kEnableCrossSiteFlagNetworkIsolationKey);
1228*6777b538SAndroid Build Coastguard Worker   } else {
1229*6777b538SAndroid Build Coastguard Worker     disabled_features.push_back(
1230*6777b538SAndroid Build Coastguard Worker         net::features::kEnableCrossSiteFlagNetworkIsolationKey);
1231*6777b538SAndroid Build Coastguard Worker   }
1232*6777b538SAndroid Build Coastguard Worker 
1233*6777b538SAndroid Build Coastguard Worker   if (test_case ==
1234*6777b538SAndroid Build Coastguard Worker       SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled) {
1235*6777b538SAndroid Build Coastguard Worker     enabled_features.push_back(
1236*6777b538SAndroid Build Coastguard Worker         net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey);
1237*6777b538SAndroid Build Coastguard Worker   } else {
1238*6777b538SAndroid Build Coastguard Worker     disabled_features.push_back(
1239*6777b538SAndroid Build Coastguard Worker         net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey);
1240*6777b538SAndroid Build Coastguard Worker   }
1241*6777b538SAndroid Build Coastguard Worker   scoped_feature_list.InitWithFeatures(enabled_features, disabled_features);
1242*6777b538SAndroid Build Coastguard Worker }
1243*6777b538SAndroid Build Coastguard Worker 
1244*6777b538SAndroid Build Coastguard Worker class HttpCacheTest_SplitCacheFeature
1245*6777b538SAndroid Build Coastguard Worker     : public HttpCacheTest,
1246*6777b538SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<SplitCacheTestCase> {
1247*6777b538SAndroid Build Coastguard Worker  public:
HttpCacheTest_SplitCacheFeature()1248*6777b538SAndroid Build Coastguard Worker   HttpCacheTest_SplitCacheFeature() {
1249*6777b538SAndroid Build Coastguard Worker     InitializeSplitCacheScopedFeatureList(feature_list_, GetParam());
1250*6777b538SAndroid Build Coastguard Worker   }
1251*6777b538SAndroid Build Coastguard Worker 
IsSplitCacheEnabled() const1252*6777b538SAndroid Build Coastguard Worker   bool IsSplitCacheEnabled() const {
1253*6777b538SAndroid Build Coastguard Worker     return GetParam() != SplitCacheTestCase::kSplitCacheDisabled;
1254*6777b538SAndroid Build Coastguard Worker   }
1255*6777b538SAndroid Build Coastguard Worker 
1256*6777b538SAndroid Build Coastguard Worker  private:
1257*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList feature_list_;
1258*6777b538SAndroid Build Coastguard Worker };
1259*6777b538SAndroid Build Coastguard Worker 
TEST_P(HttpCacheTest_SplitCacheFeature,SimpleGETVerifyGoogleFontMetrics)1260*6777b538SAndroid Build Coastguard Worker TEST_P(HttpCacheTest_SplitCacheFeature, SimpleGETVerifyGoogleFontMetrics) {
1261*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_a(GURL("http://www.a.com"));
1262*6777b538SAndroid Build Coastguard Worker 
1263*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1264*6777b538SAndroid Build Coastguard Worker 
1265*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(
1266*6777b538SAndroid Build Coastguard Worker       kSimpleGET_Transaction,
1267*6777b538SAndroid Build Coastguard Worker       "http://themes.googleusercontent.com/static/fonts/roboto");
1268*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
1269*6777b538SAndroid Build Coastguard Worker   request.network_isolation_key = NetworkIsolationKey(site_a, site_a);
1270*6777b538SAndroid Build Coastguard Worker   request.network_anonymization_key =
1271*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_a);
1272*6777b538SAndroid Build Coastguard Worker 
1273*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
1274*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
1275*6777b538SAndroid Build Coastguard Worker                                 nullptr);
1276*6777b538SAndroid Build Coastguard Worker 
1277*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
1278*6777b538SAndroid Build Coastguard Worker                                 nullptr);
1279*6777b538SAndroid Build Coastguard Worker }
1280*6777b538SAndroid Build Coastguard Worker 
1281*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
1282*6777b538SAndroid Build Coastguard Worker     All,
1283*6777b538SAndroid Build Coastguard Worker     HttpCacheTest_SplitCacheFeature,
1284*6777b538SAndroid Build Coastguard Worker     testing::ValuesIn(
1285*6777b538SAndroid Build Coastguard Worker         {SplitCacheTestCase::kSplitCacheDisabled,
1286*6777b538SAndroid Build Coastguard Worker          SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled,
1287*6777b538SAndroid Build Coastguard Worker          SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled,
1288*6777b538SAndroid Build Coastguard Worker          SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled}),
__anone6acdaec0202(const testing::TestParamInfo<SplitCacheTestCase>& info) 1289*6777b538SAndroid Build Coastguard Worker     [](const testing::TestParamInfo<SplitCacheTestCase>& info) {
1290*6777b538SAndroid Build Coastguard Worker       switch (info.param) {
1291*6777b538SAndroid Build Coastguard Worker         case (SplitCacheTestCase::kSplitCacheDisabled):
1292*6777b538SAndroid Build Coastguard Worker           return "SplitCacheDisabled";
1293*6777b538SAndroid Build Coastguard Worker         case (SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled):
1294*6777b538SAndroid Build Coastguard Worker           return "SplitCacheNikFrameSiteEnabled";
1295*6777b538SAndroid Build Coastguard Worker         case (SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled):
1296*6777b538SAndroid Build Coastguard Worker           return "SplitCacheNikCrossSiteFlagEnabled";
1297*6777b538SAndroid Build Coastguard Worker         case (SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled):
1298*6777b538SAndroid Build Coastguard Worker           return "SplitCacheNikFrameSiteSharedOpaqueEnabled";
1299*6777b538SAndroid Build Coastguard Worker       }
1300*6777b538SAndroid Build Coastguard Worker     });
1301*6777b538SAndroid Build Coastguard Worker 
1302*6777b538SAndroid Build Coastguard Worker class HttpCacheTest_SplitCacheFeatureEnabled
1303*6777b538SAndroid Build Coastguard Worker     : public HttpCacheTest_SplitCacheFeature {
1304*6777b538SAndroid Build Coastguard Worker  public:
HttpCacheTest_SplitCacheFeatureEnabled()1305*6777b538SAndroid Build Coastguard Worker   HttpCacheTest_SplitCacheFeatureEnabled() {
1306*6777b538SAndroid Build Coastguard Worker     CHECK(base::FeatureList::IsEnabled(
1307*6777b538SAndroid Build Coastguard Worker         net::features::kSplitCacheByNetworkIsolationKey));
1308*6777b538SAndroid Build Coastguard Worker   }
1309*6777b538SAndroid Build Coastguard Worker };
1310*6777b538SAndroid Build Coastguard Worker 
1311*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
1312*6777b538SAndroid Build Coastguard Worker     All,
1313*6777b538SAndroid Build Coastguard Worker     HttpCacheTest_SplitCacheFeatureEnabled,
1314*6777b538SAndroid Build Coastguard Worker     testing::ValuesIn(
1315*6777b538SAndroid Build Coastguard Worker         {SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled,
1316*6777b538SAndroid Build Coastguard Worker          SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled,
1317*6777b538SAndroid Build Coastguard Worker          SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled}),
__anone6acdaec0302(const testing::TestParamInfo<SplitCacheTestCase>& info) 1318*6777b538SAndroid Build Coastguard Worker     [](const testing::TestParamInfo<SplitCacheTestCase>& info) {
1319*6777b538SAndroid Build Coastguard Worker       switch (info.param) {
1320*6777b538SAndroid Build Coastguard Worker         case (SplitCacheTestCase::kSplitCacheDisabled):
1321*6777b538SAndroid Build Coastguard Worker           return "NotUsedForThisTestSuite";
1322*6777b538SAndroid Build Coastguard Worker         case (SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled):
1323*6777b538SAndroid Build Coastguard Worker           return "SplitCacheNikFrameSiteEnabled";
1324*6777b538SAndroid Build Coastguard Worker         case (SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled):
1325*6777b538SAndroid Build Coastguard Worker           return "SplitCacheNikCrossSiteFlagEnabled";
1326*6777b538SAndroid Build Coastguard Worker         case (SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled):
1327*6777b538SAndroid Build Coastguard Worker           return "SplitCacheNikFrameSiteSharedOpaqueEnabled";
1328*6777b538SAndroid Build Coastguard Worker       }
1329*6777b538SAndroid Build Coastguard Worker     });
1330*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGETNoDiskCache)1331*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGETNoDiskCache) {
1332*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1333*6777b538SAndroid Build Coastguard Worker 
1334*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_fail_requests(true);
1335*6777b538SAndroid Build Coastguard Worker 
1336*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_observer;
1337*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
1338*6777b538SAndroid Build Coastguard Worker 
1339*6777b538SAndroid Build Coastguard Worker   // Read from the network, and don't use the cache.
1340*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
1341*6777b538SAndroid Build Coastguard Worker                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1342*6777b538SAndroid Build Coastguard Worker                                  &load_timing_info);
1343*6777b538SAndroid Build Coastguard Worker 
1344*6777b538SAndroid Build Coastguard Worker   // Check that the NetLog was filled as expected.
1345*6777b538SAndroid Build Coastguard Worker   // (We attempted to OpenOrCreate entries, but fail).
1346*6777b538SAndroid Build Coastguard Worker   auto entries = GetFilteredNetLogEntries(net_log_observer);
1347*6777b538SAndroid Build Coastguard Worker 
1348*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4u, entries.size());
1349*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1350*6777b538SAndroid Build Coastguard Worker                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1351*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1352*6777b538SAndroid Build Coastguard Worker       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1353*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(
1354*6777b538SAndroid Build Coastguard Worker       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1355*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEndEvent(
1356*6777b538SAndroid Build Coastguard Worker       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1357*6777b538SAndroid Build Coastguard Worker 
1358*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1359*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
1360*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
1361*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
1362*6777b538SAndroid Build Coastguard Worker }
1363*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGETNoDiskCache2)1364*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGETNoDiskCache2) {
1365*6777b538SAndroid Build Coastguard Worker   // This will initialize a cache object with NULL backend.
1366*6777b538SAndroid Build Coastguard Worker   auto factory = std::make_unique<MockBlockingBackendFactory>();
1367*6777b538SAndroid Build Coastguard Worker   factory->set_fail(true);
1368*6777b538SAndroid Build Coastguard Worker   factory->FinishCreation();  // We'll complete synchronously.
1369*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache(std::move(factory));
1370*6777b538SAndroid Build Coastguard Worker 
1371*6777b538SAndroid Build Coastguard Worker   // Read from the network, and don't use the cache.
1372*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1373*6777b538SAndroid Build Coastguard Worker 
1374*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1375*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
1376*6777b538SAndroid Build Coastguard Worker }
1377*6777b538SAndroid Build Coastguard Worker 
1378*6777b538SAndroid Build Coastguard Worker // Tests that IOBuffers are not referenced after IO completes.
TEST_F(HttpCacheTest,ReleaseBuffer)1379*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ReleaseBuffer) {
1380*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1381*6777b538SAndroid Build Coastguard Worker 
1382*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
1383*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1384*6777b538SAndroid Build Coastguard Worker 
1385*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
1386*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
1387*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
1388*6777b538SAndroid Build Coastguard Worker 
1389*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 10;
1390*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
1391*6777b538SAndroid Build Coastguard Worker   ReleaseBufferCompletionCallback cb(buffer.get());
1392*6777b538SAndroid Build Coastguard Worker 
1393*6777b538SAndroid Build Coastguard Worker   int rv = trans->Start(&request, cb.callback(), NetLogWithSource());
1394*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cb.GetResult(rv), IsOk());
1395*6777b538SAndroid Build Coastguard Worker 
1396*6777b538SAndroid Build Coastguard Worker   rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
1397*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kBufferSize, cb.GetResult(rv));
1398*6777b538SAndroid Build Coastguard Worker }
1399*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures)1400*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGETWithDiskFailures) {
1401*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1402*6777b538SAndroid Build Coastguard Worker 
1403*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1404*6777b538SAndroid Build Coastguard Worker 
1405*6777b538SAndroid Build Coastguard Worker   // Read from the network, and fail to write to the cache.
1406*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1407*6777b538SAndroid Build Coastguard Worker 
1408*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1409*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
1410*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1411*6777b538SAndroid Build Coastguard Worker 
1412*6777b538SAndroid Build Coastguard Worker   // This one should see an empty cache again.
1413*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1414*6777b538SAndroid Build Coastguard Worker 
1415*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1416*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
1417*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
1418*6777b538SAndroid Build Coastguard Worker }
1419*6777b538SAndroid Build Coastguard Worker 
1420*6777b538SAndroid Build Coastguard Worker // Tests that disk failures after the transaction has started don't cause the
1421*6777b538SAndroid Build Coastguard Worker // request to fail.
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures2)1422*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGETWithDiskFailures2) {
1423*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1424*6777b538SAndroid Build Coastguard Worker 
1425*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
1426*6777b538SAndroid Build Coastguard Worker 
1427*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
1428*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
1429*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
1430*6777b538SAndroid Build Coastguard Worker 
1431*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1432*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1433*6777b538SAndroid Build Coastguard Worker   rv = c->callback.WaitForResult();
1434*6777b538SAndroid Build Coastguard Worker 
1435*6777b538SAndroid Build Coastguard Worker   // Start failing request now.
1436*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1437*6777b538SAndroid Build Coastguard Worker 
1438*6777b538SAndroid Build Coastguard Worker   // We have to open the entry again to propagate the failure flag.
1439*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* en;
1440*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &en));
1441*6777b538SAndroid Build Coastguard Worker   en->Close();
1442*6777b538SAndroid Build Coastguard Worker 
1443*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1444*6777b538SAndroid Build Coastguard Worker   c.reset();
1445*6777b538SAndroid Build Coastguard Worker 
1446*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1447*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
1448*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1449*6777b538SAndroid Build Coastguard Worker 
1450*6777b538SAndroid Build Coastguard Worker   // This one should see an empty cache again.
1451*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1452*6777b538SAndroid Build Coastguard Worker 
1453*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1454*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
1455*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
1456*6777b538SAndroid Build Coastguard Worker }
1457*6777b538SAndroid Build Coastguard Worker 
1458*6777b538SAndroid Build Coastguard Worker // Tests that we handle failures to read from the cache.
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures3)1459*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGETWithDiskFailures3) {
1460*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1461*6777b538SAndroid Build Coastguard Worker 
1462*6777b538SAndroid Build Coastguard Worker   // Read from the network, and write to the cache.
1463*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1464*6777b538SAndroid Build Coastguard Worker 
1465*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1466*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
1467*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1468*6777b538SAndroid Build Coastguard Worker 
1469*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1470*6777b538SAndroid Build Coastguard Worker 
1471*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
1472*6777b538SAndroid Build Coastguard Worker 
1473*6777b538SAndroid Build Coastguard Worker   // Now fail to read from the cache.
1474*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
1475*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
1476*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
1477*6777b538SAndroid Build Coastguard Worker 
1478*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1479*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
1480*6777b538SAndroid Build Coastguard Worker 
1481*6777b538SAndroid Build Coastguard Worker   // Now verify that the entry was removed from the cache.
1482*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_soft_failures_mask(0);
1483*6777b538SAndroid Build Coastguard Worker 
1484*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1485*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
1486*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
1487*6777b538SAndroid Build Coastguard Worker 
1488*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1489*6777b538SAndroid Build Coastguard Worker 
1490*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
1491*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
1492*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->create_count());
1493*6777b538SAndroid Build Coastguard Worker }
1494*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_LoadOnlyFromCache_Hit)1495*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadOnlyFromCache_Hit) {
1496*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1497*6777b538SAndroid Build Coastguard Worker 
1498*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_observer;
1499*6777b538SAndroid Build Coastguard Worker   NetLogWithSource net_log_with_source =
1500*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE);
1501*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
1502*6777b538SAndroid Build Coastguard Worker 
1503*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
1504*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
1505*6777b538SAndroid Build Coastguard Worker                                  net_log_with_source, &load_timing_info);
1506*6777b538SAndroid Build Coastguard Worker 
1507*6777b538SAndroid Build Coastguard Worker   // Check that the NetLog was filled as expected.
1508*6777b538SAndroid Build Coastguard Worker   auto entries = GetFilteredNetLogEntries(net_log_observer);
1509*6777b538SAndroid Build Coastguard Worker 
1510*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(6u, entries.size());
1511*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1512*6777b538SAndroid Build Coastguard Worker                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1513*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1514*6777b538SAndroid Build Coastguard Worker       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1515*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(
1516*6777b538SAndroid Build Coastguard Worker       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1517*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEndEvent(
1518*6777b538SAndroid Build Coastguard Worker       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1519*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1520*6777b538SAndroid Build Coastguard Worker                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1521*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1522*6777b538SAndroid Build Coastguard Worker                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1523*6777b538SAndroid Build Coastguard Worker 
1524*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
1525*6777b538SAndroid Build Coastguard Worker 
1526*6777b538SAndroid Build Coastguard Worker   // Force this transaction to read from the cache.
1527*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
1528*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
1529*6777b538SAndroid Build Coastguard Worker 
1530*6777b538SAndroid Build Coastguard Worker   net_log_observer.Clear();
1531*6777b538SAndroid Build Coastguard Worker 
1532*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1533*6777b538SAndroid Build Coastguard Worker                                  net_log_with_source, &load_timing_info);
1534*6777b538SAndroid Build Coastguard Worker 
1535*6777b538SAndroid Build Coastguard Worker   // Check that the NetLog was filled as expected.
1536*6777b538SAndroid Build Coastguard Worker   entries = GetFilteredNetLogEntries(net_log_observer);
1537*6777b538SAndroid Build Coastguard Worker 
1538*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(8u, entries.size());
1539*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1540*6777b538SAndroid Build Coastguard Worker                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1541*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1542*6777b538SAndroid Build Coastguard Worker       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1543*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(
1544*6777b538SAndroid Build Coastguard Worker       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1545*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEndEvent(
1546*6777b538SAndroid Build Coastguard Worker       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1547*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1548*6777b538SAndroid Build Coastguard Worker                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1549*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1550*6777b538SAndroid Build Coastguard Worker                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1551*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1552*6777b538SAndroid Build Coastguard Worker       LogContainsBeginEvent(entries, 6, NetLogEventType::HTTP_CACHE_READ_INFO));
1553*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1554*6777b538SAndroid Build Coastguard Worker       LogContainsEndEvent(entries, 7, NetLogEventType::HTTP_CACHE_READ_INFO));
1555*6777b538SAndroid Build Coastguard Worker 
1556*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1557*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
1558*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1559*6777b538SAndroid Build Coastguard Worker   TestLoadTimingCachedResponse(load_timing_info);
1560*6777b538SAndroid Build Coastguard Worker }
1561*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_LoadOnlyFromCache_Miss)1562*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadOnlyFromCache_Miss) {
1563*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1564*6777b538SAndroid Build Coastguard Worker 
1565*6777b538SAndroid Build Coastguard Worker   // force this transaction to read from the cache
1566*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
1567*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
1568*6777b538SAndroid Build Coastguard Worker 
1569*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
1570*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
1571*6777b538SAndroid Build Coastguard Worker 
1572*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
1573*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
1574*6777b538SAndroid Build Coastguard Worker 
1575*6777b538SAndroid Build Coastguard Worker   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1576*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
1577*6777b538SAndroid Build Coastguard Worker     rv = callback.WaitForResult();
1578*6777b538SAndroid Build Coastguard Worker   }
1579*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
1580*6777b538SAndroid Build Coastguard Worker 
1581*6777b538SAndroid Build Coastguard Worker   trans.reset();
1582*6777b538SAndroid Build Coastguard Worker 
1583*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.network_layer()->transaction_count());
1584*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
1585*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
1586*6777b538SAndroid Build Coastguard Worker }
1587*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_Hit)1588*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_Hit) {
1589*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1590*6777b538SAndroid Build Coastguard Worker 
1591*6777b538SAndroid Build Coastguard Worker   // write to the cache
1592*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1593*6777b538SAndroid Build Coastguard Worker 
1594*6777b538SAndroid Build Coastguard Worker   // force this transaction to read from the cache if valid
1595*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
1596*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1597*6777b538SAndroid Build Coastguard Worker 
1598*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
1599*6777b538SAndroid Build Coastguard Worker 
1600*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1601*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
1602*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1603*6777b538SAndroid Build Coastguard Worker }
1604*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_Miss)1605*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_Miss) {
1606*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1607*6777b538SAndroid Build Coastguard Worker 
1608*6777b538SAndroid Build Coastguard Worker   // force this transaction to read from the cache if valid
1609*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
1610*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1611*6777b538SAndroid Build Coastguard Worker 
1612*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
1613*6777b538SAndroid Build Coastguard Worker 
1614*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1615*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
1616*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1617*6777b538SAndroid Build Coastguard Worker }
1618*6777b538SAndroid Build Coastguard Worker 
1619*6777b538SAndroid Build Coastguard Worker // Tests LOAD_SKIP_CACHE_VALIDATION in the presence of vary headers.
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_VaryMatch)1620*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_VaryMatch) {
1621*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1622*6777b538SAndroid Build Coastguard Worker 
1623*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
1624*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
1625*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n";
1626*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
1627*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=10000\n"
1628*6777b538SAndroid Build Coastguard Worker       "Vary: Foo\n";
1629*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
1630*6777b538SAndroid Build Coastguard Worker 
1631*6777b538SAndroid Build Coastguard Worker   // Read from the cache.
1632*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1633*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
1634*6777b538SAndroid Build Coastguard Worker 
1635*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1636*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
1637*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1638*6777b538SAndroid Build Coastguard Worker }
1639*6777b538SAndroid Build Coastguard Worker 
1640*6777b538SAndroid Build Coastguard Worker // Tests LOAD_SKIP_CACHE_VALIDATION in the presence of vary headers.
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_VaryMismatch)1641*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_VaryMismatch) {
1642*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1643*6777b538SAndroid Build Coastguard Worker 
1644*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
1645*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
1646*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n";
1647*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
1648*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=10000\n"
1649*6777b538SAndroid Build Coastguard Worker       "Vary: Foo\n";
1650*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
1651*6777b538SAndroid Build Coastguard Worker 
1652*6777b538SAndroid Build Coastguard Worker   // Attempt to read from the cache... this is a vary mismatch that must reach
1653*6777b538SAndroid Build Coastguard Worker   // the network again.
1654*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1655*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: none\r\n";
1656*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
1657*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1658*6777b538SAndroid Build Coastguard Worker                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1659*6777b538SAndroid Build Coastguard Worker                                  &load_timing_info);
1660*6777b538SAndroid Build Coastguard Worker 
1661*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1662*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
1663*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1664*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
1665*6777b538SAndroid Build Coastguard Worker }
1666*6777b538SAndroid Build Coastguard Worker 
1667*6777b538SAndroid Build Coastguard Worker // Tests that we honor Vary: * with LOAD_SKIP_CACHE_VALIDATION (crbug/778681)
TEST_F(HttpCacheTest,SimpleGET_LoadSkipCacheValidation_VaryStar)1668*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadSkipCacheValidation_VaryStar) {
1669*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1670*6777b538SAndroid Build Coastguard Worker 
1671*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
1672*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
1673*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
1674*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=10000\n"
1675*6777b538SAndroid Build Coastguard Worker       "Vary: *\n";
1676*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
1677*6777b538SAndroid Build Coastguard Worker 
1678*6777b538SAndroid Build Coastguard Worker   // Attempt to read from the cache... we will still load it from network,
1679*6777b538SAndroid Build Coastguard Worker   // since Vary: * doesn't match.
1680*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1681*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
1682*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1683*6777b538SAndroid Build Coastguard Worker                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1684*6777b538SAndroid Build Coastguard Worker                                  &load_timing_info);
1685*6777b538SAndroid Build Coastguard Worker 
1686*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1687*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
1688*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1689*6777b538SAndroid Build Coastguard Worker }
1690*6777b538SAndroid Build Coastguard Worker 
1691*6777b538SAndroid Build Coastguard Worker // Tests that was_cached was set properly on a failure, even if the cached
1692*6777b538SAndroid Build Coastguard Worker // response wasn't returned.
TEST_F(HttpCacheTest,SimpleGET_CacheSignal_Failure)1693*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_CacheSignal_Failure) {
1694*6777b538SAndroid Build Coastguard Worker   for (bool use_memory_entry_data : {false, true}) {
1695*6777b538SAndroid Build Coastguard Worker     MockHttpCache cache;
1696*6777b538SAndroid Build Coastguard Worker     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
1697*6777b538SAndroid Build Coastguard Worker 
1698*6777b538SAndroid Build Coastguard Worker     // Prime cache.
1699*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kSimpleGET_Transaction);
1700*6777b538SAndroid Build Coastguard Worker     transaction.response_headers = "Cache-Control: no-cache\n";
1701*6777b538SAndroid Build Coastguard Worker 
1702*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
1703*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
1704*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
1705*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache.disk_cache()->open_count());
1706*6777b538SAndroid Build Coastguard Worker 
1707*6777b538SAndroid Build Coastguard Worker     // Network failure with error; should fail but have was_cached set.
1708*6777b538SAndroid Build Coastguard Worker     transaction.start_return_code = ERR_FAILED;
1709*6777b538SAndroid Build Coastguard Worker 
1710*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
1711*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
1712*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
1713*6777b538SAndroid Build Coastguard Worker     int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
1714*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(rv, IsOk());
1715*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(trans.get());
1716*6777b538SAndroid Build Coastguard Worker     rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1717*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.GetResult(rv), IsError(ERR_FAILED));
1718*6777b538SAndroid Build Coastguard Worker 
1719*6777b538SAndroid Build Coastguard Worker     const HttpResponseInfo* response_info = trans->GetResponseInfo();
1720*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response_info);
1721*6777b538SAndroid Build Coastguard Worker     // If use_memory_entry_data is true, we will not bother opening the entry,
1722*6777b538SAndroid Build Coastguard Worker     // and just kick it out, so was_cached will end up false.
1723*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.network_layer()->transaction_count());
1724*6777b538SAndroid Build Coastguard Worker     if (use_memory_entry_data) {
1725*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(false, response_info->was_cached);
1726*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(2, cache.disk_cache()->create_count());
1727*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(0, cache.disk_cache()->open_count());
1728*6777b538SAndroid Build Coastguard Worker     } else {
1729*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(true, response_info->was_cached);
1730*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(1, cache.disk_cache()->create_count());
1731*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(1, cache.disk_cache()->open_count());
1732*6777b538SAndroid Build Coastguard Worker     }
1733*6777b538SAndroid Build Coastguard Worker   }
1734*6777b538SAndroid Build Coastguard Worker }
1735*6777b538SAndroid Build Coastguard Worker 
1736*6777b538SAndroid Build Coastguard Worker // Tests that if the transaction is destroyed right after setting the
1737*6777b538SAndroid Build Coastguard Worker // cache_entry_status_ as CANT_CONDITIONALIZE, then RecordHistograms should not
1738*6777b538SAndroid Build Coastguard Worker // hit a dcheck.
TEST_F(HttpCacheTest,RecordHistogramsCantConditionalize)1739*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RecordHistogramsCantConditionalize) {
1740*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1741*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_support_in_memory_entry_data(true);
1742*6777b538SAndroid Build Coastguard Worker 
1743*6777b538SAndroid Build Coastguard Worker   {
1744*6777b538SAndroid Build Coastguard Worker     // Prime cache.
1745*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kSimpleGET_Transaction);
1746*6777b538SAndroid Build Coastguard Worker     transaction.response_headers = "Cache-Control: no-cache\n";
1747*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
1748*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
1749*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
1750*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache.disk_cache()->open_count());
1751*6777b538SAndroid Build Coastguard Worker   }
1752*6777b538SAndroid Build Coastguard Worker 
1753*6777b538SAndroid Build Coastguard Worker   {
1754*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kSimpleGET_Transaction);
1755*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
1756*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
1757*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
1758*6777b538SAndroid Build Coastguard Worker     int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
1759*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(rv, IsOk());
1760*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(trans.get());
1761*6777b538SAndroid Build Coastguard Worker     rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1762*6777b538SAndroid Build Coastguard Worker     // Now destroy the transaction so that RecordHistograms gets invoked.
1763*6777b538SAndroid Build Coastguard Worker     trans.reset();
1764*6777b538SAndroid Build Coastguard Worker   }
1765*6777b538SAndroid Build Coastguard Worker }
1766*6777b538SAndroid Build Coastguard Worker 
1767*6777b538SAndroid Build Coastguard Worker // Confirm if we have an empty cache, a read is marked as network verified.
TEST_F(HttpCacheTest,SimpleGET_NetworkAccessed_Network)1768*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_NetworkAccessed_Network) {
1769*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1770*6777b538SAndroid Build Coastguard Worker 
1771*6777b538SAndroid Build Coastguard Worker   // write to the cache
1772*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
1773*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1774*6777b538SAndroid Build Coastguard Worker                                      &response_info);
1775*6777b538SAndroid Build Coastguard Worker 
1776*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1777*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
1778*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1779*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.network_accessed);
1780*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CacheEntryStatus::ENTRY_NOT_IN_CACHE,
1781*6777b538SAndroid Build Coastguard Worker             response_info.cache_entry_status);
1782*6777b538SAndroid Build Coastguard Worker }
1783*6777b538SAndroid Build Coastguard Worker 
1784*6777b538SAndroid Build Coastguard Worker // Confirm if we have a fresh entry in cache, it isn't marked as
1785*6777b538SAndroid Build Coastguard Worker // network verified.
TEST_F(HttpCacheTest,SimpleGET_NetworkAccessed_Cache)1786*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_NetworkAccessed_Cache) {
1787*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1788*6777b538SAndroid Build Coastguard Worker 
1789*6777b538SAndroid Build Coastguard Worker   // Prime cache.
1790*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
1791*6777b538SAndroid Build Coastguard Worker 
1792*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
1793*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1794*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1795*6777b538SAndroid Build Coastguard Worker 
1796*6777b538SAndroid Build Coastguard Worker   // Re-run transaction; make sure we don't mark the network as accessed.
1797*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
1798*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1799*6777b538SAndroid Build Coastguard Worker                                      &response_info);
1800*6777b538SAndroid Build Coastguard Worker 
1801*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1802*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.network_accessed);
1803*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CacheEntryStatus::ENTRY_USED, response_info.cache_entry_status);
1804*6777b538SAndroid Build Coastguard Worker }
1805*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache)1806*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache) {
1807*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1808*6777b538SAndroid Build Coastguard Worker 
1809*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
1810*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1811*6777b538SAndroid Build Coastguard Worker 
1812*6777b538SAndroid Build Coastguard Worker   // Force this transaction to write to the cache again.
1813*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
1814*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_BYPASS_CACHE;
1815*6777b538SAndroid Build Coastguard Worker 
1816*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_observer;
1817*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
1818*6777b538SAndroid Build Coastguard Worker 
1819*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
1820*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1821*6777b538SAndroid Build Coastguard Worker                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1822*6777b538SAndroid Build Coastguard Worker                                  &load_timing_info);
1823*6777b538SAndroid Build Coastguard Worker 
1824*6777b538SAndroid Build Coastguard Worker   // Check that the NetLog was filled as expected.
1825*6777b538SAndroid Build Coastguard Worker   auto entries = GetFilteredNetLogEntries(net_log_observer);
1826*6777b538SAndroid Build Coastguard Worker 
1827*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(8u, entries.size());
1828*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1829*6777b538SAndroid Build Coastguard Worker                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1830*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1831*6777b538SAndroid Build Coastguard Worker       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1832*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(entries, 2,
1833*6777b538SAndroid Build Coastguard Worker                                     NetLogEventType::HTTP_CACHE_DOOM_ENTRY));
1834*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1835*6777b538SAndroid Build Coastguard Worker       LogContainsEndEvent(entries, 3, NetLogEventType::HTTP_CACHE_DOOM_ENTRY));
1836*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1837*6777b538SAndroid Build Coastguard Worker                                     NetLogEventType::HTTP_CACHE_CREATE_ENTRY));
1838*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1839*6777b538SAndroid Build Coastguard Worker                                   NetLogEventType::HTTP_CACHE_CREATE_ENTRY));
1840*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(entries, 6,
1841*6777b538SAndroid Build Coastguard Worker                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1842*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEndEvent(entries, 7,
1843*6777b538SAndroid Build Coastguard Worker                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1844*6777b538SAndroid Build Coastguard Worker 
1845*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1846*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
1847*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
1848*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
1849*6777b538SAndroid Build Coastguard Worker }
1850*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache_Implicit)1851*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache_Implicit) {
1852*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1853*6777b538SAndroid Build Coastguard Worker 
1854*6777b538SAndroid Build Coastguard Worker   // write to the cache
1855*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1856*6777b538SAndroid Build Coastguard Worker 
1857*6777b538SAndroid Build Coastguard Worker   // force this transaction to write to the cache again
1858*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
1859*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "pragma: no-cache\r\n";
1860*6777b538SAndroid Build Coastguard Worker 
1861*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
1862*6777b538SAndroid Build Coastguard Worker 
1863*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1864*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
1865*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
1866*6777b538SAndroid Build Coastguard Worker }
1867*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache_Implicit2)1868*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache_Implicit2) {
1869*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1870*6777b538SAndroid Build Coastguard Worker 
1871*6777b538SAndroid Build Coastguard Worker   // write to the cache
1872*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1873*6777b538SAndroid Build Coastguard Worker 
1874*6777b538SAndroid Build Coastguard Worker   // force this transaction to write to the cache again
1875*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
1876*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "cache-control: no-cache\r\n";
1877*6777b538SAndroid Build Coastguard Worker 
1878*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
1879*6777b538SAndroid Build Coastguard Worker 
1880*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1881*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
1882*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
1883*6777b538SAndroid Build Coastguard Worker }
1884*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_LoadValidateCache)1885*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadValidateCache) {
1886*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1887*6777b538SAndroid Build Coastguard Worker 
1888*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
1889*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1890*6777b538SAndroid Build Coastguard Worker 
1891*6777b538SAndroid Build Coastguard Worker   // Read from the cache.
1892*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1893*6777b538SAndroid Build Coastguard Worker 
1894*6777b538SAndroid Build Coastguard Worker   // Force this transaction to validate the cache.
1895*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
1896*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
1897*6777b538SAndroid Build Coastguard Worker 
1898*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
1899*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
1900*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
1901*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), transaction, &response_info,
1902*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
1903*6777b538SAndroid Build Coastguard Worker 
1904*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1905*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
1906*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1907*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.network_accessed);
1908*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
1909*6777b538SAndroid Build Coastguard Worker }
1910*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_LoadValidateCache_Implicit)1911*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_LoadValidateCache_Implicit) {
1912*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1913*6777b538SAndroid Build Coastguard Worker 
1914*6777b538SAndroid Build Coastguard Worker   // write to the cache
1915*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1916*6777b538SAndroid Build Coastguard Worker 
1917*6777b538SAndroid Build Coastguard Worker   // read from the cache
1918*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1919*6777b538SAndroid Build Coastguard Worker 
1920*6777b538SAndroid Build Coastguard Worker   // force this transaction to validate the cache
1921*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
1922*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "cache-control: max-age=0\r\n";
1923*6777b538SAndroid Build Coastguard Worker 
1924*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
1925*6777b538SAndroid Build Coastguard Worker 
1926*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1927*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
1928*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
1929*6777b538SAndroid Build Coastguard Worker }
1930*6777b538SAndroid Build Coastguard Worker 
1931*6777b538SAndroid Build Coastguard Worker // Tests that |unused_since_prefetch| is updated accordingly (e.g. it is set to
1932*6777b538SAndroid Build Coastguard Worker // true after a prefetch and set back to false when the prefetch is used).
TEST_F(HttpCacheTest,SimpleGET_UnusedSincePrefetch)1933*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_UnusedSincePrefetch) {
1934*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1935*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
1936*6777b538SAndroid Build Coastguard Worker 
1937*6777b538SAndroid Build Coastguard Worker   // A normal load does not have |unused_since_prefetch| set.
1938*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
1939*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), kSimpleGET_Transaction, &response_info,
1940*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1941*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.unused_since_prefetch);
1942*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.was_cached);
1943*6777b538SAndroid Build Coastguard Worker 
1944*6777b538SAndroid Build Coastguard Worker   // The prefetch itself does not have |unused_since_prefetch| set.
1945*6777b538SAndroid Build Coastguard Worker   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
1946*6777b538SAndroid Build Coastguard Worker   prefetch_transaction.load_flags |= LOAD_PREFETCH;
1947*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
1948*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), prefetch_transaction, &response_info,
1949*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1950*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.unused_since_prefetch);
1951*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.was_cached);
1952*6777b538SAndroid Build Coastguard Worker 
1953*6777b538SAndroid Build Coastguard Worker   // A duplicated prefetch has |unused_since_prefetch| set.
1954*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
1955*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), prefetch_transaction, &response_info,
1956*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1957*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.unused_since_prefetch);
1958*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.was_cached);
1959*6777b538SAndroid Build Coastguard Worker 
1960*6777b538SAndroid Build Coastguard Worker   // |unused_since_prefetch| is still true after two prefetches in a row.
1961*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
1962*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), kSimpleGET_Transaction, &response_info,
1963*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1964*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.unused_since_prefetch);
1965*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.was_cached);
1966*6777b538SAndroid Build Coastguard Worker 
1967*6777b538SAndroid Build Coastguard Worker   // The resource has now been used, back to normal behavior.
1968*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
1969*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), kSimpleGET_Transaction, &response_info,
1970*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1971*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.unused_since_prefetch);
1972*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.was_cached);
1973*6777b538SAndroid Build Coastguard Worker }
1974*6777b538SAndroid Build Coastguard Worker 
1975*6777b538SAndroid Build Coastguard Worker // Tests that requests made with the LOAD_RESTRICTED_PREFETCH load flag result
1976*6777b538SAndroid Build Coastguard Worker // in HttpResponseInfo entries with the |restricted_prefetch| flag set. Also
1977*6777b538SAndroid Build Coastguard Worker // tests that responses with |restricted_prefetch| flag set can only be used by
1978*6777b538SAndroid Build Coastguard Worker // requests that have the LOAD_CAN_USE_RESTRICTED_PREFETCH load flag.
TEST_F(HttpCacheTest,SimpleGET_RestrictedPrefetchIsRestrictedUntilReuse)1979*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_RestrictedPrefetchIsRestrictedUntilReuse) {
1980*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
1981*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
1982*6777b538SAndroid Build Coastguard Worker 
1983*6777b538SAndroid Build Coastguard Worker   // A normal load does not have |restricted_prefetch| set.
1984*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
1985*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), kTypicalGET_Transaction, &response_info,
1986*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1987*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.restricted_prefetch);
1988*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.was_cached);
1989*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.network_accessed);
1990*6777b538SAndroid Build Coastguard Worker 
1991*6777b538SAndroid Build Coastguard Worker   // A restricted prefetch is marked as |restricted_prefetch|.
1992*6777b538SAndroid Build Coastguard Worker   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
1993*6777b538SAndroid Build Coastguard Worker   prefetch_transaction.load_flags |= LOAD_PREFETCH;
1994*6777b538SAndroid Build Coastguard Worker   prefetch_transaction.load_flags |= LOAD_RESTRICTED_PREFETCH;
1995*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
1996*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), prefetch_transaction, &response_info,
1997*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1998*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.restricted_prefetch);
1999*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.was_cached);
2000*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.network_accessed);
2001*6777b538SAndroid Build Coastguard Worker 
2002*6777b538SAndroid Build Coastguard Worker   // Requests that are marked as able to reuse restricted prefetches can do so
2003*6777b538SAndroid Build Coastguard Worker   // correctly. Once it is reused, it is no longer considered as or marked
2004*6777b538SAndroid Build Coastguard Worker   // restricted.
2005*6777b538SAndroid Build Coastguard Worker   MockTransaction can_use_restricted_prefetch_transaction(
2006*6777b538SAndroid Build Coastguard Worker       kSimpleGET_Transaction);
2007*6777b538SAndroid Build Coastguard Worker   can_use_restricted_prefetch_transaction.load_flags |=
2008*6777b538SAndroid Build Coastguard Worker       LOAD_CAN_USE_RESTRICTED_PREFETCH;
2009*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
2010*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), can_use_restricted_prefetch_transaction,
2011*6777b538SAndroid Build Coastguard Worker       &response_info, NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2012*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.restricted_prefetch);
2013*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.was_cached);
2014*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.network_accessed);
2015*6777b538SAndroid Build Coastguard Worker 
2016*6777b538SAndroid Build Coastguard Worker   // Later reuse is still no longer marked restricted.
2017*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
2018*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2019*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2020*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.restricted_prefetch);
2021*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.was_cached);
2022*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.network_accessed);
2023*6777b538SAndroid Build Coastguard Worker }
2024*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_RestrictedPrefetchReuseIsLimited)2025*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_RestrictedPrefetchReuseIsLimited) {
2026*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2027*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
2028*6777b538SAndroid Build Coastguard Worker 
2029*6777b538SAndroid Build Coastguard Worker   // A restricted prefetch is marked as |restricted_prefetch|.
2030*6777b538SAndroid Build Coastguard Worker   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
2031*6777b538SAndroid Build Coastguard Worker   prefetch_transaction.load_flags |= LOAD_PREFETCH;
2032*6777b538SAndroid Build Coastguard Worker   prefetch_transaction.load_flags |= LOAD_RESTRICTED_PREFETCH;
2033*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
2034*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), prefetch_transaction, &response_info,
2035*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2036*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.restricted_prefetch);
2037*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.was_cached);
2038*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.network_accessed);
2039*6777b538SAndroid Build Coastguard Worker 
2040*6777b538SAndroid Build Coastguard Worker   // Requests that cannot reuse restricted prefetches fail to do so. The network
2041*6777b538SAndroid Build Coastguard Worker   // is accessed and the resulting response is not marked as
2042*6777b538SAndroid Build Coastguard Worker   // |restricted_prefetch|.
2043*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
2044*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2045*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2046*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.restricted_prefetch);
2047*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.was_cached);
2048*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.network_accessed);
2049*6777b538SAndroid Build Coastguard Worker 
2050*6777b538SAndroid Build Coastguard Worker   // Future requests that are not marked as able to reuse restricted prefetches
2051*6777b538SAndroid Build Coastguard Worker   // can use the entry in the cache now, since it has been evicted in favor of
2052*6777b538SAndroid Build Coastguard Worker   // an unrestricted one.
2053*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
2054*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2055*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2056*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.restricted_prefetch);
2057*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.was_cached);
2058*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.network_accessed);
2059*6777b538SAndroid Build Coastguard Worker }
2060*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_UnusedSincePrefetchWriteError)2061*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_UnusedSincePrefetchWriteError) {
2062*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2063*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
2064*6777b538SAndroid Build Coastguard Worker 
2065*6777b538SAndroid Build Coastguard Worker   // Do a prefetch.
2066*6777b538SAndroid Build Coastguard Worker   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
2067*6777b538SAndroid Build Coastguard Worker   prefetch_transaction.load_flags |= LOAD_PREFETCH;
2068*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
2069*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), prefetch_transaction, &response_info,
2070*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2071*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.unused_since_prefetch);
2072*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.was_cached);
2073*6777b538SAndroid Build Coastguard Worker 
2074*6777b538SAndroid Build Coastguard Worker   // Try to use it while injecting a failure on write.
2075*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_WRITE);
2076*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfoAndGetTiming(
2077*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2078*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2079*6777b538SAndroid Build Coastguard Worker }
2080*6777b538SAndroid Build Coastguard Worker 
2081*6777b538SAndroid Build Coastguard Worker // Make sure that if a prefetch entry is truncated, then an attempt to re-use it
2082*6777b538SAndroid Build Coastguard Worker // gets aborted in connected handler that truncated bit is not lost.
TEST_F(HttpCacheTest,PrefetchTruncateCancelInConnectedCallback)2083*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, PrefetchTruncateCancelInConnectedCallback) {
2084*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2085*6777b538SAndroid Build Coastguard Worker 
2086*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
2087*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
2088*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2089*6777b538SAndroid Build Coastguard Worker       "Content-Length: 20\n"
2090*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n";
2091*6777b538SAndroid Build Coastguard Worker   transaction.data = "01234567890123456789";
2092*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_PREFETCH | LOAD_CAN_USE_RESTRICTED_PREFETCH;
2093*6777b538SAndroid Build Coastguard Worker 
2094*6777b538SAndroid Build Coastguard Worker   // Do a truncated read of a prefetch request.
2095*6777b538SAndroid Build Coastguard Worker   {
2096*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
2097*6777b538SAndroid Build Coastguard Worker     Context c;
2098*6777b538SAndroid Build Coastguard Worker 
2099*6777b538SAndroid Build Coastguard Worker     int rv = cache.CreateTransaction(&c.trans);
2100*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(rv, IsOk());
2101*6777b538SAndroid Build Coastguard Worker 
2102*6777b538SAndroid Build Coastguard Worker     rv = c.callback.GetResult(
2103*6777b538SAndroid Build Coastguard Worker         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2104*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(rv, IsOk());
2105*6777b538SAndroid Build Coastguard Worker 
2106*6777b538SAndroid Build Coastguard Worker     // Read less than the whole thing.
2107*6777b538SAndroid Build Coastguard Worker     scoped_refptr<IOBufferWithSize> buf =
2108*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<IOBufferWithSize>(10);
2109*6777b538SAndroid Build Coastguard Worker     rv = c.callback.GetResult(
2110*6777b538SAndroid Build Coastguard Worker         c.trans->Read(buf.get(), buf->size(), c.callback.callback()));
2111*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(buf->size(), rv);
2112*6777b538SAndroid Build Coastguard Worker 
2113*6777b538SAndroid Build Coastguard Worker     // Destroy the transaction.
2114*6777b538SAndroid Build Coastguard Worker     c.trans.reset();
2115*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
2116*6777b538SAndroid Build Coastguard Worker 
2117*6777b538SAndroid Build Coastguard Worker     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2118*6777b538SAndroid Build Coastguard Worker                         /*data_size=*/10);
2119*6777b538SAndroid Build Coastguard Worker   }
2120*6777b538SAndroid Build Coastguard Worker 
2121*6777b538SAndroid Build Coastguard Worker   // Do a fetch that can use prefetch that aborts in connected handler.
2122*6777b538SAndroid Build Coastguard Worker   transaction.load_flags &= ~LOAD_PREFETCH;
2123*6777b538SAndroid Build Coastguard Worker   {
2124*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
2125*6777b538SAndroid Build Coastguard Worker     Context c;
2126*6777b538SAndroid Build Coastguard Worker 
2127*6777b538SAndroid Build Coastguard Worker     int rv = cache.CreateTransaction(&c.trans);
2128*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(rv, IsOk());
2129*6777b538SAndroid Build Coastguard Worker     c.trans->SetConnectedCallback(base::BindRepeating(
2130*6777b538SAndroid Build Coastguard Worker         [](const TransportInfo& info, CompletionOnceCallback callback) -> int {
2131*6777b538SAndroid Build Coastguard Worker           return net::ERR_ABORTED;
2132*6777b538SAndroid Build Coastguard Worker         }));
2133*6777b538SAndroid Build Coastguard Worker     rv = c.callback.GetResult(
2134*6777b538SAndroid Build Coastguard Worker         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2135*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::ERR_ABORTED, rv);
2136*6777b538SAndroid Build Coastguard Worker 
2137*6777b538SAndroid Build Coastguard Worker     // Destroy the transaction.
2138*6777b538SAndroid Build Coastguard Worker     c.trans.reset();
2139*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
2140*6777b538SAndroid Build Coastguard Worker 
2141*6777b538SAndroid Build Coastguard Worker     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2142*6777b538SAndroid Build Coastguard Worker                         /*data_size=*/10);
2143*6777b538SAndroid Build Coastguard Worker   }
2144*6777b538SAndroid Build Coastguard Worker 
2145*6777b538SAndroid Build Coastguard Worker   // Now try again without abort.
2146*6777b538SAndroid Build Coastguard Worker   {
2147*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
2148*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
2149*6777b538SAndroid Build Coastguard Worker                                   /*response_info=*/nullptr);
2150*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
2151*6777b538SAndroid Build Coastguard Worker 
2152*6777b538SAndroid Build Coastguard Worker     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/false,
2153*6777b538SAndroid Build Coastguard Worker                         /*data_size=*/20);
2154*6777b538SAndroid Build Coastguard Worker   }
2155*6777b538SAndroid Build Coastguard Worker }
2156*6777b538SAndroid Build Coastguard Worker 
2157*6777b538SAndroid Build Coastguard Worker // Make sure that if a stale-while-revalidate entry is truncated, then an
2158*6777b538SAndroid Build Coastguard Worker // attempt to re-use it gets aborted in connected handler that truncated bit is
2159*6777b538SAndroid Build Coastguard Worker // not lost.
TEST_F(HttpCacheTest,StaleWhiteRevalidateTruncateCancelInConnectedCallback)2160*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, StaleWhiteRevalidateTruncateCancelInConnectedCallback) {
2161*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2162*6777b538SAndroid Build Coastguard Worker 
2163*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
2164*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
2165*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2166*6777b538SAndroid Build Coastguard Worker       "Content-Length: 20\n"
2167*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0, stale-while-revalidate=60\n"
2168*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n";
2169*6777b538SAndroid Build Coastguard Worker   transaction.data = "01234567890123456789";
2170*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_SUPPORT_ASYNC_REVALIDATION;
2171*6777b538SAndroid Build Coastguard Worker 
2172*6777b538SAndroid Build Coastguard Worker   // Do a truncated read of a stale-while-revalidate resource.
2173*6777b538SAndroid Build Coastguard Worker   {
2174*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
2175*6777b538SAndroid Build Coastguard Worker     Context c;
2176*6777b538SAndroid Build Coastguard Worker 
2177*6777b538SAndroid Build Coastguard Worker     int rv = cache.CreateTransaction(&c.trans);
2178*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(rv, IsOk());
2179*6777b538SAndroid Build Coastguard Worker 
2180*6777b538SAndroid Build Coastguard Worker     rv = c.callback.GetResult(
2181*6777b538SAndroid Build Coastguard Worker         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2182*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(rv, IsOk());
2183*6777b538SAndroid Build Coastguard Worker 
2184*6777b538SAndroid Build Coastguard Worker     // Read less than the whole thing.
2185*6777b538SAndroid Build Coastguard Worker     scoped_refptr<IOBufferWithSize> buf =
2186*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<IOBufferWithSize>(10);
2187*6777b538SAndroid Build Coastguard Worker     rv = c.callback.GetResult(
2188*6777b538SAndroid Build Coastguard Worker         c.trans->Read(buf.get(), buf->size(), c.callback.callback()));
2189*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(buf->size(), rv);
2190*6777b538SAndroid Build Coastguard Worker 
2191*6777b538SAndroid Build Coastguard Worker     // Destroy the transaction.
2192*6777b538SAndroid Build Coastguard Worker     c.trans.reset();
2193*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
2194*6777b538SAndroid Build Coastguard Worker 
2195*6777b538SAndroid Build Coastguard Worker     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2196*6777b538SAndroid Build Coastguard Worker                         /*data_size=*/10);
2197*6777b538SAndroid Build Coastguard Worker   }
2198*6777b538SAndroid Build Coastguard Worker 
2199*6777b538SAndroid Build Coastguard Worker   // Do a fetch that uses that resource that aborts in connected handler.
2200*6777b538SAndroid Build Coastguard Worker   {
2201*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
2202*6777b538SAndroid Build Coastguard Worker     Context c;
2203*6777b538SAndroid Build Coastguard Worker 
2204*6777b538SAndroid Build Coastguard Worker     int rv = cache.CreateTransaction(&c.trans);
2205*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(rv, IsOk());
2206*6777b538SAndroid Build Coastguard Worker     c.trans->SetConnectedCallback(base::BindRepeating(
2207*6777b538SAndroid Build Coastguard Worker         [](const TransportInfo& info, CompletionOnceCallback callback) -> int {
2208*6777b538SAndroid Build Coastguard Worker           return net::ERR_ABORTED;
2209*6777b538SAndroid Build Coastguard Worker         }));
2210*6777b538SAndroid Build Coastguard Worker     rv = c.callback.GetResult(
2211*6777b538SAndroid Build Coastguard Worker         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2212*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::ERR_ABORTED, rv);
2213*6777b538SAndroid Build Coastguard Worker 
2214*6777b538SAndroid Build Coastguard Worker     // Destroy the transaction.
2215*6777b538SAndroid Build Coastguard Worker     c.trans.reset();
2216*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
2217*6777b538SAndroid Build Coastguard Worker 
2218*6777b538SAndroid Build Coastguard Worker     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2219*6777b538SAndroid Build Coastguard Worker                         /*data_size=*/10);
2220*6777b538SAndroid Build Coastguard Worker   }
2221*6777b538SAndroid Build Coastguard Worker 
2222*6777b538SAndroid Build Coastguard Worker   // Now try again without abort.
2223*6777b538SAndroid Build Coastguard Worker   {
2224*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
2225*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
2226*6777b538SAndroid Build Coastguard Worker                                   /*response_info=*/nullptr);
2227*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
2228*6777b538SAndroid Build Coastguard Worker 
2229*6777b538SAndroid Build Coastguard Worker     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/false,
2230*6777b538SAndroid Build Coastguard Worker                         /*data_size=*/20);
2231*6777b538SAndroid Build Coastguard Worker   }
2232*6777b538SAndroid Build Coastguard Worker }
2233*6777b538SAndroid Build Coastguard Worker 
2234*6777b538SAndroid Build Coastguard Worker static const auto kPreserveRequestHeaders =
2235*6777b538SAndroid Build Coastguard Worker     base::BindRepeating([](const net::HttpRequestInfo* request,
2236*6777b538SAndroid Build Coastguard Worker                            std::string* response_status,
2237*6777b538SAndroid Build Coastguard Worker                            std::string* response_headers,
__anone6acdaec0602(const net::HttpRequestInfo* request, std::string* response_status, std::string* response_headers, std::string* response_data) 2238*6777b538SAndroid Build Coastguard Worker                            std::string* response_data) {
2239*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
2240*6777b538SAndroid Build Coastguard Worker     });
2241*6777b538SAndroid Build Coastguard Worker 
2242*6777b538SAndroid Build Coastguard Worker // Tests that we don't remove extra headers for simple requests.
TEST_F(HttpCacheTest,SimpleGET_PreserveRequestHeaders)2243*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_PreserveRequestHeaders) {
2244*6777b538SAndroid Build Coastguard Worker   for (bool use_memory_entry_data : {false, true}) {
2245*6777b538SAndroid Build Coastguard Worker     MockHttpCache cache;
2246*6777b538SAndroid Build Coastguard Worker     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
2247*6777b538SAndroid Build Coastguard Worker 
2248*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kSimpleGET_Transaction);
2249*6777b538SAndroid Build Coastguard Worker     transaction.handler = kPreserveRequestHeaders;
2250*6777b538SAndroid Build Coastguard Worker     transaction.request_headers = EXTRA_HEADER;
2251*6777b538SAndroid Build Coastguard Worker     transaction.response_headers = "Cache-Control: max-age=0\n";
2252*6777b538SAndroid Build Coastguard Worker 
2253*6777b538SAndroid Build Coastguard Worker     // Write, then revalidate the entry.
2254*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
2255*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
2256*6777b538SAndroid Build Coastguard Worker 
2257*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2258*6777b538SAndroid Build Coastguard Worker 
2259*6777b538SAndroid Build Coastguard Worker     // If the backend supports memory entry data, we can figure out that the
2260*6777b538SAndroid Build Coastguard Worker     // entry has caching-hostile headers w/o opening it.
2261*6777b538SAndroid Build Coastguard Worker     if (use_memory_entry_data) {
2262*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(0, cache.disk_cache()->open_count());
2263*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(2, cache.disk_cache()->create_count());
2264*6777b538SAndroid Build Coastguard Worker     } else {
2265*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(1, cache.disk_cache()->open_count());
2266*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(1, cache.disk_cache()->create_count());
2267*6777b538SAndroid Build Coastguard Worker     }
2268*6777b538SAndroid Build Coastguard Worker   }
2269*6777b538SAndroid Build Coastguard Worker }
2270*6777b538SAndroid Build Coastguard Worker 
2271*6777b538SAndroid Build Coastguard Worker // Tests that we don't remove extra headers for conditionalized requests.
TEST_F(HttpCacheTest,ConditionalizedGET_PreserveRequestHeaders)2272*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ConditionalizedGET_PreserveRequestHeaders) {
2273*6777b538SAndroid Build Coastguard Worker   for (bool use_memory_entry_data : {false, true}) {
2274*6777b538SAndroid Build Coastguard Worker     MockHttpCache cache;
2275*6777b538SAndroid Build Coastguard Worker     // Unlike in SimpleGET_PreserveRequestHeaders, this entry can be
2276*6777b538SAndroid Build Coastguard Worker     // conditionalized, so memory hints don't affect behavior.
2277*6777b538SAndroid Build Coastguard Worker     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
2278*6777b538SAndroid Build Coastguard Worker 
2279*6777b538SAndroid Build Coastguard Worker     // Write to the cache.
2280*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
2281*6777b538SAndroid Build Coastguard Worker 
2282*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kETagGET_Transaction);
2283*6777b538SAndroid Build Coastguard Worker     transaction.handler = kPreserveRequestHeaders;
2284*6777b538SAndroid Build Coastguard Worker     transaction.request_headers = "If-None-Match: \"foopy\"\r\n" EXTRA_HEADER;
2285*6777b538SAndroid Build Coastguard Worker 
2286*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
2287*6777b538SAndroid Build Coastguard Worker 
2288*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2289*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->open_count());
2290*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
2291*6777b538SAndroid Build Coastguard Worker   }
2292*6777b538SAndroid Build Coastguard Worker }
2293*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_ManyReaders)2294*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ManyReaders) {
2295*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2296*6777b538SAndroid Build Coastguard Worker 
2297*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
2298*6777b538SAndroid Build Coastguard Worker 
2299*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
2300*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 5;
2301*6777b538SAndroid Build Coastguard Worker 
2302*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
2303*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
2304*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
2305*6777b538SAndroid Build Coastguard Worker 
2306*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
2307*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
2308*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2309*6777b538SAndroid Build Coastguard Worker 
2310*6777b538SAndroid Build Coastguard Worker     c->result =
2311*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2312*6777b538SAndroid Build Coastguard Worker   }
2313*6777b538SAndroid Build Coastguard Worker 
2314*6777b538SAndroid Build Coastguard Worker   // All requests are waiting for the active entry.
2315*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
2316*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
2317*6777b538SAndroid Build Coastguard Worker   }
2318*6777b538SAndroid Build Coastguard Worker 
2319*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
2320*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
2321*6777b538SAndroid Build Coastguard Worker 
2322*6777b538SAndroid Build Coastguard Worker   // All requests are added to writers.
2323*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
2324*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
2325*6777b538SAndroid Build Coastguard Worker 
2326*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2327*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
2328*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
2329*6777b538SAndroid Build Coastguard Worker 
2330*6777b538SAndroid Build Coastguard Worker   // All requests are between Start and Read, i.e. idle.
2331*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
2332*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2333*6777b538SAndroid Build Coastguard Worker   }
2334*6777b538SAndroid Build Coastguard Worker 
2335*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
2336*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
2337*6777b538SAndroid Build Coastguard Worker     if (c->result == ERR_IO_PENDING) {
2338*6777b538SAndroid Build Coastguard Worker       c->result = c->callback.WaitForResult();
2339*6777b538SAndroid Build Coastguard Worker     }
2340*6777b538SAndroid Build Coastguard Worker 
2341*6777b538SAndroid Build Coastguard Worker     // After the 1st transaction has completed the response, all transactions
2342*6777b538SAndroid Build Coastguard Worker     // get added to readers.
2343*6777b538SAndroid Build Coastguard Worker     if (i > 0) {
2344*6777b538SAndroid Build Coastguard Worker       EXPECT_FALSE(cache.IsWriterPresent(cache_key));
2345*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(kNumTransactions - i, cache.GetCountReaders(cache_key));
2346*6777b538SAndroid Build Coastguard Worker     }
2347*6777b538SAndroid Build Coastguard Worker 
2348*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
2349*6777b538SAndroid Build Coastguard Worker   }
2350*6777b538SAndroid Build Coastguard Worker 
2351*6777b538SAndroid Build Coastguard Worker   // We should not have had to re-open the disk entry
2352*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2353*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
2354*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
2355*6777b538SAndroid Build Coastguard Worker }
2356*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,RangeGET_FullAfterPartial)2357*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_FullAfterPartial) {
2358*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2359*6777b538SAndroid Build Coastguard Worker 
2360*6777b538SAndroid Build Coastguard Worker   // Request a prefix.
2361*6777b538SAndroid Build Coastguard Worker   {
2362*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2363*6777b538SAndroid Build Coastguard Worker     transaction_pre.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
2364*6777b538SAndroid Build Coastguard Worker     transaction_pre.data = "rg: 00-09 ";
2365*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request_pre(transaction_pre);
2366*6777b538SAndroid Build Coastguard Worker 
2367*6777b538SAndroid Build Coastguard Worker     HttpResponseInfo response_pre;
2368*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2369*6777b538SAndroid Build Coastguard Worker                                   request_pre, &response_pre);
2370*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response_pre.headers != nullptr);
2371*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(206, response_pre.headers->response_code());
2372*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2373*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache.disk_cache()->open_count());
2374*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
2375*6777b538SAndroid Build Coastguard Worker   }
2376*6777b538SAndroid Build Coastguard Worker 
2377*6777b538SAndroid Build Coastguard Worker   {
2378*6777b538SAndroid Build Coastguard Worker     // Now request the full thing, but set validation to fail. This would
2379*6777b538SAndroid Build Coastguard Worker     // previously fail in the middle of data and truncate it; current behavior
2380*6777b538SAndroid Build Coastguard Worker     // restarts it, somewhat wastefully but gets the data back.
2381*6777b538SAndroid Build Coastguard Worker     RangeTransactionServer handler;
2382*6777b538SAndroid Build Coastguard Worker     handler.set_modified(true);
2383*6777b538SAndroid Build Coastguard Worker 
2384*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction_all(kRangeGET_TransactionOK);
2385*6777b538SAndroid Build Coastguard Worker     transaction_all.request_headers = EXTRA_HEADER;
2386*6777b538SAndroid Build Coastguard Worker     transaction_all.data = "Not a range";
2387*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request_all(transaction_all);
2388*6777b538SAndroid Build Coastguard Worker 
2389*6777b538SAndroid Build Coastguard Worker     HttpResponseInfo response_all;
2390*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction_all,
2391*6777b538SAndroid Build Coastguard Worker                                   request_all, &response_all);
2392*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response_all.headers != nullptr);
2393*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(200, response_all.headers->response_code());
2394*6777b538SAndroid Build Coastguard Worker     // 1 from previous test, failed validation, and re-try.
2395*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2396*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->open_count());
2397*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
2398*6777b538SAndroid Build Coastguard Worker   }
2399*6777b538SAndroid Build Coastguard Worker }
2400*6777b538SAndroid Build Coastguard Worker 
2401*6777b538SAndroid Build Coastguard Worker // Tests that when a range request transaction becomes a writer for the first
2402*6777b538SAndroid Build Coastguard Worker // range and then fails conditionalization for the next range and decides to
2403*6777b538SAndroid Build Coastguard Worker // doom the entry, then there should not be a dcheck assertion hit.
TEST_F(HttpCacheTest,RangeGET_OverlappingRangesCouldntConditionalize)2404*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_OverlappingRangesCouldntConditionalize) {
2405*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2406*6777b538SAndroid Build Coastguard Worker 
2407*6777b538SAndroid Build Coastguard Worker   {
2408*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2409*6777b538SAndroid Build Coastguard Worker     transaction_pre.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2410*6777b538SAndroid Build Coastguard Worker     transaction_pre.data = "rg: 10-19 ";
2411*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request_pre(transaction_pre);
2412*6777b538SAndroid Build Coastguard Worker 
2413*6777b538SAndroid Build Coastguard Worker     HttpResponseInfo response_pre;
2414*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2415*6777b538SAndroid Build Coastguard Worker                                   request_pre, &response_pre);
2416*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response_pre.headers != nullptr);
2417*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(206, response_pre.headers->response_code());
2418*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2419*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache.disk_cache()->open_count());
2420*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
2421*6777b538SAndroid Build Coastguard Worker   }
2422*6777b538SAndroid Build Coastguard Worker 
2423*6777b538SAndroid Build Coastguard Worker   {
2424*6777b538SAndroid Build Coastguard Worker     // First range skips validation because the response is fresh while the
2425*6777b538SAndroid Build Coastguard Worker     // second range requires validation since that range is not present in the
2426*6777b538SAndroid Build Coastguard Worker     // cache and during validation it fails conditionalization.
2427*6777b538SAndroid Build Coastguard Worker     cache.FailConditionalizations();
2428*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2429*6777b538SAndroid Build Coastguard Worker     transaction_pre.request_headers = "Range: bytes = 10-29\r\n" EXTRA_HEADER;
2430*6777b538SAndroid Build Coastguard Worker 
2431*6777b538SAndroid Build Coastguard Worker     // TODO(crbug.com/992521): Fix this scenario to not return the cached bytes
2432*6777b538SAndroid Build Coastguard Worker     // repeatedly.
2433*6777b538SAndroid Build Coastguard Worker     transaction_pre.data = "rg: 10-19 rg: 10-19 rg: 20-29 ";
2434*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request_pre(transaction_pre);
2435*6777b538SAndroid Build Coastguard Worker     HttpResponseInfo response_pre;
2436*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2437*6777b538SAndroid Build Coastguard Worker                                   request_pre, &response_pre);
2438*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response_pre.headers != nullptr);
2439*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2440*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->open_count());
2441*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.disk_cache()->create_count());
2442*6777b538SAndroid Build Coastguard Worker   }
2443*6777b538SAndroid Build Coastguard Worker }
2444*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,RangeGET_FullAfterPartialReuse)2445*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_FullAfterPartialReuse) {
2446*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2447*6777b538SAndroid Build Coastguard Worker 
2448*6777b538SAndroid Build Coastguard Worker   // Request a prefix.
2449*6777b538SAndroid Build Coastguard Worker   {
2450*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2451*6777b538SAndroid Build Coastguard Worker     transaction_pre.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
2452*6777b538SAndroid Build Coastguard Worker     transaction_pre.data = "rg: 00-09 ";
2453*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request_pre(transaction_pre);
2454*6777b538SAndroid Build Coastguard Worker 
2455*6777b538SAndroid Build Coastguard Worker     HttpResponseInfo response_pre;
2456*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2457*6777b538SAndroid Build Coastguard Worker                                   request_pre, &response_pre);
2458*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response_pre.headers != nullptr);
2459*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(206, response_pre.headers->response_code());
2460*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2461*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache.disk_cache()->open_count());
2462*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
2463*6777b538SAndroid Build Coastguard Worker   }
2464*6777b538SAndroid Build Coastguard Worker 
2465*6777b538SAndroid Build Coastguard Worker   {
2466*6777b538SAndroid Build Coastguard Worker     // Now request the full thing, revalidating successfully, so the full
2467*6777b538SAndroid Build Coastguard Worker     // file gets stored via a sparse-entry.
2468*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction_all(kRangeGET_TransactionOK);
2469*6777b538SAndroid Build Coastguard Worker     transaction_all.request_headers = EXTRA_HEADER;
2470*6777b538SAndroid Build Coastguard Worker     transaction_all.data =
2471*6777b538SAndroid Build Coastguard Worker         "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49"
2472*6777b538SAndroid Build Coastguard Worker         " rg: 50-59 rg: 60-69 rg: 70-79 ";
2473*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request_all(transaction_all);
2474*6777b538SAndroid Build Coastguard Worker 
2475*6777b538SAndroid Build Coastguard Worker     HttpResponseInfo response_all;
2476*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction_all,
2477*6777b538SAndroid Build Coastguard Worker                                   request_all, &response_all);
2478*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response_all.headers != nullptr);
2479*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(200, response_all.headers->response_code());
2480*6777b538SAndroid Build Coastguard Worker     // 1 from previous test, validation, and second chunk
2481*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2482*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->open_count());
2483*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
2484*6777b538SAndroid Build Coastguard Worker   }
2485*6777b538SAndroid Build Coastguard Worker 
2486*6777b538SAndroid Build Coastguard Worker   {
2487*6777b538SAndroid Build Coastguard Worker     // Grab it again, should not need re-validation.
2488*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction_all2(kRangeGET_TransactionOK);
2489*6777b538SAndroid Build Coastguard Worker     transaction_all2.request_headers = EXTRA_HEADER;
2490*6777b538SAndroid Build Coastguard Worker     transaction_all2.data =
2491*6777b538SAndroid Build Coastguard Worker         "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49"
2492*6777b538SAndroid Build Coastguard Worker         " rg: 50-59 rg: 60-69 rg: 70-79 ";
2493*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request_all2(transaction_all2);
2494*6777b538SAndroid Build Coastguard Worker 
2495*6777b538SAndroid Build Coastguard Worker     HttpResponseInfo response_all2;
2496*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction_all2,
2497*6777b538SAndroid Build Coastguard Worker                                   request_all2, &response_all2);
2498*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response_all2.headers != nullptr);
2499*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(200, response_all2.headers->response_code());
2500*6777b538SAndroid Build Coastguard Worker 
2501*6777b538SAndroid Build Coastguard Worker     // Only one more cache open, no new network traffic.
2502*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2503*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.disk_cache()->open_count());
2504*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
2505*6777b538SAndroid Build Coastguard Worker   }
2506*6777b538SAndroid Build Coastguard Worker }
2507*6777b538SAndroid Build Coastguard Worker 
2508*6777b538SAndroid Build Coastguard Worker // This test verifies that the ConnectedCallback passed to a cache transaction
2509*6777b538SAndroid Build Coastguard Worker // is called once per subrange in the case of a range request with a partial
2510*6777b538SAndroid Build Coastguard Worker // cache hit.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackCalledForEachRange)2511*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackCalledForEachRange) {
2512*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2513*6777b538SAndroid Build Coastguard Worker 
2514*6777b538SAndroid Build Coastguard Worker   // Request an infix range and populate the cache with it.
2515*6777b538SAndroid Build Coastguard Worker   {
2516*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2517*6777b538SAndroid Build Coastguard Worker     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2518*6777b538SAndroid Build Coastguard Worker     mock_transaction.data = "rg: 20-29 ";
2519*6777b538SAndroid Build Coastguard Worker     mock_transaction.transport_info = TestTransportInfo();
2520*6777b538SAndroid Build Coastguard Worker 
2521*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), mock_transaction);
2522*6777b538SAndroid Build Coastguard Worker   }
2523*6777b538SAndroid Build Coastguard Worker 
2524*6777b538SAndroid Build Coastguard Worker   // Request a surrounding range and observe that the callback is called once
2525*6777b538SAndroid Build Coastguard Worker   // per subrange, as split up by cache hits.
2526*6777b538SAndroid Build Coastguard Worker   {
2527*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2528*6777b538SAndroid Build Coastguard Worker     mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2529*6777b538SAndroid Build Coastguard Worker     mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2530*6777b538SAndroid Build Coastguard Worker     mock_transaction.transport_info = TestTransportInfo();
2531*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(mock_transaction);
2532*6777b538SAndroid Build Coastguard Worker 
2533*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
2534*6777b538SAndroid Build Coastguard Worker 
2535*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
2536*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2537*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
2538*6777b538SAndroid Build Coastguard Worker 
2539*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
2540*6777b538SAndroid Build Coastguard Worker 
2541*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
2542*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
2543*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2544*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
2545*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsOk());
2546*6777b538SAndroid Build Coastguard Worker 
2547*6777b538SAndroid Build Coastguard Worker     // 1 call for the first range's network transaction.
2548*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2549*6777b538SAndroid Build Coastguard Worker                 ElementsAre(TestTransportInfo()));
2550*6777b538SAndroid Build Coastguard Worker 
2551*6777b538SAndroid Build Coastguard Worker     // Switch the endpoint for the next network transaction to observe.
2552*6777b538SAndroid Build Coastguard Worker     // For ease, we just switch the port number.
2553*6777b538SAndroid Build Coastguard Worker     //
2554*6777b538SAndroid Build Coastguard Worker     // NOTE: This works because only the mock transaction struct's address is
2555*6777b538SAndroid Build Coastguard Worker     // registered with the mocking framework - the pointee data is consulted
2556*6777b538SAndroid Build Coastguard Worker     // each time it is read.
2557*6777b538SAndroid Build Coastguard Worker     mock_transaction.transport_info = TestTransportInfoWithPort(123);
2558*6777b538SAndroid Build Coastguard Worker 
2559*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(transaction.get(), mock_transaction);
2560*6777b538SAndroid Build Coastguard Worker 
2561*6777b538SAndroid Build Coastguard Worker     // A second call for the cached range, reported as coming from the original
2562*6777b538SAndroid Build Coastguard Worker     // endpoint it was cached from. A third call for the last range's network
2563*6777b538SAndroid Build Coastguard Worker     // transaction.
2564*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2565*6777b538SAndroid Build Coastguard Worker                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo(),
2566*6777b538SAndroid Build Coastguard Worker                             TestTransportInfoWithPort(123)));
2567*6777b538SAndroid Build Coastguard Worker   }
2568*6777b538SAndroid Build Coastguard Worker }
2569*6777b538SAndroid Build Coastguard Worker 
2570*6777b538SAndroid Build Coastguard Worker // This test verifies that when the ConnectedCallback passed to a cache range
2571*6777b538SAndroid Build Coastguard Worker // transaction returns an `ERR_INCONSISTENT_IP_ADDRESS_SPACE` error during a
2572*6777b538SAndroid Build Coastguard Worker // partial read from cache, then the cache entry is invalidated.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnInconsistentIpError)2573*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackReturnInconsistentIpError) {
2574*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2575*6777b538SAndroid Build Coastguard Worker 
2576*6777b538SAndroid Build Coastguard Worker   // Request an infix range and populate the cache with it.
2577*6777b538SAndroid Build Coastguard Worker   {
2578*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2579*6777b538SAndroid Build Coastguard Worker     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2580*6777b538SAndroid Build Coastguard Worker     mock_transaction.data = "rg: 20-29 ";
2581*6777b538SAndroid Build Coastguard Worker     mock_transaction.transport_info = TestTransportInfo();
2582*6777b538SAndroid Build Coastguard Worker 
2583*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), mock_transaction);
2584*6777b538SAndroid Build Coastguard Worker   }
2585*6777b538SAndroid Build Coastguard Worker 
2586*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2587*6777b538SAndroid Build Coastguard Worker   mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2588*6777b538SAndroid Build Coastguard Worker   mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2589*6777b538SAndroid Build Coastguard Worker   mock_transaction.transport_info = TestTransportInfo();
2590*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(mock_transaction);
2591*6777b538SAndroid Build Coastguard Worker 
2592*6777b538SAndroid Build Coastguard Worker   // Request a surrounding range. This *should* be read in three parts:
2593*6777b538SAndroid Build Coastguard Worker   //
2594*6777b538SAndroid Build Coastguard Worker   // 1. for the prefix: from the network
2595*6777b538SAndroid Build Coastguard Worker   // 2. for the cached infix: from the cache
2596*6777b538SAndroid Build Coastguard Worker   // 3. for the suffix: from the network
2597*6777b538SAndroid Build Coastguard Worker   //
2598*6777b538SAndroid Build Coastguard Worker   // The connected callback returns OK for 1), but fails during 2). As a result,
2599*6777b538SAndroid Build Coastguard Worker   // the transaction fails partway and 3) is never created. The cache entry is
2600*6777b538SAndroid Build Coastguard Worker   // invalidated as a result of the specific error code.
2601*6777b538SAndroid Build Coastguard Worker   {
2602*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
2603*6777b538SAndroid Build Coastguard Worker 
2604*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
2605*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2606*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
2607*6777b538SAndroid Build Coastguard Worker 
2608*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
2609*6777b538SAndroid Build Coastguard Worker 
2610*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
2611*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
2612*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2613*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
2614*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsOk());
2615*6777b538SAndroid Build Coastguard Worker 
2616*6777b538SAndroid Build Coastguard Worker     // 1 call for the first range's network transaction.
2617*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2618*6777b538SAndroid Build Coastguard Worker                 ElementsAre(TestTransportInfo()));
2619*6777b538SAndroid Build Coastguard Worker 
2620*6777b538SAndroid Build Coastguard Worker     // Set the callback to return an error the next time it is called.
2621*6777b538SAndroid Build Coastguard Worker     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
2622*6777b538SAndroid Build Coastguard Worker 
2623*6777b538SAndroid Build Coastguard Worker     std::string content;
2624*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2625*6777b538SAndroid Build Coastguard Worker                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
2626*6777b538SAndroid Build Coastguard Worker 
2627*6777b538SAndroid Build Coastguard Worker     // A second call that failed.
2628*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2629*6777b538SAndroid Build Coastguard Worker                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo()));
2630*6777b538SAndroid Build Coastguard Worker   }
2631*6777b538SAndroid Build Coastguard Worker 
2632*6777b538SAndroid Build Coastguard Worker   // Request the same range again, observe that nothing is read from cache.
2633*6777b538SAndroid Build Coastguard Worker   {
2634*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
2635*6777b538SAndroid Build Coastguard Worker 
2636*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
2637*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2638*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
2639*6777b538SAndroid Build Coastguard Worker 
2640*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
2641*6777b538SAndroid Build Coastguard Worker 
2642*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
2643*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
2644*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2645*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
2646*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsOk());
2647*6777b538SAndroid Build Coastguard Worker 
2648*6777b538SAndroid Build Coastguard Worker     std::string content;
2649*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2650*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(content, mock_transaction.data);
2651*6777b538SAndroid Build Coastguard Worker 
2652*6777b538SAndroid Build Coastguard Worker     // 1 call for the network transaction from which the whole response was
2653*6777b538SAndroid Build Coastguard Worker     // read. The first 20 bytes were cached by the previous two requests, but
2654*6777b538SAndroid Build Coastguard Worker     // the cache entry was doomed during the last transaction so they are not
2655*6777b538SAndroid Build Coastguard Worker     // used here.
2656*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2657*6777b538SAndroid Build Coastguard Worker                 ElementsAre(TestTransportInfo()));
2658*6777b538SAndroid Build Coastguard Worker   }
2659*6777b538SAndroid Build Coastguard Worker }
2660*6777b538SAndroid Build Coastguard Worker 
2661*6777b538SAndroid Build Coastguard Worker // This test verifies that when the ConnectedCallback passed to a cache range
2662*6777b538SAndroid Build Coastguard Worker // transaction returns an `ERR_INCONSISTENT_IP_ADDRESS_SPACE` error during a
2663*6777b538SAndroid Build Coastguard Worker // network transaction, then the cache entry is invalidated.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnInconsistentIpErrorForNetwork)2664*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest,
2665*6777b538SAndroid Build Coastguard Worker        RangeGET_ConnectedCallbackReturnInconsistentIpErrorForNetwork) {
2666*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2667*6777b538SAndroid Build Coastguard Worker 
2668*6777b538SAndroid Build Coastguard Worker   // Request a prefix range and populate the cache with it.
2669*6777b538SAndroid Build Coastguard Worker   {
2670*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2671*6777b538SAndroid Build Coastguard Worker     mock_transaction.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2672*6777b538SAndroid Build Coastguard Worker     mock_transaction.data = "rg: 10-19 ";
2673*6777b538SAndroid Build Coastguard Worker     mock_transaction.transport_info = TestTransportInfo();
2674*6777b538SAndroid Build Coastguard Worker 
2675*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), mock_transaction);
2676*6777b538SAndroid Build Coastguard Worker   }
2677*6777b538SAndroid Build Coastguard Worker 
2678*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2679*6777b538SAndroid Build Coastguard Worker   mock_transaction.request_headers = "Range: bytes = 10-29\r\n" EXTRA_HEADER;
2680*6777b538SAndroid Build Coastguard Worker   mock_transaction.data = "rg: 10-19 rg: 20-29 ";
2681*6777b538SAndroid Build Coastguard Worker   mock_transaction.transport_info = TestTransportInfo();
2682*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(mock_transaction);
2683*6777b538SAndroid Build Coastguard Worker 
2684*6777b538SAndroid Build Coastguard Worker   // Request a longer range. This *should* be read in two parts:
2685*6777b538SAndroid Build Coastguard Worker   //
2686*6777b538SAndroid Build Coastguard Worker   // 1. for the prefix: from the cache
2687*6777b538SAndroid Build Coastguard Worker   // 2. for the suffix: from the network
2688*6777b538SAndroid Build Coastguard Worker   {
2689*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
2690*6777b538SAndroid Build Coastguard Worker 
2691*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
2692*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2693*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
2694*6777b538SAndroid Build Coastguard Worker 
2695*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
2696*6777b538SAndroid Build Coastguard Worker 
2697*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
2698*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
2699*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2700*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
2701*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsOk());
2702*6777b538SAndroid Build Coastguard Worker 
2703*6777b538SAndroid Build Coastguard Worker     // 1 call for the first range's network transaction.
2704*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2705*6777b538SAndroid Build Coastguard Worker                 ElementsAre(CachedTestTransportInfo()));
2706*6777b538SAndroid Build Coastguard Worker 
2707*6777b538SAndroid Build Coastguard Worker     // Set the callback to return an error the next time it is called.
2708*6777b538SAndroid Build Coastguard Worker     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
2709*6777b538SAndroid Build Coastguard Worker 
2710*6777b538SAndroid Build Coastguard Worker     std::string content;
2711*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2712*6777b538SAndroid Build Coastguard Worker                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
2713*6777b538SAndroid Build Coastguard Worker 
2714*6777b538SAndroid Build Coastguard Worker     // A second call that failed.
2715*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2716*6777b538SAndroid Build Coastguard Worker                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
2717*6777b538SAndroid Build Coastguard Worker   }
2718*6777b538SAndroid Build Coastguard Worker 
2719*6777b538SAndroid Build Coastguard Worker   // Request the same range again, observe that nothing is read from cache.
2720*6777b538SAndroid Build Coastguard Worker   {
2721*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
2722*6777b538SAndroid Build Coastguard Worker 
2723*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
2724*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2725*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
2726*6777b538SAndroid Build Coastguard Worker 
2727*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
2728*6777b538SAndroid Build Coastguard Worker 
2729*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
2730*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
2731*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2732*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
2733*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsOk());
2734*6777b538SAndroid Build Coastguard Worker 
2735*6777b538SAndroid Build Coastguard Worker     std::string content;
2736*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2737*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(content, mock_transaction.data);
2738*6777b538SAndroid Build Coastguard Worker 
2739*6777b538SAndroid Build Coastguard Worker     // 1 call for the network transaction from which the whole response was
2740*6777b538SAndroid Build Coastguard Worker     // read. The first 20 bytes were cached by the previous two requests, but
2741*6777b538SAndroid Build Coastguard Worker     // the cache entry was doomed during the last transaction so they are not
2742*6777b538SAndroid Build Coastguard Worker     // used here.
2743*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2744*6777b538SAndroid Build Coastguard Worker                 ElementsAre(TestTransportInfo()));
2745*6777b538SAndroid Build Coastguard Worker   }
2746*6777b538SAndroid Build Coastguard Worker }
2747*6777b538SAndroid Build Coastguard Worker 
2748*6777b538SAndroid Build Coastguard Worker // This test verifies that when the ConnectedCallback passed to a cache
2749*6777b538SAndroid Build Coastguard Worker // transaction returns an error for the second (or third) subrange transaction,
2750*6777b538SAndroid Build Coastguard Worker // the overall cache transaction fails with that error. The cache entry is still
2751*6777b538SAndroid Build Coastguard Worker // usable after that.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnErrorSecondTime)2752*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackReturnErrorSecondTime) {
2753*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2754*6777b538SAndroid Build Coastguard Worker 
2755*6777b538SAndroid Build Coastguard Worker   // Request an infix range and populate the cache with it.
2756*6777b538SAndroid Build Coastguard Worker   {
2757*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2758*6777b538SAndroid Build Coastguard Worker     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2759*6777b538SAndroid Build Coastguard Worker     mock_transaction.data = "rg: 20-29 ";
2760*6777b538SAndroid Build Coastguard Worker     mock_transaction.transport_info = TestTransportInfo();
2761*6777b538SAndroid Build Coastguard Worker 
2762*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), mock_transaction);
2763*6777b538SAndroid Build Coastguard Worker   }
2764*6777b538SAndroid Build Coastguard Worker 
2765*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2766*6777b538SAndroid Build Coastguard Worker   mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2767*6777b538SAndroid Build Coastguard Worker   mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2768*6777b538SAndroid Build Coastguard Worker   mock_transaction.transport_info = TestTransportInfo();
2769*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(mock_transaction);
2770*6777b538SAndroid Build Coastguard Worker 
2771*6777b538SAndroid Build Coastguard Worker   // Request a surrounding range. This *should* be read in three parts:
2772*6777b538SAndroid Build Coastguard Worker   //
2773*6777b538SAndroid Build Coastguard Worker   // 1. for the prefix: from the network
2774*6777b538SAndroid Build Coastguard Worker   // 2. for the cached infix: from the cache
2775*6777b538SAndroid Build Coastguard Worker   // 3. for the suffix: from the network
2776*6777b538SAndroid Build Coastguard Worker   //
2777*6777b538SAndroid Build Coastguard Worker   // The connected callback returns OK for 1), but fails during 2). As a result,
2778*6777b538SAndroid Build Coastguard Worker   // the transaction fails partway and 3) is never created. The prefix is still
2779*6777b538SAndroid Build Coastguard Worker   // cached, such that the cache entry ends up with both the prefix and infix.
2780*6777b538SAndroid Build Coastguard Worker   {
2781*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
2782*6777b538SAndroid Build Coastguard Worker 
2783*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
2784*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2785*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
2786*6777b538SAndroid Build Coastguard Worker 
2787*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
2788*6777b538SAndroid Build Coastguard Worker 
2789*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
2790*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
2791*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2792*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
2793*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsOk());
2794*6777b538SAndroid Build Coastguard Worker 
2795*6777b538SAndroid Build Coastguard Worker     // 1 call for the first range's network transaction.
2796*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2797*6777b538SAndroid Build Coastguard Worker                 ElementsAre(TestTransportInfo()));
2798*6777b538SAndroid Build Coastguard Worker 
2799*6777b538SAndroid Build Coastguard Worker     // Set the callback to return an error the next time it is called. The exact
2800*6777b538SAndroid Build Coastguard Worker     // error code is irrelevant, what matters is that it is reflected in the
2801*6777b538SAndroid Build Coastguard Worker     // overall status of the transaction.
2802*6777b538SAndroid Build Coastguard Worker     connected_handler.set_result(ERR_NOT_IMPLEMENTED);
2803*6777b538SAndroid Build Coastguard Worker 
2804*6777b538SAndroid Build Coastguard Worker     std::string content;
2805*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2806*6777b538SAndroid Build Coastguard Worker                 IsError(ERR_NOT_IMPLEMENTED));
2807*6777b538SAndroid Build Coastguard Worker 
2808*6777b538SAndroid Build Coastguard Worker     // A second call that failed.
2809*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2810*6777b538SAndroid Build Coastguard Worker                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo()));
2811*6777b538SAndroid Build Coastguard Worker   }
2812*6777b538SAndroid Build Coastguard Worker 
2813*6777b538SAndroid Build Coastguard Worker   // Request the same range again, observe that the prefix and infix are both
2814*6777b538SAndroid Build Coastguard Worker   // read from cache. Only the suffix is fetched from the network.
2815*6777b538SAndroid Build Coastguard Worker   {
2816*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
2817*6777b538SAndroid Build Coastguard Worker 
2818*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
2819*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2820*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
2821*6777b538SAndroid Build Coastguard Worker 
2822*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
2823*6777b538SAndroid Build Coastguard Worker 
2824*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
2825*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
2826*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2827*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
2828*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsOk());
2829*6777b538SAndroid Build Coastguard Worker 
2830*6777b538SAndroid Build Coastguard Worker     // 1 call for the first range's cache transaction: the first 20 bytes were
2831*6777b538SAndroid Build Coastguard Worker     // cached by the previous two requests.
2832*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2833*6777b538SAndroid Build Coastguard Worker                 ElementsAre(CachedTestTransportInfo()));
2834*6777b538SAndroid Build Coastguard Worker 
2835*6777b538SAndroid Build Coastguard Worker     std::string content;
2836*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2837*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(content, mock_transaction.data);
2838*6777b538SAndroid Build Coastguard Worker 
2839*6777b538SAndroid Build Coastguard Worker     // A second call from the network transaction for the last 10 bytes.
2840*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2841*6777b538SAndroid Build Coastguard Worker                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
2842*6777b538SAndroid Build Coastguard Worker   }
2843*6777b538SAndroid Build Coastguard Worker }
2844*6777b538SAndroid Build Coastguard Worker 
2845*6777b538SAndroid Build Coastguard Worker // This test verifies that the ConnectedCallback passed to a cache transaction
2846*6777b538SAndroid Build Coastguard Worker // is called once per subrange in the case of a range request with a partial
2847*6777b538SAndroid Build Coastguard Worker // cache hit, even when a prefix of the range is cached.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackCalledForEachRangeWithPrefix)2848*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackCalledForEachRangeWithPrefix) {
2849*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2850*6777b538SAndroid Build Coastguard Worker 
2851*6777b538SAndroid Build Coastguard Worker   // Request a prefix range and populate the cache with it.
2852*6777b538SAndroid Build Coastguard Worker   {
2853*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2854*6777b538SAndroid Build Coastguard Worker     mock_transaction.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2855*6777b538SAndroid Build Coastguard Worker     mock_transaction.data = "rg: 10-19 ";
2856*6777b538SAndroid Build Coastguard Worker     mock_transaction.transport_info = TestTransportInfo();
2857*6777b538SAndroid Build Coastguard Worker 
2858*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), mock_transaction);
2859*6777b538SAndroid Build Coastguard Worker   }
2860*6777b538SAndroid Build Coastguard Worker 
2861*6777b538SAndroid Build Coastguard Worker   // Request a surrounding range and observe that the callback is called once
2862*6777b538SAndroid Build Coastguard Worker   // per subrange, as split up by cache hits.
2863*6777b538SAndroid Build Coastguard Worker   {
2864*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2865*6777b538SAndroid Build Coastguard Worker     mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2866*6777b538SAndroid Build Coastguard Worker     mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2867*6777b538SAndroid Build Coastguard Worker     mock_transaction.transport_info = TestTransportInfoWithPort(123);
2868*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(mock_transaction);
2869*6777b538SAndroid Build Coastguard Worker 
2870*6777b538SAndroid Build Coastguard Worker     ConnectedHandler connected_handler;
2871*6777b538SAndroid Build Coastguard Worker 
2872*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> transaction;
2873*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2874*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(transaction, NotNull());
2875*6777b538SAndroid Build Coastguard Worker 
2876*6777b538SAndroid Build Coastguard Worker     transaction->SetConnectedCallback(connected_handler.Callback());
2877*6777b538SAndroid Build Coastguard Worker 
2878*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
2879*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(
2880*6777b538SAndroid Build Coastguard Worker         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2881*6777b538SAndroid Build Coastguard Worker         IsError(ERR_IO_PENDING));
2882*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.WaitForResult(), IsOk());
2883*6777b538SAndroid Build Coastguard Worker 
2884*6777b538SAndroid Build Coastguard Worker     // 1 call for the first range from the cache, reported as coming from the
2885*6777b538SAndroid Build Coastguard Worker     // endpoint which initially served the cached range.
2886*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(connected_handler.transports(),
2887*6777b538SAndroid Build Coastguard Worker                 ElementsAre(CachedTestTransportInfo()));
2888*6777b538SAndroid Build Coastguard Worker 
2889*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(transaction.get(), mock_transaction);
2890*6777b538SAndroid Build Coastguard Worker 
2891*6777b538SAndroid Build Coastguard Worker     // A second call for the last range's network transaction.
2892*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(
2893*6777b538SAndroid Build Coastguard Worker         connected_handler.transports(),
2894*6777b538SAndroid Build Coastguard Worker         ElementsAre(CachedTestTransportInfo(), TestTransportInfoWithPort(123)));
2895*6777b538SAndroid Build Coastguard Worker   }
2896*6777b538SAndroid Build Coastguard Worker }
2897*6777b538SAndroid Build Coastguard Worker 
2898*6777b538SAndroid Build Coastguard Worker // Tests that a range transaction is still usable even if it's unable to access
2899*6777b538SAndroid Build Coastguard Worker // the cache.
TEST_F(HttpCacheTest,RangeGET_FailedCacheAccess)2900*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_FailedCacheAccess) {
2901*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2902*6777b538SAndroid Build Coastguard Worker 
2903*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
2904*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
2905*6777b538SAndroid Build Coastguard Worker 
2906*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
2907*6777b538SAndroid Build Coastguard Worker   c->result = cache.CreateTransaction(&c->trans);
2908*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c->result, IsOk());
2909*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2910*6777b538SAndroid Build Coastguard Worker 
2911*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_fail_requests(true);
2912*6777b538SAndroid Build Coastguard Worker 
2913*6777b538SAndroid Build Coastguard Worker   c->result =
2914*6777b538SAndroid Build Coastguard Worker       c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2915*6777b538SAndroid Build Coastguard Worker 
2916*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
2917*6777b538SAndroid Build Coastguard Worker 
2918*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
2919*6777b538SAndroid Build Coastguard Worker 
2920*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2921*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
2922*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
2923*6777b538SAndroid Build Coastguard Worker 
2924*6777b538SAndroid Build Coastguard Worker   c->result = c->callback.WaitForResult();
2925*6777b538SAndroid Build Coastguard Worker 
2926*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
2927*6777b538SAndroid Build Coastguard Worker 
2928*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2929*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
2930*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
2931*6777b538SAndroid Build Coastguard Worker }
2932*6777b538SAndroid Build Coastguard Worker 
2933*6777b538SAndroid Build Coastguard Worker // Tests that we can have parallel validation on range requests.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatch)2934*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatch) {
2935*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
2936*6777b538SAndroid Build Coastguard Worker 
2937*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
2938*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
2939*6777b538SAndroid Build Coastguard Worker 
2940*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
2941*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 5;
2942*6777b538SAndroid Build Coastguard Worker 
2943*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
2944*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
2945*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
2946*6777b538SAndroid Build Coastguard Worker 
2947*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
2948*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
2949*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2950*6777b538SAndroid Build Coastguard Worker 
2951*6777b538SAndroid Build Coastguard Worker     c->result =
2952*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2953*6777b538SAndroid Build Coastguard Worker   }
2954*6777b538SAndroid Build Coastguard Worker 
2955*6777b538SAndroid Build Coastguard Worker   // All requests are waiting for the active entry.
2956*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
2957*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
2958*6777b538SAndroid Build Coastguard Worker   }
2959*6777b538SAndroid Build Coastguard Worker 
2960*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
2961*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
2962*6777b538SAndroid Build Coastguard Worker 
2963*6777b538SAndroid Build Coastguard Worker   // First entry created is doomed due to 2nd transaction's validation leading
2964*6777b538SAndroid Build Coastguard Worker   // to restarting of the queued transactions.
2965*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
2966*6777b538SAndroid Build Coastguard Worker 
2967*6777b538SAndroid Build Coastguard Worker   // TODO(shivanisha): The restarted transactions race for creating the entry
2968*6777b538SAndroid Build Coastguard Worker   // and thus instead of all 4 succeeding, 2 of them succeed. This is very
2969*6777b538SAndroid Build Coastguard Worker   // implementation specific and happens because the queued transactions get
2970*6777b538SAndroid Build Coastguard Worker   // restarted synchronously and get to the queue of creating the entry before
2971*6777b538SAndroid Build Coastguard Worker   // the transaction that is restarting them. Fix the test to make it less
2972*6777b538SAndroid Build Coastguard Worker   // vulnerable to any scheduling changes in the code.
2973*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, cache.network_layer()->transaction_count());
2974*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
2975*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->create_count());
2976*6777b538SAndroid Build Coastguard Worker 
2977*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
2978*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2979*6777b538SAndroid Build Coastguard Worker   }
2980*6777b538SAndroid Build Coastguard Worker 
2981*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
2982*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
2983*6777b538SAndroid Build Coastguard Worker     if (c->result == ERR_IO_PENDING) {
2984*6777b538SAndroid Build Coastguard Worker       c->result = c->callback.WaitForResult();
2985*6777b538SAndroid Build Coastguard Worker     }
2986*6777b538SAndroid Build Coastguard Worker 
2987*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
2988*6777b538SAndroid Build Coastguard Worker   }
2989*6777b538SAndroid Build Coastguard Worker 
2990*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, cache.network_layer()->transaction_count());
2991*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
2992*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->create_count());
2993*6777b538SAndroid Build Coastguard Worker }
2994*6777b538SAndroid Build Coastguard Worker 
2995*6777b538SAndroid Build Coastguard Worker // Tests that if a transaction is dooming the entry and the entry was doomed by
2996*6777b538SAndroid Build Coastguard Worker // another transaction that was not part of the entry and created a new entry,
2997*6777b538SAndroid Build Coastguard Worker // the new entry should not be incorrectly doomed. (crbug.com/736993)
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatchDoomEntry)2998*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatchDoomEntry) {
2999*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3000*6777b538SAndroid Build Coastguard Worker 
3001*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3002*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
3003*6777b538SAndroid Build Coastguard Worker 
3004*6777b538SAndroid Build Coastguard Worker   MockTransaction dooming_transaction(kRangeGET_TransactionOK);
3005*6777b538SAndroid Build Coastguard Worker   dooming_transaction.load_flags |= LOAD_BYPASS_CACHE;
3006*6777b538SAndroid Build Coastguard Worker   MockHttpRequest dooming_request(dooming_transaction);
3007*6777b538SAndroid Build Coastguard Worker 
3008*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
3009*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 3;
3010*6777b538SAndroid Build Coastguard Worker 
3011*6777b538SAndroid Build Coastguard Worker   scoped_refptr<MockDiskEntry> first_entry;
3012*6777b538SAndroid Build Coastguard Worker   scoped_refptr<MockDiskEntry> second_entry;
3013*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3014*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
3015*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
3016*6777b538SAndroid Build Coastguard Worker 
3017*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3018*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3019*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3020*6777b538SAndroid Build Coastguard Worker 
3021*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
3022*6777b538SAndroid Build Coastguard Worker 
3023*6777b538SAndroid Build Coastguard Worker     if (i == 2) {
3024*6777b538SAndroid Build Coastguard Worker       this_request = &dooming_request;
3025*6777b538SAndroid Build Coastguard Worker     }
3026*6777b538SAndroid Build Coastguard Worker 
3027*6777b538SAndroid Build Coastguard Worker     if (i == 1) {
3028*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(first_entry);
3029*6777b538SAndroid Build Coastguard Worker       first_entry->SetDefer(MockDiskEntry::DEFER_READ);
3030*6777b538SAndroid Build Coastguard Worker     }
3031*6777b538SAndroid Build Coastguard Worker 
3032*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
3033*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
3034*6777b538SAndroid Build Coastguard Worker 
3035*6777b538SAndroid Build Coastguard Worker     // Continue the transactions. 2nd will pause at the cache reading state and
3036*6777b538SAndroid Build Coastguard Worker     // 3rd transaction will doom the entry.
3037*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3038*6777b538SAndroid Build Coastguard Worker 
3039*6777b538SAndroid Build Coastguard Worker     std::string cache_key = request.CacheKey();
3040*6777b538SAndroid Build Coastguard Worker     // Check status of the first and second entries after every transaction.
3041*6777b538SAndroid Build Coastguard Worker     switch (i) {
3042*6777b538SAndroid Build Coastguard Worker       case 0:
3043*6777b538SAndroid Build Coastguard Worker         first_entry = cache.disk_cache()->GetDiskEntryRef(cache_key);
3044*6777b538SAndroid Build Coastguard Worker         break;
3045*6777b538SAndroid Build Coastguard Worker       case 1:
3046*6777b538SAndroid Build Coastguard Worker         EXPECT_FALSE(first_entry->is_doomed());
3047*6777b538SAndroid Build Coastguard Worker         break;
3048*6777b538SAndroid Build Coastguard Worker       case 2:
3049*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(first_entry->is_doomed());
3050*6777b538SAndroid Build Coastguard Worker         second_entry = cache.disk_cache()->GetDiskEntryRef(cache_key);
3051*6777b538SAndroid Build Coastguard Worker         EXPECT_FALSE(second_entry->is_doomed());
3052*6777b538SAndroid Build Coastguard Worker         break;
3053*6777b538SAndroid Build Coastguard Worker     }
3054*6777b538SAndroid Build Coastguard Worker   }
3055*6777b538SAndroid Build Coastguard Worker   // Resume cache read by 1st transaction which will lead to dooming the entry
3056*6777b538SAndroid Build Coastguard Worker   // as well since the entry cannot be validated. This double dooming should not
3057*6777b538SAndroid Build Coastguard Worker   // lead to an assertion.
3058*6777b538SAndroid Build Coastguard Worker   first_entry->ResumeDiskEntryOperation();
3059*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3060*6777b538SAndroid Build Coastguard Worker 
3061*6777b538SAndroid Build Coastguard Worker   // Since second_entry is already created, when 1st transaction goes on to
3062*6777b538SAndroid Build Coastguard Worker   // create an entry, it will get ERR_CACHE_RACE leading to dooming of
3063*6777b538SAndroid Build Coastguard Worker   // second_entry and creation of a third entry.
3064*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(second_entry->is_doomed());
3065*6777b538SAndroid Build Coastguard Worker 
3066*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3067*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3068*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->create_count());
3069*6777b538SAndroid Build Coastguard Worker 
3070*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
3071*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3072*6777b538SAndroid Build Coastguard Worker   }
3073*6777b538SAndroid Build Coastguard Worker 
3074*6777b538SAndroid Build Coastguard Worker   for (auto& c : context_list) {
3075*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
3076*6777b538SAndroid Build Coastguard Worker   }
3077*6777b538SAndroid Build Coastguard Worker 
3078*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3079*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3080*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->create_count());
3081*6777b538SAndroid Build Coastguard Worker }
3082*6777b538SAndroid Build Coastguard Worker 
3083*6777b538SAndroid Build Coastguard Worker // Same as above but tests that the 2nd transaction does not do anything if
3084*6777b538SAndroid Build Coastguard Worker // there is nothing to doom. (crbug.com/736993)
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatchDoomEntry1)3085*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatchDoomEntry1) {
3086*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3087*6777b538SAndroid Build Coastguard Worker 
3088*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3089*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
3090*6777b538SAndroid Build Coastguard Worker 
3091*6777b538SAndroid Build Coastguard Worker   MockTransaction dooming_transaction(kRangeGET_TransactionOK);
3092*6777b538SAndroid Build Coastguard Worker   dooming_transaction.load_flags |= LOAD_BYPASS_CACHE;
3093*6777b538SAndroid Build Coastguard Worker   MockHttpRequest dooming_request(dooming_transaction);
3094*6777b538SAndroid Build Coastguard Worker 
3095*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
3096*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 3;
3097*6777b538SAndroid Build Coastguard Worker 
3098*6777b538SAndroid Build Coastguard Worker   scoped_refptr<MockDiskEntry> first_entry;
3099*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3100*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
3101*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
3102*6777b538SAndroid Build Coastguard Worker 
3103*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3104*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3105*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3106*6777b538SAndroid Build Coastguard Worker 
3107*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
3108*6777b538SAndroid Build Coastguard Worker 
3109*6777b538SAndroid Build Coastguard Worker     if (i == 2) {
3110*6777b538SAndroid Build Coastguard Worker       this_request = &dooming_request;
3111*6777b538SAndroid Build Coastguard Worker       cache.disk_cache()->SetDefer(MockDiskEntry::DEFER_CREATE);
3112*6777b538SAndroid Build Coastguard Worker     }
3113*6777b538SAndroid Build Coastguard Worker 
3114*6777b538SAndroid Build Coastguard Worker     if (i == 1) {
3115*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(first_entry);
3116*6777b538SAndroid Build Coastguard Worker       first_entry->SetDefer(MockDiskEntry::DEFER_READ);
3117*6777b538SAndroid Build Coastguard Worker     }
3118*6777b538SAndroid Build Coastguard Worker 
3119*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
3120*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
3121*6777b538SAndroid Build Coastguard Worker 
3122*6777b538SAndroid Build Coastguard Worker     // Continue the transactions. 2nd will pause at the cache reading state and
3123*6777b538SAndroid Build Coastguard Worker     // 3rd transaction will doom the entry and pause before creating a new
3124*6777b538SAndroid Build Coastguard Worker     // entry.
3125*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3126*6777b538SAndroid Build Coastguard Worker 
3127*6777b538SAndroid Build Coastguard Worker     // Check status of the entry after every transaction.
3128*6777b538SAndroid Build Coastguard Worker     switch (i) {
3129*6777b538SAndroid Build Coastguard Worker       case 0:
3130*6777b538SAndroid Build Coastguard Worker         first_entry = cache.disk_cache()->GetDiskEntryRef(request.CacheKey());
3131*6777b538SAndroid Build Coastguard Worker         break;
3132*6777b538SAndroid Build Coastguard Worker       case 1:
3133*6777b538SAndroid Build Coastguard Worker         EXPECT_FALSE(first_entry->is_doomed());
3134*6777b538SAndroid Build Coastguard Worker         break;
3135*6777b538SAndroid Build Coastguard Worker       case 2:
3136*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(first_entry->is_doomed());
3137*6777b538SAndroid Build Coastguard Worker         break;
3138*6777b538SAndroid Build Coastguard Worker     }
3139*6777b538SAndroid Build Coastguard Worker   }
3140*6777b538SAndroid Build Coastguard Worker   // Resume cache read by 2nd transaction which will lead to dooming the entry
3141*6777b538SAndroid Build Coastguard Worker   // as well since the entry cannot be validated. This double dooming should not
3142*6777b538SAndroid Build Coastguard Worker   // lead to an assertion.
3143*6777b538SAndroid Build Coastguard Worker   first_entry->ResumeDiskEntryOperation();
3144*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3145*6777b538SAndroid Build Coastguard Worker 
3146*6777b538SAndroid Build Coastguard Worker   // Resume creation of entry by 3rd transaction.
3147*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->ResumeCacheOperation();
3148*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3149*6777b538SAndroid Build Coastguard Worker 
3150*6777b538SAndroid Build Coastguard Worker   // Note that since 3rd transaction's entry is already created but its
3151*6777b538SAndroid Build Coastguard Worker   // callback is deferred, MockDiskCache's implementation returns
3152*6777b538SAndroid Build Coastguard Worker   // ERR_CACHE_CREATE_FAILURE when 2nd transaction tries to create an entry
3153*6777b538SAndroid Build Coastguard Worker   // during that time, leading to it switching over to pass-through mode.
3154*6777b538SAndroid Build Coastguard Worker   // Thus the number of entries is 2 below.
3155*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3156*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3157*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
3158*6777b538SAndroid Build Coastguard Worker 
3159*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
3160*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3161*6777b538SAndroid Build Coastguard Worker   }
3162*6777b538SAndroid Build Coastguard Worker 
3163*6777b538SAndroid Build Coastguard Worker   for (auto& c : context_list) {
3164*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
3165*6777b538SAndroid Build Coastguard Worker   }
3166*6777b538SAndroid Build Coastguard Worker 
3167*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3168*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3169*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
3170*6777b538SAndroid Build Coastguard Worker }
3171*6777b538SAndroid Build Coastguard Worker 
3172*6777b538SAndroid Build Coastguard Worker // Tests parallel validation on range requests with non-overlapping ranges.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationDifferentRanges)3173*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ParallelValidationDifferentRanges) {
3174*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3175*6777b538SAndroid Build Coastguard Worker 
3176*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3177*6777b538SAndroid Build Coastguard Worker 
3178*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
3179*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
3180*6777b538SAndroid Build Coastguard Worker 
3181*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3182*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
3183*6777b538SAndroid Build Coastguard Worker   }
3184*6777b538SAndroid Build Coastguard Worker 
3185*6777b538SAndroid Build Coastguard Worker   // Let 1st transaction complete headers phase for ranges 40-49.
3186*6777b538SAndroid Build Coastguard Worker   std::string first_read;
3187*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request1(transaction);
3188*6777b538SAndroid Build Coastguard Worker   {
3189*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[0];
3190*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3191*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3192*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3193*6777b538SAndroid Build Coastguard Worker 
3194*6777b538SAndroid Build Coastguard Worker     c->result =
3195*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3196*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3197*6777b538SAndroid Build Coastguard Worker 
3198*6777b538SAndroid Build Coastguard Worker     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3199*6777b538SAndroid Build Coastguard Worker     // true.
3200*6777b538SAndroid Build Coastguard Worker     const int kBufferSize = 5;
3201*6777b538SAndroid Build Coastguard Worker     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3202*6777b538SAndroid Build Coastguard Worker     ReleaseBufferCompletionCallback cb(buffer.get());
3203*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3204*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3205*6777b538SAndroid Build Coastguard Worker 
3206*6777b538SAndroid Build Coastguard Worker     std::string data_read(buffer->data(), kBufferSize);
3207*6777b538SAndroid Build Coastguard Worker     first_read = data_read;
3208*6777b538SAndroid Build Coastguard Worker 
3209*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3210*6777b538SAndroid Build Coastguard Worker   }
3211*6777b538SAndroid Build Coastguard Worker 
3212*6777b538SAndroid Build Coastguard Worker   // 2nd transaction requests ranges 30-39.
3213*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3214*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request2(transaction);
3215*6777b538SAndroid Build Coastguard Worker   {
3216*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[1];
3217*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3218*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3219*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3220*6777b538SAndroid Build Coastguard Worker 
3221*6777b538SAndroid Build Coastguard Worker     c->result =
3222*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3223*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3224*6777b538SAndroid Build Coastguard Worker 
3225*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3226*6777b538SAndroid Build Coastguard Worker   }
3227*6777b538SAndroid Build Coastguard Worker 
3228*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request2.CacheKey();
3229*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3230*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3231*6777b538SAndroid Build Coastguard Worker 
3232*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3233*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3234*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3235*6777b538SAndroid Build Coastguard Worker 
3236*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3237*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
3238*6777b538SAndroid Build Coastguard Worker     if (c->result == ERR_IO_PENDING) {
3239*6777b538SAndroid Build Coastguard Worker       c->result = c->callback.WaitForResult();
3240*6777b538SAndroid Build Coastguard Worker     }
3241*6777b538SAndroid Build Coastguard Worker 
3242*6777b538SAndroid Build Coastguard Worker     if (i == 0) {
3243*6777b538SAndroid Build Coastguard Worker       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3244*6777b538SAndroid Build Coastguard Worker                                         transaction);
3245*6777b538SAndroid Build Coastguard Worker       continue;
3246*6777b538SAndroid Build Coastguard Worker     }
3247*6777b538SAndroid Build Coastguard Worker 
3248*6777b538SAndroid Build Coastguard Worker     transaction.data = "rg: 30-39 ";
3249*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), transaction);
3250*6777b538SAndroid Build Coastguard Worker   }
3251*6777b538SAndroid Build Coastguard Worker 
3252*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3253*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3254*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3255*6777b538SAndroid Build Coastguard Worker 
3256*6777b538SAndroid Build Coastguard Worker   // Fetch from the cache to check that ranges 30-49 have been successfully
3257*6777b538SAndroid Build Coastguard Worker   // cached.
3258*6777b538SAndroid Build Coastguard Worker   {
3259*6777b538SAndroid Build Coastguard Worker     MockTransaction range_transaction(kRangeGET_TransactionOK);
3260*6777b538SAndroid Build Coastguard Worker     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3261*6777b538SAndroid Build Coastguard Worker     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3262*6777b538SAndroid Build Coastguard Worker     std::string headers;
3263*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3264*6777b538SAndroid Build Coastguard Worker                                    &headers);
3265*6777b538SAndroid Build Coastguard Worker     Verify206Response(headers, 30, 49);
3266*6777b538SAndroid Build Coastguard Worker   }
3267*6777b538SAndroid Build Coastguard Worker 
3268*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3269*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
3270*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3271*6777b538SAndroid Build Coastguard Worker 
3272*6777b538SAndroid Build Coastguard Worker   context_list.clear();
3273*6777b538SAndroid Build Coastguard Worker }
3274*6777b538SAndroid Build Coastguard Worker 
3275*6777b538SAndroid Build Coastguard Worker // Tests that a request does not create Writers when readers is not empty.
TEST_F(HttpCacheTest,RangeGET_DoNotCreateWritersWhenReaderExists)3276*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_DoNotCreateWritersWhenReaderExists) {
3277*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3278*6777b538SAndroid Build Coastguard Worker 
3279*6777b538SAndroid Build Coastguard Worker   // Save a request in the cache so that the next request can become a
3280*6777b538SAndroid Build Coastguard Worker   // reader.
3281*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_Transaction);
3282*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
3283*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
3284*6777b538SAndroid Build Coastguard Worker 
3285*6777b538SAndroid Build Coastguard Worker   // Let this request be a reader since it doesn't need validation as per its
3286*6777b538SAndroid Build Coastguard Worker   // load flag.
3287*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
3288*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
3289*6777b538SAndroid Build Coastguard Worker   Context context;
3290*6777b538SAndroid Build Coastguard Worker   context.result = cache.CreateTransaction(&context.trans);
3291*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(context.result, IsOk());
3292*6777b538SAndroid Build Coastguard Worker   context.result = context.trans->Start(&request, context.callback.callback(),
3293*6777b538SAndroid Build Coastguard Worker                                         NetLogWithSource());
3294*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3295*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
3296*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
3297*6777b538SAndroid Build Coastguard Worker 
3298*6777b538SAndroid Build Coastguard Worker   // A range request should now "not" create Writers while readers is still
3299*6777b538SAndroid Build Coastguard Worker   // non-empty.
3300*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3301*6777b538SAndroid Build Coastguard Worker   MockHttpRequest range_request(transaction);
3302*6777b538SAndroid Build Coastguard Worker   Context range_context;
3303*6777b538SAndroid Build Coastguard Worker   range_context.result = cache.CreateTransaction(&range_context.trans);
3304*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(range_context.result, IsOk());
3305*6777b538SAndroid Build Coastguard Worker   range_context.result = range_context.trans->Start(
3306*6777b538SAndroid Build Coastguard Worker       &range_request, range_context.callback.callback(), NetLogWithSource());
3307*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3308*6777b538SAndroid Build Coastguard Worker 
3309*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
3310*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
3311*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3312*6777b538SAndroid Build Coastguard Worker }
3313*6777b538SAndroid Build Coastguard Worker 
3314*6777b538SAndroid Build Coastguard Worker // Tests parallel validation on range requests can be successfully restarted
3315*6777b538SAndroid Build Coastguard Worker // when there is a cache lock timeout.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCacheLockTimeout)3316*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ParallelValidationCacheLockTimeout) {
3317*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3318*6777b538SAndroid Build Coastguard Worker 
3319*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3320*6777b538SAndroid Build Coastguard Worker 
3321*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
3322*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
3323*6777b538SAndroid Build Coastguard Worker 
3324*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3325*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
3326*6777b538SAndroid Build Coastguard Worker   }
3327*6777b538SAndroid Build Coastguard Worker 
3328*6777b538SAndroid Build Coastguard Worker   // Let 1st transaction complete headers phase for ranges 40-49.
3329*6777b538SAndroid Build Coastguard Worker   std::string first_read;
3330*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request1(transaction);
3331*6777b538SAndroid Build Coastguard Worker   {
3332*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[0];
3333*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3334*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3335*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3336*6777b538SAndroid Build Coastguard Worker 
3337*6777b538SAndroid Build Coastguard Worker     c->result =
3338*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3339*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3340*6777b538SAndroid Build Coastguard Worker 
3341*6777b538SAndroid Build Coastguard Worker     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3342*6777b538SAndroid Build Coastguard Worker     // true.
3343*6777b538SAndroid Build Coastguard Worker     const int kBufferSize = 5;
3344*6777b538SAndroid Build Coastguard Worker     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3345*6777b538SAndroid Build Coastguard Worker     ReleaseBufferCompletionCallback cb(buffer.get());
3346*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3347*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3348*6777b538SAndroid Build Coastguard Worker 
3349*6777b538SAndroid Build Coastguard Worker     std::string data_read(buffer->data(), kBufferSize);
3350*6777b538SAndroid Build Coastguard Worker     first_read = data_read;
3351*6777b538SAndroid Build Coastguard Worker 
3352*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3353*6777b538SAndroid Build Coastguard Worker   }
3354*6777b538SAndroid Build Coastguard Worker 
3355*6777b538SAndroid Build Coastguard Worker   // Cache lock timeout will lead to dooming the entry since the transaction may
3356*6777b538SAndroid Build Coastguard Worker   // have already written the headers.
3357*6777b538SAndroid Build Coastguard Worker   cache.SimulateCacheLockTimeoutAfterHeaders();
3358*6777b538SAndroid Build Coastguard Worker 
3359*6777b538SAndroid Build Coastguard Worker   // 2nd transaction requests ranges 30-39.
3360*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3361*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request2(transaction);
3362*6777b538SAndroid Build Coastguard Worker   {
3363*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[1];
3364*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3365*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3366*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3367*6777b538SAndroid Build Coastguard Worker 
3368*6777b538SAndroid Build Coastguard Worker     c->result =
3369*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3370*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3371*6777b538SAndroid Build Coastguard Worker 
3372*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3373*6777b538SAndroid Build Coastguard Worker   }
3374*6777b538SAndroid Build Coastguard Worker 
3375*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(request1.CacheKey()));
3376*6777b538SAndroid Build Coastguard Worker 
3377*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3378*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3379*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3380*6777b538SAndroid Build Coastguard Worker 
3381*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3382*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
3383*6777b538SAndroid Build Coastguard Worker     if (c->result == ERR_IO_PENDING) {
3384*6777b538SAndroid Build Coastguard Worker       c->result = c->callback.WaitForResult();
3385*6777b538SAndroid Build Coastguard Worker     }
3386*6777b538SAndroid Build Coastguard Worker 
3387*6777b538SAndroid Build Coastguard Worker     if (i == 0) {
3388*6777b538SAndroid Build Coastguard Worker       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3389*6777b538SAndroid Build Coastguard Worker                                         transaction);
3390*6777b538SAndroid Build Coastguard Worker       continue;
3391*6777b538SAndroid Build Coastguard Worker     }
3392*6777b538SAndroid Build Coastguard Worker 
3393*6777b538SAndroid Build Coastguard Worker     transaction.data = "rg: 30-39 ";
3394*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), transaction);
3395*6777b538SAndroid Build Coastguard Worker   }
3396*6777b538SAndroid Build Coastguard Worker 
3397*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3398*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3399*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3400*6777b538SAndroid Build Coastguard Worker }
3401*6777b538SAndroid Build Coastguard Worker 
3402*6777b538SAndroid Build Coastguard Worker // Tests a full request and a simultaneous range request and the range request
3403*6777b538SAndroid Build Coastguard Worker // dooms the entry created by the full request due to not being able to
3404*6777b538SAndroid Build Coastguard Worker // conditionalize.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCouldntConditionalize)3405*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ParallelValidationCouldntConditionalize) {
3406*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3407*6777b538SAndroid Build Coastguard Worker 
3408*6777b538SAndroid Build Coastguard Worker   MockTransaction mock_transaction(kSimpleGET_Transaction);
3409*6777b538SAndroid Build Coastguard Worker   mock_transaction.url = kRangeGET_TransactionOK.url;
3410*6777b538SAndroid Build Coastguard Worker   // Remove the cache-control and other headers so that the response cannot be
3411*6777b538SAndroid Build Coastguard Worker   // conditionalized.
3412*6777b538SAndroid Build Coastguard Worker   mock_transaction.response_headers = "";
3413*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request1(mock_transaction);
3414*6777b538SAndroid Build Coastguard Worker 
3415*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
3416*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
3417*6777b538SAndroid Build Coastguard Worker 
3418*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3419*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
3420*6777b538SAndroid Build Coastguard Worker   }
3421*6777b538SAndroid Build Coastguard Worker 
3422*6777b538SAndroid Build Coastguard Worker   // Let 1st transaction complete headers phase for no range and read some part
3423*6777b538SAndroid Build Coastguard Worker   // of the response and write in the cache.
3424*6777b538SAndroid Build Coastguard Worker   std::string first_read;
3425*6777b538SAndroid Build Coastguard Worker   {
3426*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(mock_transaction);
3427*6777b538SAndroid Build Coastguard Worker     request1.url = GURL(kRangeGET_TransactionOK.url);
3428*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[0];
3429*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3430*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3431*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3432*6777b538SAndroid Build Coastguard Worker 
3433*6777b538SAndroid Build Coastguard Worker     c->result =
3434*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3435*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3436*6777b538SAndroid Build Coastguard Worker 
3437*6777b538SAndroid Build Coastguard Worker     const int kBufferSize = 5;
3438*6777b538SAndroid Build Coastguard Worker     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3439*6777b538SAndroid Build Coastguard Worker     ReleaseBufferCompletionCallback cb(buffer.get());
3440*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3441*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3442*6777b538SAndroid Build Coastguard Worker 
3443*6777b538SAndroid Build Coastguard Worker     std::string data_read(buffer->data(), kBufferSize);
3444*6777b538SAndroid Build Coastguard Worker     first_read = data_read;
3445*6777b538SAndroid Build Coastguard Worker 
3446*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3447*6777b538SAndroid Build Coastguard Worker   }
3448*6777b538SAndroid Build Coastguard Worker 
3449*6777b538SAndroid Build Coastguard Worker   // 2nd transaction requests a range.
3450*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction range_transaction(kRangeGET_TransactionOK);
3451*6777b538SAndroid Build Coastguard Worker   range_transaction.request_headers = "Range: bytes = 0-29\r\n" EXTRA_HEADER;
3452*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request2(range_transaction);
3453*6777b538SAndroid Build Coastguard Worker   {
3454*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[1];
3455*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3456*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3457*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3458*6777b538SAndroid Build Coastguard Worker 
3459*6777b538SAndroid Build Coastguard Worker     c->result =
3460*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3461*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3462*6777b538SAndroid Build Coastguard Worker 
3463*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3464*6777b538SAndroid Build Coastguard Worker   }
3465*6777b538SAndroid Build Coastguard Worker 
3466*6777b538SAndroid Build Coastguard Worker   // The second request would have doomed the 1st entry and created a new entry.
3467*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3468*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3469*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
3470*6777b538SAndroid Build Coastguard Worker 
3471*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3472*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
3473*6777b538SAndroid Build Coastguard Worker     if (c->result == ERR_IO_PENDING) {
3474*6777b538SAndroid Build Coastguard Worker       c->result = c->callback.WaitForResult();
3475*6777b538SAndroid Build Coastguard Worker     }
3476*6777b538SAndroid Build Coastguard Worker 
3477*6777b538SAndroid Build Coastguard Worker     if (i == 0) {
3478*6777b538SAndroid Build Coastguard Worker       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3479*6777b538SAndroid Build Coastguard Worker                                         mock_transaction);
3480*6777b538SAndroid Build Coastguard Worker       continue;
3481*6777b538SAndroid Build Coastguard Worker     }
3482*6777b538SAndroid Build Coastguard Worker     range_transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 ";
3483*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), range_transaction);
3484*6777b538SAndroid Build Coastguard Worker   }
3485*6777b538SAndroid Build Coastguard Worker   context_list.clear();
3486*6777b538SAndroid Build Coastguard Worker }
3487*6777b538SAndroid Build Coastguard Worker 
3488*6777b538SAndroid Build Coastguard Worker // Tests a 200 request and a simultaneous range request where conditionalization
3489*6777b538SAndroid Build Coastguard Worker // is possible.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCouldConditionalize)3490*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ParallelValidationCouldConditionalize) {
3491*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3492*6777b538SAndroid Build Coastguard Worker 
3493*6777b538SAndroid Build Coastguard Worker   MockTransaction mock_transaction(kSimpleGET_Transaction);
3494*6777b538SAndroid Build Coastguard Worker   mock_transaction.url = kRangeGET_TransactionOK.url;
3495*6777b538SAndroid Build Coastguard Worker   mock_transaction.data = kFullRangeData;
3496*6777b538SAndroid Build Coastguard Worker   std::string response_headers_str = base::StrCat(
3497*6777b538SAndroid Build Coastguard Worker       {"ETag: StrongOne\n",
3498*6777b538SAndroid Build Coastguard Worker        "Content-Length:", base::NumberToString(strlen(kFullRangeData)), "\n"});
3499*6777b538SAndroid Build Coastguard Worker   mock_transaction.response_headers = response_headers_str.c_str();
3500*6777b538SAndroid Build Coastguard Worker 
3501*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
3502*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
3503*6777b538SAndroid Build Coastguard Worker 
3504*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3505*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
3506*6777b538SAndroid Build Coastguard Worker   }
3507*6777b538SAndroid Build Coastguard Worker 
3508*6777b538SAndroid Build Coastguard Worker   // Let 1st transaction complete headers phase for no range and read some part
3509*6777b538SAndroid Build Coastguard Worker   // of the response and write in the cache.
3510*6777b538SAndroid Build Coastguard Worker   std::string first_read;
3511*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request1(mock_transaction);
3512*6777b538SAndroid Build Coastguard Worker   {
3513*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(mock_transaction);
3514*6777b538SAndroid Build Coastguard Worker     request1.url = GURL(kRangeGET_TransactionOK.url);
3515*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[0];
3516*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3517*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3518*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3519*6777b538SAndroid Build Coastguard Worker 
3520*6777b538SAndroid Build Coastguard Worker     c->result =
3521*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3522*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3523*6777b538SAndroid Build Coastguard Worker 
3524*6777b538SAndroid Build Coastguard Worker     const int kBufferSize = 5;
3525*6777b538SAndroid Build Coastguard Worker     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3526*6777b538SAndroid Build Coastguard Worker     ReleaseBufferCompletionCallback cb(buffer.get());
3527*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3528*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3529*6777b538SAndroid Build Coastguard Worker 
3530*6777b538SAndroid Build Coastguard Worker     std::string data_read(buffer->data(), kBufferSize);
3531*6777b538SAndroid Build Coastguard Worker     first_read = data_read;
3532*6777b538SAndroid Build Coastguard Worker 
3533*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3534*6777b538SAndroid Build Coastguard Worker   }
3535*6777b538SAndroid Build Coastguard Worker 
3536*6777b538SAndroid Build Coastguard Worker   // 2nd transaction requests a range.
3537*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction range_transaction(kRangeGET_TransactionOK);
3538*6777b538SAndroid Build Coastguard Worker   range_transaction.request_headers = "Range: bytes = 0-29\r\n" EXTRA_HEADER;
3539*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request2(range_transaction);
3540*6777b538SAndroid Build Coastguard Worker   {
3541*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[1];
3542*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3543*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3544*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3545*6777b538SAndroid Build Coastguard Worker 
3546*6777b538SAndroid Build Coastguard Worker     c->result =
3547*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3548*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3549*6777b538SAndroid Build Coastguard Worker 
3550*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3551*6777b538SAndroid Build Coastguard Worker   }
3552*6777b538SAndroid Build Coastguard Worker 
3553*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3554*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3555*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3556*6777b538SAndroid Build Coastguard Worker 
3557*6777b538SAndroid Build Coastguard Worker   // Finish and verify the first request.
3558*6777b538SAndroid Build Coastguard Worker   auto& c0 = context_list[0];
3559*6777b538SAndroid Build Coastguard Worker   c0->result = c0->callback.WaitForResult();
3560*6777b538SAndroid Build Coastguard Worker   ReadRemainingAndVerifyTransaction(c0->trans.get(), first_read,
3561*6777b538SAndroid Build Coastguard Worker                                     mock_transaction);
3562*6777b538SAndroid Build Coastguard Worker 
3563*6777b538SAndroid Build Coastguard Worker   // And the second.
3564*6777b538SAndroid Build Coastguard Worker   auto& c1 = context_list[1];
3565*6777b538SAndroid Build Coastguard Worker   c1->result = c1->callback.WaitForResult();
3566*6777b538SAndroid Build Coastguard Worker 
3567*6777b538SAndroid Build Coastguard Worker   range_transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 ";
3568*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(c1->trans.get(), range_transaction);
3569*6777b538SAndroid Build Coastguard Worker   context_list.clear();
3570*6777b538SAndroid Build Coastguard Worker }
3571*6777b538SAndroid Build Coastguard Worker 
3572*6777b538SAndroid Build Coastguard Worker // Tests parallel validation on range requests with overlapping ranges.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationOverlappingRanges)3573*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ParallelValidationOverlappingRanges) {
3574*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3575*6777b538SAndroid Build Coastguard Worker 
3576*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3577*6777b538SAndroid Build Coastguard Worker 
3578*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
3579*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
3580*6777b538SAndroid Build Coastguard Worker 
3581*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3582*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
3583*6777b538SAndroid Build Coastguard Worker   }
3584*6777b538SAndroid Build Coastguard Worker 
3585*6777b538SAndroid Build Coastguard Worker   // Let 1st transaction complete headers phase for ranges 40-49.
3586*6777b538SAndroid Build Coastguard Worker   std::string first_read;
3587*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request1(transaction);
3588*6777b538SAndroid Build Coastguard Worker   {
3589*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[0];
3590*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3591*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3592*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3593*6777b538SAndroid Build Coastguard Worker 
3594*6777b538SAndroid Build Coastguard Worker     c->result =
3595*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3596*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3597*6777b538SAndroid Build Coastguard Worker 
3598*6777b538SAndroid Build Coastguard Worker     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3599*6777b538SAndroid Build Coastguard Worker     // true.
3600*6777b538SAndroid Build Coastguard Worker     const int kBufferSize = 5;
3601*6777b538SAndroid Build Coastguard Worker     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3602*6777b538SAndroid Build Coastguard Worker     ReleaseBufferCompletionCallback cb(buffer.get());
3603*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3604*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3605*6777b538SAndroid Build Coastguard Worker 
3606*6777b538SAndroid Build Coastguard Worker     std::string data_read(buffer->data(), kBufferSize);
3607*6777b538SAndroid Build Coastguard Worker     first_read = data_read;
3608*6777b538SAndroid Build Coastguard Worker 
3609*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3610*6777b538SAndroid Build Coastguard Worker   }
3611*6777b538SAndroid Build Coastguard Worker 
3612*6777b538SAndroid Build Coastguard Worker   // 2nd transaction requests ranges 30-49.
3613*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3614*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request2(transaction);
3615*6777b538SAndroid Build Coastguard Worker   {
3616*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[1];
3617*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3618*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3619*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3620*6777b538SAndroid Build Coastguard Worker 
3621*6777b538SAndroid Build Coastguard Worker     c->result =
3622*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3623*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3624*6777b538SAndroid Build Coastguard Worker 
3625*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3626*6777b538SAndroid Build Coastguard Worker   }
3627*6777b538SAndroid Build Coastguard Worker 
3628*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request1.CacheKey();
3629*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3630*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3631*6777b538SAndroid Build Coastguard Worker 
3632*6777b538SAndroid Build Coastguard Worker   // Should have created another transaction for the uncached range.
3633*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3634*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3635*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3636*6777b538SAndroid Build Coastguard Worker 
3637*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3638*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
3639*6777b538SAndroid Build Coastguard Worker     if (c->result == ERR_IO_PENDING) {
3640*6777b538SAndroid Build Coastguard Worker       c->result = c->callback.WaitForResult();
3641*6777b538SAndroid Build Coastguard Worker     }
3642*6777b538SAndroid Build Coastguard Worker 
3643*6777b538SAndroid Build Coastguard Worker     if (i == 0) {
3644*6777b538SAndroid Build Coastguard Worker       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3645*6777b538SAndroid Build Coastguard Worker                                         transaction);
3646*6777b538SAndroid Build Coastguard Worker       continue;
3647*6777b538SAndroid Build Coastguard Worker     }
3648*6777b538SAndroid Build Coastguard Worker 
3649*6777b538SAndroid Build Coastguard Worker     transaction.data = "rg: 30-39 rg: 40-49 ";
3650*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), transaction);
3651*6777b538SAndroid Build Coastguard Worker   }
3652*6777b538SAndroid Build Coastguard Worker 
3653*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3654*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3655*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3656*6777b538SAndroid Build Coastguard Worker 
3657*6777b538SAndroid Build Coastguard Worker   // Fetch from the cache to check that ranges 30-49 have been successfully
3658*6777b538SAndroid Build Coastguard Worker   // cached.
3659*6777b538SAndroid Build Coastguard Worker   {
3660*6777b538SAndroid Build Coastguard Worker     MockTransaction range_transaction(kRangeGET_TransactionOK);
3661*6777b538SAndroid Build Coastguard Worker     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3662*6777b538SAndroid Build Coastguard Worker     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3663*6777b538SAndroid Build Coastguard Worker     std::string headers;
3664*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3665*6777b538SAndroid Build Coastguard Worker                                    &headers);
3666*6777b538SAndroid Build Coastguard Worker     Verify206Response(headers, 30, 49);
3667*6777b538SAndroid Build Coastguard Worker   }
3668*6777b538SAndroid Build Coastguard Worker 
3669*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3670*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3671*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3672*6777b538SAndroid Build Coastguard Worker }
3673*6777b538SAndroid Build Coastguard Worker 
3674*6777b538SAndroid Build Coastguard Worker // Tests parallel validation on range requests with overlapping ranges and the
3675*6777b538SAndroid Build Coastguard Worker // impact of deleting the writer on transactions that have validated.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationRestartDoneHeaders)3676*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ParallelValidationRestartDoneHeaders) {
3677*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3678*6777b538SAndroid Build Coastguard Worker 
3679*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3680*6777b538SAndroid Build Coastguard Worker 
3681*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
3682*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
3683*6777b538SAndroid Build Coastguard Worker 
3684*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3685*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
3686*6777b538SAndroid Build Coastguard Worker   }
3687*6777b538SAndroid Build Coastguard Worker 
3688*6777b538SAndroid Build Coastguard Worker   // Let 1st transaction complete headers phase for ranges 40-59.
3689*6777b538SAndroid Build Coastguard Worker   std::string first_read;
3690*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
3691*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request1(transaction);
3692*6777b538SAndroid Build Coastguard Worker   {
3693*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[0];
3694*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3695*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3696*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3697*6777b538SAndroid Build Coastguard Worker 
3698*6777b538SAndroid Build Coastguard Worker     c->result =
3699*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3700*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3701*6777b538SAndroid Build Coastguard Worker 
3702*6777b538SAndroid Build Coastguard Worker     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3703*6777b538SAndroid Build Coastguard Worker     // true.
3704*6777b538SAndroid Build Coastguard Worker     const int kBufferSize = 10;
3705*6777b538SAndroid Build Coastguard Worker     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3706*6777b538SAndroid Build Coastguard Worker     ReleaseBufferCompletionCallback cb(buffer.get());
3707*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3708*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3709*6777b538SAndroid Build Coastguard Worker 
3710*6777b538SAndroid Build Coastguard Worker     std::string data_read(buffer->data(), kBufferSize);
3711*6777b538SAndroid Build Coastguard Worker     first_read = data_read;
3712*6777b538SAndroid Build Coastguard Worker 
3713*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3714*6777b538SAndroid Build Coastguard Worker   }
3715*6777b538SAndroid Build Coastguard Worker 
3716*6777b538SAndroid Build Coastguard Worker   // 2nd transaction requests ranges 30-59.
3717*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
3718*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request2(transaction);
3719*6777b538SAndroid Build Coastguard Worker   {
3720*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[1];
3721*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3722*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3723*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3724*6777b538SAndroid Build Coastguard Worker 
3725*6777b538SAndroid Build Coastguard Worker     c->result =
3726*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3727*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
3728*6777b538SAndroid Build Coastguard Worker 
3729*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3730*6777b538SAndroid Build Coastguard Worker   }
3731*6777b538SAndroid Build Coastguard Worker 
3732*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request1.CacheKey();
3733*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3734*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3735*6777b538SAndroid Build Coastguard Worker 
3736*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3737*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3738*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3739*6777b538SAndroid Build Coastguard Worker 
3740*6777b538SAndroid Build Coastguard Worker   // Delete the writer transaction.
3741*6777b538SAndroid Build Coastguard Worker   context_list[0].reset();
3742*6777b538SAndroid Build Coastguard Worker 
3743*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3744*6777b538SAndroid Build Coastguard Worker 
3745*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 30-39 rg: 40-49 rg: 50-59 ";
3746*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(context_list[1]->trans.get(), transaction);
3747*6777b538SAndroid Build Coastguard Worker 
3748*6777b538SAndroid Build Coastguard Worker   // Create another network transaction since the 2nd transaction is restarted.
3749*6777b538SAndroid Build Coastguard Worker   // 30-39 will be read from network, 40-49 from the cache and 50-59 from the
3750*6777b538SAndroid Build Coastguard Worker   // network.
3751*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.network_layer()->transaction_count());
3752*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3753*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3754*6777b538SAndroid Build Coastguard Worker 
3755*6777b538SAndroid Build Coastguard Worker   // Fetch from the cache to check that ranges 30-49 have been successfully
3756*6777b538SAndroid Build Coastguard Worker   // cached.
3757*6777b538SAndroid Build Coastguard Worker   {
3758*6777b538SAndroid Build Coastguard Worker     MockTransaction range_transaction(kRangeGET_TransactionOK);
3759*6777b538SAndroid Build Coastguard Worker     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3760*6777b538SAndroid Build Coastguard Worker     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3761*6777b538SAndroid Build Coastguard Worker     std::string headers;
3762*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3763*6777b538SAndroid Build Coastguard Worker                                    &headers);
3764*6777b538SAndroid Build Coastguard Worker     Verify206Response(headers, 30, 49);
3765*6777b538SAndroid Build Coastguard Worker   }
3766*6777b538SAndroid Build Coastguard Worker 
3767*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.network_layer()->transaction_count());
3768*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
3769*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3770*6777b538SAndroid Build Coastguard Worker }
3771*6777b538SAndroid Build Coastguard Worker 
3772*6777b538SAndroid Build Coastguard Worker // A test of doing a range request to a cached 301 response
TEST_F(HttpCacheTest,RangeGET_CachedRedirect)3773*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_CachedRedirect) {
3774*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer handler;
3775*6777b538SAndroid Build Coastguard Worker   handler.set_redirect(true);
3776*6777b538SAndroid Build Coastguard Worker 
3777*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3778*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3779*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 0-\r\n" EXTRA_HEADER;
3780*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 301 Moved Permanently";
3781*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "Location: /elsewhere\nContent-Length:5";
3782*6777b538SAndroid Build Coastguard Worker   transaction.data = "12345";
3783*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
3784*6777b538SAndroid Build Coastguard Worker 
3785*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
3786*6777b538SAndroid Build Coastguard Worker 
3787*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
3788*6777b538SAndroid Build Coastguard Worker   {
3789*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
3790*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3791*6777b538SAndroid Build Coastguard Worker 
3792*6777b538SAndroid Build Coastguard Worker     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3793*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING) {
3794*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
3795*6777b538SAndroid Build Coastguard Worker     }
3796*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(rv, IsOk());
3797*6777b538SAndroid Build Coastguard Worker 
3798*6777b538SAndroid Build Coastguard Worker     const HttpResponseInfo* info = trans->GetResponseInfo();
3799*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(info);
3800*6777b538SAndroid Build Coastguard Worker 
3801*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(info->headers->response_code(), 301);
3802*6777b538SAndroid Build Coastguard Worker 
3803*6777b538SAndroid Build Coastguard Worker     std::string location;
3804*6777b538SAndroid Build Coastguard Worker     info->headers->EnumerateHeader(nullptr, "Location", &location);
3805*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(location, "/elsewhere");
3806*6777b538SAndroid Build Coastguard Worker 
3807*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(trans.get(), transaction);
3808*6777b538SAndroid Build Coastguard Worker   }
3809*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3810*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3811*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3812*6777b538SAndroid Build Coastguard Worker 
3813*6777b538SAndroid Build Coastguard Worker   // Active entries in the cache are not retired synchronously. Make
3814*6777b538SAndroid Build Coastguard Worker   // sure the next run hits the MockHttpCache and open_count is
3815*6777b538SAndroid Build Coastguard Worker   // correct.
3816*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3817*6777b538SAndroid Build Coastguard Worker 
3818*6777b538SAndroid Build Coastguard Worker   // Read from the cache.
3819*6777b538SAndroid Build Coastguard Worker   {
3820*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
3821*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3822*6777b538SAndroid Build Coastguard Worker 
3823*6777b538SAndroid Build Coastguard Worker     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3824*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING) {
3825*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
3826*6777b538SAndroid Build Coastguard Worker     }
3827*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(rv, IsOk());
3828*6777b538SAndroid Build Coastguard Worker 
3829*6777b538SAndroid Build Coastguard Worker     const HttpResponseInfo* info = trans->GetResponseInfo();
3830*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(info);
3831*6777b538SAndroid Build Coastguard Worker 
3832*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(info->headers->response_code(), 301);
3833*6777b538SAndroid Build Coastguard Worker 
3834*6777b538SAndroid Build Coastguard Worker     std::string location;
3835*6777b538SAndroid Build Coastguard Worker     info->headers->EnumerateHeader(nullptr, "Location", &location);
3836*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(location, "/elsewhere");
3837*6777b538SAndroid Build Coastguard Worker 
3838*6777b538SAndroid Build Coastguard Worker     trans->DoneReading();
3839*6777b538SAndroid Build Coastguard Worker   }
3840*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3841*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
3842*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3843*6777b538SAndroid Build Coastguard Worker 
3844*6777b538SAndroid Build Coastguard Worker   // Now read the full body. This normally would not be done for a 301 by
3845*6777b538SAndroid Build Coastguard Worker   // higher layers, but e.g. a 500 could hit a further bug here.
3846*6777b538SAndroid Build Coastguard Worker   {
3847*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
3848*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3849*6777b538SAndroid Build Coastguard Worker 
3850*6777b538SAndroid Build Coastguard Worker     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3851*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING) {
3852*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
3853*6777b538SAndroid Build Coastguard Worker     }
3854*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(rv, IsOk());
3855*6777b538SAndroid Build Coastguard Worker 
3856*6777b538SAndroid Build Coastguard Worker     const HttpResponseInfo* info = trans->GetResponseInfo();
3857*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(info);
3858*6777b538SAndroid Build Coastguard Worker 
3859*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(info->headers->response_code(), 301);
3860*6777b538SAndroid Build Coastguard Worker 
3861*6777b538SAndroid Build Coastguard Worker     std::string location;
3862*6777b538SAndroid Build Coastguard Worker     info->headers->EnumerateHeader(nullptr, "Location", &location);
3863*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(location, "/elsewhere");
3864*6777b538SAndroid Build Coastguard Worker 
3865*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(trans.get(), transaction);
3866*6777b538SAndroid Build Coastguard Worker   }
3867*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3868*6777b538SAndroid Build Coastguard Worker   // No extra open since it picks up a previous ActiveEntry.
3869*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
3870*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3871*6777b538SAndroid Build Coastguard Worker }
3872*6777b538SAndroid Build Coastguard Worker 
3873*6777b538SAndroid Build Coastguard Worker // A transaction that fails to validate an entry, while attempting to write
3874*6777b538SAndroid Build Coastguard Worker // the response, should still get data to its consumer even if the attempt to
3875*6777b538SAndroid Build Coastguard Worker // create a new entry fails.
TEST_F(HttpCacheTest,SimpleGET_ValidationFailureWithCreateFailure)3876*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ValidationFailureWithCreateFailure) {
3877*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3878*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
3879*6777b538SAndroid Build Coastguard Worker   request.load_flags |= LOAD_VALIDATE_CACHE;
3880*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
3881*6777b538SAndroid Build Coastguard Worker 
3882*6777b538SAndroid Build Coastguard Worker   // Create and run the first, successful, transaction to prime the cache.
3883*6777b538SAndroid Build Coastguard Worker   context_list.push_back(std::make_unique<Context>());
3884*6777b538SAndroid Build Coastguard Worker   auto& c1 = context_list.back();
3885*6777b538SAndroid Build Coastguard Worker   c1->result = cache.CreateTransaction(&c1->trans);
3886*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c1->result, IsOk());
3887*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_IDLE, c1->trans->GetLoadState());
3888*6777b538SAndroid Build Coastguard Worker   c1->result =
3889*6777b538SAndroid Build Coastguard Worker       c1->trans->Start(&request, c1->callback.callback(), NetLogWithSource());
3890*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c1->trans->GetLoadState());
3891*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3892*6777b538SAndroid Build Coastguard Worker 
3893*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
3894*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3895*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3896*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3897*6777b538SAndroid Build Coastguard Worker 
3898*6777b538SAndroid Build Coastguard Worker   // Create and start the second transaction, which will fail its validation
3899*6777b538SAndroid Build Coastguard Worker   // during the call to RunUntilIdle().
3900*6777b538SAndroid Build Coastguard Worker   context_list.push_back(std::make_unique<Context>());
3901*6777b538SAndroid Build Coastguard Worker   auto& c2 = context_list.back();
3902*6777b538SAndroid Build Coastguard Worker   c2->result = cache.CreateTransaction(&c2->trans);
3903*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c2->result, IsOk());
3904*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_IDLE, c2->trans->GetLoadState());
3905*6777b538SAndroid Build Coastguard Worker   c2->result =
3906*6777b538SAndroid Build Coastguard Worker       c2->trans->Start(&request, c2->callback.callback(), NetLogWithSource());
3907*6777b538SAndroid Build Coastguard Worker   // Expect idle at this point because we should be able to find and use the
3908*6777b538SAndroid Build Coastguard Worker   // Active Entry that c1 created instead of waiting on the cache to open the
3909*6777b538SAndroid Build Coastguard Worker   // entry.
3910*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_IDLE, c2->trans->GetLoadState());
3911*6777b538SAndroid Build Coastguard Worker 
3912*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_fail_requests(true);
3913*6777b538SAndroid Build Coastguard Worker   // The transaction, c2, should now attempt to validate the entry, fail when it
3914*6777b538SAndroid Build Coastguard Worker   // receives a 200 OK response, attempt to create a new entry, fail to create,
3915*6777b538SAndroid Build Coastguard Worker   // and then continue onward without an entry.
3916*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3917*6777b538SAndroid Build Coastguard Worker 
3918*6777b538SAndroid Build Coastguard Worker   // All requests depend on the writer, and the writer is between Start and
3919*6777b538SAndroid Build Coastguard Worker   // Read, i.e. idle.
3920*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
3921*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3922*6777b538SAndroid Build Coastguard Worker   }
3923*6777b538SAndroid Build Coastguard Worker 
3924*6777b538SAndroid Build Coastguard Worker   // Confirm that both transactions correctly Read() the data.
3925*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
3926*6777b538SAndroid Build Coastguard Worker     if (context->result == ERR_IO_PENDING) {
3927*6777b538SAndroid Build Coastguard Worker       context->result = context->callback.WaitForResult();
3928*6777b538SAndroid Build Coastguard Worker     }
3929*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
3930*6777b538SAndroid Build Coastguard Worker   }
3931*6777b538SAndroid Build Coastguard Worker 
3932*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3933*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3934*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
3935*6777b538SAndroid Build Coastguard Worker }
3936*6777b538SAndroid Build Coastguard Worker 
3937*6777b538SAndroid Build Coastguard Worker // Parallel validation results in 200.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationNoMatch)3938*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelValidationNoMatch) {
3939*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
3940*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
3941*6777b538SAndroid Build Coastguard Worker   request.load_flags |= LOAD_VALIDATE_CACHE;
3942*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
3943*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 5;
3944*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
3945*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
3946*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
3947*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
3948*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
3949*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3950*6777b538SAndroid Build Coastguard Worker     c->result =
3951*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
3952*6777b538SAndroid Build Coastguard Worker   }
3953*6777b538SAndroid Build Coastguard Worker 
3954*6777b538SAndroid Build Coastguard Worker   // All requests are waiting for the active entry.
3955*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
3956*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
3957*6777b538SAndroid Build Coastguard Worker   }
3958*6777b538SAndroid Build Coastguard Worker 
3959*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
3960*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3961*6777b538SAndroid Build Coastguard Worker 
3962*6777b538SAndroid Build Coastguard Worker   // The first request should be a writer at this point, and the subsequent
3963*6777b538SAndroid Build Coastguard Worker   // requests should have passed the validation phase and created their own
3964*6777b538SAndroid Build Coastguard Worker   // entries since none of them matched the headers of the earlier one.
3965*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
3966*6777b538SAndroid Build Coastguard Worker 
3967*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, cache.network_layer()->transaction_count());
3968*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3969*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, cache.disk_cache()->create_count());
3970*6777b538SAndroid Build Coastguard Worker 
3971*6777b538SAndroid Build Coastguard Worker   // All requests depend on the writer, and the writer is between Start and
3972*6777b538SAndroid Build Coastguard Worker   // Read, i.e. idle.
3973*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
3974*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3975*6777b538SAndroid Build Coastguard Worker   }
3976*6777b538SAndroid Build Coastguard Worker 
3977*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
3978*6777b538SAndroid Build Coastguard Worker     if (context->result == ERR_IO_PENDING) {
3979*6777b538SAndroid Build Coastguard Worker       context->result = context->callback.WaitForResult();
3980*6777b538SAndroid Build Coastguard Worker     }
3981*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
3982*6777b538SAndroid Build Coastguard Worker   }
3983*6777b538SAndroid Build Coastguard Worker 
3984*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, cache.network_layer()->transaction_count());
3985*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
3986*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, cache.disk_cache()->create_count());
3987*6777b538SAndroid Build Coastguard Worker }
3988*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,RangeGET_Enormous)3989*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_Enormous) {
3990*6777b538SAndroid Build Coastguard Worker   // Test for how blockfile's limit on range namespace interacts with
3991*6777b538SAndroid Build Coastguard Worker   // HttpCache::Transaction.
3992*6777b538SAndroid Build Coastguard Worker   // See https://crbug.com/770694
3993*6777b538SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
3994*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
3995*6777b538SAndroid Build Coastguard Worker 
3996*6777b538SAndroid Build Coastguard Worker   auto backend_factory = std::make_unique<HttpCache::DefaultBackend>(
3997*6777b538SAndroid Build Coastguard Worker       DISK_CACHE, CACHE_BACKEND_BLOCKFILE,
3998*6777b538SAndroid Build Coastguard Worker       /*file_operations_factory=*/nullptr, temp_dir.GetPath(), 1024 * 1024,
3999*6777b538SAndroid Build Coastguard Worker       false);
4000*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache(std::move(backend_factory));
4001*6777b538SAndroid Build Coastguard Worker 
4002*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer handler;
4003*6777b538SAndroid Build Coastguard Worker   handler.set_length(2305843009213693962);
4004*6777b538SAndroid Build Coastguard Worker 
4005*6777b538SAndroid Build Coastguard Worker   // Prime with a range it can store.
4006*6777b538SAndroid Build Coastguard Worker   {
4007*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4008*6777b538SAndroid Build Coastguard Worker     transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4009*6777b538SAndroid Build Coastguard Worker     transaction.data = "rg: 00-09 ";
4010*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
4011*6777b538SAndroid Build Coastguard Worker 
4012*6777b538SAndroid Build Coastguard Worker     HttpResponseInfo response;
4013*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4014*6777b538SAndroid Build Coastguard Worker                                   &response);
4015*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response.headers != nullptr);
4016*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(206, response.headers->response_code());
4017*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
4018*6777b538SAndroid Build Coastguard Worker   }
4019*6777b538SAndroid Build Coastguard Worker 
4020*6777b538SAndroid Build Coastguard Worker   // Try with a range it can't. Should still work.
4021*6777b538SAndroid Build Coastguard Worker   {
4022*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4023*6777b538SAndroid Build Coastguard Worker     transaction.request_headers =
4024*6777b538SAndroid Build Coastguard Worker         "Range: bytes = "
4025*6777b538SAndroid Build Coastguard Worker         "2305843009213693952-2305843009213693961\r\n" EXTRA_HEADER;
4026*6777b538SAndroid Build Coastguard Worker     transaction.data = "rg: 52-61 ";
4027*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
4028*6777b538SAndroid Build Coastguard Worker 
4029*6777b538SAndroid Build Coastguard Worker     HttpResponseInfo response;
4030*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4031*6777b538SAndroid Build Coastguard Worker                                   &response);
4032*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response.headers != nullptr);
4033*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(206, response.headers->response_code());
4034*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.network_layer()->transaction_count());
4035*6777b538SAndroid Build Coastguard Worker   }
4036*6777b538SAndroid Build Coastguard Worker 
4037*6777b538SAndroid Build Coastguard Worker   // Can't actually cache it due to backend limitations. If the network
4038*6777b538SAndroid Build Coastguard Worker   // transaction count is 2, this test isn't covering what it needs to.
4039*6777b538SAndroid Build Coastguard Worker   {
4040*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4041*6777b538SAndroid Build Coastguard Worker     transaction.request_headers =
4042*6777b538SAndroid Build Coastguard Worker         "Range: bytes = "
4043*6777b538SAndroid Build Coastguard Worker         "2305843009213693952-2305843009213693961\r\n" EXTRA_HEADER;
4044*6777b538SAndroid Build Coastguard Worker     transaction.data = "rg: 52-61 ";
4045*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
4046*6777b538SAndroid Build Coastguard Worker 
4047*6777b538SAndroid Build Coastguard Worker     HttpResponseInfo response;
4048*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4049*6777b538SAndroid Build Coastguard Worker                                   &response);
4050*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response.headers != nullptr);
4051*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(206, response.headers->response_code());
4052*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(3, cache.network_layer()->transaction_count());
4053*6777b538SAndroid Build Coastguard Worker   }
4054*6777b538SAndroid Build Coastguard Worker }
4055*6777b538SAndroid Build Coastguard Worker 
4056*6777b538SAndroid Build Coastguard Worker // Parallel validation results in 200 for 1 transaction and validation matches
4057*6777b538SAndroid Build Coastguard Worker // for subsequent transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationNoMatch1)4058*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelValidationNoMatch1) {
4059*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4060*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4061*6777b538SAndroid Build Coastguard Worker 
4062*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
4063*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
4064*6777b538SAndroid Build Coastguard Worker   MockHttpRequest validate_request(transaction);
4065*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4066*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 5;
4067*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4068*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4069*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4070*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4071*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4072*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
4073*6777b538SAndroid Build Coastguard Worker 
4074*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
4075*6777b538SAndroid Build Coastguard Worker     if (i == 1) {
4076*6777b538SAndroid Build Coastguard Worker       this_request = &validate_request;
4077*6777b538SAndroid Build Coastguard Worker     }
4078*6777b538SAndroid Build Coastguard Worker 
4079*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
4080*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
4081*6777b538SAndroid Build Coastguard Worker   }
4082*6777b538SAndroid Build Coastguard Worker 
4083*6777b538SAndroid Build Coastguard Worker   // All requests are waiting for the active entry.
4084*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
4085*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
4086*6777b538SAndroid Build Coastguard Worker   }
4087*6777b538SAndroid Build Coastguard Worker 
4088*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
4089*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4090*6777b538SAndroid Build Coastguard Worker 
4091*6777b538SAndroid Build Coastguard Worker   // The new entry will have all the transactions except the first one which
4092*6777b538SAndroid Build Coastguard Worker   // will continue in the doomed entry.
4093*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions - 1,
4094*6777b538SAndroid Build Coastguard Worker             cache.GetCountWriterTransactions(validate_request.CacheKey()));
4095*6777b538SAndroid Build Coastguard Worker 
4096*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->doomed_count());
4097*6777b538SAndroid Build Coastguard Worker 
4098*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4099*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4100*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
4101*6777b538SAndroid Build Coastguard Worker 
4102*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
4103*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
4104*6777b538SAndroid Build Coastguard Worker   }
4105*6777b538SAndroid Build Coastguard Worker 
4106*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
4107*6777b538SAndroid Build Coastguard Worker     if (context->result == ERR_IO_PENDING) {
4108*6777b538SAndroid Build Coastguard Worker       context->result = context->callback.WaitForResult();
4109*6777b538SAndroid Build Coastguard Worker     }
4110*6777b538SAndroid Build Coastguard Worker 
4111*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4112*6777b538SAndroid Build Coastguard Worker   }
4113*6777b538SAndroid Build Coastguard Worker 
4114*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4115*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4116*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
4117*6777b538SAndroid Build Coastguard Worker }
4118*6777b538SAndroid Build Coastguard Worker 
4119*6777b538SAndroid Build Coastguard Worker // Tests that a GET followed by a DELETE results in DELETE immediately starting
4120*6777b538SAndroid Build Coastguard Worker // the headers phase and the entry is doomed.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationDelete)4121*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelValidationDelete) {
4122*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4123*6777b538SAndroid Build Coastguard Worker 
4124*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4125*6777b538SAndroid Build Coastguard Worker   request.load_flags |= LOAD_VALIDATE_CACHE;
4126*6777b538SAndroid Build Coastguard Worker 
4127*6777b538SAndroid Build Coastguard Worker   MockHttpRequest delete_request(kSimpleGET_Transaction);
4128*6777b538SAndroid Build Coastguard Worker   delete_request.method = "DELETE";
4129*6777b538SAndroid Build Coastguard Worker 
4130*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4131*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
4132*6777b538SAndroid Build Coastguard Worker 
4133*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4134*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4135*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4136*6777b538SAndroid Build Coastguard Worker 
4137*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
4138*6777b538SAndroid Build Coastguard Worker     if (i == 1) {
4139*6777b538SAndroid Build Coastguard Worker       this_request = &delete_request;
4140*6777b538SAndroid Build Coastguard Worker     }
4141*6777b538SAndroid Build Coastguard Worker 
4142*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4143*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4144*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
4145*6777b538SAndroid Build Coastguard Worker 
4146*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
4147*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
4148*6777b538SAndroid Build Coastguard Worker   }
4149*6777b538SAndroid Build Coastguard Worker 
4150*6777b538SAndroid Build Coastguard Worker   // All requests are waiting for the active entry.
4151*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
4152*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
4153*6777b538SAndroid Build Coastguard Worker   }
4154*6777b538SAndroid Build Coastguard Worker 
4155*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
4156*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4157*6777b538SAndroid Build Coastguard Worker 
4158*6777b538SAndroid Build Coastguard Worker   // The first request should be a writer at this point, and the subsequent
4159*6777b538SAndroid Build Coastguard Worker   // request should have passed the validation phase and doomed the existing
4160*6777b538SAndroid Build Coastguard Worker   // entry.
4161*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.disk_cache()->IsDiskEntryDoomed(request.CacheKey()));
4162*6777b538SAndroid Build Coastguard Worker 
4163*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4164*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4165*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4166*6777b538SAndroid Build Coastguard Worker 
4167*6777b538SAndroid Build Coastguard Worker   // All requests depend on the writer, and the writer is between Start and
4168*6777b538SAndroid Build Coastguard Worker   // Read, i.e. idle.
4169*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
4170*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
4171*6777b538SAndroid Build Coastguard Worker   }
4172*6777b538SAndroid Build Coastguard Worker 
4173*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
4174*6777b538SAndroid Build Coastguard Worker     if (context->result == ERR_IO_PENDING) {
4175*6777b538SAndroid Build Coastguard Worker       context->result = context->callback.WaitForResult();
4176*6777b538SAndroid Build Coastguard Worker     }
4177*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4178*6777b538SAndroid Build Coastguard Worker   }
4179*6777b538SAndroid Build Coastguard Worker 
4180*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4181*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4182*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4183*6777b538SAndroid Build Coastguard Worker }
4184*6777b538SAndroid Build Coastguard Worker 
4185*6777b538SAndroid Build Coastguard Worker // Tests that a transaction which is in validated queue can be destroyed without
4186*6777b538SAndroid Build Coastguard Worker // any impact to other transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelValidated)4187*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelValidated) {
4188*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4189*6777b538SAndroid Build Coastguard Worker 
4190*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4191*6777b538SAndroid Build Coastguard Worker 
4192*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
4193*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4194*6777b538SAndroid Build Coastguard Worker   MockHttpRequest read_only_request(transaction);
4195*6777b538SAndroid Build Coastguard Worker 
4196*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4197*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
4198*6777b538SAndroid Build Coastguard Worker 
4199*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4200*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4201*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4202*6777b538SAndroid Build Coastguard Worker 
4203*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4204*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4205*6777b538SAndroid Build Coastguard Worker 
4206*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* current_request = i == 1 ? &read_only_request : &request;
4207*6777b538SAndroid Build Coastguard Worker 
4208*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(current_request, c->callback.callback(),
4209*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
4210*6777b538SAndroid Build Coastguard Worker   }
4211*6777b538SAndroid Build Coastguard Worker 
4212*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
4213*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4214*6777b538SAndroid Build Coastguard Worker 
4215*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4216*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4217*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4218*6777b538SAndroid Build Coastguard Worker 
4219*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
4220*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4221*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4222*6777b538SAndroid Build Coastguard Worker 
4223*6777b538SAndroid Build Coastguard Worker   context_list[1].reset();
4224*6777b538SAndroid Build Coastguard Worker 
4225*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4226*6777b538SAndroid Build Coastguard Worker 
4227*6777b538SAndroid Build Coastguard Worker   // Complete the rest of the transactions.
4228*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
4229*6777b538SAndroid Build Coastguard Worker     if (!context) {
4230*6777b538SAndroid Build Coastguard Worker       continue;
4231*6777b538SAndroid Build Coastguard Worker     }
4232*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4233*6777b538SAndroid Build Coastguard Worker   }
4234*6777b538SAndroid Build Coastguard Worker 
4235*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4236*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4237*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4238*6777b538SAndroid Build Coastguard Worker }
4239*6777b538SAndroid Build Coastguard Worker 
4240*6777b538SAndroid Build Coastguard Worker // Tests that an idle writer transaction can be deleted without impacting the
4241*6777b538SAndroid Build Coastguard Worker // existing writers.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingCancelIdleTransaction)4242*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelWritingCancelIdleTransaction) {
4243*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4244*6777b538SAndroid Build Coastguard Worker 
4245*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4246*6777b538SAndroid Build Coastguard Worker 
4247*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4248*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
4249*6777b538SAndroid Build Coastguard Worker 
4250*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4251*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4252*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4253*6777b538SAndroid Build Coastguard Worker 
4254*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4255*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4256*6777b538SAndroid Build Coastguard Worker 
4257*6777b538SAndroid Build Coastguard Worker     c->result =
4258*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4259*6777b538SAndroid Build Coastguard Worker   }
4260*6777b538SAndroid Build Coastguard Worker 
4261*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
4262*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4263*6777b538SAndroid Build Coastguard Worker 
4264*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4265*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4266*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4267*6777b538SAndroid Build Coastguard Worker 
4268*6777b538SAndroid Build Coastguard Worker   // Both transactions would be added to writers.
4269*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
4270*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
4271*6777b538SAndroid Build Coastguard Worker 
4272*6777b538SAndroid Build Coastguard Worker   context_list[1].reset();
4273*6777b538SAndroid Build Coastguard Worker 
4274*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
4275*6777b538SAndroid Build Coastguard Worker 
4276*6777b538SAndroid Build Coastguard Worker   // Complete the rest of the transactions.
4277*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
4278*6777b538SAndroid Build Coastguard Worker     if (!context) {
4279*6777b538SAndroid Build Coastguard Worker       continue;
4280*6777b538SAndroid Build Coastguard Worker     }
4281*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4282*6777b538SAndroid Build Coastguard Worker   }
4283*6777b538SAndroid Build Coastguard Worker 
4284*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4285*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4286*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4287*6777b538SAndroid Build Coastguard Worker }
4288*6777b538SAndroid Build Coastguard Worker 
4289*6777b538SAndroid Build Coastguard Worker // Tests that a transaction which is in validated queue can timeout and start
4290*6777b538SAndroid Build Coastguard Worker // the headers phase again.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationValidatedTimeout)4291*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelValidationValidatedTimeout) {
4292*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4293*6777b538SAndroid Build Coastguard Worker 
4294*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4295*6777b538SAndroid Build Coastguard Worker 
4296*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
4297*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4298*6777b538SAndroid Build Coastguard Worker   MockHttpRequest read_only_request(transaction);
4299*6777b538SAndroid Build Coastguard Worker 
4300*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4301*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
4302*6777b538SAndroid Build Coastguard Worker 
4303*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4304*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4305*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4306*6777b538SAndroid Build Coastguard Worker 
4307*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
4308*6777b538SAndroid Build Coastguard Worker     if (i == 1) {
4309*6777b538SAndroid Build Coastguard Worker       this_request = &read_only_request;
4310*6777b538SAndroid Build Coastguard Worker       cache.SimulateCacheLockTimeoutAfterHeaders();
4311*6777b538SAndroid Build Coastguard Worker     }
4312*6777b538SAndroid Build Coastguard Worker 
4313*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4314*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4315*6777b538SAndroid Build Coastguard Worker 
4316*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
4317*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
4318*6777b538SAndroid Build Coastguard Worker   }
4319*6777b538SAndroid Build Coastguard Worker 
4320*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
4321*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4322*6777b538SAndroid Build Coastguard Worker 
4323*6777b538SAndroid Build Coastguard Worker   // The first request should be a writer at this point, and the subsequent
4324*6777b538SAndroid Build Coastguard Worker   // requests should have completed validation, timed out and restarted.
4325*6777b538SAndroid Build Coastguard Worker   // Since it is a read only request, it will error out.
4326*6777b538SAndroid Build Coastguard Worker 
4327*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4328*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4329*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4330*6777b538SAndroid Build Coastguard Worker 
4331*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
4332*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
4333*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4334*6777b538SAndroid Build Coastguard Worker 
4335*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4336*6777b538SAndroid Build Coastguard Worker 
4337*6777b538SAndroid Build Coastguard Worker   int rv = context_list[1]->callback.WaitForResult();
4338*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_CACHE_MISS, rv);
4339*6777b538SAndroid Build Coastguard Worker 
4340*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(context_list[0]->trans.get(),
4341*6777b538SAndroid Build Coastguard Worker                            kSimpleGET_Transaction);
4342*6777b538SAndroid Build Coastguard Worker }
4343*6777b538SAndroid Build Coastguard Worker 
4344*6777b538SAndroid Build Coastguard Worker // Tests that a transaction which is in readers can be destroyed without
4345*6777b538SAndroid Build Coastguard Worker // any impact to other transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelReader)4346*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelReader) {
4347*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4348*6777b538SAndroid Build Coastguard Worker 
4349*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4350*6777b538SAndroid Build Coastguard Worker 
4351*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
4352*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
4353*6777b538SAndroid Build Coastguard Worker   MockHttpRequest validate_request(transaction);
4354*6777b538SAndroid Build Coastguard Worker 
4355*6777b538SAndroid Build Coastguard Worker   int kNumTransactions = 4;
4356*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4357*6777b538SAndroid Build Coastguard Worker 
4358*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4359*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4360*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4361*6777b538SAndroid Build Coastguard Worker 
4362*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4363*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4364*6777b538SAndroid Build Coastguard Worker 
4365*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
4366*6777b538SAndroid Build Coastguard Worker     if (i == 3) {
4367*6777b538SAndroid Build Coastguard Worker       this_request = &validate_request;
4368*6777b538SAndroid Build Coastguard Worker       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
4369*6777b538SAndroid Build Coastguard Worker     }
4370*6777b538SAndroid Build Coastguard Worker 
4371*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
4372*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
4373*6777b538SAndroid Build Coastguard Worker   }
4374*6777b538SAndroid Build Coastguard Worker 
4375*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
4376*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4377*6777b538SAndroid Build Coastguard Worker 
4378*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4379*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4380*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4381*6777b538SAndroid Build Coastguard Worker 
4382*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
4383*6777b538SAndroid Build Coastguard Worker 
4384*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
4385*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4386*6777b538SAndroid Build Coastguard Worker 
4387*6777b538SAndroid Build Coastguard Worker   // Complete the response body.
4388*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(context_list[0]->trans.get(),
4389*6777b538SAndroid Build Coastguard Worker                            kSimpleGET_Transaction);
4390*6777b538SAndroid Build Coastguard Worker 
4391*6777b538SAndroid Build Coastguard Worker   // Rest of the transactions should move to readers.
4392*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
4393*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions - 2, cache.GetCountReaders(cache_key));
4394*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4395*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4396*6777b538SAndroid Build Coastguard Worker 
4397*6777b538SAndroid Build Coastguard Worker   // Add 2 new transactions.
4398*6777b538SAndroid Build Coastguard Worker   kNumTransactions = 6;
4399*6777b538SAndroid Build Coastguard Worker 
4400*6777b538SAndroid Build Coastguard Worker   for (int i = 4; i < kNumTransactions; ++i) {
4401*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4402*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4403*6777b538SAndroid Build Coastguard Worker 
4404*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4405*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4406*6777b538SAndroid Build Coastguard Worker 
4407*6777b538SAndroid Build Coastguard Worker     c->result =
4408*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4409*6777b538SAndroid Build Coastguard Worker   }
4410*6777b538SAndroid Build Coastguard Worker 
4411*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.GetCountAddToEntryQueue(cache_key));
4412*6777b538SAndroid Build Coastguard Worker 
4413*6777b538SAndroid Build Coastguard Worker   // Delete a reader.
4414*6777b538SAndroid Build Coastguard Worker   context_list[1].reset();
4415*6777b538SAndroid Build Coastguard Worker 
4416*6777b538SAndroid Build Coastguard Worker   // Deleting the reader did not impact any other transaction.
4417*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
4418*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.GetCountAddToEntryQueue(cache_key));
4419*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4420*6777b538SAndroid Build Coastguard Worker 
4421*6777b538SAndroid Build Coastguard Worker   // Resume network start for headers_transaction. It will doom the entry as it
4422*6777b538SAndroid Build Coastguard Worker   // will be a 200 and will go to network for the response body.
4423*6777b538SAndroid Build Coastguard Worker   context_list[3]->trans->ResumeNetworkStart();
4424*6777b538SAndroid Build Coastguard Worker 
4425*6777b538SAndroid Build Coastguard Worker   // The pending transactions will be added to a new entry as writers.
4426*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4427*6777b538SAndroid Build Coastguard Worker 
4428*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4429*6777b538SAndroid Build Coastguard Worker 
4430*6777b538SAndroid Build Coastguard Worker   // Complete the rest of the transactions.
4431*6777b538SAndroid Build Coastguard Worker   for (int i = 2; i < kNumTransactions; ++i) {
4432*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(context_list[i]->trans.get(),
4433*6777b538SAndroid Build Coastguard Worker                              kSimpleGET_Transaction);
4434*6777b538SAndroid Build Coastguard Worker   }
4435*6777b538SAndroid Build Coastguard Worker 
4436*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4437*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4438*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
4439*6777b538SAndroid Build Coastguard Worker }
4440*6777b538SAndroid Build Coastguard Worker 
4441*6777b538SAndroid Build Coastguard Worker // Tests that when the only writer goes away, it immediately cleans up rather
4442*6777b538SAndroid Build Coastguard Worker // than wait for the network request to finish. See https://crbug.com/804868.
TEST_F(HttpCacheTest,SimpleGET_HangingCacheWriteCleanup)4443*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_HangingCacheWriteCleanup) {
4444*6777b538SAndroid Build Coastguard Worker   MockHttpCache mock_cache;
4445*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4446*6777b538SAndroid Build Coastguard Worker 
4447*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> transaction;
4448*6777b538SAndroid Build Coastguard Worker   mock_cache.CreateTransaction(&transaction);
4449*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
4450*6777b538SAndroid Build Coastguard Worker   int result =
4451*6777b538SAndroid Build Coastguard Worker       transaction->Start(&request, callback.callback(), NetLogWithSource());
4452*6777b538SAndroid Build Coastguard Worker 
4453*6777b538SAndroid Build Coastguard Worker   // Get the transaction ready to read.
4454*6777b538SAndroid Build Coastguard Worker   result = callback.GetResult(result);
4455*6777b538SAndroid Build Coastguard Worker 
4456*6777b538SAndroid Build Coastguard Worker   // Read the first byte.
4457*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<IOBufferWithSize>(1);
4458*6777b538SAndroid Build Coastguard Worker   ReleaseBufferCompletionCallback buffer_callback(buffer.get());
4459*6777b538SAndroid Build Coastguard Worker   result = transaction->Read(buffer.get(), 1, buffer_callback.callback());
4460*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, buffer_callback.GetResult(result));
4461*6777b538SAndroid Build Coastguard Worker 
4462*6777b538SAndroid Build Coastguard Worker   // Read the second byte, but leave the cache write hanging.
4463*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
4464*6777b538SAndroid Build Coastguard Worker   scoped_refptr<MockDiskEntry> entry =
4465*6777b538SAndroid Build Coastguard Worker       mock_cache.disk_cache()->GetDiskEntryRef(cache_key);
4466*6777b538SAndroid Build Coastguard Worker   entry->SetDefer(MockDiskEntry::DEFER_WRITE);
4467*6777b538SAndroid Build Coastguard Worker 
4468*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<IOBufferWithSize>(1);
4469*6777b538SAndroid Build Coastguard Worker   ReleaseBufferCompletionCallback buffer_callback2(buffer2.get());
4470*6777b538SAndroid Build Coastguard Worker   result = transaction->Read(buffer2.get(), 1, buffer_callback2.callback());
4471*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING, result);
4472*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4473*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(mock_cache.IsWriterPresent(cache_key));
4474*6777b538SAndroid Build Coastguard Worker 
4475*6777b538SAndroid Build Coastguard Worker   // At this point the next byte should have been read from the network but is
4476*6777b538SAndroid Build Coastguard Worker   // waiting to be written to the cache. Destroy the transaction and make sure
4477*6777b538SAndroid Build Coastguard Worker   // that everything has been cleaned up.
4478*6777b538SAndroid Build Coastguard Worker   transaction = nullptr;
4479*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(mock_cache.IsWriterPresent(cache_key));
4480*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(mock_cache.network_layer()->last_transaction());
4481*6777b538SAndroid Build Coastguard Worker }
4482*6777b538SAndroid Build Coastguard Worker 
4483*6777b538SAndroid Build Coastguard Worker // Tests that a transaction writer can be destroyed mid-read.
4484*6777b538SAndroid Build Coastguard Worker // A waiting for read transaction should be able to read the data that was
4485*6777b538SAndroid Build Coastguard Worker // driven by the Read started by the cancelled writer.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingCancelWriter)4486*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelWritingCancelWriter) {
4487*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4488*6777b538SAndroid Build Coastguard Worker 
4489*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4490*6777b538SAndroid Build Coastguard Worker 
4491*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
4492*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
4493*6777b538SAndroid Build Coastguard Worker   MockHttpRequest validate_request(transaction);
4494*6777b538SAndroid Build Coastguard Worker 
4495*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 3;
4496*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4497*6777b538SAndroid Build Coastguard Worker 
4498*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4499*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4500*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4501*6777b538SAndroid Build Coastguard Worker 
4502*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4503*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4504*6777b538SAndroid Build Coastguard Worker 
4505*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
4506*6777b538SAndroid Build Coastguard Worker     if (i == 2) {
4507*6777b538SAndroid Build Coastguard Worker       this_request = &validate_request;
4508*6777b538SAndroid Build Coastguard Worker       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
4509*6777b538SAndroid Build Coastguard Worker     }
4510*6777b538SAndroid Build Coastguard Worker 
4511*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
4512*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
4513*6777b538SAndroid Build Coastguard Worker   }
4514*6777b538SAndroid Build Coastguard Worker 
4515*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
4516*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4517*6777b538SAndroid Build Coastguard Worker 
4518*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4519*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4520*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4521*6777b538SAndroid Build Coastguard Worker 
4522*6777b538SAndroid Build Coastguard Worker   std::string cache_key = validate_request.CacheKey();
4523*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4524*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.GetCountWriterTransactions(cache_key));
4525*6777b538SAndroid Build Coastguard Worker 
4526*6777b538SAndroid Build Coastguard Worker   // Initiate Read from both writers and kill 1 of them mid-read.
4527*6777b538SAndroid Build Coastguard Worker   std::string first_read;
4528*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 2; i++) {
4529*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4530*6777b538SAndroid Build Coastguard Worker     const int kBufferSize = 5;
4531*6777b538SAndroid Build Coastguard Worker     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
4532*6777b538SAndroid Build Coastguard Worker     ReleaseBufferCompletionCallback cb(buffer.get());
4533*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
4534*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ERR_IO_PENDING, c->result);
4535*6777b538SAndroid Build Coastguard Worker     // Deleting one writer at this point will not impact other transactions
4536*6777b538SAndroid Build Coastguard Worker     // since writers contain more transactions.
4537*6777b538SAndroid Build Coastguard Worker     if (i == 1) {
4538*6777b538SAndroid Build Coastguard Worker       context_list[0].reset();
4539*6777b538SAndroid Build Coastguard Worker       base::RunLoop().RunUntilIdle();
4540*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
4541*6777b538SAndroid Build Coastguard Worker       std::string data_read(buffer->data(), kBufferSize);
4542*6777b538SAndroid Build Coastguard Worker       first_read = data_read;
4543*6777b538SAndroid Build Coastguard Worker     }
4544*6777b538SAndroid Build Coastguard Worker   }
4545*6777b538SAndroid Build Coastguard Worker 
4546*6777b538SAndroid Build Coastguard Worker   // Resume network start for headers_transaction. It will doom the existing
4547*6777b538SAndroid Build Coastguard Worker   // entry and create a new entry due to validation returning a 200.
4548*6777b538SAndroid Build Coastguard Worker   auto& c = context_list[2];
4549*6777b538SAndroid Build Coastguard Worker   c->trans->ResumeNetworkStart();
4550*6777b538SAndroid Build Coastguard Worker 
4551*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4552*6777b538SAndroid Build Coastguard Worker 
4553*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4554*6777b538SAndroid Build Coastguard Worker 
4555*6777b538SAndroid Build Coastguard Worker   // Complete the rest of the transactions.
4556*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; i++) {
4557*6777b538SAndroid Build Coastguard Worker     auto& context = context_list[i];
4558*6777b538SAndroid Build Coastguard Worker     if (!context) {
4559*6777b538SAndroid Build Coastguard Worker       continue;
4560*6777b538SAndroid Build Coastguard Worker     }
4561*6777b538SAndroid Build Coastguard Worker     if (i == 1) {
4562*6777b538SAndroid Build Coastguard Worker       ReadRemainingAndVerifyTransaction(context->trans.get(), first_read,
4563*6777b538SAndroid Build Coastguard Worker                                         kSimpleGET_Transaction);
4564*6777b538SAndroid Build Coastguard Worker     } else {
4565*6777b538SAndroid Build Coastguard Worker       ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4566*6777b538SAndroid Build Coastguard Worker     }
4567*6777b538SAndroid Build Coastguard Worker   }
4568*6777b538SAndroid Build Coastguard Worker 
4569*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4570*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4571*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
4572*6777b538SAndroid Build Coastguard Worker }
4573*6777b538SAndroid Build Coastguard Worker 
4574*6777b538SAndroid Build Coastguard Worker // Tests the case when network read failure happens. Idle and waiting
4575*6777b538SAndroid Build Coastguard Worker // transactions should fail and headers transaction should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingNetworkReadFailed)4576*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelWritingNetworkReadFailed) {
4577*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4578*6777b538SAndroid Build Coastguard Worker 
4579*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction fail_transaction(kSimpleGET_Transaction);
4580*6777b538SAndroid Build Coastguard Worker   fail_transaction.read_return_code = ERR_INTERNET_DISCONNECTED;
4581*6777b538SAndroid Build Coastguard Worker   MockHttpRequest failing_request(fail_transaction);
4582*6777b538SAndroid Build Coastguard Worker 
4583*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4584*6777b538SAndroid Build Coastguard Worker 
4585*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
4586*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4587*6777b538SAndroid Build Coastguard Worker   MockHttpRequest read_request(transaction);
4588*6777b538SAndroid Build Coastguard Worker 
4589*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 4;
4590*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4591*6777b538SAndroid Build Coastguard Worker 
4592*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4593*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4594*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4595*6777b538SAndroid Build Coastguard Worker 
4596*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4597*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4598*6777b538SAndroid Build Coastguard Worker 
4599*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
4600*6777b538SAndroid Build Coastguard Worker     if (i == 0) {
4601*6777b538SAndroid Build Coastguard Worker       this_request = &failing_request;
4602*6777b538SAndroid Build Coastguard Worker     }
4603*6777b538SAndroid Build Coastguard Worker     if (i == 3) {
4604*6777b538SAndroid Build Coastguard Worker       this_request = &read_request;
4605*6777b538SAndroid Build Coastguard Worker     }
4606*6777b538SAndroid Build Coastguard Worker 
4607*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
4608*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
4609*6777b538SAndroid Build Coastguard Worker   }
4610*6777b538SAndroid Build Coastguard Worker 
4611*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
4612*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4613*6777b538SAndroid Build Coastguard Worker 
4614*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4615*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4616*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4617*6777b538SAndroid Build Coastguard Worker 
4618*6777b538SAndroid Build Coastguard Worker   std::string cache_key = read_request.CacheKey();
4619*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4620*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4621*6777b538SAndroid Build Coastguard Worker 
4622*6777b538SAndroid Build Coastguard Worker   // Initiate Read from two writers and let the first get a network failure.
4623*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 2; i++) {
4624*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4625*6777b538SAndroid Build Coastguard Worker     const int kBufferSize = 5;
4626*6777b538SAndroid Build Coastguard Worker     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
4627*6777b538SAndroid Build Coastguard Worker     c->result =
4628*6777b538SAndroid Build Coastguard Worker         c->trans->Read(buffer.get(), kBufferSize, c->callback.callback());
4629*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ERR_IO_PENDING, c->result);
4630*6777b538SAndroid Build Coastguard Worker   }
4631*6777b538SAndroid Build Coastguard Worker 
4632*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4633*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 2; i++) {
4634*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4635*6777b538SAndroid Build Coastguard Worker     c->result = c->callback.WaitForResult();
4636*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ERR_INTERNET_DISCONNECTED, c->result);
4637*6777b538SAndroid Build Coastguard Worker   }
4638*6777b538SAndroid Build Coastguard Worker 
4639*6777b538SAndroid Build Coastguard Worker   // The entry should have been doomed and destroyed and the headers transaction
4640*6777b538SAndroid Build Coastguard Worker   // restarted. Since headers transaction is read-only it will error out.
4641*6777b538SAndroid Build Coastguard Worker   auto& read_only = context_list[3];
4642*6777b538SAndroid Build Coastguard Worker   read_only->result = read_only->callback.WaitForResult();
4643*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_CACHE_MISS, read_only->result);
4644*6777b538SAndroid Build Coastguard Worker 
4645*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
4646*6777b538SAndroid Build Coastguard Worker 
4647*6777b538SAndroid Build Coastguard Worker   // Invoke Read on the 3rd transaction and it should get the error code back.
4648*6777b538SAndroid Build Coastguard Worker   auto& c = context_list[2];
4649*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 5;
4650*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
4651*6777b538SAndroid Build Coastguard Worker   c->result = c->trans->Read(buffer.get(), kBufferSize, c->callback.callback());
4652*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_INTERNET_DISCONNECTED, c->result);
4653*6777b538SAndroid Build Coastguard Worker }
4654*6777b538SAndroid Build Coastguard Worker 
4655*6777b538SAndroid Build Coastguard Worker // Tests the case when cache write failure happens. Idle and waiting
4656*6777b538SAndroid Build Coastguard Worker // transactions should fail and headers transaction should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingCacheWriteFailed)4657*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelWritingCacheWriteFailed) {
4658*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4659*6777b538SAndroid Build Coastguard Worker 
4660*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4661*6777b538SAndroid Build Coastguard Worker 
4662*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
4663*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4664*6777b538SAndroid Build Coastguard Worker   MockHttpRequest read_request(transaction);
4665*6777b538SAndroid Build Coastguard Worker 
4666*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 4;
4667*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4668*6777b538SAndroid Build Coastguard Worker 
4669*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4670*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4671*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4672*6777b538SAndroid Build Coastguard Worker 
4673*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4674*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4675*6777b538SAndroid Build Coastguard Worker 
4676*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
4677*6777b538SAndroid Build Coastguard Worker     if (i == 3) {
4678*6777b538SAndroid Build Coastguard Worker       this_request = &read_request;
4679*6777b538SAndroid Build Coastguard Worker     }
4680*6777b538SAndroid Build Coastguard Worker 
4681*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
4682*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
4683*6777b538SAndroid Build Coastguard Worker   }
4684*6777b538SAndroid Build Coastguard Worker 
4685*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
4686*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4687*6777b538SAndroid Build Coastguard Worker 
4688*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4689*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4690*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4691*6777b538SAndroid Build Coastguard Worker 
4692*6777b538SAndroid Build Coastguard Worker   std::string cache_key = read_request.CacheKey();
4693*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4694*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4695*6777b538SAndroid Build Coastguard Worker 
4696*6777b538SAndroid Build Coastguard Worker   // Initiate Read from two writers and let the first get a cache write failure.
4697*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
4698*6777b538SAndroid Build Coastguard Worker   // We have to open the entry again to propagate the failure flag.
4699*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* en;
4700*6777b538SAndroid Build Coastguard Worker   cache.OpenBackendEntry(cache_key, &en);
4701*6777b538SAndroid Build Coastguard Worker   en->Close();
4702*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 5;
4703*6777b538SAndroid Build Coastguard Worker   std::vector<scoped_refptr<IOBuffer>> buffer(
4704*6777b538SAndroid Build Coastguard Worker       3, base::MakeRefCounted<IOBufferWithSize>(kBufferSize));
4705*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 2; i++) {
4706*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4707*6777b538SAndroid Build Coastguard Worker     c->result =
4708*6777b538SAndroid Build Coastguard Worker         c->trans->Read(buffer[i].get(), kBufferSize, c->callback.callback());
4709*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ERR_IO_PENDING, c->result);
4710*6777b538SAndroid Build Coastguard Worker   }
4711*6777b538SAndroid Build Coastguard Worker 
4712*6777b538SAndroid Build Coastguard Worker   std::string first_read;
4713*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4714*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 2; i++) {
4715*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4716*6777b538SAndroid Build Coastguard Worker     c->result = c->callback.WaitForResult();
4717*6777b538SAndroid Build Coastguard Worker     if (i == 0) {
4718*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(5, c->result);
4719*6777b538SAndroid Build Coastguard Worker       std::string data_read(buffer[i]->data(), kBufferSize);
4720*6777b538SAndroid Build Coastguard Worker       first_read = data_read;
4721*6777b538SAndroid Build Coastguard Worker     } else {
4722*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, c->result);
4723*6777b538SAndroid Build Coastguard Worker     }
4724*6777b538SAndroid Build Coastguard Worker   }
4725*6777b538SAndroid Build Coastguard Worker 
4726*6777b538SAndroid Build Coastguard Worker   // The entry should have been doomed and destroyed and the headers transaction
4727*6777b538SAndroid Build Coastguard Worker   // restarted. Since headers transaction is read-only it will error out.
4728*6777b538SAndroid Build Coastguard Worker   auto& read_only = context_list[3];
4729*6777b538SAndroid Build Coastguard Worker   read_only->result = read_only->callback.WaitForResult();
4730*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_CACHE_MISS, read_only->result);
4731*6777b538SAndroid Build Coastguard Worker 
4732*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
4733*6777b538SAndroid Build Coastguard Worker 
4734*6777b538SAndroid Build Coastguard Worker   // Invoke Read on the 3rd transaction and it should get the error code back.
4735*6777b538SAndroid Build Coastguard Worker   auto& c = context_list[2];
4736*6777b538SAndroid Build Coastguard Worker   c->result =
4737*6777b538SAndroid Build Coastguard Worker       c->trans->Read(buffer[2].get(), kBufferSize, c->callback.callback());
4738*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, c->result);
4739*6777b538SAndroid Build Coastguard Worker 
4740*6777b538SAndroid Build Coastguard Worker   // The first transaction should be able to continue to read from the network
4741*6777b538SAndroid Build Coastguard Worker   // without writing to the cache.
4742*6777b538SAndroid Build Coastguard Worker   auto& succ_read = context_list[0];
4743*6777b538SAndroid Build Coastguard Worker   ReadRemainingAndVerifyTransaction(succ_read->trans.get(), first_read,
4744*6777b538SAndroid Build Coastguard Worker                                     kSimpleGET_Transaction);
4745*6777b538SAndroid Build Coastguard Worker }
4746*6777b538SAndroid Build Coastguard Worker 
4747*6777b538SAndroid Build Coastguard Worker // Tests that POST requests do not join existing transactions for parallel
4748*6777b538SAndroid Build Coastguard Worker // writing to the cache. Note that two POSTs only map to the same entry if their
4749*6777b538SAndroid Build Coastguard Worker // upload data identifier is same and that should happen for back-forward case
4750*6777b538SAndroid Build Coastguard Worker // (LOAD_ONLY_FROM_CACHE). But this test tests without LOAD_ONLY_FROM_CACHE
4751*6777b538SAndroid Build Coastguard Worker // because read-only transactions anyways do not join parallel writing.
4752*6777b538SAndroid Build Coastguard Worker // TODO(shivanisha) Testing this because it is allowed by the code but looks
4753*6777b538SAndroid Build Coastguard Worker // like the code should disallow two POSTs without LOAD_ONLY_FROM_CACHE with the
4754*6777b538SAndroid Build Coastguard Worker // same upload data identifier to map to the same entry.
TEST_F(HttpCacheTest,SimplePOST_ParallelWritingDisallowed)4755*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePOST_ParallelWritingDisallowed) {
4756*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4757*6777b538SAndroid Build Coastguard Worker 
4758*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimplePOST_Transaction);
4759*6777b538SAndroid Build Coastguard Worker 
4760*6777b538SAndroid Build Coastguard Worker   const int64_t kUploadId = 1;  // Just a dummy value.
4761*6777b538SAndroid Build Coastguard Worker 
4762*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
4763*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
4764*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
4765*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
4766*6777b538SAndroid Build Coastguard Worker                                               kUploadId);
4767*6777b538SAndroid Build Coastguard Worker 
4768*6777b538SAndroid Build Coastguard Worker   // Note that both transactions should have the same upload_data_stream
4769*6777b538SAndroid Build Coastguard Worker   // identifier to map to the same entry.
4770*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_SKIP_CACHE_VALIDATION;
4771*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
4772*6777b538SAndroid Build Coastguard Worker   request.upload_data_stream = &upload_data_stream;
4773*6777b538SAndroid Build Coastguard Worker 
4774*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
4775*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4776*6777b538SAndroid Build Coastguard Worker 
4777*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4778*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4779*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4780*6777b538SAndroid Build Coastguard Worker 
4781*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4782*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4783*6777b538SAndroid Build Coastguard Worker 
4784*6777b538SAndroid Build Coastguard Worker     c->result =
4785*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4786*6777b538SAndroid Build Coastguard Worker 
4787*6777b538SAndroid Build Coastguard Worker     // Complete the headers phase request.
4788*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
4789*6777b538SAndroid Build Coastguard Worker   }
4790*6777b538SAndroid Build Coastguard Worker 
4791*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
4792*6777b538SAndroid Build Coastguard Worker   // Only the 1st transaction gets added to writers.
4793*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4794*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4795*6777b538SAndroid Build Coastguard Worker 
4796*6777b538SAndroid Build Coastguard Worker   // Read the 1st transaction.
4797*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(context_list[0]->trans.get(),
4798*6777b538SAndroid Build Coastguard Worker                            kSimplePOST_Transaction);
4799*6777b538SAndroid Build Coastguard Worker 
4800*6777b538SAndroid Build Coastguard Worker   // 2nd transaction should now become a reader.
4801*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4802*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
4803*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4804*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(context_list[1]->trans.get(),
4805*6777b538SAndroid Build Coastguard Worker                            kSimplePOST_Transaction);
4806*6777b538SAndroid Build Coastguard Worker 
4807*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4808*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4809*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4810*6777b538SAndroid Build Coastguard Worker 
4811*6777b538SAndroid Build Coastguard Worker   context_list.clear();
4812*6777b538SAndroid Build Coastguard Worker }
4813*6777b538SAndroid Build Coastguard Worker 
4814*6777b538SAndroid Build Coastguard Worker // Tests the case when parallel writing succeeds. Tests both idle and waiting
4815*6777b538SAndroid Build Coastguard Worker // transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingSuccess)4816*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelWritingSuccess) {
4817*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4818*6777b538SAndroid Build Coastguard Worker 
4819*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4820*6777b538SAndroid Build Coastguard Worker 
4821*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
4822*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4823*6777b538SAndroid Build Coastguard Worker   MockHttpRequest read_request(transaction);
4824*6777b538SAndroid Build Coastguard Worker 
4825*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 4;
4826*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4827*6777b538SAndroid Build Coastguard Worker 
4828*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4829*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4830*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4831*6777b538SAndroid Build Coastguard Worker 
4832*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4833*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4834*6777b538SAndroid Build Coastguard Worker 
4835*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
4836*6777b538SAndroid Build Coastguard Worker     if (i == 3) {
4837*6777b538SAndroid Build Coastguard Worker       this_request = &read_request;
4838*6777b538SAndroid Build Coastguard Worker     }
4839*6777b538SAndroid Build Coastguard Worker 
4840*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
4841*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
4842*6777b538SAndroid Build Coastguard Worker   }
4843*6777b538SAndroid Build Coastguard Worker 
4844*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
4845*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4846*6777b538SAndroid Build Coastguard Worker 
4847*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4848*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4849*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4850*6777b538SAndroid Build Coastguard Worker 
4851*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
4852*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4853*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4854*6777b538SAndroid Build Coastguard Worker 
4855*6777b538SAndroid Build Coastguard Worker   // Initiate Read from two writers.
4856*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 5;
4857*6777b538SAndroid Build Coastguard Worker   std::vector<scoped_refptr<IOBuffer>> buffer(
4858*6777b538SAndroid Build Coastguard Worker       3, base::MakeRefCounted<IOBufferWithSize>(kBufferSize));
4859*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 2; i++) {
4860*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4861*6777b538SAndroid Build Coastguard Worker     c->result =
4862*6777b538SAndroid Build Coastguard Worker         c->trans->Read(buffer[i].get(), kBufferSize, c->callback.callback());
4863*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ERR_IO_PENDING, c->result);
4864*6777b538SAndroid Build Coastguard Worker   }
4865*6777b538SAndroid Build Coastguard Worker 
4866*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> first_read(2);
4867*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4868*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 2; i++) {
4869*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4870*6777b538SAndroid Build Coastguard Worker     c->result = c->callback.WaitForResult();
4871*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(5, c->result);
4872*6777b538SAndroid Build Coastguard Worker     std::string data_read(buffer[i]->data(), kBufferSize);
4873*6777b538SAndroid Build Coastguard Worker     first_read[i] = data_read;
4874*6777b538SAndroid Build Coastguard Worker   }
4875*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(first_read[0], first_read[1]);
4876*6777b538SAndroid Build Coastguard Worker 
4877*6777b538SAndroid Build Coastguard Worker   // The first transaction should be able to continue to read from the network
4878*6777b538SAndroid Build Coastguard Worker   // without writing to the cache.
4879*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 2; i++) {
4880*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4881*6777b538SAndroid Build Coastguard Worker     ReadRemainingAndVerifyTransaction(c->trans.get(), first_read[i],
4882*6777b538SAndroid Build Coastguard Worker                                       kSimpleGET_Transaction);
4883*6777b538SAndroid Build Coastguard Worker     if (i == 0) {
4884*6777b538SAndroid Build Coastguard Worker       // Remaining transactions should now be readers.
4885*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(3, cache.GetCountReaders(cache_key));
4886*6777b538SAndroid Build Coastguard Worker     }
4887*6777b538SAndroid Build Coastguard Worker   }
4888*6777b538SAndroid Build Coastguard Worker 
4889*6777b538SAndroid Build Coastguard Worker   // Verify the rest of the transactions.
4890*6777b538SAndroid Build Coastguard Worker   for (int i = 2; i < kNumTransactions; i++) {
4891*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4892*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
4893*6777b538SAndroid Build Coastguard Worker   }
4894*6777b538SAndroid Build Coastguard Worker 
4895*6777b538SAndroid Build Coastguard Worker   context_list.clear();
4896*6777b538SAndroid Build Coastguard Worker }
4897*6777b538SAndroid Build Coastguard Worker 
4898*6777b538SAndroid Build Coastguard Worker // Tests the case when parallel writing involves things bigger than what cache
4899*6777b538SAndroid Build Coastguard Worker // can store. In this case, the best we can do is re-fetch it.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingHuge)4900*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelWritingHuge) {
4901*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4902*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_max_file_size(10);
4903*6777b538SAndroid Build Coastguard Worker 
4904*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
4905*6777b538SAndroid Build Coastguard Worker   std::string response_headers = base::StrCat(
4906*6777b538SAndroid Build Coastguard Worker       {kSimpleGET_Transaction.response_headers, "Content-Length: ",
4907*6777b538SAndroid Build Coastguard Worker        base::NumberToString(strlen(kSimpleGET_Transaction.data)), "\n"});
4908*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = response_headers.c_str();
4909*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
4910*6777b538SAndroid Build Coastguard Worker 
4911*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 4;
4912*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4913*6777b538SAndroid Build Coastguard Worker 
4914*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4915*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4916*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4917*6777b538SAndroid Build Coastguard Worker 
4918*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4919*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4920*6777b538SAndroid Build Coastguard Worker 
4921*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
4922*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
4923*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
4924*6777b538SAndroid Build Coastguard Worker   }
4925*6777b538SAndroid Build Coastguard Worker 
4926*6777b538SAndroid Build Coastguard Worker   // Start them up.
4927*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4928*6777b538SAndroid Build Coastguard Worker 
4929*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4930*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4931*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4932*6777b538SAndroid Build Coastguard Worker 
4933*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
4934*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4935*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions - 1, cache.GetCountDoneHeadersQueue(cache_key));
4936*6777b538SAndroid Build Coastguard Worker 
4937*6777b538SAndroid Build Coastguard Worker   // Initiate Read from first transaction.
4938*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 5;
4939*6777b538SAndroid Build Coastguard Worker   std::vector<scoped_refptr<IOBuffer>> buffer(
4940*6777b538SAndroid Build Coastguard Worker       kNumTransactions, base::MakeRefCounted<IOBufferWithSize>(kBufferSize));
4941*6777b538SAndroid Build Coastguard Worker   auto& c = context_list[0];
4942*6777b538SAndroid Build Coastguard Worker   c->result =
4943*6777b538SAndroid Build Coastguard Worker       c->trans->Read(buffer[0].get(), kBufferSize, c->callback.callback());
4944*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING, c->result);
4945*6777b538SAndroid Build Coastguard Worker 
4946*6777b538SAndroid Build Coastguard Worker   // ... and complete it.
4947*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> first_read(kNumTransactions);
4948*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4949*6777b538SAndroid Build Coastguard Worker   c->result = c->callback.WaitForResult();
4950*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kBufferSize, c->result);
4951*6777b538SAndroid Build Coastguard Worker   std::string data_read(buffer[0]->data(), kBufferSize);
4952*6777b538SAndroid Build Coastguard Worker   first_read[0] = data_read;
4953*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("<html", first_read[0]);
4954*6777b538SAndroid Build Coastguard Worker 
4955*6777b538SAndroid Build Coastguard Worker   // Complete all of them.
4956*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; i++) {
4957*6777b538SAndroid Build Coastguard Worker     ReadRemainingAndVerifyTransaction(context_list[i]->trans.get(),
4958*6777b538SAndroid Build Coastguard Worker                                       first_read[i], kSimpleGET_Transaction);
4959*6777b538SAndroid Build Coastguard Worker   }
4960*6777b538SAndroid Build Coastguard Worker 
4961*6777b538SAndroid Build Coastguard Worker   // Sadly all of them have to hit the network
4962*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions, cache.network_layer()->transaction_count());
4963*6777b538SAndroid Build Coastguard Worker 
4964*6777b538SAndroid Build Coastguard Worker   context_list.clear();
4965*6777b538SAndroid Build Coastguard Worker }
4966*6777b538SAndroid Build Coastguard Worker 
4967*6777b538SAndroid Build Coastguard Worker // Tests that network transaction's info is saved correctly when a writer
4968*6777b538SAndroid Build Coastguard Worker // transaction that created the network transaction becomes a reader. Also
4969*6777b538SAndroid Build Coastguard Worker // verifies that the network bytes are only attributed to the transaction that
4970*6777b538SAndroid Build Coastguard Worker // created the network transaction.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingVerifyNetworkBytes)4971*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelWritingVerifyNetworkBytes) {
4972*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
4973*6777b538SAndroid Build Coastguard Worker 
4974*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
4975*6777b538SAndroid Build Coastguard Worker 
4976*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
4977*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
4978*6777b538SAndroid Build Coastguard Worker 
4979*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
4980*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
4981*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
4982*6777b538SAndroid Build Coastguard Worker 
4983*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
4984*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
4985*6777b538SAndroid Build Coastguard Worker 
4986*6777b538SAndroid Build Coastguard Worker     c->result =
4987*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4988*6777b538SAndroid Build Coastguard Worker   }
4989*6777b538SAndroid Build Coastguard Worker 
4990*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
4991*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4992*6777b538SAndroid Build Coastguard Worker 
4993*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4994*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
4995*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
4996*6777b538SAndroid Build Coastguard Worker 
4997*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
4998*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.GetCountWriterTransactions(cache_key));
4999*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
5000*6777b538SAndroid Build Coastguard Worker 
5001*6777b538SAndroid Build Coastguard Worker   // Get the network bytes read by the first transaction.
5002*6777b538SAndroid Build Coastguard Worker   int total_received_bytes = context_list[0]->trans->GetTotalReceivedBytes();
5003*6777b538SAndroid Build Coastguard Worker   EXPECT_GT(total_received_bytes, 0);
5004*6777b538SAndroid Build Coastguard Worker 
5005*6777b538SAndroid Build Coastguard Worker   // Complete Read by the 2nd transaction so that the 1st transaction that
5006*6777b538SAndroid Build Coastguard Worker   // created the network transaction is now a reader.
5007*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(context_list[1]->trans.get(),
5008*6777b538SAndroid Build Coastguard Worker                            kSimpleGET_Transaction);
5009*6777b538SAndroid Build Coastguard Worker 
5010*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
5011*6777b538SAndroid Build Coastguard Worker 
5012*6777b538SAndroid Build Coastguard Worker   // Verify that the network bytes read are not attributed to the 2nd
5013*6777b538SAndroid Build Coastguard Worker   // transaction but to the 1st.
5014*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, context_list[1]->trans->GetTotalReceivedBytes());
5015*6777b538SAndroid Build Coastguard Worker 
5016*6777b538SAndroid Build Coastguard Worker   EXPECT_GE(total_received_bytes,
5017*6777b538SAndroid Build Coastguard Worker             context_list[0]->trans->GetTotalReceivedBytes());
5018*6777b538SAndroid Build Coastguard Worker 
5019*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(context_list[0]->trans.get(),
5020*6777b538SAndroid Build Coastguard Worker                            kSimpleGET_Transaction);
5021*6777b538SAndroid Build Coastguard Worker }
5022*6777b538SAndroid Build Coastguard Worker 
5023*6777b538SAndroid Build Coastguard Worker // Tests than extra Read from the consumer should not hang/crash the browser.
TEST_F(HttpCacheTest,SimpleGET_ExtraRead)5024*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ExtraRead) {
5025*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5026*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5027*6777b538SAndroid Build Coastguard Worker   Context c;
5028*6777b538SAndroid Build Coastguard Worker 
5029*6777b538SAndroid Build Coastguard Worker   c.result = cache.CreateTransaction(&c.trans);
5030*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c.result, IsOk());
5031*6777b538SAndroid Build Coastguard Worker 
5032*6777b538SAndroid Build Coastguard Worker   c.result =
5033*6777b538SAndroid Build Coastguard Worker       c.trans->Start(&request, c.callback.callback(), NetLogWithSource());
5034*6777b538SAndroid Build Coastguard Worker 
5035*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5036*6777b538SAndroid Build Coastguard Worker 
5037*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5038*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5039*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5040*6777b538SAndroid Build Coastguard Worker 
5041*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
5042*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
5043*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
5044*6777b538SAndroid Build Coastguard Worker 
5045*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(c.trans.get(), kSimpleGET_Transaction);
5046*6777b538SAndroid Build Coastguard Worker 
5047*6777b538SAndroid Build Coastguard Worker   // Perform an extra Read.
5048*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 10;
5049*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
5050*6777b538SAndroid Build Coastguard Worker   c.result = c.trans->Read(buffer.get(), kBufferSize, c.callback.callback());
5051*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, c.result);
5052*6777b538SAndroid Build Coastguard Worker }
5053*6777b538SAndroid Build Coastguard Worker 
5054*6777b538SAndroid Build Coastguard Worker // Tests when a writer is destroyed mid-read, all the other writer transactions
5055*6777b538SAndroid Build Coastguard Worker // can continue writing to the entry.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelWriter)5056*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelWriter) {
5057*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5058*6777b538SAndroid Build Coastguard Worker 
5059*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
5060*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
5061*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5062*6777b538SAndroid Build Coastguard Worker       "Content-Length: 22\n"
5063*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n";
5064*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
5065*6777b538SAndroid Build Coastguard Worker 
5066*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 3;
5067*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5068*6777b538SAndroid Build Coastguard Worker 
5069*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5070*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5071*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
5072*6777b538SAndroid Build Coastguard Worker 
5073*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5074*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5075*6777b538SAndroid Build Coastguard Worker 
5076*6777b538SAndroid Build Coastguard Worker     c->result =
5077*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5078*6777b538SAndroid Build Coastguard Worker   }
5079*6777b538SAndroid Build Coastguard Worker 
5080*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
5081*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5082*6777b538SAndroid Build Coastguard Worker 
5083*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5084*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5085*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5086*6777b538SAndroid Build Coastguard Worker 
5087*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
5088*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5089*6777b538SAndroid Build Coastguard Worker 
5090*6777b538SAndroid Build Coastguard Worker   // Let first transaction read some bytes.
5091*6777b538SAndroid Build Coastguard Worker   {
5092*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[0];
5093*6777b538SAndroid Build Coastguard Worker     const int kBufferSize = 5;
5094*6777b538SAndroid Build Coastguard Worker     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
5095*6777b538SAndroid Build Coastguard Worker     ReleaseBufferCompletionCallback cb(buffer.get());
5096*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
5097*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
5098*6777b538SAndroid Build Coastguard Worker   }
5099*6777b538SAndroid Build Coastguard Worker 
5100*6777b538SAndroid Build Coastguard Worker   // Deleting the active transaction at this point will not impact the other
5101*6777b538SAndroid Build Coastguard Worker   // transactions since there are other transactions in writers.
5102*6777b538SAndroid Build Coastguard Worker   context_list[0].reset();
5103*6777b538SAndroid Build Coastguard Worker 
5104*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5105*6777b538SAndroid Build Coastguard Worker 
5106*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5107*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5108*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5109*6777b538SAndroid Build Coastguard Worker 
5110*6777b538SAndroid Build Coastguard Worker   // Complete the rest of the transactions.
5111*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
5112*6777b538SAndroid Build Coastguard Worker     if (!context) {
5113*6777b538SAndroid Build Coastguard Worker       continue;
5114*6777b538SAndroid Build Coastguard Worker     }
5115*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5116*6777b538SAndroid Build Coastguard Worker   }
5117*6777b538SAndroid Build Coastguard Worker }
5118*6777b538SAndroid Build Coastguard Worker 
5119*6777b538SAndroid Build Coastguard Worker // Tests that when StopCaching is invoked on a writer, dependent transactions
5120*6777b538SAndroid Build Coastguard Worker // are restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationStopCaching)5121*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelValidationStopCaching) {
5122*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5123*6777b538SAndroid Build Coastguard Worker 
5124*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5125*6777b538SAndroid Build Coastguard Worker 
5126*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
5127*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
5128*6777b538SAndroid Build Coastguard Worker   MockHttpRequest read_only_request(transaction);
5129*6777b538SAndroid Build Coastguard Worker 
5130*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
5131*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5132*6777b538SAndroid Build Coastguard Worker 
5133*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5134*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5135*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
5136*6777b538SAndroid Build Coastguard Worker 
5137*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5138*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5139*6777b538SAndroid Build Coastguard Worker 
5140*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
5141*6777b538SAndroid Build Coastguard Worker     if (i == 1) {
5142*6777b538SAndroid Build Coastguard Worker       this_request = &read_only_request;
5143*6777b538SAndroid Build Coastguard Worker     }
5144*6777b538SAndroid Build Coastguard Worker 
5145*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
5146*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
5147*6777b538SAndroid Build Coastguard Worker   }
5148*6777b538SAndroid Build Coastguard Worker 
5149*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
5150*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5151*6777b538SAndroid Build Coastguard Worker 
5152*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5153*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5154*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5155*6777b538SAndroid Build Coastguard Worker 
5156*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
5157*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
5158*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
5159*6777b538SAndroid Build Coastguard Worker 
5160*6777b538SAndroid Build Coastguard Worker   // Invoking StopCaching on the writer will lead to dooming the entry and
5161*6777b538SAndroid Build Coastguard Worker   // restarting the validated transactions. Since it is a read-only transaction
5162*6777b538SAndroid Build Coastguard Worker   // it will error out.
5163*6777b538SAndroid Build Coastguard Worker   context_list[0]->trans->StopCaching();
5164*6777b538SAndroid Build Coastguard Worker 
5165*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5166*6777b538SAndroid Build Coastguard Worker 
5167*6777b538SAndroid Build Coastguard Worker   int rv = context_list[1]->callback.WaitForResult();
5168*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_CACHE_MISS, rv);
5169*6777b538SAndroid Build Coastguard Worker 
5170*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(context_list[0]->trans.get(),
5171*6777b538SAndroid Build Coastguard Worker                            kSimpleGET_Transaction);
5172*6777b538SAndroid Build Coastguard Worker }
5173*6777b538SAndroid Build Coastguard Worker 
5174*6777b538SAndroid Build Coastguard Worker // Tests that when StopCaching is invoked on a writer transaction, it is a
5175*6777b538SAndroid Build Coastguard Worker // no-op if there are other writer transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritersStopCachingNoOp)5176*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelWritersStopCachingNoOp) {
5177*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5178*6777b538SAndroid Build Coastguard Worker 
5179*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5180*6777b538SAndroid Build Coastguard Worker 
5181*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
5182*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
5183*6777b538SAndroid Build Coastguard Worker   MockHttpRequest validate_request(transaction);
5184*6777b538SAndroid Build Coastguard Worker 
5185*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 3;
5186*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5187*6777b538SAndroid Build Coastguard Worker 
5188*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5189*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5190*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
5191*6777b538SAndroid Build Coastguard Worker 
5192*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5193*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5194*6777b538SAndroid Build Coastguard Worker 
5195*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
5196*6777b538SAndroid Build Coastguard Worker     if (i == 2) {
5197*6777b538SAndroid Build Coastguard Worker       this_request = &validate_request;
5198*6777b538SAndroid Build Coastguard Worker       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
5199*6777b538SAndroid Build Coastguard Worker     }
5200*6777b538SAndroid Build Coastguard Worker 
5201*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
5202*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
5203*6777b538SAndroid Build Coastguard Worker   }
5204*6777b538SAndroid Build Coastguard Worker 
5205*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
5206*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5207*6777b538SAndroid Build Coastguard Worker 
5208*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5209*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5210*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5211*6777b538SAndroid Build Coastguard Worker 
5212*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
5213*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
5214*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
5215*6777b538SAndroid Build Coastguard Worker 
5216*6777b538SAndroid Build Coastguard Worker   // Invoking StopCaching on the writer will be a no-op since there are multiple
5217*6777b538SAndroid Build Coastguard Worker   // transaction in writers.
5218*6777b538SAndroid Build Coastguard Worker   context_list[0]->trans->StopCaching();
5219*6777b538SAndroid Build Coastguard Worker 
5220*6777b538SAndroid Build Coastguard Worker   // Resume network start for headers_transaction.
5221*6777b538SAndroid Build Coastguard Worker   auto& c = context_list[2];
5222*6777b538SAndroid Build Coastguard Worker   c->trans->ResumeNetworkStart();
5223*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5224*6777b538SAndroid Build Coastguard Worker   // After validation old entry will be doomed and headers_transaction will be
5225*6777b538SAndroid Build Coastguard Worker   // added to the new entry.
5226*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
5227*6777b538SAndroid Build Coastguard Worker 
5228*6777b538SAndroid Build Coastguard Worker   // Complete the rest of the transactions.
5229*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
5230*6777b538SAndroid Build Coastguard Worker     if (!context) {
5231*6777b538SAndroid Build Coastguard Worker       continue;
5232*6777b538SAndroid Build Coastguard Worker     }
5233*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5234*6777b538SAndroid Build Coastguard Worker   }
5235*6777b538SAndroid Build Coastguard Worker 
5236*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5237*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5238*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
5239*6777b538SAndroid Build Coastguard Worker }
5240*6777b538SAndroid Build Coastguard Worker 
5241*6777b538SAndroid Build Coastguard Worker // Tests that a transaction is currently in headers phase and is destroyed
5242*6777b538SAndroid Build Coastguard Worker // leading to destroying the entry.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelHeaders)5243*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelHeaders) {
5244*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5245*6777b538SAndroid Build Coastguard Worker 
5246*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5247*6777b538SAndroid Build Coastguard Worker 
5248*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
5249*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5250*6777b538SAndroid Build Coastguard Worker 
5251*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5252*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5253*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
5254*6777b538SAndroid Build Coastguard Worker 
5255*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5256*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5257*6777b538SAndroid Build Coastguard Worker 
5258*6777b538SAndroid Build Coastguard Worker     if (i == 0) {
5259*6777b538SAndroid Build Coastguard Worker       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
5260*6777b538SAndroid Build Coastguard Worker     }
5261*6777b538SAndroid Build Coastguard Worker 
5262*6777b538SAndroid Build Coastguard Worker     c->result =
5263*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5264*6777b538SAndroid Build Coastguard Worker   }
5265*6777b538SAndroid Build Coastguard Worker 
5266*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5267*6777b538SAndroid Build Coastguard Worker 
5268*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
5269*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
5270*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.GetCountAddToEntryQueue(cache_key));
5271*6777b538SAndroid Build Coastguard Worker 
5272*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5273*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5274*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5275*6777b538SAndroid Build Coastguard Worker 
5276*6777b538SAndroid Build Coastguard Worker   // Delete the headers transaction.
5277*6777b538SAndroid Build Coastguard Worker   context_list[0].reset();
5278*6777b538SAndroid Build Coastguard Worker 
5279*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5280*6777b538SAndroid Build Coastguard Worker 
5281*6777b538SAndroid Build Coastguard Worker   // Complete the rest of the transactions.
5282*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
5283*6777b538SAndroid Build Coastguard Worker     if (!context) {
5284*6777b538SAndroid Build Coastguard Worker       continue;
5285*6777b538SAndroid Build Coastguard Worker     }
5286*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5287*6777b538SAndroid Build Coastguard Worker   }
5288*6777b538SAndroid Build Coastguard Worker 
5289*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5290*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5291*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
5292*6777b538SAndroid Build Coastguard Worker }
5293*6777b538SAndroid Build Coastguard Worker 
5294*6777b538SAndroid Build Coastguard Worker // Similar to the above test, except here cache write fails and the
5295*6777b538SAndroid Build Coastguard Worker // validated transactions should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritersFailWrite)5296*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ParallelWritersFailWrite) {
5297*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5298*6777b538SAndroid Build Coastguard Worker 
5299*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5300*6777b538SAndroid Build Coastguard Worker 
5301*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 5;
5302*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5303*6777b538SAndroid Build Coastguard Worker 
5304*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5305*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5306*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
5307*6777b538SAndroid Build Coastguard Worker 
5308*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5309*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5310*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
5311*6777b538SAndroid Build Coastguard Worker 
5312*6777b538SAndroid Build Coastguard Worker     c->result =
5313*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5314*6777b538SAndroid Build Coastguard Worker   }
5315*6777b538SAndroid Build Coastguard Worker 
5316*6777b538SAndroid Build Coastguard Worker   // All requests are waiting for the active entry.
5317*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
5318*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
5319*6777b538SAndroid Build Coastguard Worker   }
5320*6777b538SAndroid Build Coastguard Worker 
5321*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
5322*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5323*6777b538SAndroid Build Coastguard Worker 
5324*6777b538SAndroid Build Coastguard Worker   // All transactions become writers.
5325*6777b538SAndroid Build Coastguard Worker   std::string cache_key = request.CacheKey();
5326*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5327*6777b538SAndroid Build Coastguard Worker 
5328*6777b538SAndroid Build Coastguard Worker   // All requests depend on the writer, and the writer is between Start and
5329*6777b538SAndroid Build Coastguard Worker   // Read, i.e. idle.
5330*6777b538SAndroid Build Coastguard Worker   for (auto& context : context_list) {
5331*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
5332*6777b538SAndroid Build Coastguard Worker   }
5333*6777b538SAndroid Build Coastguard Worker 
5334*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5335*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5336*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5337*6777b538SAndroid Build Coastguard Worker 
5338*6777b538SAndroid Build Coastguard Worker   // Fail the request.
5339*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
5340*6777b538SAndroid Build Coastguard Worker   // We have to open the entry again to propagate the failure flag.
5341*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* en;
5342*6777b538SAndroid Build Coastguard Worker   cache.OpenBackendEntry(cache_key, &en);
5343*6777b538SAndroid Build Coastguard Worker   en->Close();
5344*6777b538SAndroid Build Coastguard Worker 
5345*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5346*6777b538SAndroid Build Coastguard Worker     auto& c = context_list[i];
5347*6777b538SAndroid Build Coastguard Worker     if (c->result == ERR_IO_PENDING) {
5348*6777b538SAndroid Build Coastguard Worker       c->result = c->callback.WaitForResult();
5349*6777b538SAndroid Build Coastguard Worker     }
5350*6777b538SAndroid Build Coastguard Worker     if (i == 1) {
5351*6777b538SAndroid Build Coastguard Worker       // The earlier entry must be destroyed and its disk entry doomed.
5352*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(cache.disk_cache()->IsDiskEntryDoomed(cache_key));
5353*6777b538SAndroid Build Coastguard Worker     }
5354*6777b538SAndroid Build Coastguard Worker 
5355*6777b538SAndroid Build Coastguard Worker     if (i == 0) {
5356*6777b538SAndroid Build Coastguard Worker       // Consumer gets the response even if cache write failed.
5357*6777b538SAndroid Build Coastguard Worker       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5358*6777b538SAndroid Build Coastguard Worker     } else {
5359*6777b538SAndroid Build Coastguard Worker       // Read should lead to a failure being returned.
5360*6777b538SAndroid Build Coastguard Worker       const int kBufferSize = 5;
5361*6777b538SAndroid Build Coastguard Worker       auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
5362*6777b538SAndroid Build Coastguard Worker       ReleaseBufferCompletionCallback cb(buffer.get());
5363*6777b538SAndroid Build Coastguard Worker       c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
5364*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, cb.GetResult(c->result));
5365*6777b538SAndroid Build Coastguard Worker     }
5366*6777b538SAndroid Build Coastguard Worker   }
5367*6777b538SAndroid Build Coastguard Worker }
5368*6777b538SAndroid Build Coastguard Worker 
5369*6777b538SAndroid Build Coastguard Worker // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
5370*6777b538SAndroid Build Coastguard Worker // If cancelling a request is racing with another request for the same resource
5371*6777b538SAndroid Build Coastguard Worker // finishing, we have to make sure that we remove both transactions from the
5372*6777b538SAndroid Build Coastguard Worker // entry.
TEST_F(HttpCacheTest,SimpleGET_RacingReaders)5373*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_RacingReaders) {
5374*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5375*6777b538SAndroid Build Coastguard Worker 
5376*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5377*6777b538SAndroid Build Coastguard Worker   MockHttpRequest reader_request(kSimpleGET_Transaction);
5378*6777b538SAndroid Build Coastguard Worker   reader_request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
5379*6777b538SAndroid Build Coastguard Worker 
5380*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5381*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 5;
5382*6777b538SAndroid Build Coastguard Worker 
5383*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5384*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5385*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5386*6777b538SAndroid Build Coastguard Worker 
5387*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5388*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5389*6777b538SAndroid Build Coastguard Worker 
5390*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
5391*6777b538SAndroid Build Coastguard Worker     if (i == 1 || i == 2) {
5392*6777b538SAndroid Build Coastguard Worker       this_request = &reader_request;
5393*6777b538SAndroid Build Coastguard Worker     }
5394*6777b538SAndroid Build Coastguard Worker 
5395*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
5396*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
5397*6777b538SAndroid Build Coastguard Worker   }
5398*6777b538SAndroid Build Coastguard Worker 
5399*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
5400*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5401*6777b538SAndroid Build Coastguard Worker 
5402*6777b538SAndroid Build Coastguard Worker   // The first request should be a writer at this point, and the subsequent
5403*6777b538SAndroid Build Coastguard Worker   // requests should be pending.
5404*6777b538SAndroid Build Coastguard Worker 
5405*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5406*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5407*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5408*6777b538SAndroid Build Coastguard Worker 
5409*6777b538SAndroid Build Coastguard Worker   Context* c = context_list[0].get();
5410*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5411*6777b538SAndroid Build Coastguard Worker   c->result = c->callback.WaitForResult();
5412*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5413*6777b538SAndroid Build Coastguard Worker 
5414*6777b538SAndroid Build Coastguard Worker   // Now all transactions should be waiting for read to be invoked. Two readers
5415*6777b538SAndroid Build Coastguard Worker   // are because of the load flags and remaining two transactions were converted
5416*6777b538SAndroid Build Coastguard Worker   // to readers after skipping validation. Note that the remaining two went on
5417*6777b538SAndroid Build Coastguard Worker   // to process the headers in parallel with readers present on the entry.
5418*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
5419*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState());
5420*6777b538SAndroid Build Coastguard Worker 
5421*6777b538SAndroid Build Coastguard Worker   c = context_list[1].get();
5422*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5423*6777b538SAndroid Build Coastguard Worker   c->result = c->callback.WaitForResult();
5424*6777b538SAndroid Build Coastguard Worker   if (c->result == OK) {
5425*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5426*6777b538SAndroid Build Coastguard Worker   }
5427*6777b538SAndroid Build Coastguard Worker 
5428*6777b538SAndroid Build Coastguard Worker   // At this point we have one reader, two pending transactions and a task on
5429*6777b538SAndroid Build Coastguard Worker   // the queue to move to the next transaction. Now we cancel the request that
5430*6777b538SAndroid Build Coastguard Worker   // is the current reader, and expect the queued task to be able to start the
5431*6777b538SAndroid Build Coastguard Worker   // next request.
5432*6777b538SAndroid Build Coastguard Worker 
5433*6777b538SAndroid Build Coastguard Worker   c = context_list[2].get();
5434*6777b538SAndroid Build Coastguard Worker   c->trans.reset();
5435*6777b538SAndroid Build Coastguard Worker 
5436*6777b538SAndroid Build Coastguard Worker   for (int i = 3; i < kNumTransactions; ++i) {
5437*6777b538SAndroid Build Coastguard Worker     c = context_list[i].get();
5438*6777b538SAndroid Build Coastguard Worker     if (c->result == ERR_IO_PENDING) {
5439*6777b538SAndroid Build Coastguard Worker       c->result = c->callback.WaitForResult();
5440*6777b538SAndroid Build Coastguard Worker     }
5441*6777b538SAndroid Build Coastguard Worker     if (c->result == OK) {
5442*6777b538SAndroid Build Coastguard Worker       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5443*6777b538SAndroid Build Coastguard Worker     }
5444*6777b538SAndroid Build Coastguard Worker   }
5445*6777b538SAndroid Build Coastguard Worker 
5446*6777b538SAndroid Build Coastguard Worker   // We should not have had to re-open the disk entry.
5447*6777b538SAndroid Build Coastguard Worker 
5448*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5449*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5450*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5451*6777b538SAndroid Build Coastguard Worker }
5452*6777b538SAndroid Build Coastguard Worker 
5453*6777b538SAndroid Build Coastguard Worker // Tests that we can doom an entry with pending transactions and delete one of
5454*6777b538SAndroid Build Coastguard Worker // the pending transactions before the first one completes.
5455*6777b538SAndroid Build Coastguard Worker // See http://code.google.com/p/chromium/issues/detail?id=25588
TEST_F(HttpCacheTest,SimpleGET_DoomWithPending)5456*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_DoomWithPending) {
5457*6777b538SAndroid Build Coastguard Worker   // We need simultaneous doomed / not_doomed entries so let's use a real cache.
5458*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
5459*6777b538SAndroid Build Coastguard Worker 
5460*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5461*6777b538SAndroid Build Coastguard Worker   MockHttpRequest writer_request(kSimpleGET_Transaction);
5462*6777b538SAndroid Build Coastguard Worker   writer_request.load_flags = LOAD_BYPASS_CACHE;
5463*6777b538SAndroid Build Coastguard Worker 
5464*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5465*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 4;
5466*6777b538SAndroid Build Coastguard Worker 
5467*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5468*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5469*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5470*6777b538SAndroid Build Coastguard Worker 
5471*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5472*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5473*6777b538SAndroid Build Coastguard Worker 
5474*6777b538SAndroid Build Coastguard Worker     MockHttpRequest* this_request = &request;
5475*6777b538SAndroid Build Coastguard Worker     if (i == 3) {
5476*6777b538SAndroid Build Coastguard Worker       this_request = &writer_request;
5477*6777b538SAndroid Build Coastguard Worker     }
5478*6777b538SAndroid Build Coastguard Worker 
5479*6777b538SAndroid Build Coastguard Worker     c->result = c->trans->Start(this_request, c->callback.callback(),
5480*6777b538SAndroid Build Coastguard Worker                                 NetLogWithSource());
5481*6777b538SAndroid Build Coastguard Worker   }
5482*6777b538SAndroid Build Coastguard Worker 
5483*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5484*6777b538SAndroid Build Coastguard Worker 
5485*6777b538SAndroid Build Coastguard Worker   // The first request should be a writer at this point, and the two subsequent
5486*6777b538SAndroid Build Coastguard Worker   // requests should be pending. The last request doomed the first entry.
5487*6777b538SAndroid Build Coastguard Worker 
5488*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5489*6777b538SAndroid Build Coastguard Worker 
5490*6777b538SAndroid Build Coastguard Worker   // Cancel the second transaction. Note that this and the 3rd transactions
5491*6777b538SAndroid Build Coastguard Worker   // would have completed their headers phase and would be waiting in the
5492*6777b538SAndroid Build Coastguard Worker   // done_headers_queue when the 2nd transaction is cancelled.
5493*6777b538SAndroid Build Coastguard Worker   context_list[1].reset();
5494*6777b538SAndroid Build Coastguard Worker 
5495*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5496*6777b538SAndroid Build Coastguard Worker     if (i == 1) {
5497*6777b538SAndroid Build Coastguard Worker       continue;
5498*6777b538SAndroid Build Coastguard Worker     }
5499*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5500*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5501*6777b538SAndroid Build Coastguard Worker     c->result = c->callback.WaitForResult();
5502*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5503*6777b538SAndroid Build Coastguard Worker   }
5504*6777b538SAndroid Build Coastguard Worker }
5505*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,DoomDoesNotSetHints)5506*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, DoomDoesNotSetHints) {
5507*6777b538SAndroid Build Coastguard Worker   // Test that a doomed writer doesn't set in-memory index hints.
5508*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5509*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_support_in_memory_entry_data(true);
5510*6777b538SAndroid Build Coastguard Worker 
5511*6777b538SAndroid Build Coastguard Worker   // Request 1 is a normal one to a no-cache/no-etag resource, to potentially
5512*6777b538SAndroid Build Coastguard Worker   // set a "this is unvalidatable" hint in the cache. We also need it to
5513*6777b538SAndroid Build Coastguard Worker   // actually write out to the doomed entry after request 2 does its thing,
5514*6777b538SAndroid Build Coastguard Worker   // so its transaction is paused.
5515*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
5516*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "Cache-Control: no-cache\n";
5517*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request1(transaction);
5518*6777b538SAndroid Build Coastguard Worker 
5519*6777b538SAndroid Build Coastguard Worker   Context c1;
5520*6777b538SAndroid Build Coastguard Worker   c1.result = cache.CreateTransaction(&c1.trans);
5521*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c1.result, IsOk());
5522*6777b538SAndroid Build Coastguard Worker   c1.trans->SetBeforeNetworkStartCallback(
5523*6777b538SAndroid Build Coastguard Worker       base::BindOnce([](bool* defer) { *defer = true; }));
5524*6777b538SAndroid Build Coastguard Worker   c1.result =
5525*6777b538SAndroid Build Coastguard Worker       c1.trans->Start(&request1, c1.callback.callback(), NetLogWithSource());
5526*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c1.result, IsError(ERR_IO_PENDING));
5527*6777b538SAndroid Build Coastguard Worker 
5528*6777b538SAndroid Build Coastguard Worker   // It starts, copies over headers info, but doesn't get to proceed.
5529*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5530*6777b538SAndroid Build Coastguard Worker 
5531*6777b538SAndroid Build Coastguard Worker   // Request 2 sets LOAD_BYPASS_CACHE to force the first one to be doomed ---
5532*6777b538SAndroid Build Coastguard Worker   // it'll want to be a writer.
5533*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = kSimpleGET_Transaction.response_headers;
5534*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request2(transaction);
5535*6777b538SAndroid Build Coastguard Worker   request2.load_flags = LOAD_BYPASS_CACHE;
5536*6777b538SAndroid Build Coastguard Worker 
5537*6777b538SAndroid Build Coastguard Worker   Context c2;
5538*6777b538SAndroid Build Coastguard Worker   c2.result = cache.CreateTransaction(&c2.trans);
5539*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c2.result, IsOk());
5540*6777b538SAndroid Build Coastguard Worker   c2.result =
5541*6777b538SAndroid Build Coastguard Worker       c2.trans->Start(&request2, c2.callback.callback(), NetLogWithSource());
5542*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c2.result, IsError(ERR_IO_PENDING));
5543*6777b538SAndroid Build Coastguard Worker 
5544*6777b538SAndroid Build Coastguard Worker   // Run Request2, then let the first one wrap up.
5545*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5546*6777b538SAndroid Build Coastguard Worker   c2.callback.WaitForResult();
5547*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
5548*6777b538SAndroid Build Coastguard Worker 
5549*6777b538SAndroid Build Coastguard Worker   c1.trans->ResumeNetworkStart();
5550*6777b538SAndroid Build Coastguard Worker   c1.callback.WaitForResult();
5551*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
5552*6777b538SAndroid Build Coastguard Worker 
5553*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5554*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5555*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
5556*6777b538SAndroid Build Coastguard Worker 
5557*6777b538SAndroid Build Coastguard Worker   // Request 3 tries to read from cache, and it should successfully do so. It's
5558*6777b538SAndroid Build Coastguard Worker   // run after the previous two transactions finish so it doesn't try to
5559*6777b538SAndroid Build Coastguard Worker   // cooperate with them, and is entirely driven by the state of the cache.
5560*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request3(kSimpleGET_Transaction);
5561*6777b538SAndroid Build Coastguard Worker   Context context3;
5562*6777b538SAndroid Build Coastguard Worker   context3.result = cache.CreateTransaction(&context3.trans);
5563*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(context3.result, IsOk());
5564*6777b538SAndroid Build Coastguard Worker   context3.result = context3.trans->Start(
5565*6777b538SAndroid Build Coastguard Worker       &request3, context3.callback.callback(), NetLogWithSource());
5566*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5567*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(context3.result, IsError(ERR_IO_PENDING));
5568*6777b538SAndroid Build Coastguard Worker   context3.result = context3.callback.WaitForResult();
5569*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(context3.trans.get(), kSimpleGET_Transaction);
5570*6777b538SAndroid Build Coastguard Worker 
5571*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5572*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
5573*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
5574*6777b538SAndroid Build Coastguard Worker }
5575*6777b538SAndroid Build Coastguard Worker 
5576*6777b538SAndroid Build Coastguard Worker // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
5577*6777b538SAndroid Build Coastguard Worker // We may attempt to delete an entry synchronously with the act of adding a new
5578*6777b538SAndroid Build Coastguard Worker // transaction to said entry.
TEST_F(HttpCacheTest,FastNoStoreGET_DoneWithPending)5579*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, FastNoStoreGET_DoneWithPending) {
5580*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5581*6777b538SAndroid Build Coastguard Worker 
5582*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kFastNoStoreGET_Transaction);
5583*6777b538SAndroid Build Coastguard Worker   // The headers will be served right from the call to Start() the request.
5584*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
5585*6777b538SAndroid Build Coastguard Worker   FastTransactionServer request_handler;
5586*6777b538SAndroid Build Coastguard Worker 
5587*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5588*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 3;
5589*6777b538SAndroid Build Coastguard Worker 
5590*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5591*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5592*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5593*6777b538SAndroid Build Coastguard Worker 
5594*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5595*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5596*6777b538SAndroid Build Coastguard Worker 
5597*6777b538SAndroid Build Coastguard Worker     c->result =
5598*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5599*6777b538SAndroid Build Coastguard Worker   }
5600*6777b538SAndroid Build Coastguard Worker 
5601*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
5602*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5603*6777b538SAndroid Build Coastguard Worker 
5604*6777b538SAndroid Build Coastguard Worker   // The first request should be a writer at this point, and the subsequent
5605*6777b538SAndroid Build Coastguard Worker   // requests should have completed validation. Since the validation does not
5606*6777b538SAndroid Build Coastguard Worker   // result in a match, a new entry would be created.
5607*6777b538SAndroid Build Coastguard Worker 
5608*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5609*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5610*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->create_count());
5611*6777b538SAndroid Build Coastguard Worker 
5612*6777b538SAndroid Build Coastguard Worker   // Now, make sure that the second request asks for the entry not to be stored.
5613*6777b538SAndroid Build Coastguard Worker   request_handler.set_no_store(true);
5614*6777b538SAndroid Build Coastguard Worker 
5615*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5616*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5617*6777b538SAndroid Build Coastguard Worker     if (c->result == ERR_IO_PENDING) {
5618*6777b538SAndroid Build Coastguard Worker       c->result = c->callback.WaitForResult();
5619*6777b538SAndroid Build Coastguard Worker     }
5620*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), transaction);
5621*6777b538SAndroid Build Coastguard Worker     context_list[i].reset();
5622*6777b538SAndroid Build Coastguard Worker   }
5623*6777b538SAndroid Build Coastguard Worker 
5624*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5625*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5626*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->create_count());
5627*6777b538SAndroid Build Coastguard Worker }
5628*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_CancelFirst)5629*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ManyWriters_CancelFirst) {
5630*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5631*6777b538SAndroid Build Coastguard Worker 
5632*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5633*6777b538SAndroid Build Coastguard Worker 
5634*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5635*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 2;
5636*6777b538SAndroid Build Coastguard Worker 
5637*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5638*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5639*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5640*6777b538SAndroid Build Coastguard Worker 
5641*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5642*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5643*6777b538SAndroid Build Coastguard Worker 
5644*6777b538SAndroid Build Coastguard Worker     c->result =
5645*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5646*6777b538SAndroid Build Coastguard Worker   }
5647*6777b538SAndroid Build Coastguard Worker 
5648*6777b538SAndroid Build Coastguard Worker   // Allow all requests to move from the Create queue to the active entry.
5649*6777b538SAndroid Build Coastguard Worker   // All would have been added to writers.
5650*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5651*6777b538SAndroid Build Coastguard Worker   std::string cache_key =
5652*6777b538SAndroid Build Coastguard Worker       *cache.http_cache()->GenerateCacheKeyForRequest(&request);
5653*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5654*6777b538SAndroid Build Coastguard Worker 
5655*6777b538SAndroid Build Coastguard Worker   // The second transaction skipped validation, thus only one network
5656*6777b538SAndroid Build Coastguard Worker   // transaction is created.
5657*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5658*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5659*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5660*6777b538SAndroid Build Coastguard Worker 
5661*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5662*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5663*6777b538SAndroid Build Coastguard Worker     if (c->result == ERR_IO_PENDING) {
5664*6777b538SAndroid Build Coastguard Worker       c->result = c->callback.WaitForResult();
5665*6777b538SAndroid Build Coastguard Worker     }
5666*6777b538SAndroid Build Coastguard Worker     // Destroy only the first transaction.
5667*6777b538SAndroid Build Coastguard Worker     // This should not impact the other writer transaction and the network
5668*6777b538SAndroid Build Coastguard Worker     // transaction will continue to be used by that transaction.
5669*6777b538SAndroid Build Coastguard Worker     if (i == 0) {
5670*6777b538SAndroid Build Coastguard Worker       context_list[i].reset();
5671*6777b538SAndroid Build Coastguard Worker     }
5672*6777b538SAndroid Build Coastguard Worker   }
5673*6777b538SAndroid Build Coastguard Worker 
5674*6777b538SAndroid Build Coastguard Worker   // Complete the rest of the transactions.
5675*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i < kNumTransactions; ++i) {
5676*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5677*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5678*6777b538SAndroid Build Coastguard Worker   }
5679*6777b538SAndroid Build Coastguard Worker 
5680*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5681*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5682*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5683*6777b538SAndroid Build Coastguard Worker }
5684*6777b538SAndroid Build Coastguard Worker 
5685*6777b538SAndroid Build Coastguard Worker // Tests that we can cancel requests that are queued waiting to open the disk
5686*6777b538SAndroid Build Coastguard Worker // cache entry.
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_CancelCreate)5687*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ManyWriters_CancelCreate) {
5688*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5689*6777b538SAndroid Build Coastguard Worker 
5690*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5691*6777b538SAndroid Build Coastguard Worker 
5692*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5693*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 5;
5694*6777b538SAndroid Build Coastguard Worker 
5695*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; i++) {
5696*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5697*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5698*6777b538SAndroid Build Coastguard Worker 
5699*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5700*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5701*6777b538SAndroid Build Coastguard Worker 
5702*6777b538SAndroid Build Coastguard Worker     c->result =
5703*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5704*6777b538SAndroid Build Coastguard Worker   }
5705*6777b538SAndroid Build Coastguard Worker 
5706*6777b538SAndroid Build Coastguard Worker   // The first request should be creating the disk cache entry and the others
5707*6777b538SAndroid Build Coastguard Worker   // should be pending.
5708*6777b538SAndroid Build Coastguard Worker 
5709*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.network_layer()->transaction_count());
5710*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5711*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5712*6777b538SAndroid Build Coastguard Worker 
5713*6777b538SAndroid Build Coastguard Worker   // Cancel a request from the pending queue.
5714*6777b538SAndroid Build Coastguard Worker   context_list[3].reset();
5715*6777b538SAndroid Build Coastguard Worker 
5716*6777b538SAndroid Build Coastguard Worker   // Cancel the request that is creating the entry. This will force the pending
5717*6777b538SAndroid Build Coastguard Worker   // operations to restart.
5718*6777b538SAndroid Build Coastguard Worker   context_list[0].reset();
5719*6777b538SAndroid Build Coastguard Worker 
5720*6777b538SAndroid Build Coastguard Worker   // Complete the rest of the transactions.
5721*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i < kNumTransactions; i++) {
5722*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5723*6777b538SAndroid Build Coastguard Worker     if (c) {
5724*6777b538SAndroid Build Coastguard Worker       c->result = c->callback.GetResult(c->result);
5725*6777b538SAndroid Build Coastguard Worker       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5726*6777b538SAndroid Build Coastguard Worker     }
5727*6777b538SAndroid Build Coastguard Worker   }
5728*6777b538SAndroid Build Coastguard Worker 
5729*6777b538SAndroid Build Coastguard Worker   // We should have had to re-create the disk entry.
5730*6777b538SAndroid Build Coastguard Worker 
5731*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5732*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5733*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
5734*6777b538SAndroid Build Coastguard Worker }
5735*6777b538SAndroid Build Coastguard Worker 
5736*6777b538SAndroid Build Coastguard Worker // Tests that we can cancel a single request to open a disk cache entry.
TEST_F(HttpCacheTest,SimpleGET_CancelCreate)5737*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_CancelCreate) {
5738*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5739*6777b538SAndroid Build Coastguard Worker 
5740*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5741*6777b538SAndroid Build Coastguard Worker 
5742*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
5743*6777b538SAndroid Build Coastguard Worker 
5744*6777b538SAndroid Build Coastguard Worker   c->result = cache.CreateTransaction(&c->trans);
5745*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c->result, IsOk());
5746*6777b538SAndroid Build Coastguard Worker 
5747*6777b538SAndroid Build Coastguard Worker   c->result =
5748*6777b538SAndroid Build Coastguard Worker       c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5749*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c->result, IsError(ERR_IO_PENDING));
5750*6777b538SAndroid Build Coastguard Worker 
5751*6777b538SAndroid Build Coastguard Worker   // Release the reference that the mock disk cache keeps for this entry, so
5752*6777b538SAndroid Build Coastguard Worker   // that we test that the http cache handles the cancellation correctly.
5753*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->ReleaseAll();
5754*6777b538SAndroid Build Coastguard Worker   c.reset();
5755*6777b538SAndroid Build Coastguard Worker 
5756*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5757*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
5758*6777b538SAndroid Build Coastguard Worker }
5759*6777b538SAndroid Build Coastguard Worker 
5760*6777b538SAndroid Build Coastguard Worker // Tests that we delete/create entries even if multiple requests are queued.
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_BypassCache)5761*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ManyWriters_BypassCache) {
5762*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5763*6777b538SAndroid Build Coastguard Worker 
5764*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5765*6777b538SAndroid Build Coastguard Worker   request.load_flags = LOAD_BYPASS_CACHE;
5766*6777b538SAndroid Build Coastguard Worker 
5767*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5768*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 5;
5769*6777b538SAndroid Build Coastguard Worker 
5770*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; i++) {
5771*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5772*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5773*6777b538SAndroid Build Coastguard Worker 
5774*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5775*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5776*6777b538SAndroid Build Coastguard Worker 
5777*6777b538SAndroid Build Coastguard Worker     c->result =
5778*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5779*6777b538SAndroid Build Coastguard Worker   }
5780*6777b538SAndroid Build Coastguard Worker 
5781*6777b538SAndroid Build Coastguard Worker   // The first request should be deleting the disk cache entry and the others
5782*6777b538SAndroid Build Coastguard Worker   // should be pending.
5783*6777b538SAndroid Build Coastguard Worker 
5784*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.network_layer()->transaction_count());
5785*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5786*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
5787*6777b538SAndroid Build Coastguard Worker 
5788*6777b538SAndroid Build Coastguard Worker   // Complete the transactions.
5789*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; i++) {
5790*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5791*6777b538SAndroid Build Coastguard Worker     c->result = c->callback.GetResult(c->result);
5792*6777b538SAndroid Build Coastguard Worker     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5793*6777b538SAndroid Build Coastguard Worker   }
5794*6777b538SAndroid Build Coastguard Worker 
5795*6777b538SAndroid Build Coastguard Worker   // We should have had to re-create the disk entry multiple times.
5796*6777b538SAndroid Build Coastguard Worker 
5797*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, cache.network_layer()->transaction_count());
5798*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
5799*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, cache.disk_cache()->create_count());
5800*6777b538SAndroid Build Coastguard Worker }
5801*6777b538SAndroid Build Coastguard Worker 
5802*6777b538SAndroid Build Coastguard Worker // Tests that a (simulated) timeout allows transactions waiting on the cache
5803*6777b538SAndroid Build Coastguard Worker // lock to continue.
TEST_F(HttpCacheTest,SimpleGET_WriterTimeout)5804*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_WriterTimeout) {
5805*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5806*6777b538SAndroid Build Coastguard Worker   cache.SimulateCacheLockTimeout();
5807*6777b538SAndroid Build Coastguard Worker 
5808*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5809*6777b538SAndroid Build Coastguard Worker   Context c1, c2;
5810*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk());
5811*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(),
5812*6777b538SAndroid Build Coastguard Worker                                             NetLogWithSource()));
5813*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&c2.trans), IsOk());
5814*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(ERR_IO_PENDING, c2.trans->Start(&request, c2.callback.callback(),
5815*6777b538SAndroid Build Coastguard Worker                                             NetLogWithSource()));
5816*6777b538SAndroid Build Coastguard Worker 
5817*6777b538SAndroid Build Coastguard Worker   // The second request is queued after the first one.
5818*6777b538SAndroid Build Coastguard Worker 
5819*6777b538SAndroid Build Coastguard Worker   c2.callback.WaitForResult();
5820*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
5821*6777b538SAndroid Build Coastguard Worker 
5822*6777b538SAndroid Build Coastguard Worker   // Complete the first transaction.
5823*6777b538SAndroid Build Coastguard Worker   c1.callback.WaitForResult();
5824*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
5825*6777b538SAndroid Build Coastguard Worker }
5826*6777b538SAndroid Build Coastguard Worker 
5827*6777b538SAndroid Build Coastguard Worker // Tests that a (simulated) timeout allows transactions waiting on the cache
5828*6777b538SAndroid Build Coastguard Worker // lock to continue but read only transactions to error out.
TEST_F(HttpCacheTest,SimpleGET_WriterTimeoutReadOnlyError)5829*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_WriterTimeoutReadOnlyError) {
5830*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5831*6777b538SAndroid Build Coastguard Worker 
5832*6777b538SAndroid Build Coastguard Worker   // Simulate timeout.
5833*6777b538SAndroid Build Coastguard Worker   cache.SimulateCacheLockTimeout();
5834*6777b538SAndroid Build Coastguard Worker 
5835*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5836*6777b538SAndroid Build Coastguard Worker   Context c1, c2;
5837*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk());
5838*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(),
5839*6777b538SAndroid Build Coastguard Worker                                             NetLogWithSource()));
5840*6777b538SAndroid Build Coastguard Worker 
5841*6777b538SAndroid Build Coastguard Worker   request.load_flags = LOAD_ONLY_FROM_CACHE;
5842*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&c2.trans), IsOk());
5843*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(ERR_IO_PENDING, c2.trans->Start(&request, c2.callback.callback(),
5844*6777b538SAndroid Build Coastguard Worker                                             NetLogWithSource()));
5845*6777b538SAndroid Build Coastguard Worker 
5846*6777b538SAndroid Build Coastguard Worker   // The second request is queued after the first one.
5847*6777b538SAndroid Build Coastguard Worker   int res = c2.callback.WaitForResult();
5848*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(ERR_CACHE_MISS, res);
5849*6777b538SAndroid Build Coastguard Worker 
5850*6777b538SAndroid Build Coastguard Worker   // Complete the first transaction.
5851*6777b538SAndroid Build Coastguard Worker   c1.callback.WaitForResult();
5852*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
5853*6777b538SAndroid Build Coastguard Worker }
5854*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_AbandonedCacheRead)5855*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_AbandonedCacheRead) {
5856*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
5857*6777b538SAndroid Build Coastguard Worker 
5858*6777b538SAndroid Build Coastguard Worker   // write to the cache
5859*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5860*6777b538SAndroid Build Coastguard Worker 
5861*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5862*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
5863*6777b538SAndroid Build Coastguard Worker 
5864*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
5865*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
5866*6777b538SAndroid Build Coastguard Worker   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5867*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
5868*6777b538SAndroid Build Coastguard Worker     rv = callback.WaitForResult();
5869*6777b538SAndroid Build Coastguard Worker   }
5870*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
5871*6777b538SAndroid Build Coastguard Worker 
5872*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
5873*6777b538SAndroid Build Coastguard Worker   rv = trans->Read(buf.get(), 256, callback.callback());
5874*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5875*6777b538SAndroid Build Coastguard Worker 
5876*6777b538SAndroid Build Coastguard Worker   // Test that destroying the transaction while it is reading from the cache
5877*6777b538SAndroid Build Coastguard Worker   // works properly.
5878*6777b538SAndroid Build Coastguard Worker   trans.reset();
5879*6777b538SAndroid Build Coastguard Worker 
5880*6777b538SAndroid Build Coastguard Worker   // Make sure we pump any pending events, which should include a call to
5881*6777b538SAndroid Build Coastguard Worker   // HttpCache::Transaction::OnCacheReadCompleted.
5882*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5883*6777b538SAndroid Build Coastguard Worker }
5884*6777b538SAndroid Build Coastguard Worker 
5885*6777b538SAndroid Build Coastguard Worker // Tests that we can delete the HttpCache and deal with queued transactions
5886*6777b538SAndroid Build Coastguard Worker // ("waiting for the backend" as opposed to Active or Doomed entries).
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_DeleteCache)5887*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_ManyWriters_DeleteCache) {
5888*6777b538SAndroid Build Coastguard Worker   auto cache = std::make_unique<MockHttpCache>(
5889*6777b538SAndroid Build Coastguard Worker       std::make_unique<MockBackendNoCbFactory>());
5890*6777b538SAndroid Build Coastguard Worker 
5891*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
5892*6777b538SAndroid Build Coastguard Worker 
5893*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5894*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 5;
5895*6777b538SAndroid Build Coastguard Worker 
5896*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; i++) {
5897*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5898*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5899*6777b538SAndroid Build Coastguard Worker 
5900*6777b538SAndroid Build Coastguard Worker     c->result = cache->CreateTransaction(&c->trans);
5901*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5902*6777b538SAndroid Build Coastguard Worker 
5903*6777b538SAndroid Build Coastguard Worker     c->result =
5904*6777b538SAndroid Build Coastguard Worker         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5905*6777b538SAndroid Build Coastguard Worker   }
5906*6777b538SAndroid Build Coastguard Worker 
5907*6777b538SAndroid Build Coastguard Worker   // The first request should be creating the disk cache entry and the others
5908*6777b538SAndroid Build Coastguard Worker   // should be pending.
5909*6777b538SAndroid Build Coastguard Worker 
5910*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache->network_layer()->transaction_count());
5911*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache->disk_cache()->open_count());
5912*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache->disk_cache()->create_count());
5913*6777b538SAndroid Build Coastguard Worker 
5914*6777b538SAndroid Build Coastguard Worker   cache.reset();
5915*6777b538SAndroid Build Coastguard Worker }
5916*6777b538SAndroid Build Coastguard Worker 
5917*6777b538SAndroid Build Coastguard Worker // Tests that we queue requests when initializing the backend.
TEST_F(HttpCacheTest,SimpleGET_WaitForBackend)5918*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_WaitForBackend) {
5919*6777b538SAndroid Build Coastguard Worker   auto factory = std::make_unique<MockBlockingBackendFactory>();
5920*6777b538SAndroid Build Coastguard Worker   MockBlockingBackendFactory* factory_ptr = factory.get();
5921*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache(std::move(factory));
5922*6777b538SAndroid Build Coastguard Worker 
5923*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request0(kSimpleGET_Transaction);
5924*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request1(kTypicalGET_Transaction);
5925*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request2(kETagGET_Transaction);
5926*6777b538SAndroid Build Coastguard Worker 
5927*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5928*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 3;
5929*6777b538SAndroid Build Coastguard Worker 
5930*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; i++) {
5931*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5932*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5933*6777b538SAndroid Build Coastguard Worker 
5934*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5935*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5936*6777b538SAndroid Build Coastguard Worker   }
5937*6777b538SAndroid Build Coastguard Worker 
5938*6777b538SAndroid Build Coastguard Worker   context_list[0]->result = context_list[0]->trans->Start(
5939*6777b538SAndroid Build Coastguard Worker       &request0, context_list[0]->callback.callback(), NetLogWithSource());
5940*6777b538SAndroid Build Coastguard Worker   context_list[1]->result = context_list[1]->trans->Start(
5941*6777b538SAndroid Build Coastguard Worker       &request1, context_list[1]->callback.callback(), NetLogWithSource());
5942*6777b538SAndroid Build Coastguard Worker   context_list[2]->result = context_list[2]->trans->Start(
5943*6777b538SAndroid Build Coastguard Worker       &request2, context_list[2]->callback.callback(), NetLogWithSource());
5944*6777b538SAndroid Build Coastguard Worker 
5945*6777b538SAndroid Build Coastguard Worker   // Just to make sure that everything is still pending.
5946*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5947*6777b538SAndroid Build Coastguard Worker 
5948*6777b538SAndroid Build Coastguard Worker   // The first request should be creating the disk cache.
5949*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(context_list[0]->callback.have_result());
5950*6777b538SAndroid Build Coastguard Worker 
5951*6777b538SAndroid Build Coastguard Worker   factory_ptr->FinishCreation();
5952*6777b538SAndroid Build Coastguard Worker 
5953*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5954*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5955*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->create_count());
5956*6777b538SAndroid Build Coastguard Worker 
5957*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; ++i) {
5958*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(context_list[i]->callback.have_result());
5959*6777b538SAndroid Build Coastguard Worker     context_list[i].reset();
5960*6777b538SAndroid Build Coastguard Worker   }
5961*6777b538SAndroid Build Coastguard Worker }
5962*6777b538SAndroid Build Coastguard Worker 
5963*6777b538SAndroid Build Coastguard Worker // Tests that we can cancel requests that are queued waiting for the backend
5964*6777b538SAndroid Build Coastguard Worker // to be initialized.
TEST_F(HttpCacheTest,SimpleGET_WaitForBackend_CancelCreate)5965*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate) {
5966*6777b538SAndroid Build Coastguard Worker   auto factory = std::make_unique<MockBlockingBackendFactory>();
5967*6777b538SAndroid Build Coastguard Worker   MockBlockingBackendFactory* factory_ptr = factory.get();
5968*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache(std::move(factory));
5969*6777b538SAndroid Build Coastguard Worker 
5970*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request0(kSimpleGET_Transaction);
5971*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request1(kTypicalGET_Transaction);
5972*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request2(kETagGET_Transaction);
5973*6777b538SAndroid Build Coastguard Worker 
5974*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Context>> context_list;
5975*6777b538SAndroid Build Coastguard Worker   const int kNumTransactions = 3;
5976*6777b538SAndroid Build Coastguard Worker 
5977*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTransactions; i++) {
5978*6777b538SAndroid Build Coastguard Worker     context_list.push_back(std::make_unique<Context>());
5979*6777b538SAndroid Build Coastguard Worker     Context* c = context_list[i].get();
5980*6777b538SAndroid Build Coastguard Worker 
5981*6777b538SAndroid Build Coastguard Worker     c->result = cache.CreateTransaction(&c->trans);
5982*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(c->result, IsOk());
5983*6777b538SAndroid Build Coastguard Worker   }
5984*6777b538SAndroid Build Coastguard Worker 
5985*6777b538SAndroid Build Coastguard Worker   context_list[0]->result = context_list[0]->trans->Start(
5986*6777b538SAndroid Build Coastguard Worker       &request0, context_list[0]->callback.callback(), NetLogWithSource());
5987*6777b538SAndroid Build Coastguard Worker   context_list[1]->result = context_list[1]->trans->Start(
5988*6777b538SAndroid Build Coastguard Worker       &request1, context_list[1]->callback.callback(), NetLogWithSource());
5989*6777b538SAndroid Build Coastguard Worker   context_list[2]->result = context_list[2]->trans->Start(
5990*6777b538SAndroid Build Coastguard Worker       &request2, context_list[2]->callback.callback(), NetLogWithSource());
5991*6777b538SAndroid Build Coastguard Worker 
5992*6777b538SAndroid Build Coastguard Worker   // Just to make sure that everything is still pending.
5993*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5994*6777b538SAndroid Build Coastguard Worker 
5995*6777b538SAndroid Build Coastguard Worker   // The first request should be creating the disk cache.
5996*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(context_list[0]->callback.have_result());
5997*6777b538SAndroid Build Coastguard Worker 
5998*6777b538SAndroid Build Coastguard Worker   // Cancel a request from the pending queue.
5999*6777b538SAndroid Build Coastguard Worker   context_list[1].reset();
6000*6777b538SAndroid Build Coastguard Worker 
6001*6777b538SAndroid Build Coastguard Worker   // Cancel the request that is creating the entry.
6002*6777b538SAndroid Build Coastguard Worker   context_list[0].reset();
6003*6777b538SAndroid Build Coastguard Worker 
6004*6777b538SAndroid Build Coastguard Worker   // Complete the last transaction.
6005*6777b538SAndroid Build Coastguard Worker   factory_ptr->FinishCreation();
6006*6777b538SAndroid Build Coastguard Worker 
6007*6777b538SAndroid Build Coastguard Worker   context_list[2]->result =
6008*6777b538SAndroid Build Coastguard Worker       context_list[2]->callback.GetResult(context_list[2]->result);
6009*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
6010*6777b538SAndroid Build Coastguard Worker 
6011*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6012*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6013*6777b538SAndroid Build Coastguard Worker }
6014*6777b538SAndroid Build Coastguard Worker 
6015*6777b538SAndroid Build Coastguard Worker // Tests that we can delete the HttpCache while creating the backend.
TEST_F(HttpCacheTest,DeleteCacheWaitingForBackend)6016*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend) {
6017*6777b538SAndroid Build Coastguard Worker   auto factory = std::make_unique<MockBlockingBackendFactory>();
6018*6777b538SAndroid Build Coastguard Worker   MockBlockingBackendFactory* factory_ptr = factory.get();
6019*6777b538SAndroid Build Coastguard Worker   auto cache = std::make_unique<MockHttpCache>(std::move(factory));
6020*6777b538SAndroid Build Coastguard Worker 
6021*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
6022*6777b538SAndroid Build Coastguard Worker 
6023*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
6024*6777b538SAndroid Build Coastguard Worker   c->result = cache->CreateTransaction(&c->trans);
6025*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c->result, IsOk());
6026*6777b538SAndroid Build Coastguard Worker 
6027*6777b538SAndroid Build Coastguard Worker   c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
6028*6777b538SAndroid Build Coastguard Worker 
6029*6777b538SAndroid Build Coastguard Worker   // Just to make sure that everything is still pending.
6030*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
6031*6777b538SAndroid Build Coastguard Worker 
6032*6777b538SAndroid Build Coastguard Worker   // The request should be creating the disk cache.
6033*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(c->callback.have_result());
6034*6777b538SAndroid Build Coastguard Worker 
6035*6777b538SAndroid Build Coastguard Worker   // Manually arrange for completion to happen after ~HttpCache.
6036*6777b538SAndroid Build Coastguard Worker   // This can't be done via FinishCreation() since that's in `factory`, and
6037*6777b538SAndroid Build Coastguard Worker   // that's owned by `cache`.
6038*6777b538SAndroid Build Coastguard Worker   disk_cache::BackendResultCallback callback = factory_ptr->ReleaseCallback();
6039*6777b538SAndroid Build Coastguard Worker 
6040*6777b538SAndroid Build Coastguard Worker   cache.reset();
6041*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
6042*6777b538SAndroid Build Coastguard Worker 
6043*6777b538SAndroid Build Coastguard Worker   // Simulate the backend completion callback running now the HttpCache is gone.
6044*6777b538SAndroid Build Coastguard Worker   std::move(callback).Run(disk_cache::BackendResult::MakeError(ERR_ABORTED));
6045*6777b538SAndroid Build Coastguard Worker }
6046*6777b538SAndroid Build Coastguard Worker 
6047*6777b538SAndroid Build Coastguard Worker // Tests that we can delete the cache while creating the backend, from within
6048*6777b538SAndroid Build Coastguard Worker // one of the callbacks.
TEST_F(HttpCacheTest,DeleteCacheWaitingForBackend2)6049*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend2) {
6050*6777b538SAndroid Build Coastguard Worker   auto factory = std::make_unique<MockBlockingBackendFactory>();
6051*6777b538SAndroid Build Coastguard Worker   MockBlockingBackendFactory* factory_ptr = factory.get();
6052*6777b538SAndroid Build Coastguard Worker   auto cache = std::make_unique<MockHttpCache>(std::move(factory));
6053*6777b538SAndroid Build Coastguard Worker   auto* cache_ptr = cache.get();
6054*6777b538SAndroid Build Coastguard Worker 
6055*6777b538SAndroid Build Coastguard Worker   DeleteCacheCompletionCallback cb(std::move(cache));
6056*6777b538SAndroid Build Coastguard Worker   disk_cache::Backend* backend;
6057*6777b538SAndroid Build Coastguard Worker   int rv = cache_ptr->http_cache()->GetBackend(&backend, cb.callback());
6058*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6059*6777b538SAndroid Build Coastguard Worker 
6060*6777b538SAndroid Build Coastguard Worker   // Now let's queue a regular transaction
6061*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
6062*6777b538SAndroid Build Coastguard Worker 
6063*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
6064*6777b538SAndroid Build Coastguard Worker   c->result = cache_ptr->CreateTransaction(&c->trans);
6065*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(c->result, IsOk());
6066*6777b538SAndroid Build Coastguard Worker 
6067*6777b538SAndroid Build Coastguard Worker   c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
6068*6777b538SAndroid Build Coastguard Worker 
6069*6777b538SAndroid Build Coastguard Worker   // And another direct backend request.
6070*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback cb2;
6071*6777b538SAndroid Build Coastguard Worker   rv = cache_ptr->http_cache()->GetBackend(&backend, cb2.callback());
6072*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6073*6777b538SAndroid Build Coastguard Worker 
6074*6777b538SAndroid Build Coastguard Worker   // Just to make sure that everything is still pending.
6075*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
6076*6777b538SAndroid Build Coastguard Worker 
6077*6777b538SAndroid Build Coastguard Worker   // The request should be queued.
6078*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(c->callback.have_result());
6079*6777b538SAndroid Build Coastguard Worker 
6080*6777b538SAndroid Build Coastguard Worker   // Generate the callback.
6081*6777b538SAndroid Build Coastguard Worker   factory_ptr->FinishCreation();
6082*6777b538SAndroid Build Coastguard Worker   rv = cb.WaitForResult();
6083*6777b538SAndroid Build Coastguard Worker 
6084*6777b538SAndroid Build Coastguard Worker   // The cache should be gone by now.
6085*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
6086*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c->callback.GetResult(c->result), IsOk());
6087*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cb2.have_result());
6088*6777b538SAndroid Build Coastguard Worker }
6089*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,TypicalGET_ConditionalRequest)6090*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, TypicalGET_ConditionalRequest) {
6091*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6092*6777b538SAndroid Build Coastguard Worker 
6093*6777b538SAndroid Build Coastguard Worker   // write to the cache
6094*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
6095*6777b538SAndroid Build Coastguard Worker 
6096*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6097*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
6098*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6099*6777b538SAndroid Build Coastguard Worker 
6100*6777b538SAndroid Build Coastguard Worker   // Get the same URL again, but this time we expect it to result
6101*6777b538SAndroid Build Coastguard Worker   // in a conditional request.
6102*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
6103*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
6104*6777b538SAndroid Build Coastguard Worker                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6105*6777b538SAndroid Build Coastguard Worker                                  &load_timing_info);
6106*6777b538SAndroid Build Coastguard Worker 
6107*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6108*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6109*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6110*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
6111*6777b538SAndroid Build Coastguard Worker }
6112*6777b538SAndroid Build Coastguard Worker 
6113*6777b538SAndroid Build Coastguard Worker static const auto kETagGetConditionalRequestHandler =
6114*6777b538SAndroid Build Coastguard Worker     base::BindRepeating([](const HttpRequestInfo* request,
6115*6777b538SAndroid Build Coastguard Worker                            std::string* response_status,
6116*6777b538SAndroid Build Coastguard Worker                            std::string* response_headers,
__anone6acdaec0802(const HttpRequestInfo* request, std::string* response_status, std::string* response_headers, std::string* response_data) 6117*6777b538SAndroid Build Coastguard Worker                            std::string* response_data) {
6118*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(
6119*6777b538SAndroid Build Coastguard Worker           request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6120*6777b538SAndroid Build Coastguard Worker       response_status->assign("HTTP/1.1 304 Not Modified");
6121*6777b538SAndroid Build Coastguard Worker       response_headers->assign(kETagGET_Transaction.response_headers);
6122*6777b538SAndroid Build Coastguard Worker       response_data->clear();
6123*6777b538SAndroid Build Coastguard Worker     });
6124*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,ETagGET_ConditionalRequest_304)6125*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ETagGET_ConditionalRequest_304) {
6126*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6127*6777b538SAndroid Build Coastguard Worker 
6128*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kETagGET_Transaction);
6129*6777b538SAndroid Build Coastguard Worker 
6130*6777b538SAndroid Build Coastguard Worker   // write to the cache
6131*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6132*6777b538SAndroid Build Coastguard Worker 
6133*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6134*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
6135*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6136*6777b538SAndroid Build Coastguard Worker 
6137*6777b538SAndroid Build Coastguard Worker   // Get the same URL again, but this time we expect it to result
6138*6777b538SAndroid Build Coastguard Worker   // in a conditional request.
6139*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_VALIDATE_CACHE;
6140*6777b538SAndroid Build Coastguard Worker   transaction.handler = kETagGetConditionalRequestHandler;
6141*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
6142*6777b538SAndroid Build Coastguard Worker   IPEndPoint remote_endpoint;
6143*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTimingAndConnectedSocketAddress(
6144*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), transaction,
6145*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info,
6146*6777b538SAndroid Build Coastguard Worker       &remote_endpoint);
6147*6777b538SAndroid Build Coastguard Worker 
6148*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6149*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6150*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6151*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
6152*6777b538SAndroid Build Coastguard Worker 
6153*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(remote_endpoint.address().empty());
6154*6777b538SAndroid Build Coastguard Worker }
6155*6777b538SAndroid Build Coastguard Worker 
6156*6777b538SAndroid Build Coastguard Worker class RevalidationServer {
6157*6777b538SAndroid Build Coastguard Worker  public:
6158*6777b538SAndroid Build Coastguard Worker   RevalidationServer() = default;
6159*6777b538SAndroid Build Coastguard Worker 
EtagUsed()6160*6777b538SAndroid Build Coastguard Worker   bool EtagUsed() { return etag_used_; }
LastModifiedUsed()6161*6777b538SAndroid Build Coastguard Worker   bool LastModifiedUsed() { return last_modified_used_; }
6162*6777b538SAndroid Build Coastguard Worker 
GetHandlerCallback()6163*6777b538SAndroid Build Coastguard Worker   MockTransactionHandler GetHandlerCallback() {
6164*6777b538SAndroid Build Coastguard Worker     return base::BindLambdaForTesting([this](const HttpRequestInfo* request,
6165*6777b538SAndroid Build Coastguard Worker                                              std::string* response_status,
6166*6777b538SAndroid Build Coastguard Worker                                              std::string* response_headers,
6167*6777b538SAndroid Build Coastguard Worker                                              std::string* response_data) {
6168*6777b538SAndroid Build Coastguard Worker       if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch)) {
6169*6777b538SAndroid Build Coastguard Worker         etag_used_ = true;
6170*6777b538SAndroid Build Coastguard Worker       }
6171*6777b538SAndroid Build Coastguard Worker 
6172*6777b538SAndroid Build Coastguard Worker       if (request->extra_headers.HasHeader(
6173*6777b538SAndroid Build Coastguard Worker               HttpRequestHeaders::kIfModifiedSince)) {
6174*6777b538SAndroid Build Coastguard Worker         last_modified_used_ = true;
6175*6777b538SAndroid Build Coastguard Worker       }
6176*6777b538SAndroid Build Coastguard Worker 
6177*6777b538SAndroid Build Coastguard Worker       if (etag_used_ || last_modified_used_) {
6178*6777b538SAndroid Build Coastguard Worker         response_status->assign("HTTP/1.1 304 Not Modified");
6179*6777b538SAndroid Build Coastguard Worker         response_headers->assign(kTypicalGET_Transaction.response_headers);
6180*6777b538SAndroid Build Coastguard Worker         response_data->clear();
6181*6777b538SAndroid Build Coastguard Worker       } else {
6182*6777b538SAndroid Build Coastguard Worker         response_status->assign(kTypicalGET_Transaction.status);
6183*6777b538SAndroid Build Coastguard Worker         response_headers->assign(kTypicalGET_Transaction.response_headers);
6184*6777b538SAndroid Build Coastguard Worker         response_data->assign(kTypicalGET_Transaction.data);
6185*6777b538SAndroid Build Coastguard Worker       }
6186*6777b538SAndroid Build Coastguard Worker     });
6187*6777b538SAndroid Build Coastguard Worker   }
6188*6777b538SAndroid Build Coastguard Worker 
6189*6777b538SAndroid Build Coastguard Worker  private:
6190*6777b538SAndroid Build Coastguard Worker   bool etag_used_ = false;
6191*6777b538SAndroid Build Coastguard Worker   bool last_modified_used_ = false;
6192*6777b538SAndroid Build Coastguard Worker };
6193*6777b538SAndroid Build Coastguard Worker 
6194*6777b538SAndroid Build Coastguard Worker // Tests revalidation after a vary match.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch)6195*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch) {
6196*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6197*6777b538SAndroid Build Coastguard Worker 
6198*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
6199*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6200*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n";
6201*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
6202*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6203*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6204*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n"
6205*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
6206*6777b538SAndroid Build Coastguard Worker       "Vary: Foo\n";
6207*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6208*6777b538SAndroid Build Coastguard Worker 
6209*6777b538SAndroid Build Coastguard Worker   // Read from the cache.
6210*6777b538SAndroid Build Coastguard Worker   RevalidationServer server;
6211*6777b538SAndroid Build Coastguard Worker   transaction.handler = server.GetHandlerCallback();
6212*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
6213*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6214*6777b538SAndroid Build Coastguard Worker                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6215*6777b538SAndroid Build Coastguard Worker                                  &load_timing_info);
6216*6777b538SAndroid Build Coastguard Worker 
6217*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(server.EtagUsed());
6218*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(server.LastModifiedUsed());
6219*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6220*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6221*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6222*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
6223*6777b538SAndroid Build Coastguard Worker }
6224*6777b538SAndroid Build Coastguard Worker 
6225*6777b538SAndroid Build Coastguard Worker // Tests revalidation after a vary mismatch if etag is present.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch)6226*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch) {
6227*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6228*6777b538SAndroid Build Coastguard Worker 
6229*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
6230*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6231*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n";
6232*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
6233*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6234*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6235*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n"
6236*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
6237*6777b538SAndroid Build Coastguard Worker       "Vary: Foo\n";
6238*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6239*6777b538SAndroid Build Coastguard Worker 
6240*6777b538SAndroid Build Coastguard Worker   // Read from the cache and revalidate the entry.
6241*6777b538SAndroid Build Coastguard Worker   RevalidationServer server;
6242*6777b538SAndroid Build Coastguard Worker   transaction.handler = server.GetHandlerCallback();
6243*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: none\r\n";
6244*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
6245*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6246*6777b538SAndroid Build Coastguard Worker                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6247*6777b538SAndroid Build Coastguard Worker                                  &load_timing_info);
6248*6777b538SAndroid Build Coastguard Worker 
6249*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(server.EtagUsed());
6250*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(server.LastModifiedUsed());
6251*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6252*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6253*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6254*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
6255*6777b538SAndroid Build Coastguard Worker }
6256*6777b538SAndroid Build Coastguard Worker 
6257*6777b538SAndroid Build Coastguard Worker // Tests revalidation after a vary mismatch due to vary: * if etag is present.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatchStar)6258*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatchStar) {
6259*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6260*6777b538SAndroid Build Coastguard Worker 
6261*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
6262*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6263*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
6264*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6265*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6266*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n"
6267*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
6268*6777b538SAndroid Build Coastguard Worker       "Vary: *\n";
6269*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6270*6777b538SAndroid Build Coastguard Worker 
6271*6777b538SAndroid Build Coastguard Worker   // Read from the cache and revalidate the entry.
6272*6777b538SAndroid Build Coastguard Worker   RevalidationServer server;
6273*6777b538SAndroid Build Coastguard Worker   transaction.handler = server.GetHandlerCallback();
6274*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
6275*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6276*6777b538SAndroid Build Coastguard Worker                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6277*6777b538SAndroid Build Coastguard Worker                                  &load_timing_info);
6278*6777b538SAndroid Build Coastguard Worker 
6279*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(server.EtagUsed());
6280*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(server.LastModifiedUsed());
6281*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6282*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6283*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6284*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
6285*6777b538SAndroid Build Coastguard Worker }
6286*6777b538SAndroid Build Coastguard Worker 
6287*6777b538SAndroid Build Coastguard Worker // Tests lack of revalidation after a vary mismatch and no etag.
TEST_F(HttpCacheTest,GET_DontValidateCache_VaryMismatch)6288*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_DontValidateCache_VaryMismatch) {
6289*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6290*6777b538SAndroid Build Coastguard Worker 
6291*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
6292*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6293*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n";
6294*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
6295*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6296*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6297*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
6298*6777b538SAndroid Build Coastguard Worker       "Vary: Foo\n";
6299*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6300*6777b538SAndroid Build Coastguard Worker 
6301*6777b538SAndroid Build Coastguard Worker   // Read from the cache and don't revalidate the entry.
6302*6777b538SAndroid Build Coastguard Worker   RevalidationServer server;
6303*6777b538SAndroid Build Coastguard Worker   transaction.handler = server.GetHandlerCallback();
6304*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: none\r\n";
6305*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
6306*6777b538SAndroid Build Coastguard Worker   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6307*6777b538SAndroid Build Coastguard Worker                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6308*6777b538SAndroid Build Coastguard Worker                                  &load_timing_info);
6309*6777b538SAndroid Build Coastguard Worker 
6310*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(server.EtagUsed());
6311*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(server.LastModifiedUsed());
6312*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6313*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6314*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6315*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
6316*6777b538SAndroid Build Coastguard Worker }
6317*6777b538SAndroid Build Coastguard Worker 
6318*6777b538SAndroid Build Coastguard Worker // Tests that a new vary header provided when revalidating an entry is saved.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch_UpdateVary)6319*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch_UpdateVary) {
6320*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6321*6777b538SAndroid Build Coastguard Worker 
6322*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
6323*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6324*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
6325*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
6326*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n"
6327*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
6328*6777b538SAndroid Build Coastguard Worker       "Vary: Foo\n";
6329*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6330*6777b538SAndroid Build Coastguard Worker 
6331*6777b538SAndroid Build Coastguard Worker   // Validate the entry and change the vary field in the response.
6332*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n Name: none\r\n";
6333*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 304 Not Modified";
6334*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
6335*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n"
6336*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=3600\n"
6337*6777b538SAndroid Build Coastguard Worker       "Vary: Name\n";
6338*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6339*6777b538SAndroid Build Coastguard Worker 
6340*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6341*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6342*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6343*6777b538SAndroid Build Coastguard Worker 
6344*6777b538SAndroid Build Coastguard Worker   // Make sure that the ActiveEntry is gone.
6345*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
6346*6777b538SAndroid Build Coastguard Worker 
6347*6777b538SAndroid Build Coastguard Worker   // Generate a vary mismatch.
6348*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
6349*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6350*6777b538SAndroid Build Coastguard Worker 
6351*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6352*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
6353*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6354*6777b538SAndroid Build Coastguard Worker }
6355*6777b538SAndroid Build Coastguard Worker 
6356*6777b538SAndroid Build Coastguard Worker // Tests that new request headers causing a vary mismatch are paired with the
6357*6777b538SAndroid Build Coastguard Worker // new response when the server says the old response can be used.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch_UpdateRequestHeader)6358*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch_UpdateRequestHeader) {
6359*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6360*6777b538SAndroid Build Coastguard Worker 
6361*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
6362*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6363*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n";
6364*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
6365*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n"
6366*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=3600\n"
6367*6777b538SAndroid Build Coastguard Worker       "Vary: Foo\n";
6368*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6369*6777b538SAndroid Build Coastguard Worker 
6370*6777b538SAndroid Build Coastguard Worker   // Vary-mismatch validation receives 304.
6371*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: none\r\n";
6372*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 304 Not Modified";
6373*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6374*6777b538SAndroid Build Coastguard Worker 
6375*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6376*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6377*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6378*6777b538SAndroid Build Coastguard Worker 
6379*6777b538SAndroid Build Coastguard Worker   // Make sure that the ActiveEntry is gone.
6380*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
6381*6777b538SAndroid Build Coastguard Worker 
6382*6777b538SAndroid Build Coastguard Worker   // Generate a vary mismatch.
6383*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n";
6384*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6385*6777b538SAndroid Build Coastguard Worker 
6386*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6387*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
6388*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6389*6777b538SAndroid Build Coastguard Worker }
6390*6777b538SAndroid Build Coastguard Worker 
6391*6777b538SAndroid Build Coastguard Worker // Tests that a 304 without vary headers doesn't delete the previously stored
6392*6777b538SAndroid Build Coastguard Worker // vary data after a vary match revalidation.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch_DontDeleteVary)6393*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch_DontDeleteVary) {
6394*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6395*6777b538SAndroid Build Coastguard Worker 
6396*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
6397*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6398*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n";
6399*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
6400*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n"
6401*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
6402*6777b538SAndroid Build Coastguard Worker       "Vary: Foo\n";
6403*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6404*6777b538SAndroid Build Coastguard Worker 
6405*6777b538SAndroid Build Coastguard Worker   // Validate the entry and remove the vary field in the response.
6406*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 304 Not Modified";
6407*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
6408*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n"
6409*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=3600\n";
6410*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6411*6777b538SAndroid Build Coastguard Worker 
6412*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6413*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6414*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6415*6777b538SAndroid Build Coastguard Worker 
6416*6777b538SAndroid Build Coastguard Worker   // Make sure that the ActiveEntry is gone.
6417*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
6418*6777b538SAndroid Build Coastguard Worker 
6419*6777b538SAndroid Build Coastguard Worker   // Generate a vary mismatch.
6420*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: none\r\n";
6421*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6422*6777b538SAndroid Build Coastguard Worker 
6423*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6424*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
6425*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6426*6777b538SAndroid Build Coastguard Worker }
6427*6777b538SAndroid Build Coastguard Worker 
6428*6777b538SAndroid Build Coastguard Worker // Tests that a 304 without vary headers doesn't delete the previously stored
6429*6777b538SAndroid Build Coastguard Worker // vary data after a vary mismatch.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch_DontDeleteVary)6430*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch_DontDeleteVary) {
6431*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6432*6777b538SAndroid Build Coastguard Worker 
6433*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
6434*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6435*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n";
6436*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
6437*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n"
6438*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=3600\n"
6439*6777b538SAndroid Build Coastguard Worker       "Vary: Foo\n";
6440*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6441*6777b538SAndroid Build Coastguard Worker 
6442*6777b538SAndroid Build Coastguard Worker   // Vary-mismatch validation receives 304 and no vary header.
6443*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: none\r\n";
6444*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 304 Not Modified";
6445*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
6446*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n"
6447*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=3600\n";
6448*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6449*6777b538SAndroid Build Coastguard Worker 
6450*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6451*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6452*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6453*6777b538SAndroid Build Coastguard Worker 
6454*6777b538SAndroid Build Coastguard Worker   // Make sure that the ActiveEntry is gone.
6455*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
6456*6777b538SAndroid Build Coastguard Worker 
6457*6777b538SAndroid Build Coastguard Worker   // Generate a vary mismatch.
6458*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n";
6459*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6460*6777b538SAndroid Build Coastguard Worker 
6461*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6462*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
6463*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6464*6777b538SAndroid Build Coastguard Worker }
6465*6777b538SAndroid Build Coastguard Worker 
ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)6466*6777b538SAndroid Build Coastguard Worker static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo* request,
6467*6777b538SAndroid Build Coastguard Worker                                                  std::string* response_status,
6468*6777b538SAndroid Build Coastguard Worker                                                  std::string* response_headers,
6469*6777b538SAndroid Build Coastguard Worker                                                  std::string* response_data) {
6470*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
6471*6777b538SAndroid Build Coastguard Worker       request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6472*6777b538SAndroid Build Coastguard Worker }
6473*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,ETagGET_Http10)6474*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ETagGET_Http10) {
6475*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6476*6777b538SAndroid Build Coastguard Worker 
6477*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kETagGET_Transaction);
6478*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.0 200 OK";
6479*6777b538SAndroid Build Coastguard Worker 
6480*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
6481*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6482*6777b538SAndroid Build Coastguard Worker 
6483*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6484*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
6485*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6486*6777b538SAndroid Build Coastguard Worker 
6487*6777b538SAndroid Build Coastguard Worker   // Get the same URL again, without generating a conditional request.
6488*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_VALIDATE_CACHE;
6489*6777b538SAndroid Build Coastguard Worker   transaction.handler =
6490*6777b538SAndroid Build Coastguard Worker       base::BindRepeating(&ETagGet_UnconditionalRequest_Handler);
6491*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6492*6777b538SAndroid Build Coastguard Worker 
6493*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6494*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6495*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6496*6777b538SAndroid Build Coastguard Worker }
6497*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,ETagGET_Http10_Range)6498*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ETagGET_Http10_Range) {
6499*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6500*6777b538SAndroid Build Coastguard Worker 
6501*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kETagGET_Transaction);
6502*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.0 200 OK";
6503*6777b538SAndroid Build Coastguard Worker 
6504*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
6505*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6506*6777b538SAndroid Build Coastguard Worker 
6507*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6508*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
6509*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6510*6777b538SAndroid Build Coastguard Worker 
6511*6777b538SAndroid Build Coastguard Worker   // Get the same URL again, but use a byte range request.
6512*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_VALIDATE_CACHE;
6513*6777b538SAndroid Build Coastguard Worker   transaction.handler =
6514*6777b538SAndroid Build Coastguard Worker       base::BindRepeating(&ETagGet_UnconditionalRequest_Handler);
6515*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 5-\r\n";
6516*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6517*6777b538SAndroid Build Coastguard Worker 
6518*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6519*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6520*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
6521*6777b538SAndroid Build Coastguard Worker }
6522*6777b538SAndroid Build Coastguard Worker 
ETagGet_ConditionalRequest_NoStore_Handler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)6523*6777b538SAndroid Build Coastguard Worker static void ETagGet_ConditionalRequest_NoStore_Handler(
6524*6777b538SAndroid Build Coastguard Worker     const HttpRequestInfo* request,
6525*6777b538SAndroid Build Coastguard Worker     std::string* response_status,
6526*6777b538SAndroid Build Coastguard Worker     std::string* response_headers,
6527*6777b538SAndroid Build Coastguard Worker     std::string* response_data) {
6528*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
6529*6777b538SAndroid Build Coastguard Worker       request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6530*6777b538SAndroid Build Coastguard Worker   response_status->assign("HTTP/1.1 304 Not Modified");
6531*6777b538SAndroid Build Coastguard Worker   response_headers->assign("Cache-Control: no-store\n");
6532*6777b538SAndroid Build Coastguard Worker   response_data->clear();
6533*6777b538SAndroid Build Coastguard Worker }
6534*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,ETagGET_ConditionalRequest_304_NoStore)6535*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ETagGET_ConditionalRequest_304_NoStore) {
6536*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6537*6777b538SAndroid Build Coastguard Worker 
6538*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kETagGET_Transaction);
6539*6777b538SAndroid Build Coastguard Worker 
6540*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
6541*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6542*6777b538SAndroid Build Coastguard Worker 
6543*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6544*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
6545*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6546*6777b538SAndroid Build Coastguard Worker 
6547*6777b538SAndroid Build Coastguard Worker   // Get the same URL again, but this time we expect it to result
6548*6777b538SAndroid Build Coastguard Worker   // in a conditional request.
6549*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_VALIDATE_CACHE;
6550*6777b538SAndroid Build Coastguard Worker   transaction.handler =
6551*6777b538SAndroid Build Coastguard Worker       base::BindRepeating(&ETagGet_ConditionalRequest_NoStore_Handler);
6552*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6553*6777b538SAndroid Build Coastguard Worker 
6554*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6555*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6556*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6557*6777b538SAndroid Build Coastguard Worker 
6558*6777b538SAndroid Build Coastguard Worker   // Reset transaction
6559*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = kETagGET_Transaction.load_flags;
6560*6777b538SAndroid Build Coastguard Worker   transaction.handler = kETagGET_Transaction.handler;
6561*6777b538SAndroid Build Coastguard Worker 
6562*6777b538SAndroid Build Coastguard Worker   // Write to the cache again. This should create a new entry.
6563*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
6564*6777b538SAndroid Build Coastguard Worker 
6565*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6566*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6567*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
6568*6777b538SAndroid Build Coastguard Worker }
6569*6777b538SAndroid Build Coastguard Worker 
6570*6777b538SAndroid Build Coastguard Worker // Helper that does 4 requests using HttpCache:
6571*6777b538SAndroid Build Coastguard Worker //
6572*6777b538SAndroid Build Coastguard Worker // (1) loads |kUrl| -- expects |net_response_1| to be returned.
6573*6777b538SAndroid Build Coastguard Worker // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
6574*6777b538SAndroid Build Coastguard Worker // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
6575*6777b538SAndroid Build Coastguard Worker //     be returned.
6576*6777b538SAndroid Build Coastguard Worker // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
6577*6777b538SAndroid Build Coastguard Worker //     returned.
6578*6777b538SAndroid Build Coastguard Worker // The entry will be created once and will be opened for the 3 subsequent
6579*6777b538SAndroid Build Coastguard Worker // requests.
ConditionalizedRequestUpdatesCacheHelper(const Response & net_response_1,const Response & net_response_2,const Response & cached_response_2,const char * extra_request_headers)6580*6777b538SAndroid Build Coastguard Worker static void ConditionalizedRequestUpdatesCacheHelper(
6581*6777b538SAndroid Build Coastguard Worker     const Response& net_response_1,
6582*6777b538SAndroid Build Coastguard Worker     const Response& net_response_2,
6583*6777b538SAndroid Build Coastguard Worker     const Response& cached_response_2,
6584*6777b538SAndroid Build Coastguard Worker     const char* extra_request_headers) {
6585*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6586*6777b538SAndroid Build Coastguard Worker 
6587*6777b538SAndroid Build Coastguard Worker   // The URL we will be requesting.
6588*6777b538SAndroid Build Coastguard Worker   const char kUrl[] = "http://foobar.com/main.css";
6589*6777b538SAndroid Build Coastguard Worker 
6590*6777b538SAndroid Build Coastguard Worker   // Junk network response.
6591*6777b538SAndroid Build Coastguard Worker   static const Response kUnexpectedResponse = {"HTTP/1.1 500 Unexpected",
6592*6777b538SAndroid Build Coastguard Worker                                                "Server: unexpected_header",
6593*6777b538SAndroid Build Coastguard Worker                                                "unexpected body"};
6594*6777b538SAndroid Build Coastguard Worker 
6595*6777b538SAndroid Build Coastguard Worker   // We will control the network layer's responses for |kUrl| using
6596*6777b538SAndroid Build Coastguard Worker   // |mock_network_response|.
6597*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_network_response(kUrl);
6598*6777b538SAndroid Build Coastguard Worker 
6599*6777b538SAndroid Build Coastguard Worker   // Request |kUrl| for the first time. It should hit the network and
6600*6777b538SAndroid Build Coastguard Worker   // receive |kNetResponse1|, which it saves into the HTTP cache.
6601*6777b538SAndroid Build Coastguard Worker 
6602*6777b538SAndroid Build Coastguard Worker   MockTransaction request = {nullptr};
6603*6777b538SAndroid Build Coastguard Worker   request.url = kUrl;
6604*6777b538SAndroid Build Coastguard Worker   request.method = "GET";
6605*6777b538SAndroid Build Coastguard Worker   request.request_headers = "";
6606*6777b538SAndroid Build Coastguard Worker 
6607*6777b538SAndroid Build Coastguard Worker   net_response_1.AssignTo(&mock_network_response);  // Network mock.
6608*6777b538SAndroid Build Coastguard Worker   net_response_1.AssignTo(&request);                // Expected result.
6609*6777b538SAndroid Build Coastguard Worker 
6610*6777b538SAndroid Build Coastguard Worker   std::string response_headers;
6611*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), request,
6612*6777b538SAndroid Build Coastguard Worker                                  &response_headers);
6613*6777b538SAndroid Build Coastguard Worker 
6614*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
6615*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6616*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
6617*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6618*6777b538SAndroid Build Coastguard Worker 
6619*6777b538SAndroid Build Coastguard Worker   // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
6620*6777b538SAndroid Build Coastguard Worker   // cache, so we don't hit the network.
6621*6777b538SAndroid Build Coastguard Worker 
6622*6777b538SAndroid Build Coastguard Worker   request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
6623*6777b538SAndroid Build Coastguard Worker 
6624*6777b538SAndroid Build Coastguard Worker   kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
6625*6777b538SAndroid Build Coastguard Worker   net_response_1.AssignTo(&request);                     // Expected result.
6626*6777b538SAndroid Build Coastguard Worker 
6627*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), request,
6628*6777b538SAndroid Build Coastguard Worker                                  &response_headers);
6629*6777b538SAndroid Build Coastguard Worker 
6630*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
6631*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6632*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6633*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6634*6777b538SAndroid Build Coastguard Worker 
6635*6777b538SAndroid Build Coastguard Worker   // Request |kUrl| yet again, but this time give the request an
6636*6777b538SAndroid Build Coastguard Worker   // "If-Modified-Since" header. This will cause the request to re-hit the
6637*6777b538SAndroid Build Coastguard Worker   // network. However now the network response is going to be
6638*6777b538SAndroid Build Coastguard Worker   // different -- this simulates a change made to the CSS file.
6639*6777b538SAndroid Build Coastguard Worker 
6640*6777b538SAndroid Build Coastguard Worker   request.request_headers = extra_request_headers;
6641*6777b538SAndroid Build Coastguard Worker   request.load_flags = LOAD_NORMAL;
6642*6777b538SAndroid Build Coastguard Worker 
6643*6777b538SAndroid Build Coastguard Worker   net_response_2.AssignTo(&mock_network_response);  // Network mock.
6644*6777b538SAndroid Build Coastguard Worker   net_response_2.AssignTo(&request);                // Expected result.
6645*6777b538SAndroid Build Coastguard Worker 
6646*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), request,
6647*6777b538SAndroid Build Coastguard Worker                                  &response_headers);
6648*6777b538SAndroid Build Coastguard Worker 
6649*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
6650*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6651*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6652*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6653*6777b538SAndroid Build Coastguard Worker 
6654*6777b538SAndroid Build Coastguard Worker   // Finally, request |kUrl| again. This request should be serviced from
6655*6777b538SAndroid Build Coastguard Worker   // the cache. Moreover, the value in the cache should be |kNetResponse2|
6656*6777b538SAndroid Build Coastguard Worker   // and NOT |kNetResponse1|. The previous step should have replaced the
6657*6777b538SAndroid Build Coastguard Worker   // value in the cache with the modified response.
6658*6777b538SAndroid Build Coastguard Worker 
6659*6777b538SAndroid Build Coastguard Worker   request.request_headers = "";
6660*6777b538SAndroid Build Coastguard Worker   request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
6661*6777b538SAndroid Build Coastguard Worker 
6662*6777b538SAndroid Build Coastguard Worker   kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
6663*6777b538SAndroid Build Coastguard Worker   cached_response_2.AssignTo(&request);                  // Expected result.
6664*6777b538SAndroid Build Coastguard Worker 
6665*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), request,
6666*6777b538SAndroid Build Coastguard Worker                                  &response_headers);
6667*6777b538SAndroid Build Coastguard Worker 
6668*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
6669*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6670*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
6671*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6672*6777b538SAndroid Build Coastguard Worker }
6673*6777b538SAndroid Build Coastguard Worker 
6674*6777b538SAndroid Build Coastguard Worker // Check that when an "if-modified-since" header is attached
6675*6777b538SAndroid Build Coastguard Worker // to the request, the result still updates the cached entry.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache1)6676*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache1) {
6677*6777b538SAndroid Build Coastguard Worker   // First network response for |kUrl|.
6678*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse1 = {
6679*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6680*6777b538SAndroid Build Coastguard Worker       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6681*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6682*6777b538SAndroid Build Coastguard Worker       "body1"};
6683*6777b538SAndroid Build Coastguard Worker 
6684*6777b538SAndroid Build Coastguard Worker   // Second network response for |kUrl|.
6685*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse2 = {
6686*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6687*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6688*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6689*6777b538SAndroid Build Coastguard Worker       "body2"};
6690*6777b538SAndroid Build Coastguard Worker 
6691*6777b538SAndroid Build Coastguard Worker   const char extra_headers[] =
6692*6777b538SAndroid Build Coastguard Worker       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6693*6777b538SAndroid Build Coastguard Worker 
6694*6777b538SAndroid Build Coastguard Worker   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6695*6777b538SAndroid Build Coastguard Worker                                            kNetResponse2, extra_headers);
6696*6777b538SAndroid Build Coastguard Worker }
6697*6777b538SAndroid Build Coastguard Worker 
6698*6777b538SAndroid Build Coastguard Worker // Check that when an "if-none-match" header is attached
6699*6777b538SAndroid Build Coastguard Worker // to the request, the result updates the cached entry.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache2)6700*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache2) {
6701*6777b538SAndroid Build Coastguard Worker   // First network response for |kUrl|.
6702*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse1 = {
6703*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6704*6777b538SAndroid Build Coastguard Worker       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6705*6777b538SAndroid Build Coastguard Worker       "Etag: \"ETAG1\"\n"
6706*6777b538SAndroid Build Coastguard Worker       "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
6707*6777b538SAndroid Build Coastguard Worker       "body1"};
6708*6777b538SAndroid Build Coastguard Worker 
6709*6777b538SAndroid Build Coastguard Worker   // Second network response for |kUrl|.
6710*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse2 = {
6711*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6712*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6713*6777b538SAndroid Build Coastguard Worker       "Etag: \"ETAG2\"\n"
6714*6777b538SAndroid Build Coastguard Worker       "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
6715*6777b538SAndroid Build Coastguard Worker       "body2"};
6716*6777b538SAndroid Build Coastguard Worker 
6717*6777b538SAndroid Build Coastguard Worker   const char extra_headers[] = "If-None-Match: \"ETAG1\"\r\n";
6718*6777b538SAndroid Build Coastguard Worker 
6719*6777b538SAndroid Build Coastguard Worker   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6720*6777b538SAndroid Build Coastguard Worker                                            kNetResponse2, extra_headers);
6721*6777b538SAndroid Build Coastguard Worker }
6722*6777b538SAndroid Build Coastguard Worker 
6723*6777b538SAndroid Build Coastguard Worker // Check that when an "if-modified-since" header is attached
6724*6777b538SAndroid Build Coastguard Worker // to a request, the 304 (not modified result) result updates the cached
6725*6777b538SAndroid Build Coastguard Worker // headers, and the 304 response is returned rather than the cached response.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache3)6726*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache3) {
6727*6777b538SAndroid Build Coastguard Worker   // First network response for |kUrl|.
6728*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse1 = {
6729*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6730*6777b538SAndroid Build Coastguard Worker       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6731*6777b538SAndroid Build Coastguard Worker       "Server: server1\n"
6732*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6733*6777b538SAndroid Build Coastguard Worker       "body1"};
6734*6777b538SAndroid Build Coastguard Worker 
6735*6777b538SAndroid Build Coastguard Worker   // Second network response for |kUrl|.
6736*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse2 = {
6737*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 304 Not Modified",
6738*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6739*6777b538SAndroid Build Coastguard Worker       "Server: server2\n"
6740*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6741*6777b538SAndroid Build Coastguard Worker       ""};
6742*6777b538SAndroid Build Coastguard Worker 
6743*6777b538SAndroid Build Coastguard Worker   static const Response kCachedResponse2 = {
6744*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6745*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6746*6777b538SAndroid Build Coastguard Worker       "Server: server2\n"
6747*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6748*6777b538SAndroid Build Coastguard Worker       "body1"};
6749*6777b538SAndroid Build Coastguard Worker 
6750*6777b538SAndroid Build Coastguard Worker   const char extra_headers[] =
6751*6777b538SAndroid Build Coastguard Worker       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6752*6777b538SAndroid Build Coastguard Worker 
6753*6777b538SAndroid Build Coastguard Worker   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6754*6777b538SAndroid Build Coastguard Worker                                            kCachedResponse2, extra_headers);
6755*6777b538SAndroid Build Coastguard Worker }
6756*6777b538SAndroid Build Coastguard Worker 
6757*6777b538SAndroid Build Coastguard Worker // Test that when doing an externally conditionalized if-modified-since
6758*6777b538SAndroid Build Coastguard Worker // and there is no corresponding cache entry, a new cache entry is NOT
6759*6777b538SAndroid Build Coastguard Worker // created (304 response).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache4)6760*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache4) {
6761*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6762*6777b538SAndroid Build Coastguard Worker 
6763*6777b538SAndroid Build Coastguard Worker   const char kUrl[] = "http://foobar.com/main.css";
6764*6777b538SAndroid Build Coastguard Worker 
6765*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse = {
6766*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 304 Not Modified",
6767*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6768*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6769*6777b538SAndroid Build Coastguard Worker       ""};
6770*6777b538SAndroid Build Coastguard Worker 
6771*6777b538SAndroid Build Coastguard Worker   const char kExtraRequestHeaders[] =
6772*6777b538SAndroid Build Coastguard Worker       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6773*6777b538SAndroid Build Coastguard Worker 
6774*6777b538SAndroid Build Coastguard Worker   // We will control the network layer's responses for |kUrl| using
6775*6777b538SAndroid Build Coastguard Worker   // |mock_network_response|.
6776*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_network_response(kUrl);
6777*6777b538SAndroid Build Coastguard Worker 
6778*6777b538SAndroid Build Coastguard Worker   MockTransaction request = {nullptr};
6779*6777b538SAndroid Build Coastguard Worker   request.url = kUrl;
6780*6777b538SAndroid Build Coastguard Worker   request.method = "GET";
6781*6777b538SAndroid Build Coastguard Worker   request.request_headers = kExtraRequestHeaders;
6782*6777b538SAndroid Build Coastguard Worker 
6783*6777b538SAndroid Build Coastguard Worker   kNetResponse.AssignTo(&mock_network_response);  // Network mock.
6784*6777b538SAndroid Build Coastguard Worker   kNetResponse.AssignTo(&request);                // Expected result.
6785*6777b538SAndroid Build Coastguard Worker 
6786*6777b538SAndroid Build Coastguard Worker   std::string response_headers;
6787*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), request,
6788*6777b538SAndroid Build Coastguard Worker                                  &response_headers);
6789*6777b538SAndroid Build Coastguard Worker 
6790*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
6791*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6792*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
6793*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
6794*6777b538SAndroid Build Coastguard Worker }
6795*6777b538SAndroid Build Coastguard Worker 
6796*6777b538SAndroid Build Coastguard Worker // Test that when doing an externally conditionalized if-modified-since
6797*6777b538SAndroid Build Coastguard Worker // and there is no corresponding cache entry, a new cache entry is NOT
6798*6777b538SAndroid Build Coastguard Worker // created (200 response).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache5)6799*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache5) {
6800*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6801*6777b538SAndroid Build Coastguard Worker 
6802*6777b538SAndroid Build Coastguard Worker   const char kUrl[] = "http://foobar.com/main.css";
6803*6777b538SAndroid Build Coastguard Worker 
6804*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse = {
6805*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6806*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6807*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6808*6777b538SAndroid Build Coastguard Worker       "foobar!!!"};
6809*6777b538SAndroid Build Coastguard Worker 
6810*6777b538SAndroid Build Coastguard Worker   const char kExtraRequestHeaders[] =
6811*6777b538SAndroid Build Coastguard Worker       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6812*6777b538SAndroid Build Coastguard Worker 
6813*6777b538SAndroid Build Coastguard Worker   // We will control the network layer's responses for |kUrl| using
6814*6777b538SAndroid Build Coastguard Worker   // |mock_network_response|.
6815*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_network_response(kUrl);
6816*6777b538SAndroid Build Coastguard Worker 
6817*6777b538SAndroid Build Coastguard Worker   MockTransaction request = {nullptr};
6818*6777b538SAndroid Build Coastguard Worker   request.url = kUrl;
6819*6777b538SAndroid Build Coastguard Worker   request.method = "GET";
6820*6777b538SAndroid Build Coastguard Worker   request.request_headers = kExtraRequestHeaders;
6821*6777b538SAndroid Build Coastguard Worker 
6822*6777b538SAndroid Build Coastguard Worker   kNetResponse.AssignTo(&mock_network_response);  // Network mock.
6823*6777b538SAndroid Build Coastguard Worker   kNetResponse.AssignTo(&request);                // Expected result.
6824*6777b538SAndroid Build Coastguard Worker 
6825*6777b538SAndroid Build Coastguard Worker   std::string response_headers;
6826*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), request,
6827*6777b538SAndroid Build Coastguard Worker                                  &response_headers);
6828*6777b538SAndroid Build Coastguard Worker 
6829*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
6830*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6831*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
6832*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
6833*6777b538SAndroid Build Coastguard Worker }
6834*6777b538SAndroid Build Coastguard Worker 
6835*6777b538SAndroid Build Coastguard Worker // Test that when doing an externally conditionalized if-modified-since
6836*6777b538SAndroid Build Coastguard Worker // if the date does not match the cache entry's last-modified date,
6837*6777b538SAndroid Build Coastguard Worker // then we do NOT use the response (304) to update the cache.
6838*6777b538SAndroid Build Coastguard Worker // (the if-modified-since date is 2 days AFTER the cache's modification date).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache6)6839*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache6) {
6840*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse1 = {
6841*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6842*6777b538SAndroid Build Coastguard Worker       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6843*6777b538SAndroid Build Coastguard Worker       "Server: server1\n"
6844*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6845*6777b538SAndroid Build Coastguard Worker       "body1"};
6846*6777b538SAndroid Build Coastguard Worker 
6847*6777b538SAndroid Build Coastguard Worker   // Second network response for |kUrl|.
6848*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse2 = {
6849*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 304 Not Modified",
6850*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6851*6777b538SAndroid Build Coastguard Worker       "Server: server2\n"
6852*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6853*6777b538SAndroid Build Coastguard Worker       ""};
6854*6777b538SAndroid Build Coastguard Worker 
6855*6777b538SAndroid Build Coastguard Worker   // This is two days in the future from the original response's last-modified
6856*6777b538SAndroid Build Coastguard Worker   // date!
6857*6777b538SAndroid Build Coastguard Worker   const char kExtraRequestHeaders[] =
6858*6777b538SAndroid Build Coastguard Worker       "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
6859*6777b538SAndroid Build Coastguard Worker 
6860*6777b538SAndroid Build Coastguard Worker   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6861*6777b538SAndroid Build Coastguard Worker                                            kNetResponse1, kExtraRequestHeaders);
6862*6777b538SAndroid Build Coastguard Worker }
6863*6777b538SAndroid Build Coastguard Worker 
6864*6777b538SAndroid Build Coastguard Worker // Test that when doing an externally conditionalized if-none-match
6865*6777b538SAndroid Build Coastguard Worker // if the etag does not match the cache entry's etag, then we do not use the
6866*6777b538SAndroid Build Coastguard Worker // response (304) to update the cache.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache7)6867*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache7) {
6868*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse1 = {
6869*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6870*6777b538SAndroid Build Coastguard Worker       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6871*6777b538SAndroid Build Coastguard Worker       "Etag: \"Foo1\"\n"
6872*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6873*6777b538SAndroid Build Coastguard Worker       "body1"};
6874*6777b538SAndroid Build Coastguard Worker 
6875*6777b538SAndroid Build Coastguard Worker   // Second network response for |kUrl|.
6876*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse2 = {
6877*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 304 Not Modified",
6878*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6879*6777b538SAndroid Build Coastguard Worker       "Etag: \"Foo2\"\n"
6880*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6881*6777b538SAndroid Build Coastguard Worker       ""};
6882*6777b538SAndroid Build Coastguard Worker 
6883*6777b538SAndroid Build Coastguard Worker   // Different etag from original response.
6884*6777b538SAndroid Build Coastguard Worker   const char kExtraRequestHeaders[] = "If-None-Match: \"Foo2\"\r\n";
6885*6777b538SAndroid Build Coastguard Worker 
6886*6777b538SAndroid Build Coastguard Worker   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6887*6777b538SAndroid Build Coastguard Worker                                            kNetResponse1, kExtraRequestHeaders);
6888*6777b538SAndroid Build Coastguard Worker }
6889*6777b538SAndroid Build Coastguard Worker 
6890*6777b538SAndroid Build Coastguard Worker // Test that doing an externally conditionalized request with both if-none-match
6891*6777b538SAndroid Build Coastguard Worker // and if-modified-since updates the cache.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache8)6892*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache8) {
6893*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse1 = {
6894*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6895*6777b538SAndroid Build Coastguard Worker       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6896*6777b538SAndroid Build Coastguard Worker       "Etag: \"Foo1\"\n"
6897*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6898*6777b538SAndroid Build Coastguard Worker       "body1"};
6899*6777b538SAndroid Build Coastguard Worker 
6900*6777b538SAndroid Build Coastguard Worker   // Second network response for |kUrl|.
6901*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse2 = {
6902*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6903*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6904*6777b538SAndroid Build Coastguard Worker       "Etag: \"Foo2\"\n"
6905*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6906*6777b538SAndroid Build Coastguard Worker       "body2"};
6907*6777b538SAndroid Build Coastguard Worker 
6908*6777b538SAndroid Build Coastguard Worker   const char kExtraRequestHeaders[] =
6909*6777b538SAndroid Build Coastguard Worker       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
6910*6777b538SAndroid Build Coastguard Worker       "If-None-Match: \"Foo1\"\r\n";
6911*6777b538SAndroid Build Coastguard Worker 
6912*6777b538SAndroid Build Coastguard Worker   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6913*6777b538SAndroid Build Coastguard Worker                                            kNetResponse2, kExtraRequestHeaders);
6914*6777b538SAndroid Build Coastguard Worker }
6915*6777b538SAndroid Build Coastguard Worker 
6916*6777b538SAndroid Build Coastguard Worker // Test that doing an externally conditionalized request with both if-none-match
6917*6777b538SAndroid Build Coastguard Worker // and if-modified-since does not update the cache with only one match.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache9)6918*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache9) {
6919*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse1 = {
6920*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6921*6777b538SAndroid Build Coastguard Worker       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6922*6777b538SAndroid Build Coastguard Worker       "Etag: \"Foo1\"\n"
6923*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6924*6777b538SAndroid Build Coastguard Worker       "body1"};
6925*6777b538SAndroid Build Coastguard Worker 
6926*6777b538SAndroid Build Coastguard Worker   // Second network response for |kUrl|.
6927*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse2 = {
6928*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6929*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6930*6777b538SAndroid Build Coastguard Worker       "Etag: \"Foo2\"\n"
6931*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6932*6777b538SAndroid Build Coastguard Worker       "body2"};
6933*6777b538SAndroid Build Coastguard Worker 
6934*6777b538SAndroid Build Coastguard Worker   // The etag doesn't match what we have stored.
6935*6777b538SAndroid Build Coastguard Worker   const char kExtraRequestHeaders[] =
6936*6777b538SAndroid Build Coastguard Worker       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
6937*6777b538SAndroid Build Coastguard Worker       "If-None-Match: \"Foo2\"\r\n";
6938*6777b538SAndroid Build Coastguard Worker 
6939*6777b538SAndroid Build Coastguard Worker   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6940*6777b538SAndroid Build Coastguard Worker                                            kNetResponse1, kExtraRequestHeaders);
6941*6777b538SAndroid Build Coastguard Worker }
6942*6777b538SAndroid Build Coastguard Worker 
6943*6777b538SAndroid Build Coastguard Worker // Test that doing an externally conditionalized request with both if-none-match
6944*6777b538SAndroid Build Coastguard Worker // and if-modified-since does not update the cache with only one match.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache10)6945*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache10) {
6946*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse1 = {
6947*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6948*6777b538SAndroid Build Coastguard Worker       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6949*6777b538SAndroid Build Coastguard Worker       "Etag: \"Foo1\"\n"
6950*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6951*6777b538SAndroid Build Coastguard Worker       "body1"};
6952*6777b538SAndroid Build Coastguard Worker 
6953*6777b538SAndroid Build Coastguard Worker   // Second network response for |kUrl|.
6954*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse2 = {
6955*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
6956*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6957*6777b538SAndroid Build Coastguard Worker       "Etag: \"Foo2\"\n"
6958*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6959*6777b538SAndroid Build Coastguard Worker       "body2"};
6960*6777b538SAndroid Build Coastguard Worker 
6961*6777b538SAndroid Build Coastguard Worker   // The modification date doesn't match what we have stored.
6962*6777b538SAndroid Build Coastguard Worker   const char kExtraRequestHeaders[] =
6963*6777b538SAndroid Build Coastguard Worker       "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
6964*6777b538SAndroid Build Coastguard Worker       "If-None-Match: \"Foo1\"\r\n";
6965*6777b538SAndroid Build Coastguard Worker 
6966*6777b538SAndroid Build Coastguard Worker   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6967*6777b538SAndroid Build Coastguard Worker                                            kNetResponse1, kExtraRequestHeaders);
6968*6777b538SAndroid Build Coastguard Worker }
6969*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,UrlContainingHash)6970*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, UrlContainingHash) {
6971*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6972*6777b538SAndroid Build Coastguard Worker 
6973*6777b538SAndroid Build Coastguard Worker   // Do a typical GET request -- should write an entry into our cache.
6974*6777b538SAndroid Build Coastguard Worker   MockTransaction trans(kTypicalGET_Transaction);
6975*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), trans);
6976*6777b538SAndroid Build Coastguard Worker 
6977*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6978*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
6979*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6980*6777b538SAndroid Build Coastguard Worker 
6981*6777b538SAndroid Build Coastguard Worker   // Request the same URL, but this time with a reference section (hash).
6982*6777b538SAndroid Build Coastguard Worker   // Since the cache key strips the hash sections, this should be a cache hit.
6983*6777b538SAndroid Build Coastguard Worker   std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
6984*6777b538SAndroid Build Coastguard Worker   trans.url = url_with_hash.c_str();
6985*6777b538SAndroid Build Coastguard Worker   trans.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
6986*6777b538SAndroid Build Coastguard Worker 
6987*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), trans);
6988*6777b538SAndroid Build Coastguard Worker 
6989*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6990*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
6991*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
6992*6777b538SAndroid Build Coastguard Worker }
6993*6777b538SAndroid Build Coastguard Worker 
6994*6777b538SAndroid Build Coastguard Worker // Tests that we skip the cache for POST requests that do not have an upload
6995*6777b538SAndroid Build Coastguard Worker // identifier.
TEST_F(HttpCacheTest,SimplePOST_SkipsCache)6996*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePOST_SkipsCache) {
6997*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
6998*6777b538SAndroid Build Coastguard Worker 
6999*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
7000*6777b538SAndroid Build Coastguard Worker 
7001*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7002*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7003*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
7004*6777b538SAndroid Build Coastguard Worker }
7005*6777b538SAndroid Build Coastguard Worker 
7006*6777b538SAndroid Build Coastguard Worker // Tests POST handling with a disabled cache (no DCHECK).
TEST_F(HttpCacheTest,SimplePOST_DisabledCache)7007*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePOST_DisabledCache) {
7008*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7009*6777b538SAndroid Build Coastguard Worker   cache.http_cache()->set_mode(HttpCache::Mode::DISABLE);
7010*6777b538SAndroid Build Coastguard Worker 
7011*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
7012*6777b538SAndroid Build Coastguard Worker 
7013*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7014*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7015*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
7016*6777b538SAndroid Build Coastguard Worker }
7017*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimplePOST_LoadOnlyFromCache_Miss)7018*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePOST_LoadOnlyFromCache_Miss) {
7019*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7020*6777b538SAndroid Build Coastguard Worker 
7021*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimplePOST_Transaction);
7022*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7023*6777b538SAndroid Build Coastguard Worker 
7024*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
7025*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
7026*6777b538SAndroid Build Coastguard Worker 
7027*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
7028*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7029*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(trans.get());
7030*6777b538SAndroid Build Coastguard Worker 
7031*6777b538SAndroid Build Coastguard Worker   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7032*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(callback.GetResult(rv), IsError(ERR_CACHE_MISS));
7033*6777b538SAndroid Build Coastguard Worker 
7034*6777b538SAndroid Build Coastguard Worker   trans.reset();
7035*6777b538SAndroid Build Coastguard Worker 
7036*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7037*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7038*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
7039*6777b538SAndroid Build Coastguard Worker }
7040*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimplePOST_LoadOnlyFromCache_Hit)7041*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePOST_LoadOnlyFromCache_Hit) {
7042*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7043*6777b538SAndroid Build Coastguard Worker 
7044*6777b538SAndroid Build Coastguard Worker   // Test that we hit the cache for POST requests.
7045*6777b538SAndroid Build Coastguard Worker 
7046*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimplePOST_Transaction);
7047*6777b538SAndroid Build Coastguard Worker 
7048*6777b538SAndroid Build Coastguard Worker   const int64_t kUploadId = 1;  // Just a dummy value.
7049*6777b538SAndroid Build Coastguard Worker 
7050*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7051*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7052*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7053*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
7054*6777b538SAndroid Build Coastguard Worker                                               kUploadId);
7055*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
7056*6777b538SAndroid Build Coastguard Worker   request.upload_data_stream = &upload_data_stream;
7057*6777b538SAndroid Build Coastguard Worker 
7058*6777b538SAndroid Build Coastguard Worker   // Populate the cache.
7059*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7060*6777b538SAndroid Build Coastguard Worker                                 nullptr);
7061*6777b538SAndroid Build Coastguard Worker 
7062*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7063*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7064*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7065*6777b538SAndroid Build Coastguard Worker 
7066*6777b538SAndroid Build Coastguard Worker   // Load from cache.
7067*6777b538SAndroid Build Coastguard Worker   request.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7068*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7069*6777b538SAndroid Build Coastguard Worker                                 nullptr);
7070*6777b538SAndroid Build Coastguard Worker 
7071*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7072*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7073*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7074*6777b538SAndroid Build Coastguard Worker }
7075*6777b538SAndroid Build Coastguard Worker 
7076*6777b538SAndroid Build Coastguard Worker // Test that we don't hit the cache for POST requests if there is a byte range.
TEST_F(HttpCacheTest,SimplePOST_WithRanges)7077*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePOST_WithRanges) {
7078*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7079*6777b538SAndroid Build Coastguard Worker 
7080*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimplePOST_Transaction);
7081*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 0-4\r\n";
7082*6777b538SAndroid Build Coastguard Worker 
7083*6777b538SAndroid Build Coastguard Worker   const int64_t kUploadId = 1;  // Just a dummy value.
7084*6777b538SAndroid Build Coastguard Worker 
7085*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7086*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7087*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7088*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
7089*6777b538SAndroid Build Coastguard Worker                                               kUploadId);
7090*6777b538SAndroid Build Coastguard Worker 
7091*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
7092*6777b538SAndroid Build Coastguard Worker   request.upload_data_stream = &upload_data_stream;
7093*6777b538SAndroid Build Coastguard Worker 
7094*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7095*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7096*6777b538SAndroid Build Coastguard Worker                                 nullptr);
7097*6777b538SAndroid Build Coastguard Worker 
7098*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7099*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7100*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
7101*6777b538SAndroid Build Coastguard Worker }
7102*6777b538SAndroid Build Coastguard Worker 
7103*6777b538SAndroid Build Coastguard Worker // Tests that a POST is cached separately from a GET.
TEST_F(HttpCacheTest,SimplePOST_SeparateCache)7104*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePOST_SeparateCache) {
7105*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7106*6777b538SAndroid Build Coastguard Worker 
7107*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7108*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7109*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7110*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7111*6777b538SAndroid Build Coastguard Worker 
7112*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimplePOST_Transaction);
7113*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req1(transaction);
7114*6777b538SAndroid Build Coastguard Worker   req1.upload_data_stream = &upload_data_stream;
7115*6777b538SAndroid Build Coastguard Worker 
7116*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7117*6777b538SAndroid Build Coastguard Worker 
7118*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7119*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7120*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7121*6777b538SAndroid Build Coastguard Worker 
7122*6777b538SAndroid Build Coastguard Worker   transaction.method = "GET";
7123*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req2(transaction);
7124*6777b538SAndroid Build Coastguard Worker 
7125*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7126*6777b538SAndroid Build Coastguard Worker 
7127*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7128*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7129*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7130*6777b538SAndroid Build Coastguard Worker }
7131*6777b538SAndroid Build Coastguard Worker 
7132*6777b538SAndroid Build Coastguard Worker // Tests that a successful POST invalidates a previously cached GET.
TEST_F(HttpCacheTest,SimplePOST_Invalidate_205)7133*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePOST_Invalidate_205) {
7134*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7135*6777b538SAndroid Build Coastguard Worker 
7136*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7137*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req1(transaction);
7138*6777b538SAndroid Build Coastguard Worker 
7139*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7140*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7141*6777b538SAndroid Build Coastguard Worker 
7142*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7143*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7144*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7145*6777b538SAndroid Build Coastguard Worker 
7146*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7147*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7148*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7149*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7150*6777b538SAndroid Build Coastguard Worker 
7151*6777b538SAndroid Build Coastguard Worker   transaction.method = "POST";
7152*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 205 No Content";
7153*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req2(transaction);
7154*6777b538SAndroid Build Coastguard Worker   req2.upload_data_stream = &upload_data_stream;
7155*6777b538SAndroid Build Coastguard Worker 
7156*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7157*6777b538SAndroid Build Coastguard Worker 
7158*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7159*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7160*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7161*6777b538SAndroid Build Coastguard Worker 
7162*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7163*6777b538SAndroid Build Coastguard Worker 
7164*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7165*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7166*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->create_count());
7167*6777b538SAndroid Build Coastguard Worker }
7168*6777b538SAndroid Build Coastguard Worker 
7169*6777b538SAndroid Build Coastguard Worker // Tests that a successful POST invalidates a previously cached GET,
7170*6777b538SAndroid Build Coastguard Worker // with cache split by top-frame origin.
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SimplePOST_Invalidate_205_SplitCache)7171*6777b538SAndroid Build Coastguard Worker TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
7172*6777b538SAndroid Build Coastguard Worker        SimplePOST_Invalidate_205_SplitCache) {
7173*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_a(GURL("http://a.com"));
7174*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_b(GURL("http://b.com"));
7175*6777b538SAndroid Build Coastguard Worker 
7176*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7177*6777b538SAndroid Build Coastguard Worker 
7178*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7179*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req1(transaction);
7180*6777b538SAndroid Build Coastguard Worker   req1.network_isolation_key = NetworkIsolationKey(site_a, site_a);
7181*6777b538SAndroid Build Coastguard Worker   req1.network_anonymization_key =
7182*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_a);
7183*6777b538SAndroid Build Coastguard Worker 
7184*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7185*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7186*6777b538SAndroid Build Coastguard Worker 
7187*6777b538SAndroid Build Coastguard Worker   // Same for a different origin.
7188*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req1b(transaction);
7189*6777b538SAndroid Build Coastguard Worker   req1b.network_isolation_key = NetworkIsolationKey(site_b, site_b);
7190*6777b538SAndroid Build Coastguard Worker   req1b.network_anonymization_key =
7191*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_b);
7192*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1b,
7193*6777b538SAndroid Build Coastguard Worker                                 nullptr);
7194*6777b538SAndroid Build Coastguard Worker 
7195*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7196*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7197*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7198*6777b538SAndroid Build Coastguard Worker 
7199*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7200*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7201*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7202*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7203*6777b538SAndroid Build Coastguard Worker 
7204*6777b538SAndroid Build Coastguard Worker   transaction.method = "POST";
7205*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 205 No Content";
7206*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req2(transaction);
7207*6777b538SAndroid Build Coastguard Worker   req2.upload_data_stream = &upload_data_stream;
7208*6777b538SAndroid Build Coastguard Worker   req2.network_isolation_key = NetworkIsolationKey(site_a, site_a);
7209*6777b538SAndroid Build Coastguard Worker   req2.network_anonymization_key =
7210*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_a);
7211*6777b538SAndroid Build Coastguard Worker 
7212*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7213*6777b538SAndroid Build Coastguard Worker 
7214*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7215*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7216*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->create_count());
7217*6777b538SAndroid Build Coastguard Worker 
7218*6777b538SAndroid Build Coastguard Worker   // req1b should still be cached, since it has a different top-level frame
7219*6777b538SAndroid Build Coastguard Worker   // origin.
7220*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1b,
7221*6777b538SAndroid Build Coastguard Worker                                 nullptr);
7222*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7223*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7224*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->create_count());
7225*6777b538SAndroid Build Coastguard Worker 
7226*6777b538SAndroid Build Coastguard Worker   // req1 should not be cached after the POST.
7227*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7228*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.network_layer()->transaction_count());
7229*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7230*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.disk_cache()->create_count());
7231*6777b538SAndroid Build Coastguard Worker }
7232*6777b538SAndroid Build Coastguard Worker 
7233*6777b538SAndroid Build Coastguard Worker // Tests that a successful POST invalidates a previously cached GET, even when
7234*6777b538SAndroid Build Coastguard Worker // there is no upload identifier.
TEST_F(HttpCacheTest,SimplePOST_NoUploadId_Invalidate_205)7235*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePOST_NoUploadId_Invalidate_205) {
7236*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7237*6777b538SAndroid Build Coastguard Worker 
7238*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7239*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req1(transaction);
7240*6777b538SAndroid Build Coastguard Worker 
7241*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7242*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7243*6777b538SAndroid Build Coastguard Worker 
7244*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7245*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7246*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7247*6777b538SAndroid Build Coastguard Worker 
7248*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7249*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7250*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7251*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7252*6777b538SAndroid Build Coastguard Worker 
7253*6777b538SAndroid Build Coastguard Worker   transaction.method = "POST";
7254*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 205 No Content";
7255*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req2(transaction);
7256*6777b538SAndroid Build Coastguard Worker   req2.upload_data_stream = &upload_data_stream;
7257*6777b538SAndroid Build Coastguard Worker 
7258*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7259*6777b538SAndroid Build Coastguard Worker 
7260*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7261*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7262*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7263*6777b538SAndroid Build Coastguard Worker 
7264*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7265*6777b538SAndroid Build Coastguard Worker 
7266*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7267*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7268*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7269*6777b538SAndroid Build Coastguard Worker }
7270*6777b538SAndroid Build Coastguard Worker 
7271*6777b538SAndroid Build Coastguard Worker // Tests that processing a POST before creating the backend doesn't crash.
TEST_F(HttpCacheTest,SimplePOST_NoUploadId_NoBackend)7272*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePOST_NoUploadId_NoBackend) {
7273*6777b538SAndroid Build Coastguard Worker   // This will initialize a cache object with NULL backend.
7274*6777b538SAndroid Build Coastguard Worker   auto factory = std::make_unique<MockBlockingBackendFactory>();
7275*6777b538SAndroid Build Coastguard Worker   factory->set_fail(true);
7276*6777b538SAndroid Build Coastguard Worker   factory->FinishCreation();
7277*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache(std::move(factory));
7278*6777b538SAndroid Build Coastguard Worker 
7279*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7280*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7281*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7282*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7283*6777b538SAndroid Build Coastguard Worker 
7284*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimplePOST_Transaction);
7285*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req(transaction);
7286*6777b538SAndroid Build Coastguard Worker   req.upload_data_stream = &upload_data_stream;
7287*6777b538SAndroid Build Coastguard Worker 
7288*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req, nullptr);
7289*6777b538SAndroid Build Coastguard Worker }
7290*6777b538SAndroid Build Coastguard Worker 
7291*6777b538SAndroid Build Coastguard Worker // Tests that we don't invalidate entries as a result of a failed POST.
TEST_F(HttpCacheTest,SimplePOST_DontInvalidate_100)7292*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePOST_DontInvalidate_100) {
7293*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7294*6777b538SAndroid Build Coastguard Worker 
7295*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7296*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req1(transaction);
7297*6777b538SAndroid Build Coastguard Worker 
7298*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7299*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7300*6777b538SAndroid Build Coastguard Worker 
7301*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7302*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7303*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7304*6777b538SAndroid Build Coastguard Worker 
7305*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7306*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7307*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7308*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7309*6777b538SAndroid Build Coastguard Worker 
7310*6777b538SAndroid Build Coastguard Worker   transaction.method = "POST";
7311*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 100 Continue";
7312*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req2(transaction);
7313*6777b538SAndroid Build Coastguard Worker   req2.upload_data_stream = &upload_data_stream;
7314*6777b538SAndroid Build Coastguard Worker 
7315*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7316*6777b538SAndroid Build Coastguard Worker 
7317*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7318*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7319*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7320*6777b538SAndroid Build Coastguard Worker 
7321*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7322*6777b538SAndroid Build Coastguard Worker 
7323*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7324*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7325*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7326*6777b538SAndroid Build Coastguard Worker }
7327*6777b538SAndroid Build Coastguard Worker 
7328*6777b538SAndroid Build Coastguard Worker // Tests that a HEAD request is not cached by itself.
TEST_F(HttpCacheTest,SimpleHEAD_LoadOnlyFromCache_Miss)7329*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleHEAD_LoadOnlyFromCache_Miss) {
7330*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7331*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimplePOST_Transaction);
7332*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7333*6777b538SAndroid Build Coastguard Worker   transaction.method = "HEAD";
7334*6777b538SAndroid Build Coastguard Worker 
7335*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
7336*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
7337*6777b538SAndroid Build Coastguard Worker 
7338*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
7339*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7340*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(trans.get());
7341*6777b538SAndroid Build Coastguard Worker 
7342*6777b538SAndroid Build Coastguard Worker   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7343*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(callback.GetResult(rv), IsError(ERR_CACHE_MISS));
7344*6777b538SAndroid Build Coastguard Worker 
7345*6777b538SAndroid Build Coastguard Worker   trans.reset();
7346*6777b538SAndroid Build Coastguard Worker 
7347*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7348*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7349*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
7350*6777b538SAndroid Build Coastguard Worker }
7351*6777b538SAndroid Build Coastguard Worker 
7352*6777b538SAndroid Build Coastguard Worker // Tests that a HEAD request is served from a cached GET.
TEST_F(HttpCacheTest,SimpleHEAD_LoadOnlyFromCache_Hit)7353*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleHEAD_LoadOnlyFromCache_Hit) {
7354*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7355*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7356*6777b538SAndroid Build Coastguard Worker 
7357*6777b538SAndroid Build Coastguard Worker   // Populate the cache.
7358*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7359*6777b538SAndroid Build Coastguard Worker 
7360*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7361*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7362*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7363*6777b538SAndroid Build Coastguard Worker 
7364*6777b538SAndroid Build Coastguard Worker   // Load from cache.
7365*6777b538SAndroid Build Coastguard Worker   transaction.method = "HEAD";
7366*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7367*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
7368*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7369*6777b538SAndroid Build Coastguard Worker 
7370*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7371*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7372*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7373*6777b538SAndroid Build Coastguard Worker }
7374*6777b538SAndroid Build Coastguard Worker 
7375*6777b538SAndroid Build Coastguard Worker // Tests that a read-only request served from the cache preserves CL.
TEST_F(HttpCacheTest,SimpleHEAD_ContentLengthOnHit_Read)7376*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleHEAD_ContentLengthOnHit_Read) {
7377*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7378*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7379*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "Content-Length: 42\n";
7380*6777b538SAndroid Build Coastguard Worker 
7381*6777b538SAndroid Build Coastguard Worker   // Populate the cache.
7382*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7383*6777b538SAndroid Build Coastguard Worker 
7384*6777b538SAndroid Build Coastguard Worker   // Load from cache.
7385*6777b538SAndroid Build Coastguard Worker   transaction.method = "HEAD";
7386*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7387*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
7388*6777b538SAndroid Build Coastguard Worker   std::string headers;
7389*6777b538SAndroid Build Coastguard Worker 
7390*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7391*6777b538SAndroid Build Coastguard Worker 
7392*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
7393*6777b538SAndroid Build Coastguard Worker }
7394*6777b538SAndroid Build Coastguard Worker 
7395*6777b538SAndroid Build Coastguard Worker // Tests that a read-write request served from the cache preserves CL.
TEST_F(HttpCacheTest,ETagHEAD_ContentLengthOnHit_ReadWrite)7396*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ETagHEAD_ContentLengthOnHit_ReadWrite) {
7397*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7398*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kETagGET_Transaction);
7399*6777b538SAndroid Build Coastguard Worker   std::string server_headers(kETagGET_Transaction.response_headers);
7400*6777b538SAndroid Build Coastguard Worker   server_headers.append("Content-Length: 42\n");
7401*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = server_headers.data();
7402*6777b538SAndroid Build Coastguard Worker 
7403*6777b538SAndroid Build Coastguard Worker   // Populate the cache.
7404*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7405*6777b538SAndroid Build Coastguard Worker 
7406*6777b538SAndroid Build Coastguard Worker   // Load from cache.
7407*6777b538SAndroid Build Coastguard Worker   transaction.method = "HEAD";
7408*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
7409*6777b538SAndroid Build Coastguard Worker   std::string headers;
7410*6777b538SAndroid Build Coastguard Worker 
7411*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7412*6777b538SAndroid Build Coastguard Worker 
7413*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
7414*6777b538SAndroid Build Coastguard Worker }
7415*6777b538SAndroid Build Coastguard Worker 
7416*6777b538SAndroid Build Coastguard Worker // Tests that a HEAD request that includes byte ranges bypasses the cache.
TEST_F(HttpCacheTest,SimpleHEAD_WithRanges)7417*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleHEAD_WithRanges) {
7418*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7419*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7420*6777b538SAndroid Build Coastguard Worker 
7421*6777b538SAndroid Build Coastguard Worker   // Populate the cache.
7422*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7423*6777b538SAndroid Build Coastguard Worker 
7424*6777b538SAndroid Build Coastguard Worker   // Load from cache.
7425*6777b538SAndroid Build Coastguard Worker   transaction.method = "HEAD";
7426*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 0-4\r\n";
7427*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7428*6777b538SAndroid Build Coastguard Worker   transaction.start_return_code = ERR_CACHE_MISS;
7429*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7430*6777b538SAndroid Build Coastguard Worker 
7431*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7432*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7433*6777b538SAndroid Build Coastguard Worker }
7434*6777b538SAndroid Build Coastguard Worker 
7435*6777b538SAndroid Build Coastguard Worker // Tests that a HEAD request can be served from a partially cached resource.
TEST_F(HttpCacheTest,SimpleHEAD_WithCachedRanges)7436*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleHEAD_WithCachedRanges) {
7437*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7438*6777b538SAndroid Build Coastguard Worker   {
7439*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction scoped_mock_transaction(kRangeGET_TransactionOK);
7440*6777b538SAndroid Build Coastguard Worker     // Write to the cache (40-49).
7441*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
7442*6777b538SAndroid Build Coastguard Worker   }
7443*6777b538SAndroid Build Coastguard Worker 
7444*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction,
7445*6777b538SAndroid Build Coastguard Worker                                     kRangeGET_TransactionOK.url);
7446*6777b538SAndroid Build Coastguard Worker   transaction.method = "HEAD";
7447*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
7448*6777b538SAndroid Build Coastguard Worker   std::string headers;
7449*6777b538SAndroid Build Coastguard Worker 
7450*6777b538SAndroid Build Coastguard Worker   // Load from cache.
7451*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7452*6777b538SAndroid Build Coastguard Worker 
7453*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7454*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
7455*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
7456*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7457*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7458*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7459*6777b538SAndroid Build Coastguard Worker }
7460*6777b538SAndroid Build Coastguard Worker 
7461*6777b538SAndroid Build Coastguard Worker // Tests that a HEAD request can be served from a truncated resource.
TEST_F(HttpCacheTest,SimpleHEAD_WithTruncatedEntry)7462*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleHEAD_WithTruncatedEntry) {
7463*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7464*6777b538SAndroid Build Coastguard Worker   {
7465*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction scoped_mock_transaction(kRangeGET_TransactionOK);
7466*6777b538SAndroid Build Coastguard Worker     std::string raw_headers(
7467*6777b538SAndroid Build Coastguard Worker         "HTTP/1.1 200 OK\n"
7468*6777b538SAndroid Build Coastguard Worker         "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7469*6777b538SAndroid Build Coastguard Worker         "ETag: \"foo\"\n"
7470*6777b538SAndroid Build Coastguard Worker         "Accept-Ranges: bytes\n"
7471*6777b538SAndroid Build Coastguard Worker         "Content-Length: 80\n");
7472*6777b538SAndroid Build Coastguard Worker     CreateTruncatedEntry(raw_headers, &cache);
7473*6777b538SAndroid Build Coastguard Worker   }
7474*6777b538SAndroid Build Coastguard Worker 
7475*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction,
7476*6777b538SAndroid Build Coastguard Worker                                     kRangeGET_TransactionOK.url);
7477*6777b538SAndroid Build Coastguard Worker   transaction.method = "HEAD";
7478*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
7479*6777b538SAndroid Build Coastguard Worker   std::string headers;
7480*6777b538SAndroid Build Coastguard Worker 
7481*6777b538SAndroid Build Coastguard Worker   // Load from cache.
7482*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7483*6777b538SAndroid Build Coastguard Worker 
7484*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7485*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
7486*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
7487*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7488*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7489*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7490*6777b538SAndroid Build Coastguard Worker }
7491*6777b538SAndroid Build Coastguard Worker 
7492*6777b538SAndroid Build Coastguard Worker // Tests that a HEAD request updates the cached response.
TEST_F(HttpCacheTest,TypicalHEAD_UpdatesResponse)7493*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, TypicalHEAD_UpdatesResponse) {
7494*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7495*6777b538SAndroid Build Coastguard Worker   std::string headers;
7496*6777b538SAndroid Build Coastguard Worker   {
7497*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kTypicalGET_Transaction);
7498*6777b538SAndroid Build Coastguard Worker 
7499*6777b538SAndroid Build Coastguard Worker     // Populate the cache.
7500*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
7501*6777b538SAndroid Build Coastguard Worker 
7502*6777b538SAndroid Build Coastguard Worker     // Update the cache.
7503*6777b538SAndroid Build Coastguard Worker     transaction.method = "HEAD";
7504*6777b538SAndroid Build Coastguard Worker     transaction.response_headers = "Foo: bar\n";
7505*6777b538SAndroid Build Coastguard Worker     transaction.data = "";
7506*6777b538SAndroid Build Coastguard Worker     transaction.status = "HTTP/1.1 304 Not Modified\n";
7507*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7508*6777b538SAndroid Build Coastguard Worker   }
7509*6777b538SAndroid Build Coastguard Worker 
7510*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7511*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7512*6777b538SAndroid Build Coastguard Worker 
7513*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction2(kTypicalGET_Transaction);
7514*6777b538SAndroid Build Coastguard Worker 
7515*6777b538SAndroid Build Coastguard Worker   // Make sure we are done with the previous transaction.
7516*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
7517*6777b538SAndroid Build Coastguard Worker 
7518*6777b538SAndroid Build Coastguard Worker   // Load from the cache.
7519*6777b538SAndroid Build Coastguard Worker   transaction2.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7520*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
7521*6777b538SAndroid Build Coastguard Worker 
7522*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
7523*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7524*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
7525*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7526*6777b538SAndroid Build Coastguard Worker }
7527*6777b538SAndroid Build Coastguard Worker 
7528*6777b538SAndroid Build Coastguard Worker // Tests that an externally conditionalized HEAD request updates the cache.
TEST_F(HttpCacheTest,TypicalHEAD_ConditionalizedRequestUpdatesResponse)7529*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
7530*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7531*6777b538SAndroid Build Coastguard Worker   std::string headers;
7532*6777b538SAndroid Build Coastguard Worker 
7533*6777b538SAndroid Build Coastguard Worker   {
7534*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kTypicalGET_Transaction);
7535*6777b538SAndroid Build Coastguard Worker 
7536*6777b538SAndroid Build Coastguard Worker     // Populate the cache.
7537*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
7538*6777b538SAndroid Build Coastguard Worker 
7539*6777b538SAndroid Build Coastguard Worker     // Update the cache.
7540*6777b538SAndroid Build Coastguard Worker     transaction.method = "HEAD";
7541*6777b538SAndroid Build Coastguard Worker     transaction.request_headers =
7542*6777b538SAndroid Build Coastguard Worker         "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
7543*6777b538SAndroid Build Coastguard Worker     transaction.response_headers = "Foo: bar\n";
7544*6777b538SAndroid Build Coastguard Worker     transaction.data = "";
7545*6777b538SAndroid Build Coastguard Worker     transaction.status = "HTTP/1.1 304 Not Modified\n";
7546*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7547*6777b538SAndroid Build Coastguard Worker 
7548*6777b538SAndroid Build Coastguard Worker     EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
7549*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.network_layer()->transaction_count());
7550*6777b538SAndroid Build Coastguard Worker 
7551*6777b538SAndroid Build Coastguard Worker     // Make sure we are done with the previous transaction.
7552*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
7553*6777b538SAndroid Build Coastguard Worker   }
7554*6777b538SAndroid Build Coastguard Worker   {
7555*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction2(kTypicalGET_Transaction);
7556*6777b538SAndroid Build Coastguard Worker 
7557*6777b538SAndroid Build Coastguard Worker     // Load from the cache.
7558*6777b538SAndroid Build Coastguard Worker     transaction2.load_flags |=
7559*6777b538SAndroid Build Coastguard Worker         LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7560*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
7561*6777b538SAndroid Build Coastguard Worker 
7562*6777b538SAndroid Build Coastguard Worker     EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
7563*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.network_layer()->transaction_count());
7564*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.disk_cache()->open_count());
7565*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
7566*6777b538SAndroid Build Coastguard Worker   }
7567*6777b538SAndroid Build Coastguard Worker }
7568*6777b538SAndroid Build Coastguard Worker 
7569*6777b538SAndroid Build Coastguard Worker // Tests that a HEAD request invalidates an old cached entry.
TEST_F(HttpCacheTest,SimpleHEAD_InvalidatesEntry)7570*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleHEAD_InvalidatesEntry) {
7571*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7572*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
7573*6777b538SAndroid Build Coastguard Worker 
7574*6777b538SAndroid Build Coastguard Worker   // Populate the cache.
7575*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7576*6777b538SAndroid Build Coastguard Worker 
7577*6777b538SAndroid Build Coastguard Worker   // Update the cache.
7578*6777b538SAndroid Build Coastguard Worker   transaction.method = "HEAD";
7579*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
7580*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7581*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7582*6777b538SAndroid Build Coastguard Worker 
7583*6777b538SAndroid Build Coastguard Worker   // Load from the cache.
7584*6777b538SAndroid Build Coastguard Worker   transaction.method = "GET";
7585*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7586*6777b538SAndroid Build Coastguard Worker   transaction.start_return_code = ERR_CACHE_MISS;
7587*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7588*6777b538SAndroid Build Coastguard Worker }
7589*6777b538SAndroid Build Coastguard Worker 
7590*6777b538SAndroid Build Coastguard Worker // Tests that we do not cache the response of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Miss)7591*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePUT_Miss) {
7592*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7593*6777b538SAndroid Build Coastguard Worker 
7594*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimplePOST_Transaction);
7595*6777b538SAndroid Build Coastguard Worker   transaction.method = "PUT";
7596*6777b538SAndroid Build Coastguard Worker 
7597*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7598*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7599*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7600*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7601*6777b538SAndroid Build Coastguard Worker 
7602*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
7603*6777b538SAndroid Build Coastguard Worker   request.upload_data_stream = &upload_data_stream;
7604*6777b538SAndroid Build Coastguard Worker 
7605*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7606*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7607*6777b538SAndroid Build Coastguard Worker                                 nullptr);
7608*6777b538SAndroid Build Coastguard Worker 
7609*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7610*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7611*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
7612*6777b538SAndroid Build Coastguard Worker }
7613*6777b538SAndroid Build Coastguard Worker 
7614*6777b538SAndroid Build Coastguard Worker // Tests that we invalidate entries as a result of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Invalidate)7615*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePUT_Invalidate) {
7616*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7617*6777b538SAndroid Build Coastguard Worker 
7618*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
7619*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req1(transaction);
7620*6777b538SAndroid Build Coastguard Worker 
7621*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7622*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7623*6777b538SAndroid Build Coastguard Worker 
7624*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7625*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7626*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7627*6777b538SAndroid Build Coastguard Worker 
7628*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7629*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7630*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7631*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7632*6777b538SAndroid Build Coastguard Worker 
7633*6777b538SAndroid Build Coastguard Worker   transaction.method = "PUT";
7634*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req2(transaction);
7635*6777b538SAndroid Build Coastguard Worker   req2.upload_data_stream = &upload_data_stream;
7636*6777b538SAndroid Build Coastguard Worker 
7637*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7638*6777b538SAndroid Build Coastguard Worker 
7639*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7640*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7641*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7642*6777b538SAndroid Build Coastguard Worker 
7643*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7644*6777b538SAndroid Build Coastguard Worker 
7645*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7646*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7647*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7648*6777b538SAndroid Build Coastguard Worker }
7649*6777b538SAndroid Build Coastguard Worker 
7650*6777b538SAndroid Build Coastguard Worker // Tests that we invalidate entries as a result of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Invalidate_305)7651*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePUT_Invalidate_305) {
7652*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7653*6777b538SAndroid Build Coastguard Worker 
7654*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7655*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req1(transaction);
7656*6777b538SAndroid Build Coastguard Worker 
7657*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7658*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7659*6777b538SAndroid Build Coastguard Worker 
7660*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7661*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7662*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7663*6777b538SAndroid Build Coastguard Worker 
7664*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7665*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7666*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7667*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7668*6777b538SAndroid Build Coastguard Worker 
7669*6777b538SAndroid Build Coastguard Worker   transaction.method = "PUT";
7670*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 305 Use Proxy";
7671*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req2(transaction);
7672*6777b538SAndroid Build Coastguard Worker   req2.upload_data_stream = &upload_data_stream;
7673*6777b538SAndroid Build Coastguard Worker 
7674*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7675*6777b538SAndroid Build Coastguard Worker 
7676*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7677*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7678*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7679*6777b538SAndroid Build Coastguard Worker 
7680*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7681*6777b538SAndroid Build Coastguard Worker 
7682*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7683*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7684*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7685*6777b538SAndroid Build Coastguard Worker }
7686*6777b538SAndroid Build Coastguard Worker 
7687*6777b538SAndroid Build Coastguard Worker // Tests that we don't invalidate entries as a result of a failed PUT.
TEST_F(HttpCacheTest,SimplePUT_DontInvalidate_404)7688*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePUT_DontInvalidate_404) {
7689*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7690*6777b538SAndroid Build Coastguard Worker 
7691*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7692*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req1(transaction);
7693*6777b538SAndroid Build Coastguard Worker 
7694*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7695*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7696*6777b538SAndroid Build Coastguard Worker 
7697*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7698*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7699*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7700*6777b538SAndroid Build Coastguard Worker 
7701*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7702*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7703*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7704*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7705*6777b538SAndroid Build Coastguard Worker 
7706*6777b538SAndroid Build Coastguard Worker   transaction.method = "PUT";
7707*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 404 Not Found";
7708*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req2(transaction);
7709*6777b538SAndroid Build Coastguard Worker   req2.upload_data_stream = &upload_data_stream;
7710*6777b538SAndroid Build Coastguard Worker 
7711*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7712*6777b538SAndroid Build Coastguard Worker 
7713*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7714*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7715*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7716*6777b538SAndroid Build Coastguard Worker 
7717*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7718*6777b538SAndroid Build Coastguard Worker 
7719*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7720*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
7721*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7722*6777b538SAndroid Build Coastguard Worker }
7723*6777b538SAndroid Build Coastguard Worker 
7724*6777b538SAndroid Build Coastguard Worker // Tests that we do not cache the response of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Miss)7725*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleDELETE_Miss) {
7726*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7727*6777b538SAndroid Build Coastguard Worker 
7728*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimplePOST_Transaction);
7729*6777b538SAndroid Build Coastguard Worker   transaction.method = "DELETE";
7730*6777b538SAndroid Build Coastguard Worker 
7731*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7732*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7733*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7734*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7735*6777b538SAndroid Build Coastguard Worker 
7736*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
7737*6777b538SAndroid Build Coastguard Worker   request.upload_data_stream = &upload_data_stream;
7738*6777b538SAndroid Build Coastguard Worker 
7739*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7740*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7741*6777b538SAndroid Build Coastguard Worker                                 nullptr);
7742*6777b538SAndroid Build Coastguard Worker 
7743*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7744*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7745*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
7746*6777b538SAndroid Build Coastguard Worker }
7747*6777b538SAndroid Build Coastguard Worker 
7748*6777b538SAndroid Build Coastguard Worker // Tests that we invalidate entries as a result of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Invalidate)7749*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleDELETE_Invalidate) {
7750*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7751*6777b538SAndroid Build Coastguard Worker 
7752*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
7753*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req1(transaction);
7754*6777b538SAndroid Build Coastguard Worker 
7755*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7756*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7757*6777b538SAndroid Build Coastguard Worker 
7758*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7759*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7760*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7761*6777b538SAndroid Build Coastguard Worker 
7762*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7763*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7764*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7765*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7766*6777b538SAndroid Build Coastguard Worker 
7767*6777b538SAndroid Build Coastguard Worker   transaction.method = "DELETE";
7768*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req2(transaction);
7769*6777b538SAndroid Build Coastguard Worker   req2.upload_data_stream = &upload_data_stream;
7770*6777b538SAndroid Build Coastguard Worker 
7771*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7772*6777b538SAndroid Build Coastguard Worker 
7773*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7774*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7775*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7776*6777b538SAndroid Build Coastguard Worker 
7777*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7778*6777b538SAndroid Build Coastguard Worker 
7779*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7780*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7781*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7782*6777b538SAndroid Build Coastguard Worker }
7783*6777b538SAndroid Build Coastguard Worker 
7784*6777b538SAndroid Build Coastguard Worker // Tests that we invalidate entries as a result of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Invalidate_301)7785*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleDELETE_Invalidate_301) {
7786*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7787*6777b538SAndroid Build Coastguard Worker 
7788*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7789*6777b538SAndroid Build Coastguard Worker 
7790*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7791*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7792*6777b538SAndroid Build Coastguard Worker 
7793*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7794*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7795*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7796*6777b538SAndroid Build Coastguard Worker 
7797*6777b538SAndroid Build Coastguard Worker   transaction.method = "DELETE";
7798*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 301 Moved Permanently ";
7799*6777b538SAndroid Build Coastguard Worker 
7800*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7801*6777b538SAndroid Build Coastguard Worker 
7802*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7803*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7804*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7805*6777b538SAndroid Build Coastguard Worker 
7806*6777b538SAndroid Build Coastguard Worker   transaction.method = "GET";
7807*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7808*6777b538SAndroid Build Coastguard Worker 
7809*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7810*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7811*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7812*6777b538SAndroid Build Coastguard Worker }
7813*6777b538SAndroid Build Coastguard Worker 
7814*6777b538SAndroid Build Coastguard Worker // Tests that we don't invalidate entries as a result of a failed DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_DontInvalidate_416)7815*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleDELETE_DontInvalidate_416) {
7816*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7817*6777b538SAndroid Build Coastguard Worker 
7818*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7819*6777b538SAndroid Build Coastguard Worker 
7820*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7821*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7822*6777b538SAndroid Build Coastguard Worker 
7823*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7824*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7825*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7826*6777b538SAndroid Build Coastguard Worker 
7827*6777b538SAndroid Build Coastguard Worker   transaction.method = "DELETE";
7828*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
7829*6777b538SAndroid Build Coastguard Worker 
7830*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7831*6777b538SAndroid Build Coastguard Worker 
7832*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7833*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7834*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7835*6777b538SAndroid Build Coastguard Worker 
7836*6777b538SAndroid Build Coastguard Worker   transaction.method = "GET";
7837*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 200 OK";
7838*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7839*6777b538SAndroid Build Coastguard Worker 
7840*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7841*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
7842*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7843*6777b538SAndroid Build Coastguard Worker }
7844*6777b538SAndroid Build Coastguard Worker 
7845*6777b538SAndroid Build Coastguard Worker // Tests that we invalidate entries as a result of a PATCH.
TEST_F(HttpCacheTest,SimplePATCH_Invalidate)7846*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePATCH_Invalidate) {
7847*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7848*6777b538SAndroid Build Coastguard Worker 
7849*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
7850*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req1(transaction);
7851*6777b538SAndroid Build Coastguard Worker 
7852*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7853*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7854*6777b538SAndroid Build Coastguard Worker 
7855*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7856*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7857*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7858*6777b538SAndroid Build Coastguard Worker 
7859*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7860*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
7861*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
7862*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7863*6777b538SAndroid Build Coastguard Worker 
7864*6777b538SAndroid Build Coastguard Worker   transaction.method = "PATCH";
7865*6777b538SAndroid Build Coastguard Worker   MockHttpRequest req2(transaction);
7866*6777b538SAndroid Build Coastguard Worker   req2.upload_data_stream = &upload_data_stream;
7867*6777b538SAndroid Build Coastguard Worker 
7868*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7869*6777b538SAndroid Build Coastguard Worker 
7870*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7871*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7872*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7873*6777b538SAndroid Build Coastguard Worker 
7874*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7875*6777b538SAndroid Build Coastguard Worker 
7876*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7877*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7878*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7879*6777b538SAndroid Build Coastguard Worker }
7880*6777b538SAndroid Build Coastguard Worker 
7881*6777b538SAndroid Build Coastguard Worker // Tests that we invalidate entries as a result of a PATCH.
TEST_F(HttpCacheTest,SimplePATCH_Invalidate_301)7882*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePATCH_Invalidate_301) {
7883*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7884*6777b538SAndroid Build Coastguard Worker 
7885*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7886*6777b538SAndroid Build Coastguard Worker 
7887*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7888*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7889*6777b538SAndroid Build Coastguard Worker 
7890*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7891*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7892*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7893*6777b538SAndroid Build Coastguard Worker 
7894*6777b538SAndroid Build Coastguard Worker   transaction.method = "PATCH";
7895*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 301 Moved Permanently ";
7896*6777b538SAndroid Build Coastguard Worker 
7897*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7898*6777b538SAndroid Build Coastguard Worker 
7899*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7900*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7901*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7902*6777b538SAndroid Build Coastguard Worker 
7903*6777b538SAndroid Build Coastguard Worker   transaction.method = "GET";
7904*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7905*6777b538SAndroid Build Coastguard Worker 
7906*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7907*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7908*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
7909*6777b538SAndroid Build Coastguard Worker }
7910*6777b538SAndroid Build Coastguard Worker 
7911*6777b538SAndroid Build Coastguard Worker // Tests that we don't invalidate entries as a result of a failed PATCH.
TEST_F(HttpCacheTest,SimplePATCH_DontInvalidate_416)7912*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimplePATCH_DontInvalidate_416) {
7913*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7914*6777b538SAndroid Build Coastguard Worker 
7915*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7916*6777b538SAndroid Build Coastguard Worker 
7917*6777b538SAndroid Build Coastguard Worker   // Attempt to populate the cache.
7918*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7919*6777b538SAndroid Build Coastguard Worker 
7920*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7921*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7922*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7923*6777b538SAndroid Build Coastguard Worker 
7924*6777b538SAndroid Build Coastguard Worker   transaction.method = "PATCH";
7925*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
7926*6777b538SAndroid Build Coastguard Worker 
7927*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7928*6777b538SAndroid Build Coastguard Worker 
7929*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7930*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
7931*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7932*6777b538SAndroid Build Coastguard Worker 
7933*6777b538SAndroid Build Coastguard Worker   transaction.method = "GET";
7934*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 200 OK";
7935*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7936*6777b538SAndroid Build Coastguard Worker 
7937*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7938*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
7939*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
7940*6777b538SAndroid Build Coastguard Worker }
7941*6777b538SAndroid Build Coastguard Worker 
7942*6777b538SAndroid Build Coastguard Worker // Tests that we don't invalidate entries after a failed network transaction.
TEST_F(HttpCacheTest,SimpleGET_DontInvalidateOnFailure)7943*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_DontInvalidateOnFailure) {
7944*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7945*6777b538SAndroid Build Coastguard Worker 
7946*6777b538SAndroid Build Coastguard Worker   // Populate the cache.
7947*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
7948*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7949*6777b538SAndroid Build Coastguard Worker 
7950*6777b538SAndroid Build Coastguard Worker   // Fail the network request.
7951*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7952*6777b538SAndroid Build Coastguard Worker   transaction.start_return_code = ERR_FAILED;
7953*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
7954*6777b538SAndroid Build Coastguard Worker 
7955*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7956*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7957*6777b538SAndroid Build Coastguard Worker 
7958*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7959*6777b538SAndroid Build Coastguard Worker   transaction.start_return_code = OK;
7960*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7961*6777b538SAndroid Build Coastguard Worker 
7962*6777b538SAndroid Build Coastguard Worker   // Make sure the transaction didn't reach the network.
7963*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7964*6777b538SAndroid Build Coastguard Worker }
7965*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,RangeGET_SkipsCache)7966*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_SkipsCache) {
7967*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
7968*6777b538SAndroid Build Coastguard Worker 
7969*6777b538SAndroid Build Coastguard Worker   // Test that we skip the cache for range GET requests.  Eventually, we will
7970*6777b538SAndroid Build Coastguard Worker   // want to cache these, but we'll still have cases where skipping the cache
7971*6777b538SAndroid Build Coastguard Worker   // makes sense, so we want to make sure that it works properly.
7972*6777b538SAndroid Build Coastguard Worker 
7973*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
7974*6777b538SAndroid Build Coastguard Worker 
7975*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7976*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7977*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
7978*6777b538SAndroid Build Coastguard Worker 
7979*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
7980*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "If-None-Match: foo\r\n";
7981*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7982*6777b538SAndroid Build Coastguard Worker 
7983*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7984*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7985*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
7986*6777b538SAndroid Build Coastguard Worker 
7987*6777b538SAndroid Build Coastguard Worker   transaction.request_headers =
7988*6777b538SAndroid Build Coastguard Worker       "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
7989*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
7990*6777b538SAndroid Build Coastguard Worker 
7991*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7992*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
7993*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
7994*6777b538SAndroid Build Coastguard Worker }
7995*6777b538SAndroid Build Coastguard Worker 
7996*6777b538SAndroid Build Coastguard Worker // Test that we skip the cache for range requests that include a validation
7997*6777b538SAndroid Build Coastguard Worker // header.
TEST_F(HttpCacheTest,RangeGET_SkipsCache2)7998*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_SkipsCache2) {
7999*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8000*6777b538SAndroid Build Coastguard Worker 
8001*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_Transaction);
8002*6777b538SAndroid Build Coastguard Worker   transaction.request_headers =
8003*6777b538SAndroid Build Coastguard Worker       "If-None-Match: foo\r\n" EXTRA_HEADER "Range: bytes = 40-49\r\n";
8004*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8005*6777b538SAndroid Build Coastguard Worker 
8006*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8007*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8008*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
8009*6777b538SAndroid Build Coastguard Worker 
8010*6777b538SAndroid Build Coastguard Worker   transaction.request_headers =
8011*6777b538SAndroid Build Coastguard Worker       "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n" EXTRA_HEADER
8012*6777b538SAndroid Build Coastguard Worker       "Range: bytes = 40-49\r\n";
8013*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8014*6777b538SAndroid Build Coastguard Worker 
8015*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8016*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8017*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
8018*6777b538SAndroid Build Coastguard Worker 
8019*6777b538SAndroid Build Coastguard Worker   transaction.request_headers =
8020*6777b538SAndroid Build Coastguard Worker       "If-Range: bla\r\n" EXTRA_HEADER "Range: bytes = 40-49\r\n";
8021*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8022*6777b538SAndroid Build Coastguard Worker 
8023*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8024*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8025*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
8026*6777b538SAndroid Build Coastguard Worker }
8027*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SimpleGET_DoesntLogHeaders)8028*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_DoesntLogHeaders) {
8029*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8030*6777b538SAndroid Build Coastguard Worker 
8031*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_observer;
8032*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
8033*6777b538SAndroid Build Coastguard Worker                             NetLogWithSource::Make(NetLogSourceType::NONE));
8034*6777b538SAndroid Build Coastguard Worker 
8035*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(LogContainsEventType(
8036*6777b538SAndroid Build Coastguard Worker       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8037*6777b538SAndroid Build Coastguard Worker }
8038*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,RangeGET_LogsHeaders)8039*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_LogsHeaders) {
8040*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8041*6777b538SAndroid Build Coastguard Worker 
8042*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_observer;
8043*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithLog(cache.http_cache(), kRangeGET_Transaction,
8044*6777b538SAndroid Build Coastguard Worker                             NetLogWithSource::Make(NetLogSourceType::NONE));
8045*6777b538SAndroid Build Coastguard Worker 
8046*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEventType(
8047*6777b538SAndroid Build Coastguard Worker       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8048*6777b538SAndroid Build Coastguard Worker }
8049*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,ExternalValidation_LogsHeaders)8050*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ExternalValidation_LogsHeaders) {
8051*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8052*6777b538SAndroid Build Coastguard Worker 
8053*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_observer;
8054*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
8055*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "If-None-Match: foo\r\n" EXTRA_HEADER;
8056*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithLog(cache.http_cache(), transaction,
8057*6777b538SAndroid Build Coastguard Worker                             NetLogWithSource::Make(NetLogSourceType::NONE));
8058*6777b538SAndroid Build Coastguard Worker 
8059*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEventType(
8060*6777b538SAndroid Build Coastguard Worker       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8061*6777b538SAndroid Build Coastguard Worker }
8062*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SpecialHeaders_LogsHeaders)8063*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SpecialHeaders_LogsHeaders) {
8064*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8065*6777b538SAndroid Build Coastguard Worker 
8066*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_observer;
8067*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
8068*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "cache-control: no-cache\r\n" EXTRA_HEADER;
8069*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithLog(cache.http_cache(), transaction,
8070*6777b538SAndroid Build Coastguard Worker                             NetLogWithSource::Make(NetLogSourceType::NONE));
8071*6777b538SAndroid Build Coastguard Worker 
8072*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEventType(
8073*6777b538SAndroid Build Coastguard Worker       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8074*6777b538SAndroid Build Coastguard Worker }
8075*6777b538SAndroid Build Coastguard Worker 
8076*6777b538SAndroid Build Coastguard Worker // Tests that receiving 206 for a regular request is handled correctly.
TEST_F(HttpCacheTest,GET_Crazy206)8077*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_Crazy206) {
8078*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8079*6777b538SAndroid Build Coastguard Worker 
8080*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
8081*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8082*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
8083*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
8084*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8085*6777b538SAndroid Build Coastguard Worker 
8086*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8087*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8088*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8089*6777b538SAndroid Build Coastguard Worker 
8090*6777b538SAndroid Build Coastguard Worker   // This should read again from the net.
8091*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8092*6777b538SAndroid Build Coastguard Worker 
8093*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8094*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8095*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8096*6777b538SAndroid Build Coastguard Worker }
8097*6777b538SAndroid Build Coastguard Worker 
8098*6777b538SAndroid Build Coastguard Worker // Tests that receiving 416 for a regular request is handled correctly.
TEST_F(HttpCacheTest,GET_Crazy416)8099*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_Crazy416) {
8100*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8101*6777b538SAndroid Build Coastguard Worker 
8102*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
8103*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
8104*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
8105*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8106*6777b538SAndroid Build Coastguard Worker 
8107*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8108*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8109*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8110*6777b538SAndroid Build Coastguard Worker }
8111*6777b538SAndroid Build Coastguard Worker 
8112*6777b538SAndroid Build Coastguard Worker // Tests that we don't store partial responses that can't be validated.
TEST_F(HttpCacheTest,RangeGET_NoStrongValidators)8113*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_NoStrongValidators) {
8114*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8115*6777b538SAndroid Build Coastguard Worker   std::string headers;
8116*6777b538SAndroid Build Coastguard Worker 
8117*6777b538SAndroid Build Coastguard Worker   // Attempt to write to the cache (40-49).
8118*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8119*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
8120*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n"
8121*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=3600\n"
8122*6777b538SAndroid Build Coastguard Worker       "ETag: w/\"foo\"\n";
8123*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8124*6777b538SAndroid Build Coastguard Worker 
8125*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8126*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8127*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8128*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8129*6777b538SAndroid Build Coastguard Worker 
8130*6777b538SAndroid Build Coastguard Worker   // Now verify that there's no cached data.
8131*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8132*6777b538SAndroid Build Coastguard Worker                                  &headers);
8133*6777b538SAndroid Build Coastguard Worker 
8134*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8135*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8136*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8137*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8138*6777b538SAndroid Build Coastguard Worker }
8139*6777b538SAndroid Build Coastguard Worker 
8140*6777b538SAndroid Build Coastguard Worker // Tests failures to conditionalize byte range requests.
TEST_F(HttpCacheTest,RangeGET_NoConditionalization)8141*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_NoConditionalization) {
8142*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8143*6777b538SAndroid Build Coastguard Worker   cache.FailConditionalizations();
8144*6777b538SAndroid Build Coastguard Worker   std::string headers;
8145*6777b538SAndroid Build Coastguard Worker 
8146*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
8147*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8148*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
8149*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n"
8150*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n";
8151*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8152*6777b538SAndroid Build Coastguard Worker 
8153*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8154*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8155*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8156*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8157*6777b538SAndroid Build Coastguard Worker 
8158*6777b538SAndroid Build Coastguard Worker   // Now verify that the cached data is not used.
8159*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8160*6777b538SAndroid Build Coastguard Worker                                  &headers);
8161*6777b538SAndroid Build Coastguard Worker 
8162*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8163*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8164*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8165*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8166*6777b538SAndroid Build Coastguard Worker }
8167*6777b538SAndroid Build Coastguard Worker 
8168*6777b538SAndroid Build Coastguard Worker // Tests that restarting a partial request when the cached data cannot be
8169*6777b538SAndroid Build Coastguard Worker // revalidated logs an event.
TEST_F(HttpCacheTest,RangeGET_NoValidation_LogsRestart)8170*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_NoValidation_LogsRestart) {
8171*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8172*6777b538SAndroid Build Coastguard Worker   cache.FailConditionalizations();
8173*6777b538SAndroid Build Coastguard Worker 
8174*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
8175*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8176*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
8177*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n"
8178*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n";
8179*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8180*6777b538SAndroid Build Coastguard Worker 
8181*6777b538SAndroid Build Coastguard Worker   // Now verify that the cached data is not used.
8182*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_observer;
8183*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithLog(cache.http_cache(), kRangeGET_TransactionOK,
8184*6777b538SAndroid Build Coastguard Worker                             NetLogWithSource::Make(NetLogSourceType::NONE));
8185*6777b538SAndroid Build Coastguard Worker 
8186*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEventType(
8187*6777b538SAndroid Build Coastguard Worker       net_log_observer, NetLogEventType::HTTP_CACHE_RESTART_PARTIAL_REQUEST));
8188*6777b538SAndroid Build Coastguard Worker }
8189*6777b538SAndroid Build Coastguard Worker 
8190*6777b538SAndroid Build Coastguard Worker // Tests that a failure to conditionalize a regular request (no range) with a
8191*6777b538SAndroid Build Coastguard Worker // sparse entry results in a full response.
TEST_F(HttpCacheTest,GET_NoConditionalization)8192*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_NoConditionalization) {
8193*6777b538SAndroid Build Coastguard Worker   for (bool use_memory_entry_data : {false, true}) {
8194*6777b538SAndroid Build Coastguard Worker     MockHttpCache cache;
8195*6777b538SAndroid Build Coastguard Worker     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
8196*6777b538SAndroid Build Coastguard Worker     cache.FailConditionalizations();
8197*6777b538SAndroid Build Coastguard Worker     std::string headers;
8198*6777b538SAndroid Build Coastguard Worker 
8199*6777b538SAndroid Build Coastguard Worker     // Write to the cache (40-49).
8200*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8201*6777b538SAndroid Build Coastguard Worker     transaction.response_headers =
8202*6777b538SAndroid Build Coastguard Worker         "Content-Length: 10\n"
8203*6777b538SAndroid Build Coastguard Worker         "ETag: \"foo\"\n";
8204*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8205*6777b538SAndroid Build Coastguard Worker 
8206*6777b538SAndroid Build Coastguard Worker     Verify206Response(headers, 40, 49);
8207*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
8208*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache.disk_cache()->open_count());
8209*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
8210*6777b538SAndroid Build Coastguard Worker 
8211*6777b538SAndroid Build Coastguard Worker     // Now verify that the cached data is not used.
8212*6777b538SAndroid Build Coastguard Worker     // Don't ask for a range. The cache will attempt to use the cached data but
8213*6777b538SAndroid Build Coastguard Worker     // should discard it as it cannot be validated. A regular request should go
8214*6777b538SAndroid Build Coastguard Worker     // to the server and a new entry should be created.
8215*6777b538SAndroid Build Coastguard Worker     transaction.request_headers = EXTRA_HEADER;
8216*6777b538SAndroid Build Coastguard Worker     transaction.data = "Not a range";
8217*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8218*6777b538SAndroid Build Coastguard Worker 
8219*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
8220*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.network_layer()->transaction_count());
8221*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->open_count());
8222*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.disk_cache()->create_count());
8223*6777b538SAndroid Build Coastguard Worker 
8224*6777b538SAndroid Build Coastguard Worker     // The last response was saved.
8225*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
8226*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(3, cache.network_layer()->transaction_count());
8227*6777b538SAndroid Build Coastguard Worker     if (use_memory_entry_data) {
8228*6777b538SAndroid Build Coastguard Worker       // The cache entry isn't really useful, since when
8229*6777b538SAndroid Build Coastguard Worker       // &RangeTransactionServer::RangeHandler gets a non-range request,
8230*6777b538SAndroid Build Coastguard Worker       // (the network transaction #2) it returns headers without ETag,
8231*6777b538SAndroid Build Coastguard Worker       // Last-Modified or caching headers, with a Date in 2007 (so no heuristic
8232*6777b538SAndroid Build Coastguard Worker       // freshness), so it's both expired and not conditionalizable --- so in
8233*6777b538SAndroid Build Coastguard Worker       // this branch we avoid opening it.
8234*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(1, cache.disk_cache()->open_count());
8235*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(3, cache.disk_cache()->create_count());
8236*6777b538SAndroid Build Coastguard Worker     } else {
8237*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(2, cache.disk_cache()->open_count());
8238*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(2, cache.disk_cache()->create_count());
8239*6777b538SAndroid Build Coastguard Worker     }
8240*6777b538SAndroid Build Coastguard Worker   }
8241*6777b538SAndroid Build Coastguard Worker }
8242*6777b538SAndroid Build Coastguard Worker 
8243*6777b538SAndroid Build Coastguard Worker // Verifies that conditionalization failures when asking for a range that would
8244*6777b538SAndroid Build Coastguard Worker // require the cache to modify the range to ask, result in a network request
8245*6777b538SAndroid Build Coastguard Worker // that matches the user's one.
TEST_F(HttpCacheTest,RangeGET_NoConditionalization2)8246*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_NoConditionalization2) {
8247*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8248*6777b538SAndroid Build Coastguard Worker   cache.FailConditionalizations();
8249*6777b538SAndroid Build Coastguard Worker   std::string headers;
8250*6777b538SAndroid Build Coastguard Worker 
8251*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
8252*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8253*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
8254*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n"
8255*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n";
8256*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8257*6777b538SAndroid Build Coastguard Worker 
8258*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8259*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8260*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8261*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8262*6777b538SAndroid Build Coastguard Worker 
8263*6777b538SAndroid Build Coastguard Worker   // Now verify that the cached data is not used.
8264*6777b538SAndroid Build Coastguard Worker   // Ask for a range that extends before and after the cached data so that the
8265*6777b538SAndroid Build Coastguard Worker   // cache would normally mix data from three sources. After deleting the entry,
8266*6777b538SAndroid Build Coastguard Worker   // the response will come from a single network request.
8267*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8268*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8269*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = kRangeGET_TransactionOK.response_headers;
8270*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8271*6777b538SAndroid Build Coastguard Worker 
8272*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 20, 59);
8273*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8274*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8275*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8276*6777b538SAndroid Build Coastguard Worker 
8277*6777b538SAndroid Build Coastguard Worker   // The last response was saved.
8278*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8279*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8280*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
8281*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8282*6777b538SAndroid Build Coastguard Worker }
8283*6777b538SAndroid Build Coastguard Worker 
8284*6777b538SAndroid Build Coastguard Worker // Tests that we cache partial responses that lack content-length.
TEST_F(HttpCacheTest,RangeGET_NoContentLength)8285*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_NoContentLength) {
8286*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8287*6777b538SAndroid Build Coastguard Worker   std::string headers;
8288*6777b538SAndroid Build Coastguard Worker 
8289*6777b538SAndroid Build Coastguard Worker   // Attempt to write to the cache (40-49).
8290*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8291*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
8292*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
8293*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
8294*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes 40-49/80\n";
8295*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
8296*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8297*6777b538SAndroid Build Coastguard Worker 
8298*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8299*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8300*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8301*6777b538SAndroid Build Coastguard Worker 
8302*6777b538SAndroid Build Coastguard Worker   // Now verify that there's no cached data.
8303*6777b538SAndroid Build Coastguard Worker   transaction.handler =
8304*6777b538SAndroid Build Coastguard Worker       base::BindRepeating(&RangeTransactionServer::RangeHandler);
8305*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8306*6777b538SAndroid Build Coastguard Worker                                  &headers);
8307*6777b538SAndroid Build Coastguard Worker 
8308*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8309*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8310*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8311*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8312*6777b538SAndroid Build Coastguard Worker }
8313*6777b538SAndroid Build Coastguard Worker 
8314*6777b538SAndroid Build Coastguard Worker // Tests that we can cache range requests and fetch random blocks from the
8315*6777b538SAndroid Build Coastguard Worker // cache and the network.
TEST_F(HttpCacheTest,RangeGET_OK)8316*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_OK) {
8317*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8318*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
8319*6777b538SAndroid Build Coastguard Worker   std::string headers;
8320*6777b538SAndroid Build Coastguard Worker 
8321*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
8322*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8323*6777b538SAndroid Build Coastguard Worker                                  &headers);
8324*6777b538SAndroid Build Coastguard Worker 
8325*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8326*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8327*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8328*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8329*6777b538SAndroid Build Coastguard Worker 
8330*6777b538SAndroid Build Coastguard Worker   // Read from the cache (40-49).
8331*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8332*6777b538SAndroid Build Coastguard Worker                                  &headers);
8333*6777b538SAndroid Build Coastguard Worker 
8334*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8335*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8336*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8337*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8338*6777b538SAndroid Build Coastguard Worker 
8339*6777b538SAndroid Build Coastguard Worker   // Make sure we are done with the previous transaction.
8340*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
8341*6777b538SAndroid Build Coastguard Worker 
8342*6777b538SAndroid Build Coastguard Worker   // Write to the cache (30-39).
8343*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_TransactionOK);
8344*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
8345*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 30-39 ";
8346*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8347*6777b538SAndroid Build Coastguard Worker 
8348*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 30, 39);
8349*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8350*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
8351*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8352*6777b538SAndroid Build Coastguard Worker 
8353*6777b538SAndroid Build Coastguard Worker   // Make sure we are done with the previous transaction.
8354*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
8355*6777b538SAndroid Build Coastguard Worker 
8356*6777b538SAndroid Build Coastguard Worker   // Write and read from the cache (20-59).
8357*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8358*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8359*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
8360*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseAndGetTiming(
8361*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), transaction, &headers,
8362*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
8363*6777b538SAndroid Build Coastguard Worker 
8364*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 20, 59);
8365*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8366*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->open_count());
8367*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8368*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
8369*6777b538SAndroid Build Coastguard Worker }
8370*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,RangeGET_CacheReadError)8371*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_CacheReadError) {
8372*6777b538SAndroid Build Coastguard Worker   // Tests recovery on cache read error on range request.
8373*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8374*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8375*6777b538SAndroid Build Coastguard Worker   std::string headers;
8376*6777b538SAndroid Build Coastguard Worker 
8377*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
8378*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8379*6777b538SAndroid Build Coastguard Worker                                  &headers);
8380*6777b538SAndroid Build Coastguard Worker 
8381*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8382*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8383*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8384*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8385*6777b538SAndroid Build Coastguard Worker 
8386*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_soft_failures_one_instance(MockDiskEntry::FAIL_ALL);
8387*6777b538SAndroid Build Coastguard Worker 
8388*6777b538SAndroid Build Coastguard Worker   // Try to read from the cache (40-49), which will fail quickly enough to
8389*6777b538SAndroid Build Coastguard Worker   // restart, due to the failure injected above.  This should still be a range
8390*6777b538SAndroid Build Coastguard Worker   // request. (https://crbug.com/891212)
8391*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8392*6777b538SAndroid Build Coastguard Worker                                  &headers);
8393*6777b538SAndroid Build Coastguard Worker 
8394*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8395*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8396*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8397*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8398*6777b538SAndroid Build Coastguard Worker }
8399*6777b538SAndroid Build Coastguard Worker 
8400*6777b538SAndroid Build Coastguard Worker // Tests that range requests with no-store get correct content-length
8401*6777b538SAndroid Build Coastguard Worker // (https://crbug.com/700197).
TEST_F(HttpCacheTest,RangeGET_NoStore)8402*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_NoStore) {
8403*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8404*6777b538SAndroid Build Coastguard Worker 
8405*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8406*6777b538SAndroid Build Coastguard Worker   std::string response_headers = base::StrCat(
8407*6777b538SAndroid Build Coastguard Worker       {kRangeGET_TransactionOK.response_headers, "Cache-Control: no-store\n"});
8408*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = response_headers.c_str();
8409*6777b538SAndroid Build Coastguard Worker 
8410*6777b538SAndroid Build Coastguard Worker   std::string headers;
8411*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8412*6777b538SAndroid Build Coastguard Worker 
8413*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8414*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8415*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8416*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8417*6777b538SAndroid Build Coastguard Worker }
8418*6777b538SAndroid Build Coastguard Worker 
8419*6777b538SAndroid Build Coastguard Worker // Tests a 304 setting no-store on existing 206 entry.
TEST_F(HttpCacheTest,RangeGET_NoStore304)8420*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_NoStore304) {
8421*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8422*6777b538SAndroid Build Coastguard Worker 
8423*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8424*6777b538SAndroid Build Coastguard Worker   std::string response_headers = base::StrCat(
8425*6777b538SAndroid Build Coastguard Worker       {kRangeGET_TransactionOK.response_headers, "Cache-Control: max-age=0\n"});
8426*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = response_headers.c_str();
8427*6777b538SAndroid Build Coastguard Worker 
8428*6777b538SAndroid Build Coastguard Worker   std::string headers;
8429*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8430*6777b538SAndroid Build Coastguard Worker 
8431*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8432*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8433*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8434*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8435*6777b538SAndroid Build Coastguard Worker 
8436*6777b538SAndroid Build Coastguard Worker   response_headers = base::StrCat(
8437*6777b538SAndroid Build Coastguard Worker       {kRangeGET_TransactionOK.response_headers, "Cache-Control: no-store\n"});
8438*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = response_headers.c_str();
8439*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8440*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8441*6777b538SAndroid Build Coastguard Worker 
8442*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8443*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8444*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8445*6777b538SAndroid Build Coastguard Worker 
8446*6777b538SAndroid Build Coastguard Worker   // Fetch again, this one should be from newly created cache entry, due to
8447*6777b538SAndroid Build Coastguard Worker   // earlier no-store.
8448*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = kRangeGET_TransactionOK.response_headers;
8449*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8450*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8451*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8452*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8453*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8454*6777b538SAndroid Build Coastguard Worker }
8455*6777b538SAndroid Build Coastguard Worker 
8456*6777b538SAndroid Build Coastguard Worker // Tests that we can cache range requests and fetch random blocks from the
8457*6777b538SAndroid Build Coastguard Worker // cache and the network, with synchronous responses.
TEST_F(HttpCacheTest,RangeGET_SyncOK)8458*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_SyncOK) {
8459*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8460*6777b538SAndroid Build Coastguard Worker 
8461*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8462*6777b538SAndroid Build Coastguard Worker   transaction.test_mode = TEST_MODE_SYNC_ALL;
8463*6777b538SAndroid Build Coastguard Worker 
8464*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
8465*6777b538SAndroid Build Coastguard Worker   std::string headers;
8466*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8467*6777b538SAndroid Build Coastguard Worker 
8468*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8469*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8470*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8471*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8472*6777b538SAndroid Build Coastguard Worker 
8473*6777b538SAndroid Build Coastguard Worker   // Read from the cache (40-49).
8474*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8475*6777b538SAndroid Build Coastguard Worker 
8476*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8477*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8478*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8479*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8480*6777b538SAndroid Build Coastguard Worker 
8481*6777b538SAndroid Build Coastguard Worker   // Make sure we are done with the previous transaction.
8482*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
8483*6777b538SAndroid Build Coastguard Worker 
8484*6777b538SAndroid Build Coastguard Worker   // Write to the cache (30-39).
8485*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
8486*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 30-39 ";
8487*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8488*6777b538SAndroid Build Coastguard Worker 
8489*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 30, 39);
8490*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8491*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8492*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8493*6777b538SAndroid Build Coastguard Worker 
8494*6777b538SAndroid Build Coastguard Worker   // Make sure we are done with the previous transaction.
8495*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
8496*6777b538SAndroid Build Coastguard Worker 
8497*6777b538SAndroid Build Coastguard Worker   // Write and read from the cache (20-59).
8498*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8499*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8500*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
8501*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseAndGetTiming(
8502*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), transaction, &headers,
8503*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
8504*6777b538SAndroid Build Coastguard Worker 
8505*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 20, 59);
8506*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8507*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
8508*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8509*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
8510*6777b538SAndroid Build Coastguard Worker }
8511*6777b538SAndroid Build Coastguard Worker 
8512*6777b538SAndroid Build Coastguard Worker // Tests that if the previous transaction is cancelled while busy (doing sparse
8513*6777b538SAndroid Build Coastguard Worker // IO), a new transaction (that reuses that same ActiveEntry) waits until the
8514*6777b538SAndroid Build Coastguard Worker // entry is ready again.
TEST_F(HttpCacheTest,Sparse_WaitForEntry)8515*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, Sparse_WaitForEntry) {
8516*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8517*6777b538SAndroid Build Coastguard Worker 
8518*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8519*6777b538SAndroid Build Coastguard Worker 
8520*6777b538SAndroid Build Coastguard Worker   // Create a sparse entry.
8521*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8522*6777b538SAndroid Build Coastguard Worker 
8523*6777b538SAndroid Build Coastguard Worker   // Simulate a previous transaction being cancelled.
8524*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
8525*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
8526*6777b538SAndroid Build Coastguard Worker   std::string cache_key =
8527*6777b538SAndroid Build Coastguard Worker       *cache.http_cache()->GenerateCacheKeyForRequest(&request);
8528*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache.OpenBackendEntry(cache_key, &entry));
8529*6777b538SAndroid Build Coastguard Worker   entry->CancelSparseIO();
8530*6777b538SAndroid Build Coastguard Worker 
8531*6777b538SAndroid Build Coastguard Worker   // Test with a range request.
8532*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8533*6777b538SAndroid Build Coastguard Worker 
8534*6777b538SAndroid Build Coastguard Worker   // Now test with a regular request.
8535*6777b538SAndroid Build Coastguard Worker   entry->CancelSparseIO();
8536*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
8537*6777b538SAndroid Build Coastguard Worker   transaction.data = kFullRangeData;
8538*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8539*6777b538SAndroid Build Coastguard Worker 
8540*6777b538SAndroid Build Coastguard Worker   entry->Close();
8541*6777b538SAndroid Build Coastguard Worker }
8542*6777b538SAndroid Build Coastguard Worker 
8543*6777b538SAndroid Build Coastguard Worker // Tests that we don't revalidate an entry unless we are required to do so.
TEST_F(HttpCacheTest,RangeGET_Revalidate1)8544*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_Revalidate1) {
8545*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8546*6777b538SAndroid Build Coastguard Worker   std::string headers;
8547*6777b538SAndroid Build Coastguard Worker 
8548*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
8549*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8550*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
8551*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
8552*6777b538SAndroid Build Coastguard Worker       "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n"  // Should never expire.
8553*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
8554*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
8555*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n";
8556*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8557*6777b538SAndroid Build Coastguard Worker 
8558*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8559*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8560*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8561*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8562*6777b538SAndroid Build Coastguard Worker 
8563*6777b538SAndroid Build Coastguard Worker   // Read from the cache (40-49).
8564*6777b538SAndroid Build Coastguard Worker   NetLogWithSource net_log_with_source =
8565*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE);
8566*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
8567*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
8568*6777b538SAndroid Build Coastguard Worker                                              &headers, net_log_with_source,
8569*6777b538SAndroid Build Coastguard Worker                                              &load_timing_info);
8570*6777b538SAndroid Build Coastguard Worker 
8571*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8572*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8573*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8574*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8575*6777b538SAndroid Build Coastguard Worker   TestLoadTimingCachedResponse(load_timing_info);
8576*6777b538SAndroid Build Coastguard Worker 
8577*6777b538SAndroid Build Coastguard Worker   // Read again forcing the revalidation.
8578*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8579*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
8580*6777b538SAndroid Build Coastguard Worker                                              &headers, net_log_with_source,
8581*6777b538SAndroid Build Coastguard Worker                                              &load_timing_info);
8582*6777b538SAndroid Build Coastguard Worker 
8583*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8584*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8585*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8586*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8587*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
8588*6777b538SAndroid Build Coastguard Worker }
8589*6777b538SAndroid Build Coastguard Worker 
8590*6777b538SAndroid Build Coastguard Worker // Checks that we revalidate an entry when the headers say so.
TEST_F(HttpCacheTest,RangeGET_Revalidate2)8591*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_Revalidate2) {
8592*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8593*6777b538SAndroid Build Coastguard Worker   std::string headers;
8594*6777b538SAndroid Build Coastguard Worker 
8595*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
8596*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8597*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
8598*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
8599*6777b538SAndroid Build Coastguard Worker       "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n"  // Expired.
8600*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
8601*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
8602*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n";
8603*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8604*6777b538SAndroid Build Coastguard Worker 
8605*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8606*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8607*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8608*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8609*6777b538SAndroid Build Coastguard Worker 
8610*6777b538SAndroid Build Coastguard Worker   // Read from the cache (40-49).
8611*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8612*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8613*6777b538SAndroid Build Coastguard Worker 
8614*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8615*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8616*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8617*6777b538SAndroid Build Coastguard Worker }
8618*6777b538SAndroid Build Coastguard Worker 
8619*6777b538SAndroid Build Coastguard Worker // Tests that we deal with 304s for range requests.
TEST_F(HttpCacheTest,RangeGET_304)8620*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_304) {
8621*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8622*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
8623*6777b538SAndroid Build Coastguard Worker   std::string headers;
8624*6777b538SAndroid Build Coastguard Worker 
8625*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
8626*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), scoped_transaction,
8627*6777b538SAndroid Build Coastguard Worker                                  &headers);
8628*6777b538SAndroid Build Coastguard Worker 
8629*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8630*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8631*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8632*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8633*6777b538SAndroid Build Coastguard Worker 
8634*6777b538SAndroid Build Coastguard Worker   // Read from the cache (40-49).
8635*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer handler;
8636*6777b538SAndroid Build Coastguard Worker   handler.set_not_modified(true);
8637*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_TransactionOK);
8638*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8639*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8640*6777b538SAndroid Build Coastguard Worker 
8641*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8642*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8643*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8644*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8645*6777b538SAndroid Build Coastguard Worker }
8646*6777b538SAndroid Build Coastguard Worker 
8647*6777b538SAndroid Build Coastguard Worker // Tests that we deal with 206s when revalidating range requests.
TEST_F(HttpCacheTest,RangeGET_ModifiedResult)8648*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_ModifiedResult) {
8649*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8650*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
8651*6777b538SAndroid Build Coastguard Worker   std::string headers;
8652*6777b538SAndroid Build Coastguard Worker 
8653*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
8654*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), scoped_transaction,
8655*6777b538SAndroid Build Coastguard Worker                                  &headers);
8656*6777b538SAndroid Build Coastguard Worker 
8657*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8658*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8659*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8660*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8661*6777b538SAndroid Build Coastguard Worker 
8662*6777b538SAndroid Build Coastguard Worker   // Attempt to read from the cache (40-49).
8663*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer handler;
8664*6777b538SAndroid Build Coastguard Worker   handler.set_modified(true);
8665*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_TransactionOK);
8666*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8667*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8668*6777b538SAndroid Build Coastguard Worker 
8669*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8670*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8671*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8672*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8673*6777b538SAndroid Build Coastguard Worker 
8674*6777b538SAndroid Build Coastguard Worker   // And the entry should be gone.
8675*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
8676*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8677*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8678*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8679*6777b538SAndroid Build Coastguard Worker }
8680*6777b538SAndroid Build Coastguard Worker 
8681*6777b538SAndroid Build Coastguard Worker // Tests that when a server returns 206 with a sub-range of the requested range,
8682*6777b538SAndroid Build Coastguard Worker // and there is nothing stored in the cache, the returned response is passed to
8683*6777b538SAndroid Build Coastguard Worker // the caller as is. In this context, a subrange means a response that starts
8684*6777b538SAndroid Build Coastguard Worker // with the same byte that was requested, but that is not the whole range that
8685*6777b538SAndroid Build Coastguard Worker // was requested.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSubrangeRange_NoCachedContent)8686*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_206ReturnsSubrangeRange_NoCachedContent) {
8687*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8688*6777b538SAndroid Build Coastguard Worker   std::string headers;
8689*6777b538SAndroid Build Coastguard Worker 
8690*6777b538SAndroid Build Coastguard Worker   // Request a large range (40-59). The server sends 40-49.
8691*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8692*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
8693*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
8694*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8695*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
8696*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
8697*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n"
8698*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes 40-49/80\n";
8699*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
8700*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8701*6777b538SAndroid Build Coastguard Worker 
8702*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8703*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8704*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8705*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8706*6777b538SAndroid Build Coastguard Worker }
8707*6777b538SAndroid Build Coastguard Worker 
8708*6777b538SAndroid Build Coastguard Worker // Tests that when a server returns 206 with a sub-range of the requested range,
8709*6777b538SAndroid Build Coastguard Worker // and there was an entry stored in the cache, the cache gets out of the way.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSubrangeRange_CachedContent)8710*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_206ReturnsSubrangeRange_CachedContent) {
8711*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8712*6777b538SAndroid Build Coastguard Worker   std::string headers;
8713*6777b538SAndroid Build Coastguard Worker 
8714*6777b538SAndroid Build Coastguard Worker   // Write to the cache (70-79).
8715*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8716*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8717*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 70-79 ";
8718*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8719*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 70, 79);
8720*6777b538SAndroid Build Coastguard Worker 
8721*6777b538SAndroid Build Coastguard Worker   // Request a large range (40-79). The cache will ask the server for 40-59.
8722*6777b538SAndroid Build Coastguard Worker   // The server returns 40-49. The cache should consider the server confused and
8723*6777b538SAndroid Build Coastguard Worker   // abort caching, restarting the request without caching.
8724*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 40-79\r\n" EXTRA_HEADER;
8725*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
8726*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8727*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
8728*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
8729*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n"
8730*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes 40-49/80\n";
8731*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
8732*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8733*6777b538SAndroid Build Coastguard Worker 
8734*6777b538SAndroid Build Coastguard Worker   // Two new network requests were issued, one from the cache and another after
8735*6777b538SAndroid Build Coastguard Worker   // deleting the entry.
8736*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8737*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8738*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8739*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8740*6777b538SAndroid Build Coastguard Worker 
8741*6777b538SAndroid Build Coastguard Worker   // The entry was deleted.
8742*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8743*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8744*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8745*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8746*6777b538SAndroid Build Coastguard Worker }
8747*6777b538SAndroid Build Coastguard Worker 
8748*6777b538SAndroid Build Coastguard Worker // Tests that when a server returns 206 with a sub-range of the requested range,
8749*6777b538SAndroid Build Coastguard Worker // and there was an entry stored in the cache, the cache gets out of the way,
8750*6777b538SAndroid Build Coastguard Worker // when the caller is not using ranges.
TEST_F(HttpCacheTest,GET_206ReturnsSubrangeRange_CachedContent)8751*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_206ReturnsSubrangeRange_CachedContent) {
8752*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8753*6777b538SAndroid Build Coastguard Worker   std::string headers;
8754*6777b538SAndroid Build Coastguard Worker 
8755*6777b538SAndroid Build Coastguard Worker   // Write to the cache (70-79).
8756*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8757*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8758*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 70-79 ";
8759*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8760*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 70, 79);
8761*6777b538SAndroid Build Coastguard Worker 
8762*6777b538SAndroid Build Coastguard Worker   // Don't ask for a range. The cache will ask the server for 0-69.
8763*6777b538SAndroid Build Coastguard Worker   // The server returns 40-49. The cache should consider the server confused and
8764*6777b538SAndroid Build Coastguard Worker   // abort caching, restarting the request.
8765*6777b538SAndroid Build Coastguard Worker   // The second network request should not be a byte range request so the server
8766*6777b538SAndroid Build Coastguard Worker   // should return 200 + "Not a range"
8767*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER;
8768*6777b538SAndroid Build Coastguard Worker   transaction.data = "Not a range";
8769*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8770*6777b538SAndroid Build Coastguard Worker 
8771*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
8772*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8773*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8774*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8775*6777b538SAndroid Build Coastguard Worker 
8776*6777b538SAndroid Build Coastguard Worker   // The entry was deleted.
8777*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8778*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8779*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8780*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8781*6777b538SAndroid Build Coastguard Worker }
8782*6777b538SAndroid Build Coastguard Worker 
8783*6777b538SAndroid Build Coastguard Worker // Tests that when a server returns 206 with a random range and there is
8784*6777b538SAndroid Build Coastguard Worker // nothing stored in the cache, the returned response is passed to the caller
8785*6777b538SAndroid Build Coastguard Worker // as is. In this context, a WrongRange means that the returned range may or may
8786*6777b538SAndroid Build Coastguard Worker // not have any relationship with the requested range (may or may not be
8787*6777b538SAndroid Build Coastguard Worker // contained). The important part is that the first byte doesn't match the first
8788*6777b538SAndroid Build Coastguard Worker // requested byte.
TEST_F(HttpCacheTest,RangeGET_206ReturnsWrongRange_NoCachedContent)8789*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_206ReturnsWrongRange_NoCachedContent) {
8790*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8791*6777b538SAndroid Build Coastguard Worker   std::string headers;
8792*6777b538SAndroid Build Coastguard Worker 
8793*6777b538SAndroid Build Coastguard Worker   // Request a large range (30-59). The server sends (40-49).
8794*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8795*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
8796*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
8797*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8798*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
8799*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
8800*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n"
8801*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes 40-49/80\n";
8802*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
8803*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8804*6777b538SAndroid Build Coastguard Worker 
8805*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8806*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8807*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8808*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8809*6777b538SAndroid Build Coastguard Worker 
8810*6777b538SAndroid Build Coastguard Worker   // The entry was deleted.
8811*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8812*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8813*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8814*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8815*6777b538SAndroid Build Coastguard Worker }
8816*6777b538SAndroid Build Coastguard Worker 
8817*6777b538SAndroid Build Coastguard Worker // Tests that when a server returns 206 with a random range and there is
8818*6777b538SAndroid Build Coastguard Worker // an entry stored in the cache, the cache gets out of the way.
TEST_F(HttpCacheTest,RangeGET_206ReturnsWrongRange_CachedContent)8819*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_206ReturnsWrongRange_CachedContent) {
8820*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8821*6777b538SAndroid Build Coastguard Worker   std::string headers;
8822*6777b538SAndroid Build Coastguard Worker 
8823*6777b538SAndroid Build Coastguard Worker   // Write to the cache (70-79).
8824*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8825*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8826*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 70-79 ";
8827*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8828*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 70, 79);
8829*6777b538SAndroid Build Coastguard Worker 
8830*6777b538SAndroid Build Coastguard Worker   // Request a large range (30-79). The cache will ask the server for 30-69.
8831*6777b538SAndroid Build Coastguard Worker   // The server returns 40-49. The cache should consider the server confused and
8832*6777b538SAndroid Build Coastguard Worker   // abort caching, returning the weird range to the caller.
8833*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 30-79\r\n" EXTRA_HEADER;
8834*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
8835*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8836*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
8837*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
8838*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n"
8839*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes 40-49/80\n";
8840*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
8841*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8842*6777b538SAndroid Build Coastguard Worker 
8843*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
8844*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8845*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8846*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8847*6777b538SAndroid Build Coastguard Worker 
8848*6777b538SAndroid Build Coastguard Worker   // The entry was deleted.
8849*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8850*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8851*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8852*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8853*6777b538SAndroid Build Coastguard Worker }
8854*6777b538SAndroid Build Coastguard Worker 
8855*6777b538SAndroid Build Coastguard Worker // Tests that when a caller asks for a range beyond EOF, with an empty cache,
8856*6777b538SAndroid Build Coastguard Worker // the response matches the one provided by the server.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSmallerFile_NoCachedContent)8857*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_206ReturnsSmallerFile_NoCachedContent) {
8858*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8859*6777b538SAndroid Build Coastguard Worker   std::string headers;
8860*6777b538SAndroid Build Coastguard Worker 
8861*6777b538SAndroid Build Coastguard Worker   // Request a large range (70-99). The server sends 70-79.
8862*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8863*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
8864*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 70-79 ";
8865*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8866*6777b538SAndroid Build Coastguard Worker 
8867*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 70, 79);
8868*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8869*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8870*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8871*6777b538SAndroid Build Coastguard Worker 
8872*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
8873*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8874*6777b538SAndroid Build Coastguard Worker }
8875*6777b538SAndroid Build Coastguard Worker 
8876*6777b538SAndroid Build Coastguard Worker // Tests that when a caller asks for a range beyond EOF, with a cached entry,
8877*6777b538SAndroid Build Coastguard Worker // the cache automatically fixes the request.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSmallerFile_CachedContent)8878*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_206ReturnsSmallerFile_CachedContent) {
8879*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8880*6777b538SAndroid Build Coastguard Worker   std::string headers;
8881*6777b538SAndroid Build Coastguard Worker 
8882*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
8883*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8884*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8885*6777b538SAndroid Build Coastguard Worker 
8886*6777b538SAndroid Build Coastguard Worker   // Request a large range (70-99). The server sends 70-79.
8887*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
8888*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 70-79 ";
8889*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8890*6777b538SAndroid Build Coastguard Worker 
8891*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 70, 79);
8892*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8893*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8894*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8895*6777b538SAndroid Build Coastguard Worker 
8896*6777b538SAndroid Build Coastguard Worker   // The entry was not deleted (the range was automatically fixed).
8897*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8898*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8899*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
8900*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8901*6777b538SAndroid Build Coastguard Worker }
8902*6777b538SAndroid Build Coastguard Worker 
8903*6777b538SAndroid Build Coastguard Worker // Tests that when a caller asks for a not-satisfiable range, the server's
8904*6777b538SAndroid Build Coastguard Worker // response is forwarded to the caller.
TEST_F(HttpCacheTest,RangeGET_416_NoCachedContent)8905*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_416_NoCachedContent) {
8906*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8907*6777b538SAndroid Build Coastguard Worker   std::string headers;
8908*6777b538SAndroid Build Coastguard Worker 
8909*6777b538SAndroid Build Coastguard Worker   // Request a range beyond EOF (80-99).
8910*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8911*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 80-99\r\n" EXTRA_HEADER;
8912*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
8913*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
8914*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8915*6777b538SAndroid Build Coastguard Worker 
8916*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, headers.find(transaction.status));
8917*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8918*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8919*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8920*6777b538SAndroid Build Coastguard Worker 
8921*6777b538SAndroid Build Coastguard Worker   // The entry was deleted.
8922*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
8923*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
8924*6777b538SAndroid Build Coastguard Worker }
8925*6777b538SAndroid Build Coastguard Worker 
8926*6777b538SAndroid Build Coastguard Worker // Tests that we cache 301s for range requests.
TEST_F(HttpCacheTest,RangeGET_301)8927*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_301) {
8928*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8929*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8930*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 301 Moved Permanently";
8931*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "Location: http://www.bar.com/\n";
8932*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
8933*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
8934*6777b538SAndroid Build Coastguard Worker 
8935*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
8936*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8937*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8938*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8939*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8940*6777b538SAndroid Build Coastguard Worker 
8941*6777b538SAndroid Build Coastguard Worker   // Read from the cache.
8942*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
8943*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8944*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8945*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8946*6777b538SAndroid Build Coastguard Worker }
8947*6777b538SAndroid Build Coastguard Worker 
8948*6777b538SAndroid Build Coastguard Worker // Tests that we can cache range requests when the start or end is unknown.
8949*6777b538SAndroid Build Coastguard Worker // We start with one suffix request, followed by a request from a given point.
TEST_F(HttpCacheTest,UnknownRangeGET_1)8950*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, UnknownRangeGET_1) {
8951*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8952*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
8953*6777b538SAndroid Build Coastguard Worker   std::string headers;
8954*6777b538SAndroid Build Coastguard Worker 
8955*6777b538SAndroid Build Coastguard Worker   // Write to the cache (70-79).
8956*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_TransactionOK);
8957*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
8958*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 70-79 ";
8959*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8960*6777b538SAndroid Build Coastguard Worker 
8961*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 70, 79);
8962*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8963*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
8964*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8965*6777b538SAndroid Build Coastguard Worker 
8966*6777b538SAndroid Build Coastguard Worker   // Make sure we are done with the previous transaction.
8967*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
8968*6777b538SAndroid Build Coastguard Worker 
8969*6777b538SAndroid Build Coastguard Worker   // Write and read from the cache (60-79).
8970*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
8971*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 60-69 rg: 70-79 ";
8972*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8973*6777b538SAndroid Build Coastguard Worker 
8974*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 60, 79);
8975*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8976*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
8977*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
8978*6777b538SAndroid Build Coastguard Worker }
8979*6777b538SAndroid Build Coastguard Worker 
8980*6777b538SAndroid Build Coastguard Worker // Tests that we can cache range requests when the start or end is unknown.
8981*6777b538SAndroid Build Coastguard Worker // We start with one request from a given point, followed by a suffix request.
8982*6777b538SAndroid Build Coastguard Worker // We'll also verify that synchronous cache responses work as intended.
TEST_F(HttpCacheTest,UnknownRangeGET_2)8983*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, UnknownRangeGET_2) {
8984*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
8985*6777b538SAndroid Build Coastguard Worker   std::string headers;
8986*6777b538SAndroid Build Coastguard Worker 
8987*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8988*6777b538SAndroid Build Coastguard Worker   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
8989*6777b538SAndroid Build Coastguard Worker                           TEST_MODE_SYNC_CACHE_READ |
8990*6777b538SAndroid Build Coastguard Worker                           TEST_MODE_SYNC_CACHE_WRITE;
8991*6777b538SAndroid Build Coastguard Worker 
8992*6777b538SAndroid Build Coastguard Worker   // Write to the cache (70-79).
8993*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
8994*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 70-79 ";
8995*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8996*6777b538SAndroid Build Coastguard Worker 
8997*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 70, 79);
8998*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8999*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9000*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9001*6777b538SAndroid Build Coastguard Worker 
9002*6777b538SAndroid Build Coastguard Worker   // Make sure we are done with the previous transaction.
9003*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
9004*6777b538SAndroid Build Coastguard Worker 
9005*6777b538SAndroid Build Coastguard Worker   // Write and read from the cache (60-79).
9006*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
9007*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 60-69 rg: 70-79 ";
9008*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9009*6777b538SAndroid Build Coastguard Worker 
9010*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 60, 79);
9011*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9012*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9013*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9014*6777b538SAndroid Build Coastguard Worker }
9015*6777b538SAndroid Build Coastguard Worker 
9016*6777b538SAndroid Build Coastguard Worker // Similar to UnknownRangeGET_2, except that the resource size is empty.
9017*6777b538SAndroid Build Coastguard Worker // Regression test for crbug.com/813061, and probably https://crbug.com/1375128
TEST_F(HttpCacheTest,UnknownRangeGET_3)9018*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, UnknownRangeGET_3) {
9019*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9020*6777b538SAndroid Build Coastguard Worker   std::string headers;
9021*6777b538SAndroid Build Coastguard Worker 
9022*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9023*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
9024*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=10000\n"
9025*6777b538SAndroid Build Coastguard Worker       "Content-Length: 0\n",
9026*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
9027*6777b538SAndroid Build Coastguard Worker   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9028*6777b538SAndroid Build Coastguard Worker                           TEST_MODE_SYNC_CACHE_READ |
9029*6777b538SAndroid Build Coastguard Worker                           TEST_MODE_SYNC_CACHE_WRITE;
9030*6777b538SAndroid Build Coastguard Worker 
9031*6777b538SAndroid Build Coastguard Worker   // Write the empty resource to the cache.
9032*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9033*6777b538SAndroid Build Coastguard Worker 
9034*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
9035*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\nCache-Control: max-age=10000\nContent-Length: 0\n",
9036*6777b538SAndroid Build Coastguard Worker       headers);
9037*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9038*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9039*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9040*6777b538SAndroid Build Coastguard Worker 
9041*6777b538SAndroid Build Coastguard Worker   // Make sure we are done with the previous transaction.
9042*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
9043*6777b538SAndroid Build Coastguard Worker 
9044*6777b538SAndroid Build Coastguard Worker   // Write and read from the cache. This used to trigger a DCHECK
9045*6777b538SAndroid Build Coastguard Worker   // (or loop infinitely with it off).
9046*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
9047*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9048*6777b538SAndroid Build Coastguard Worker 
9049*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
9050*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\nCache-Control: max-age=10000\nContent-Length: 0\n",
9051*6777b538SAndroid Build Coastguard Worker       headers);
9052*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9053*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9054*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9055*6777b538SAndroid Build Coastguard Worker }
9056*6777b538SAndroid Build Coastguard Worker 
9057*6777b538SAndroid Build Coastguard Worker // Testcase for https://crbug.com/1433305, validation of range request to a
9058*6777b538SAndroid Build Coastguard Worker // cache 302, which is notably bodiless.
TEST_F(HttpCacheTest,UnknownRangeGET_302)9059*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, UnknownRangeGET_302) {
9060*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9061*6777b538SAndroid Build Coastguard Worker   std::string headers;
9062*6777b538SAndroid Build Coastguard Worker 
9063*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9064*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 302 Found";
9065*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
9066*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
9067*6777b538SAndroid Build Coastguard Worker       "Content-Length: 0\n"
9068*6777b538SAndroid Build Coastguard Worker       "Location: https://example.org/\n",
9069*6777b538SAndroid Build Coastguard Worker 
9070*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
9071*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 0-\r\n" EXTRA_HEADER;
9072*6777b538SAndroid Build Coastguard Worker   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9073*6777b538SAndroid Build Coastguard Worker                           TEST_MODE_SYNC_CACHE_READ |
9074*6777b538SAndroid Build Coastguard Worker                           TEST_MODE_SYNC_CACHE_WRITE;
9075*6777b538SAndroid Build Coastguard Worker 
9076*6777b538SAndroid Build Coastguard Worker   // Write the empty resource to the cache.
9077*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9078*6777b538SAndroid Build Coastguard Worker 
9079*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
9080*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 302 Found\n"
9081*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
9082*6777b538SAndroid Build Coastguard Worker       "Content-Length: 0\n"
9083*6777b538SAndroid Build Coastguard Worker       "Location: https://example.org/\n",
9084*6777b538SAndroid Build Coastguard Worker       headers);
9085*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9086*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9087*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9088*6777b538SAndroid Build Coastguard Worker 
9089*6777b538SAndroid Build Coastguard Worker   // Make sure we are done with the previous transaction.
9090*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
9091*6777b538SAndroid Build Coastguard Worker 
9092*6777b538SAndroid Build Coastguard Worker   // Try to read from the cache. This should send a network request to
9093*6777b538SAndroid Build Coastguard Worker   // validate it, and get a different redirect.
9094*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
9095*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
9096*6777b538SAndroid Build Coastguard Worker       "Content-Length: 0\n"
9097*6777b538SAndroid Build Coastguard Worker       "Location: https://example.com/\n",
9098*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9099*6777b538SAndroid Build Coastguard Worker 
9100*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
9101*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 302 Found\n"
9102*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
9103*6777b538SAndroid Build Coastguard Worker       "Content-Length: 0\n"
9104*6777b538SAndroid Build Coastguard Worker       "Location: https://example.com/\n",
9105*6777b538SAndroid Build Coastguard Worker       headers);
9106*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9107*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9108*6777b538SAndroid Build Coastguard Worker   // A new entry is created since this one isn't conditionalizable.
9109*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
9110*6777b538SAndroid Build Coastguard Worker }
9111*6777b538SAndroid Build Coastguard Worker 
9112*6777b538SAndroid Build Coastguard Worker // Testcase for https://crbug.com/1433305, validation of range request to a
9113*6777b538SAndroid Build Coastguard Worker // cache 302, which is notably bodiless, where the 302 is replaced with an
9114*6777b538SAndroid Build Coastguard Worker // actual body.
TEST_F(HttpCacheTest,UnknownRangeGET_302_Replaced)9115*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, UnknownRangeGET_302_Replaced) {
9116*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9117*6777b538SAndroid Build Coastguard Worker   std::string headers;
9118*6777b538SAndroid Build Coastguard Worker 
9119*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9120*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 302 Found";
9121*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
9122*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
9123*6777b538SAndroid Build Coastguard Worker       "Content-Length: 0\n"
9124*6777b538SAndroid Build Coastguard Worker       "Location: https://example.org/\n",
9125*6777b538SAndroid Build Coastguard Worker 
9126*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
9127*6777b538SAndroid Build Coastguard Worker   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9128*6777b538SAndroid Build Coastguard Worker                           TEST_MODE_SYNC_CACHE_READ |
9129*6777b538SAndroid Build Coastguard Worker                           TEST_MODE_SYNC_CACHE_WRITE;
9130*6777b538SAndroid Build Coastguard Worker 
9131*6777b538SAndroid Build Coastguard Worker   // Write the empty resource to the cache.
9132*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9133*6777b538SAndroid Build Coastguard Worker 
9134*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
9135*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 302 Found\n"
9136*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
9137*6777b538SAndroid Build Coastguard Worker       "Content-Length: 0\n"
9138*6777b538SAndroid Build Coastguard Worker       "Location: https://example.org/\n",
9139*6777b538SAndroid Build Coastguard Worker       headers);
9140*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9141*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9142*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9143*6777b538SAndroid Build Coastguard Worker 
9144*6777b538SAndroid Build Coastguard Worker   // Make sure we are done with the previous transaction.
9145*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
9146*6777b538SAndroid Build Coastguard Worker 
9147*6777b538SAndroid Build Coastguard Worker   // Try to read from the cache. This should send a network request to
9148*6777b538SAndroid Build Coastguard Worker   // validate it, and get a different response.
9149*6777b538SAndroid Build Coastguard Worker   transaction.handler =
9150*6777b538SAndroid Build Coastguard Worker       base::BindRepeating(&RangeTransactionServer::RangeHandler);
9151*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = -30\r\n" EXTRA_HEADER;
9152*6777b538SAndroid Build Coastguard Worker   // Tail 30 bytes out of 80
9153*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 50-59 rg: 60-69 rg: 70-79 ";
9154*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 206 Partial Content";
9155*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "Content-Length: 10\n";
9156*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9157*6777b538SAndroid Build Coastguard Worker 
9158*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
9159*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 206 Partial Content\n"
9160*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes 50-79/80\n"
9161*6777b538SAndroid Build Coastguard Worker       "Content-Length: 30\n",
9162*6777b538SAndroid Build Coastguard Worker       headers);
9163*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9164*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9165*6777b538SAndroid Build Coastguard Worker   // A new entry is created since this one isn't conditionalizable.
9166*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
9167*6777b538SAndroid Build Coastguard Worker }
9168*6777b538SAndroid Build Coastguard Worker 
9169*6777b538SAndroid Build Coastguard Worker // Tests that receiving Not Modified when asking for an open range doesn't mess
9170*6777b538SAndroid Build Coastguard Worker // up things.
TEST_F(HttpCacheTest,UnknownRangeGET_304)9171*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, UnknownRangeGET_304) {
9172*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9173*6777b538SAndroid Build Coastguard Worker   std::string headers;
9174*6777b538SAndroid Build Coastguard Worker 
9175*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9176*6777b538SAndroid Build Coastguard Worker 
9177*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer handler;
9178*6777b538SAndroid Build Coastguard Worker   handler.set_not_modified(true);
9179*6777b538SAndroid Build Coastguard Worker 
9180*6777b538SAndroid Build Coastguard Worker   // Ask for the end of the file, without knowing the length.
9181*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
9182*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
9183*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9184*6777b538SAndroid Build Coastguard Worker 
9185*6777b538SAndroid Build Coastguard Worker   // We just bypass the cache.
9186*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
9187*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9188*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9189*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9190*6777b538SAndroid Build Coastguard Worker 
9191*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
9192*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
9193*6777b538SAndroid Build Coastguard Worker }
9194*6777b538SAndroid Build Coastguard Worker 
9195*6777b538SAndroid Build Coastguard Worker // Tests that we can handle non-range requests when we have cached a range.
TEST_F(HttpCacheTest,GET_Previous206)9196*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_Previous206) {
9197*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9198*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9199*6777b538SAndroid Build Coastguard Worker   std::string headers;
9200*6777b538SAndroid Build Coastguard Worker   NetLogWithSource net_log_with_source =
9201*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE);
9202*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
9203*6777b538SAndroid Build Coastguard Worker 
9204*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
9205*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseAndGetTiming(
9206*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), kRangeGET_TransactionOK, &headers,
9207*6777b538SAndroid Build Coastguard Worker       net_log_with_source, &load_timing_info);
9208*6777b538SAndroid Build Coastguard Worker 
9209*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
9210*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9211*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9212*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9213*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
9214*6777b538SAndroid Build Coastguard Worker 
9215*6777b538SAndroid Build Coastguard Worker   // Write and read from the cache (0-79), when not asked for a range.
9216*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_TransactionOK);
9217*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
9218*6777b538SAndroid Build Coastguard Worker   transaction.data = kFullRangeData;
9219*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9220*6777b538SAndroid Build Coastguard Worker                                              &headers, net_log_with_source,
9221*6777b538SAndroid Build Coastguard Worker                                              &load_timing_info);
9222*6777b538SAndroid Build Coastguard Worker 
9223*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9224*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
9225*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9226*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9227*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
9228*6777b538SAndroid Build Coastguard Worker }
9229*6777b538SAndroid Build Coastguard Worker 
9230*6777b538SAndroid Build Coastguard Worker // Tests that we can handle non-range requests when we have cached the first
9231*6777b538SAndroid Build Coastguard Worker // part of the object and the server replies with 304 (Not Modified).
TEST_F(HttpCacheTest,GET_Previous206_NotModified)9232*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_Previous206_NotModified) {
9233*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9234*6777b538SAndroid Build Coastguard Worker 
9235*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9236*6777b538SAndroid Build Coastguard Worker   std::string headers;
9237*6777b538SAndroid Build Coastguard Worker   NetLogWithSource net_log_with_source =
9238*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE);
9239*6777b538SAndroid Build Coastguard Worker 
9240*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
9241*6777b538SAndroid Build Coastguard Worker 
9242*6777b538SAndroid Build Coastguard Worker   // Write to the cache (0-9).
9243*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
9244*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 00-09 ";
9245*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9246*6777b538SAndroid Build Coastguard Worker                                              &headers, net_log_with_source,
9247*6777b538SAndroid Build Coastguard Worker                                              &load_timing_info);
9248*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 0, 9);
9249*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
9250*6777b538SAndroid Build Coastguard Worker 
9251*6777b538SAndroid Build Coastguard Worker   // Write to the cache (70-79).
9252*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
9253*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 70-79 ";
9254*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9255*6777b538SAndroid Build Coastguard Worker                                              &headers, net_log_with_source,
9256*6777b538SAndroid Build Coastguard Worker                                              &load_timing_info);
9257*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 70, 79);
9258*6777b538SAndroid Build Coastguard Worker 
9259*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9260*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9261*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9262*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
9263*6777b538SAndroid Build Coastguard Worker 
9264*6777b538SAndroid Build Coastguard Worker   // Read from the cache (0-9), write and read from cache (10 - 79).
9265*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
9266*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
9267*6777b538SAndroid Build Coastguard Worker   transaction.data = kFullRangeData;
9268*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9269*6777b538SAndroid Build Coastguard Worker                                              &headers, net_log_with_source,
9270*6777b538SAndroid Build Coastguard Worker                                              &load_timing_info);
9271*6777b538SAndroid Build Coastguard Worker 
9272*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9273*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.network_layer()->transaction_count());
9274*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
9275*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9276*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
9277*6777b538SAndroid Build Coastguard Worker }
9278*6777b538SAndroid Build Coastguard Worker 
9279*6777b538SAndroid Build Coastguard Worker // Tests that we can handle a regular request to a sparse entry, that results in
9280*6777b538SAndroid Build Coastguard Worker // new content provided by the server (206).
TEST_F(HttpCacheTest,GET_Previous206_NewContent)9281*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_Previous206_NewContent) {
9282*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9283*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9284*6777b538SAndroid Build Coastguard Worker   std::string headers;
9285*6777b538SAndroid Build Coastguard Worker 
9286*6777b538SAndroid Build Coastguard Worker   // Write to the cache (0-9).
9287*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_TransactionOK);
9288*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
9289*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 00-09 ";
9290*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9291*6777b538SAndroid Build Coastguard Worker 
9292*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 0, 9);
9293*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9294*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9295*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9296*6777b538SAndroid Build Coastguard Worker 
9297*6777b538SAndroid Build Coastguard Worker   // Now we'll issue a request without any range that should result first in a
9298*6777b538SAndroid Build Coastguard Worker   // 206 (when revalidating), and then in a weird standard answer: the test
9299*6777b538SAndroid Build Coastguard Worker   // server will not modify the response so we'll get the default range... a
9300*6777b538SAndroid Build Coastguard Worker   // real server will answer with 200.
9301*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction2(kRangeGET_TransactionOK);
9302*6777b538SAndroid Build Coastguard Worker   transaction2.request_headers = EXTRA_HEADER;
9303*6777b538SAndroid Build Coastguard Worker   transaction2.load_flags |= LOAD_VALIDATE_CACHE;
9304*6777b538SAndroid Build Coastguard Worker   transaction2.data = "Not a range";
9305*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer handler;
9306*6777b538SAndroid Build Coastguard Worker   handler.set_modified(true);
9307*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
9308*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseAndGetTiming(
9309*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), transaction2, &headers,
9310*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
9311*6777b538SAndroid Build Coastguard Worker 
9312*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9313*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
9314*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9315*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9316*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
9317*6777b538SAndroid Build Coastguard Worker 
9318*6777b538SAndroid Build Coastguard Worker   // Verify that the previous request deleted the entry.
9319*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
9320*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
9321*6777b538SAndroid Build Coastguard Worker }
9322*6777b538SAndroid Build Coastguard Worker 
9323*6777b538SAndroid Build Coastguard Worker // Tests that we can handle cached 206 responses that are not sparse.
TEST_F(HttpCacheTest,GET_Previous206_NotSparse)9324*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_Previous206_NotSparse) {
9325*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9326*6777b538SAndroid Build Coastguard Worker 
9327*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
9328*6777b538SAndroid Build Coastguard Worker   // Create a disk cache entry that stores 206 headers while not being sparse.
9329*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
9330*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9331*6777b538SAndroid Build Coastguard Worker 
9332*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(kRangeGET_TransactionOK.status);
9333*6777b538SAndroid Build Coastguard Worker   raw_headers.append("\n");
9334*6777b538SAndroid Build Coastguard Worker   raw_headers.append(kRangeGET_TransactionOK.response_headers);
9335*6777b538SAndroid Build Coastguard Worker 
9336*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
9337*6777b538SAndroid Build Coastguard Worker   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9338*6777b538SAndroid Build Coastguard Worker       HttpUtil::AssembleRawHeaders(raw_headers));
9339*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9340*6777b538SAndroid Build Coastguard Worker 
9341*6777b538SAndroid Build Coastguard Worker   auto buf(base::MakeRefCounted<IOBufferWithSize>(500));
9342*6777b538SAndroid Build Coastguard Worker   int len = static_cast<int>(
9343*6777b538SAndroid Build Coastguard Worker       base::strlcpy(buf->data(), kRangeGET_TransactionOK.data, 500));
9344*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback cb;
9345*6777b538SAndroid Build Coastguard Worker   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9346*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(len, cb.GetResult(rv));
9347*6777b538SAndroid Build Coastguard Worker   entry->Close();
9348*6777b538SAndroid Build Coastguard Worker 
9349*6777b538SAndroid Build Coastguard Worker   // Now see that we don't use the stored entry.
9350*6777b538SAndroid Build Coastguard Worker   std::string headers;
9351*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo load_timing_info;
9352*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseAndGetTiming(
9353*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), kSimpleGET_Transaction, &headers,
9354*6777b538SAndroid Build Coastguard Worker       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
9355*6777b538SAndroid Build Coastguard Worker 
9356*6777b538SAndroid Build Coastguard Worker   // We are expecting a 200.
9357*6777b538SAndroid Build Coastguard Worker   std::string expected_headers(kSimpleGET_Transaction.status);
9358*6777b538SAndroid Build Coastguard Worker   expected_headers.append("\n");
9359*6777b538SAndroid Build Coastguard Worker   expected_headers.append(kSimpleGET_Transaction.response_headers);
9360*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_headers, headers);
9361*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9362*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9363*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
9364*6777b538SAndroid Build Coastguard Worker   TestLoadTimingNetworkRequest(load_timing_info);
9365*6777b538SAndroid Build Coastguard Worker }
9366*6777b538SAndroid Build Coastguard Worker 
9367*6777b538SAndroid Build Coastguard Worker // Tests that we can handle cached 206 responses that are not sparse. This time
9368*6777b538SAndroid Build Coastguard Worker // we issue a range request and expect to receive a range.
TEST_F(HttpCacheTest,RangeGET_Previous206_NotSparse_2)9369*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_Previous206_NotSparse_2) {
9370*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9371*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9372*6777b538SAndroid Build Coastguard Worker 
9373*6777b538SAndroid Build Coastguard Worker   // Create a disk cache entry that stores 206 headers while not being sparse.
9374*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kRangeGET_TransactionOK);
9375*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
9376*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9377*6777b538SAndroid Build Coastguard Worker 
9378*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(kRangeGET_TransactionOK.status);
9379*6777b538SAndroid Build Coastguard Worker   raw_headers.append("\n");
9380*6777b538SAndroid Build Coastguard Worker   raw_headers.append(kRangeGET_TransactionOK.response_headers);
9381*6777b538SAndroid Build Coastguard Worker 
9382*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
9383*6777b538SAndroid Build Coastguard Worker   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9384*6777b538SAndroid Build Coastguard Worker       HttpUtil::AssembleRawHeaders(raw_headers));
9385*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9386*6777b538SAndroid Build Coastguard Worker 
9387*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<IOBufferWithSize>(500);
9388*6777b538SAndroid Build Coastguard Worker   int len = static_cast<int>(
9389*6777b538SAndroid Build Coastguard Worker       base::strlcpy(buf->data(), kRangeGET_TransactionOK.data, 500));
9390*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback cb;
9391*6777b538SAndroid Build Coastguard Worker   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9392*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(len, cb.GetResult(rv));
9393*6777b538SAndroid Build Coastguard Worker   entry->Close();
9394*6777b538SAndroid Build Coastguard Worker 
9395*6777b538SAndroid Build Coastguard Worker   // Now see that we don't use the stored entry.
9396*6777b538SAndroid Build Coastguard Worker   std::string headers;
9397*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9398*6777b538SAndroid Build Coastguard Worker                                  &headers);
9399*6777b538SAndroid Build Coastguard Worker 
9400*6777b538SAndroid Build Coastguard Worker   // We are expecting a 206.
9401*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
9402*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9403*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9404*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
9405*6777b538SAndroid Build Coastguard Worker }
9406*6777b538SAndroid Build Coastguard Worker 
9407*6777b538SAndroid Build Coastguard Worker // Tests that we can handle cached 206 responses that can't be validated.
TEST_F(HttpCacheTest,GET_Previous206_NotValidation)9408*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_Previous206_NotValidation) {
9409*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9410*6777b538SAndroid Build Coastguard Worker 
9411*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
9412*6777b538SAndroid Build Coastguard Worker   // Create a disk cache entry that stores 206 headers.
9413*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
9414*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9415*6777b538SAndroid Build Coastguard Worker 
9416*6777b538SAndroid Build Coastguard Worker   // Make sure that the headers cannot be validated with the server.
9417*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(kRangeGET_TransactionOK.status);
9418*6777b538SAndroid Build Coastguard Worker   raw_headers.append("\n");
9419*6777b538SAndroid Build Coastguard Worker   raw_headers.append("Content-Length: 80\n");
9420*6777b538SAndroid Build Coastguard Worker 
9421*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
9422*6777b538SAndroid Build Coastguard Worker   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9423*6777b538SAndroid Build Coastguard Worker       HttpUtil::AssembleRawHeaders(raw_headers));
9424*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9425*6777b538SAndroid Build Coastguard Worker 
9426*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<IOBufferWithSize>(500);
9427*6777b538SAndroid Build Coastguard Worker   int len = static_cast<int>(
9428*6777b538SAndroid Build Coastguard Worker       base::strlcpy(buf->data(), kRangeGET_TransactionOK.data, 500));
9429*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback cb;
9430*6777b538SAndroid Build Coastguard Worker   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9431*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(len, cb.GetResult(rv));
9432*6777b538SAndroid Build Coastguard Worker   entry->Close();
9433*6777b538SAndroid Build Coastguard Worker 
9434*6777b538SAndroid Build Coastguard Worker   // Now see that we don't use the stored entry.
9435*6777b538SAndroid Build Coastguard Worker   std::string headers;
9436*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
9437*6777b538SAndroid Build Coastguard Worker                                  &headers);
9438*6777b538SAndroid Build Coastguard Worker 
9439*6777b538SAndroid Build Coastguard Worker   // We are expecting a 200.
9440*6777b538SAndroid Build Coastguard Worker   std::string expected_headers(kSimpleGET_Transaction.status);
9441*6777b538SAndroid Build Coastguard Worker   expected_headers.append("\n");
9442*6777b538SAndroid Build Coastguard Worker   expected_headers.append(kSimpleGET_Transaction.response_headers);
9443*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_headers, headers);
9444*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9445*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9446*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
9447*6777b538SAndroid Build Coastguard Worker }
9448*6777b538SAndroid Build Coastguard Worker 
9449*6777b538SAndroid Build Coastguard Worker // Tests that we can handle range requests with cached 200 responses.
TEST_F(HttpCacheTest,RangeGET_Previous200)9450*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_Previous200) {
9451*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9452*6777b538SAndroid Build Coastguard Worker 
9453*6777b538SAndroid Build Coastguard Worker   {
9454*6777b538SAndroid Build Coastguard Worker     // Store the whole thing with status 200.
9455*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kTypicalGET_Transaction,
9456*6777b538SAndroid Build Coastguard Worker                                       kRangeGET_TransactionOK.url);
9457*6777b538SAndroid Build Coastguard Worker     transaction.data = kFullRangeData;
9458*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
9459*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
9460*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache.disk_cache()->open_count());
9461*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
9462*6777b538SAndroid Build Coastguard Worker   }
9463*6777b538SAndroid Build Coastguard Worker 
9464*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9465*6777b538SAndroid Build Coastguard Worker   // Now see that we use the stored entry.
9466*6777b538SAndroid Build Coastguard Worker   std::string headers;
9467*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction2(kRangeGET_TransactionOK);
9468*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer handler;
9469*6777b538SAndroid Build Coastguard Worker   handler.set_not_modified(true);
9470*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9471*6777b538SAndroid Build Coastguard Worker 
9472*6777b538SAndroid Build Coastguard Worker   // We are expecting a 206.
9473*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
9474*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9475*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9476*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9477*6777b538SAndroid Build Coastguard Worker 
9478*6777b538SAndroid Build Coastguard Worker   // The last transaction has finished so make sure the entry is deactivated.
9479*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
9480*6777b538SAndroid Build Coastguard Worker 
9481*6777b538SAndroid Build Coastguard Worker   // Make a request for an invalid range.
9482*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction3(kRangeGET_TransactionOK);
9483*6777b538SAndroid Build Coastguard Worker   transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
9484*6777b538SAndroid Build Coastguard Worker   transaction3.data = kFullRangeData;
9485*6777b538SAndroid Build Coastguard Worker   transaction3.load_flags = LOAD_SKIP_CACHE_VALIDATION;
9486*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
9487*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
9488*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
9489*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
9490*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
9491*6777b538SAndroid Build Coastguard Worker 
9492*6777b538SAndroid Build Coastguard Worker   // Make sure the entry is deactivated.
9493*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
9494*6777b538SAndroid Build Coastguard Worker 
9495*6777b538SAndroid Build Coastguard Worker   // Even though the request was invalid, we should have the entry.
9496*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction2);
9497*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.disk_cache()->open_count());
9498*6777b538SAndroid Build Coastguard Worker 
9499*6777b538SAndroid Build Coastguard Worker   // Make sure the entry is deactivated.
9500*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
9501*6777b538SAndroid Build Coastguard Worker 
9502*6777b538SAndroid Build Coastguard Worker   // Now we should receive a range from the server and drop the stored entry.
9503*6777b538SAndroid Build Coastguard Worker   handler.set_not_modified(false);
9504*6777b538SAndroid Build Coastguard Worker   transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
9505*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9506*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
9507*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.network_layer()->transaction_count());
9508*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache.disk_cache()->open_count());
9509*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9510*6777b538SAndroid Build Coastguard Worker 
9511*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction2);
9512*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
9513*6777b538SAndroid Build Coastguard Worker }
9514*6777b538SAndroid Build Coastguard Worker 
9515*6777b538SAndroid Build Coastguard Worker // Tests that we can handle a 200 response when dealing with sparse entries.
TEST_F(HttpCacheTest,RangeRequestResultsIn200)9516*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeRequestResultsIn200) {
9517*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9518*6777b538SAndroid Build Coastguard Worker   std::string headers;
9519*6777b538SAndroid Build Coastguard Worker 
9520*6777b538SAndroid Build Coastguard Worker   {
9521*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9522*6777b538SAndroid Build Coastguard Worker     // Write to the cache (70-79).
9523*6777b538SAndroid Build Coastguard Worker     transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
9524*6777b538SAndroid Build Coastguard Worker     transaction.data = "rg: 70-79 ";
9525*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9526*6777b538SAndroid Build Coastguard Worker 
9527*6777b538SAndroid Build Coastguard Worker     Verify206Response(headers, 70, 79);
9528*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
9529*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache.disk_cache()->open_count());
9530*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
9531*6777b538SAndroid Build Coastguard Worker   }
9532*6777b538SAndroid Build Coastguard Worker   // Now we'll issue a request that results in a plain 200 response, but to
9533*6777b538SAndroid Build Coastguard Worker   // the to the same URL that we used to store sparse data, and making sure
9534*6777b538SAndroid Build Coastguard Worker   // that we ask for a range.
9535*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction2(kSimpleGET_Transaction,
9536*6777b538SAndroid Build Coastguard Worker                                      kRangeGET_TransactionOK.url);
9537*6777b538SAndroid Build Coastguard Worker   transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
9538*6777b538SAndroid Build Coastguard Worker 
9539*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9540*6777b538SAndroid Build Coastguard Worker 
9541*6777b538SAndroid Build Coastguard Worker   std::string expected_headers(kSimpleGET_Transaction.status);
9542*6777b538SAndroid Build Coastguard Worker   expected_headers.append("\n");
9543*6777b538SAndroid Build Coastguard Worker   expected_headers.append(kSimpleGET_Transaction.response_headers);
9544*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_headers, headers);
9545*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9546*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9547*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9548*6777b538SAndroid Build Coastguard Worker }
9549*6777b538SAndroid Build Coastguard Worker 
9550*6777b538SAndroid Build Coastguard Worker // Tests that a range request that falls outside of the size that we know about
9551*6777b538SAndroid Build Coastguard Worker // only deletes the entry if the resource has indeed changed.
TEST_F(HttpCacheTest,RangeGET_MoreThanCurrentSize)9552*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_MoreThanCurrentSize) {
9553*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9554*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9555*6777b538SAndroid Build Coastguard Worker   std::string headers;
9556*6777b538SAndroid Build Coastguard Worker 
9557*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
9558*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9559*6777b538SAndroid Build Coastguard Worker                                  &headers);
9560*6777b538SAndroid Build Coastguard Worker 
9561*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
9562*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9563*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9564*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9565*6777b538SAndroid Build Coastguard Worker 
9566*6777b538SAndroid Build Coastguard Worker   // A weird request should not delete this entry. Ask for bytes 120-.
9567*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_TransactionOK);
9568*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
9569*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
9570*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9571*6777b538SAndroid Build Coastguard Worker 
9572*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
9573*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9574*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9575*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9576*6777b538SAndroid Build Coastguard Worker 
9577*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9578*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->open_count());
9579*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9580*6777b538SAndroid Build Coastguard Worker }
9581*6777b538SAndroid Build Coastguard Worker 
9582*6777b538SAndroid Build Coastguard Worker // Tests that we don't delete a sparse entry when we cancel a request.
TEST_F(HttpCacheTest,RangeGET_Cancel)9583*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_Cancel) {
9584*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9585*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9586*6777b538SAndroid Build Coastguard Worker 
9587*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kRangeGET_TransactionOK);
9588*6777b538SAndroid Build Coastguard Worker 
9589*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
9590*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
9591*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
9592*6777b538SAndroid Build Coastguard Worker 
9593*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9594*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
9595*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
9596*6777b538SAndroid Build Coastguard Worker   }
9597*6777b538SAndroid Build Coastguard Worker 
9598*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9599*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9600*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9601*6777b538SAndroid Build Coastguard Worker 
9602*6777b538SAndroid Build Coastguard Worker   // Make sure that the entry has some data stored.
9603*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
9604*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(10);
9605*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9606*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
9607*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
9608*6777b538SAndroid Build Coastguard Worker   }
9609*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(buf->size(), rv);
9610*6777b538SAndroid Build Coastguard Worker 
9611*6777b538SAndroid Build Coastguard Worker   // Destroy the transaction.
9612*6777b538SAndroid Build Coastguard Worker   c.reset();
9613*6777b538SAndroid Build Coastguard Worker 
9614*6777b538SAndroid Build Coastguard Worker   // Verify that the entry has not been deleted.
9615*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
9616*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9617*6777b538SAndroid Build Coastguard Worker   entry->Close();
9618*6777b538SAndroid Build Coastguard Worker }
9619*6777b538SAndroid Build Coastguard Worker 
9620*6777b538SAndroid Build Coastguard Worker // Tests that we don't mark an entry as truncated if it is partial and not
9621*6777b538SAndroid Build Coastguard Worker // already truncated.
TEST_F(HttpCacheTest,RangeGET_CancelWhileReading)9622*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_CancelWhileReading) {
9623*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9624*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9625*6777b538SAndroid Build Coastguard Worker 
9626*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kRangeGET_TransactionOK);
9627*6777b538SAndroid Build Coastguard Worker 
9628*6777b538SAndroid Build Coastguard Worker   auto context = std::make_unique<Context>();
9629*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&context->trans);
9630*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
9631*6777b538SAndroid Build Coastguard Worker 
9632*6777b538SAndroid Build Coastguard Worker   rv = context->trans->Start(&request, context->callback.callback(),
9633*6777b538SAndroid Build Coastguard Worker                              NetLogWithSource());
9634*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
9635*6777b538SAndroid Build Coastguard Worker     rv = context->callback.WaitForResult();
9636*6777b538SAndroid Build Coastguard Worker   }
9637*6777b538SAndroid Build Coastguard Worker 
9638*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9639*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9640*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9641*6777b538SAndroid Build Coastguard Worker 
9642*6777b538SAndroid Build Coastguard Worker   // Start Read.
9643*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
9644*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(5);
9645*6777b538SAndroid Build Coastguard Worker   rv = context->trans->Read(buf.get(), buf->size(),
9646*6777b538SAndroid Build Coastguard Worker                             context->callback.callback());
9647*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9648*6777b538SAndroid Build Coastguard Worker 
9649*6777b538SAndroid Build Coastguard Worker   // Destroy the transaction.
9650*6777b538SAndroid Build Coastguard Worker   context.reset();
9651*6777b538SAndroid Build Coastguard Worker 
9652*6777b538SAndroid Build Coastguard Worker   // Complete Read.
9653*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
9654*6777b538SAndroid Build Coastguard Worker 
9655*6777b538SAndroid Build Coastguard Worker   // Verify that the entry has not been marked as truncated.
9656*6777b538SAndroid Build Coastguard Worker   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 0);
9657*6777b538SAndroid Build Coastguard Worker }
9658*6777b538SAndroid Build Coastguard Worker 
9659*6777b538SAndroid Build Coastguard Worker // Tests that we don't delete a sparse entry when we start a new request after
9660*6777b538SAndroid Build Coastguard Worker // cancelling the previous one.
TEST_F(HttpCacheTest,RangeGET_Cancel2)9661*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_Cancel2) {
9662*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9663*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9664*6777b538SAndroid Build Coastguard Worker 
9665*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9666*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kRangeGET_TransactionOK);
9667*6777b538SAndroid Build Coastguard Worker   request.load_flags |= LOAD_VALIDATE_CACHE;
9668*6777b538SAndroid Build Coastguard Worker 
9669*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
9670*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
9671*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
9672*6777b538SAndroid Build Coastguard Worker 
9673*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9674*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
9675*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
9676*6777b538SAndroid Build Coastguard Worker   }
9677*6777b538SAndroid Build Coastguard Worker 
9678*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9679*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9680*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9681*6777b538SAndroid Build Coastguard Worker 
9682*6777b538SAndroid Build Coastguard Worker   // Make sure that we revalidate the entry and read from the cache (a single
9683*6777b538SAndroid Build Coastguard Worker   // read will return while waiting for the network).
9684*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
9685*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(5);
9686*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9687*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, c->callback.GetResult(rv));
9688*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9689*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9690*6777b538SAndroid Build Coastguard Worker 
9691*6777b538SAndroid Build Coastguard Worker   // Destroy the transaction before completing the read.
9692*6777b538SAndroid Build Coastguard Worker   c.reset();
9693*6777b538SAndroid Build Coastguard Worker 
9694*6777b538SAndroid Build Coastguard Worker   // We have the read and the delete (OnProcessPendingQueue) waiting on the
9695*6777b538SAndroid Build Coastguard Worker   // message loop. This means that a new transaction will just reuse the same
9696*6777b538SAndroid Build Coastguard Worker   // active entry (no open or create).
9697*6777b538SAndroid Build Coastguard Worker 
9698*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9699*6777b538SAndroid Build Coastguard Worker 
9700*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9701*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9702*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9703*6777b538SAndroid Build Coastguard Worker }
9704*6777b538SAndroid Build Coastguard Worker 
9705*6777b538SAndroid Build Coastguard Worker // A slight variation of the previous test, this time we cancel two requests in
9706*6777b538SAndroid Build Coastguard Worker // a row, making sure that the second is waiting for the entry to be ready.
TEST_F(HttpCacheTest,RangeGET_Cancel3)9707*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_Cancel3) {
9708*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9709*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9710*6777b538SAndroid Build Coastguard Worker 
9711*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9712*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kRangeGET_TransactionOK);
9713*6777b538SAndroid Build Coastguard Worker   request.load_flags |= LOAD_VALIDATE_CACHE;
9714*6777b538SAndroid Build Coastguard Worker 
9715*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
9716*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
9717*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
9718*6777b538SAndroid Build Coastguard Worker 
9719*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9720*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9721*6777b538SAndroid Build Coastguard Worker   rv = c->callback.WaitForResult();
9722*6777b538SAndroid Build Coastguard Worker 
9723*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9724*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9725*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9726*6777b538SAndroid Build Coastguard Worker 
9727*6777b538SAndroid Build Coastguard Worker   // Make sure that we revalidate the entry and read from the cache (a single
9728*6777b538SAndroid Build Coastguard Worker   // read will return while waiting for the network).
9729*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
9730*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(5);
9731*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9732*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, c->callback.GetResult(rv));
9733*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9734*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9735*6777b538SAndroid Build Coastguard Worker 
9736*6777b538SAndroid Build Coastguard Worker   // Destroy the previous transaction before completing the read.
9737*6777b538SAndroid Build Coastguard Worker   c.reset();
9738*6777b538SAndroid Build Coastguard Worker 
9739*6777b538SAndroid Build Coastguard Worker   // We have the read and the delete (OnProcessPendingQueue) waiting on the
9740*6777b538SAndroid Build Coastguard Worker   // message loop. This means that a new transaction will just reuse the same
9741*6777b538SAndroid Build Coastguard Worker   // active entry (no open or create).
9742*6777b538SAndroid Build Coastguard Worker 
9743*6777b538SAndroid Build Coastguard Worker   c = std::make_unique<Context>();
9744*6777b538SAndroid Build Coastguard Worker   rv = cache.CreateTransaction(&c->trans);
9745*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
9746*6777b538SAndroid Build Coastguard Worker 
9747*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9748*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9749*6777b538SAndroid Build Coastguard Worker 
9750*6777b538SAndroid Build Coastguard Worker   MockDiskEntry::IgnoreCallbacks(true);
9751*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
9752*6777b538SAndroid Build Coastguard Worker   MockDiskEntry::IgnoreCallbacks(false);
9753*6777b538SAndroid Build Coastguard Worker 
9754*6777b538SAndroid Build Coastguard Worker   // The new transaction is waiting for the query range callback.
9755*6777b538SAndroid Build Coastguard Worker   c.reset();
9756*6777b538SAndroid Build Coastguard Worker 
9757*6777b538SAndroid Build Coastguard Worker   // And we should not crash when the callback is delivered.
9758*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
9759*6777b538SAndroid Build Coastguard Worker 
9760*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9761*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9762*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9763*6777b538SAndroid Build Coastguard Worker }
9764*6777b538SAndroid Build Coastguard Worker 
9765*6777b538SAndroid Build Coastguard Worker // Tests that an invalid range response results in no cached entry.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse1)9766*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_InvalidResponse1) {
9767*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9768*6777b538SAndroid Build Coastguard Worker   std::string headers;
9769*6777b538SAndroid Build Coastguard Worker 
9770*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9771*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
9772*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
9773*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes 40-49/45\n"
9774*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n";
9775*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9776*6777b538SAndroid Build Coastguard Worker 
9777*6777b538SAndroid Build Coastguard Worker   std::string expected(transaction.status);
9778*6777b538SAndroid Build Coastguard Worker   expected.append("\n");
9779*6777b538SAndroid Build Coastguard Worker   expected.append(transaction.response_headers);
9780*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected, headers);
9781*6777b538SAndroid Build Coastguard Worker 
9782*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9783*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9784*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9785*6777b538SAndroid Build Coastguard Worker 
9786*6777b538SAndroid Build Coastguard Worker   // Verify that we don't have a cached entry.
9787*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
9788*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
9789*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9790*6777b538SAndroid Build Coastguard Worker }
9791*6777b538SAndroid Build Coastguard Worker 
9792*6777b538SAndroid Build Coastguard Worker // Tests that we reject a range that doesn't match the content-length.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse2)9793*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_InvalidResponse2) {
9794*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9795*6777b538SAndroid Build Coastguard Worker   std::string headers;
9796*6777b538SAndroid Build Coastguard Worker 
9797*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9798*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
9799*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
9800*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes 40-49/80\n"
9801*6777b538SAndroid Build Coastguard Worker       "Content-Length: 20\n";
9802*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9803*6777b538SAndroid Build Coastguard Worker 
9804*6777b538SAndroid Build Coastguard Worker   std::string expected(transaction.status);
9805*6777b538SAndroid Build Coastguard Worker   expected.append("\n");
9806*6777b538SAndroid Build Coastguard Worker   expected.append(transaction.response_headers);
9807*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected, headers);
9808*6777b538SAndroid Build Coastguard Worker 
9809*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9810*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9811*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9812*6777b538SAndroid Build Coastguard Worker 
9813*6777b538SAndroid Build Coastguard Worker   // Verify that we don't have a cached entry.
9814*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
9815*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
9816*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9817*6777b538SAndroid Build Coastguard Worker }
9818*6777b538SAndroid Build Coastguard Worker 
9819*6777b538SAndroid Build Coastguard Worker // Tests that if a server tells us conflicting information about a resource we
9820*6777b538SAndroid Build Coastguard Worker // drop the entry.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse3)9821*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_InvalidResponse3) {
9822*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9823*6777b538SAndroid Build Coastguard Worker   std::string headers;
9824*6777b538SAndroid Build Coastguard Worker   {
9825*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9826*6777b538SAndroid Build Coastguard Worker     transaction.handler = MockTransactionHandler();
9827*6777b538SAndroid Build Coastguard Worker     transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
9828*6777b538SAndroid Build Coastguard Worker     std::string response_headers(transaction.response_headers);
9829*6777b538SAndroid Build Coastguard Worker     response_headers.append("Content-Range: bytes 50-59/160\n");
9830*6777b538SAndroid Build Coastguard Worker     transaction.response_headers = response_headers.c_str();
9831*6777b538SAndroid Build Coastguard Worker     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9832*6777b538SAndroid Build Coastguard Worker 
9833*6777b538SAndroid Build Coastguard Worker     Verify206Response(headers, 50, 59);
9834*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
9835*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache.disk_cache()->open_count());
9836*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
9837*6777b538SAndroid Build Coastguard Worker   }
9838*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9839*6777b538SAndroid Build Coastguard Worker 
9840*6777b538SAndroid Build Coastguard Worker   // This transaction will report a resource size of 80 bytes, and we think it's
9841*6777b538SAndroid Build Coastguard Worker   // 160 so we should ignore the response.
9842*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9843*6777b538SAndroid Build Coastguard Worker                                  &headers);
9844*6777b538SAndroid Build Coastguard Worker 
9845*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
9846*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9847*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9848*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9849*6777b538SAndroid Build Coastguard Worker 
9850*6777b538SAndroid Build Coastguard Worker   // Verify that the entry is gone.
9851*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9852*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9853*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
9854*6777b538SAndroid Build Coastguard Worker }
9855*6777b538SAndroid Build Coastguard Worker 
9856*6777b538SAndroid Build Coastguard Worker // Tests that we handle large range values properly.
TEST_F(HttpCacheTest,RangeGET_LargeValues)9857*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_LargeValues) {
9858*6777b538SAndroid Build Coastguard Worker   // We need a real sparse cache for this test.
9859*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
9860*6777b538SAndroid Build Coastguard Worker   std::string headers;
9861*6777b538SAndroid Build Coastguard Worker 
9862*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9863*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
9864*6777b538SAndroid Build Coastguard Worker   transaction.request_headers =
9865*6777b538SAndroid Build Coastguard Worker       "Range: bytes = 4294967288-4294967297\r\n" EXTRA_HEADER;
9866*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
9867*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
9868*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes 4294967288-4294967297/4294967299\n"
9869*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n";
9870*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9871*6777b538SAndroid Build Coastguard Worker 
9872*6777b538SAndroid Build Coastguard Worker   std::string expected(transaction.status);
9873*6777b538SAndroid Build Coastguard Worker   expected.append("\n");
9874*6777b538SAndroid Build Coastguard Worker   expected.append(transaction.response_headers);
9875*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected, headers);
9876*6777b538SAndroid Build Coastguard Worker 
9877*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9878*6777b538SAndroid Build Coastguard Worker 
9879*6777b538SAndroid Build Coastguard Worker   // Verify that we have a cached entry.
9880*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* en;
9881*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
9882*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &en));
9883*6777b538SAndroid Build Coastguard Worker   en->Close();
9884*6777b538SAndroid Build Coastguard Worker }
9885*6777b538SAndroid Build Coastguard Worker 
9886*6777b538SAndroid Build Coastguard Worker // Tests that we don't crash with a range request if the disk cache was not
9887*6777b538SAndroid Build Coastguard Worker // initialized properly.
TEST_F(HttpCacheTest,RangeGET_NoDiskCache)9888*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_NoDiskCache) {
9889*6777b538SAndroid Build Coastguard Worker   auto factory = std::make_unique<MockBlockingBackendFactory>();
9890*6777b538SAndroid Build Coastguard Worker   factory->set_fail(true);
9891*6777b538SAndroid Build Coastguard Worker   factory->FinishCreation();  // We'll complete synchronously.
9892*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache(std::move(factory));
9893*6777b538SAndroid Build Coastguard Worker 
9894*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9895*6777b538SAndroid Build Coastguard Worker 
9896*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9897*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9898*6777b538SAndroid Build Coastguard Worker }
9899*6777b538SAndroid Build Coastguard Worker 
9900*6777b538SAndroid Build Coastguard Worker // Tests that we handle byte range requests that skip the cache.
TEST_F(HttpCacheTest,RangeHEAD)9901*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeHEAD) {
9902*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9903*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9904*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
9905*6777b538SAndroid Build Coastguard Worker   transaction.method = "HEAD";
9906*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 70-79 ";
9907*6777b538SAndroid Build Coastguard Worker 
9908*6777b538SAndroid Build Coastguard Worker   std::string headers;
9909*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9910*6777b538SAndroid Build Coastguard Worker 
9911*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 70, 79);
9912*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9913*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9914*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->create_count());
9915*6777b538SAndroid Build Coastguard Worker }
9916*6777b538SAndroid Build Coastguard Worker 
9917*6777b538SAndroid Build Coastguard Worker // Tests that we don't crash when after reading from the cache we issue a
9918*6777b538SAndroid Build Coastguard Worker // request for the next range and the server gives us a 200 synchronously.
TEST_F(HttpCacheTest,RangeGET_FastFlakyServer)9919*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_FastFlakyServer) {
9920*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9921*6777b538SAndroid Build Coastguard Worker 
9922*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9923*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
9924*6777b538SAndroid Build Coastguard Worker   transaction.test_mode = TEST_MODE_SYNC_NET_START;
9925*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
9926*6777b538SAndroid Build Coastguard Worker 
9927*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
9928*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9929*6777b538SAndroid Build Coastguard Worker 
9930*6777b538SAndroid Build Coastguard Worker   // And now read from the cache and the network.
9931*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer handler;
9932*6777b538SAndroid Build Coastguard Worker   handler.set_bad_200(true);
9933*6777b538SAndroid Build Coastguard Worker   transaction.data = "Not a range";
9934*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_observer;
9935*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithLog(cache.http_cache(), transaction,
9936*6777b538SAndroid Build Coastguard Worker                             NetLogWithSource::Make(NetLogSourceType::NONE));
9937*6777b538SAndroid Build Coastguard Worker 
9938*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache.network_layer()->transaction_count());
9939*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9940*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9941*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEventType(
9942*6777b538SAndroid Build Coastguard Worker       net_log_observer, NetLogEventType::HTTP_CACHE_RE_SEND_PARTIAL_REQUEST));
9943*6777b538SAndroid Build Coastguard Worker }
9944*6777b538SAndroid Build Coastguard Worker 
9945*6777b538SAndroid Build Coastguard Worker // Tests that when the server gives us less data than expected, we don't keep
9946*6777b538SAndroid Build Coastguard Worker // asking for more data.
TEST_F(HttpCacheTest,RangeGET_FastFlakyServer2)9947*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_FastFlakyServer2) {
9948*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9949*6777b538SAndroid Build Coastguard Worker 
9950*6777b538SAndroid Build Coastguard Worker   // First, check with an empty cache (WRITE mode).
9951*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9952*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
9953*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 40-";  // Less than expected.
9954*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
9955*6777b538SAndroid Build Coastguard Worker   std::string headers(transaction.response_headers);
9956*6777b538SAndroid Build Coastguard Worker   headers.append("Content-Range: bytes 40-49/80\n");
9957*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = headers.c_str();
9958*6777b538SAndroid Build Coastguard Worker 
9959*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
9960*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
9961*6777b538SAndroid Build Coastguard Worker 
9962*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9963*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9964*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9965*6777b538SAndroid Build Coastguard Worker 
9966*6777b538SAndroid Build Coastguard Worker   // Now verify that even in READ_WRITE mode, we forward the bad response to
9967*6777b538SAndroid Build Coastguard Worker   // the caller.
9968*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
9969*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 60-";  // Less than expected.
9970*6777b538SAndroid Build Coastguard Worker   headers = kRangeGET_TransactionOK.response_headers;
9971*6777b538SAndroid Build Coastguard Worker   headers.append("Content-Range: bytes 60-69/80\n");
9972*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = headers.c_str();
9973*6777b538SAndroid Build Coastguard Worker 
9974*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
9975*6777b538SAndroid Build Coastguard Worker 
9976*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9977*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
9978*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9979*6777b538SAndroid Build Coastguard Worker }
9980*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,RangeGET_OK_LoadOnlyFromCache)9981*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_OK_LoadOnlyFromCache) {
9982*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
9983*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9984*6777b538SAndroid Build Coastguard Worker 
9985*6777b538SAndroid Build Coastguard Worker   // Write to the cache (40-49).
9986*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9987*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9988*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
9989*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
9990*6777b538SAndroid Build Coastguard Worker 
9991*6777b538SAndroid Build Coastguard Worker   // Force this transaction to read from the cache.
9992*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
9993*6777b538SAndroid Build Coastguard Worker 
9994*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
9995*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
9996*6777b538SAndroid Build Coastguard Worker 
9997*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
9998*6777b538SAndroid Build Coastguard Worker   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
9999*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsOk());
10000*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(trans.get());
10001*6777b538SAndroid Build Coastguard Worker 
10002*6777b538SAndroid Build Coastguard Worker   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
10003*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
10004*6777b538SAndroid Build Coastguard Worker     rv = callback.WaitForResult();
10005*6777b538SAndroid Build Coastguard Worker   }
10006*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
10007*6777b538SAndroid Build Coastguard Worker 
10008*6777b538SAndroid Build Coastguard Worker   trans.reset();
10009*6777b538SAndroid Build Coastguard Worker 
10010*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10011*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
10012*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10013*6777b538SAndroid Build Coastguard Worker }
10014*6777b538SAndroid Build Coastguard Worker 
10015*6777b538SAndroid Build Coastguard Worker // Tests the handling of the "truncation" flag.
TEST_F(HttpCacheTest,WriteResponseInfo_Truncated)10016*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, WriteResponseInfo_Truncated) {
10017*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10018*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
10019*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache.CreateBackendEntry(
10020*6777b538SAndroid Build Coastguard Worker       GenerateCacheKey("http://www.google.com"), &entry, nullptr));
10021*6777b538SAndroid Build Coastguard Worker 
10022*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
10023*6777b538SAndroid Build Coastguard Worker   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
10024*6777b538SAndroid Build Coastguard Worker       HttpUtil::AssembleRawHeaders("HTTP/1.1 200 OK"));
10025*6777b538SAndroid Build Coastguard Worker 
10026*6777b538SAndroid Build Coastguard Worker   // Set the last argument for this to be an incomplete request.
10027*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
10028*6777b538SAndroid Build Coastguard Worker   bool truncated = false;
10029*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
10030*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(truncated);
10031*6777b538SAndroid Build Coastguard Worker 
10032*6777b538SAndroid Build Coastguard Worker   // And now test the opposite case.
10033*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
10034*6777b538SAndroid Build Coastguard Worker   truncated = true;
10035*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
10036*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(truncated);
10037*6777b538SAndroid Build Coastguard Worker   entry->Close();
10038*6777b538SAndroid Build Coastguard Worker }
10039*6777b538SAndroid Build Coastguard Worker 
10040*6777b538SAndroid Build Coastguard Worker // Tests basic pickling/unpickling of HttpResponseInfo.
TEST_F(HttpCacheTest,PersistHttpResponseInfo)10041*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, PersistHttpResponseInfo) {
10042*6777b538SAndroid Build Coastguard Worker   const IPEndPoint expected_endpoint = IPEndPoint(IPAddress(1, 2, 3, 4), 80);
10043*6777b538SAndroid Build Coastguard Worker   // Set some fields (add more if needed.)
10044*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response1;
10045*6777b538SAndroid Build Coastguard Worker   response1.was_cached = false;
10046*6777b538SAndroid Build Coastguard Worker   response1.remote_endpoint = expected_endpoint;
10047*6777b538SAndroid Build Coastguard Worker   response1.headers =
10048*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<HttpResponseHeaders>("HTTP/1.1 200 OK");
10049*6777b538SAndroid Build Coastguard Worker 
10050*6777b538SAndroid Build Coastguard Worker   // Pickle.
10051*6777b538SAndroid Build Coastguard Worker   base::Pickle pickle;
10052*6777b538SAndroid Build Coastguard Worker   response1.Persist(&pickle, false, false);
10053*6777b538SAndroid Build Coastguard Worker 
10054*6777b538SAndroid Build Coastguard Worker   // Unpickle.
10055*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response2;
10056*6777b538SAndroid Build Coastguard Worker   bool response_truncated;
10057*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
10058*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_truncated);
10059*6777b538SAndroid Build Coastguard Worker 
10060*6777b538SAndroid Build Coastguard Worker   // Verify fields.
10061*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response2.was_cached);  // InitFromPickle sets this flag.
10062*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_endpoint, response2.remote_endpoint);
10063*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
10064*6777b538SAndroid Build Coastguard Worker }
10065*6777b538SAndroid Build Coastguard Worker 
10066*6777b538SAndroid Build Coastguard Worker // Tests that we delete an entry when the request is cancelled before starting
10067*6777b538SAndroid Build Coastguard Worker // to read from the network.
TEST_F(HttpCacheTest,DoomOnDestruction)10068*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, DoomOnDestruction) {
10069*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10070*6777b538SAndroid Build Coastguard Worker 
10071*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
10072*6777b538SAndroid Build Coastguard Worker 
10073*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
10074*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
10075*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
10076*6777b538SAndroid Build Coastguard Worker 
10077*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10078*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
10079*6777b538SAndroid Build Coastguard Worker     c->result = c->callback.WaitForResult();
10080*6777b538SAndroid Build Coastguard Worker   }
10081*6777b538SAndroid Build Coastguard Worker 
10082*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10083*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10084*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10085*6777b538SAndroid Build Coastguard Worker 
10086*6777b538SAndroid Build Coastguard Worker   // Destroy the transaction. We only have the headers so we should delete this
10087*6777b538SAndroid Build Coastguard Worker   // entry.
10088*6777b538SAndroid Build Coastguard Worker   c.reset();
10089*6777b538SAndroid Build Coastguard Worker 
10090*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10091*6777b538SAndroid Build Coastguard Worker 
10092*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10093*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10094*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
10095*6777b538SAndroid Build Coastguard Worker }
10096*6777b538SAndroid Build Coastguard Worker 
10097*6777b538SAndroid Build Coastguard Worker // Tests that we delete an entry when the request is cancelled if the response
10098*6777b538SAndroid Build Coastguard Worker // does not have content-length and strong validators.
TEST_F(HttpCacheTest,DoomOnDestruction2)10099*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, DoomOnDestruction2) {
10100*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10101*6777b538SAndroid Build Coastguard Worker 
10102*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
10103*6777b538SAndroid Build Coastguard Worker 
10104*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
10105*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
10106*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
10107*6777b538SAndroid Build Coastguard Worker 
10108*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10109*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
10110*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
10111*6777b538SAndroid Build Coastguard Worker   }
10112*6777b538SAndroid Build Coastguard Worker 
10113*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10114*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10115*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10116*6777b538SAndroid Build Coastguard Worker 
10117*6777b538SAndroid Build Coastguard Worker   // Make sure that the entry has some data stored.
10118*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
10119*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(10);
10120*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10121*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
10122*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
10123*6777b538SAndroid Build Coastguard Worker   }
10124*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(buf->size(), rv);
10125*6777b538SAndroid Build Coastguard Worker 
10126*6777b538SAndroid Build Coastguard Worker   // Destroy the transaction.
10127*6777b538SAndroid Build Coastguard Worker   c.reset();
10128*6777b538SAndroid Build Coastguard Worker 
10129*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10130*6777b538SAndroid Build Coastguard Worker 
10131*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10132*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10133*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
10134*6777b538SAndroid Build Coastguard Worker }
10135*6777b538SAndroid Build Coastguard Worker 
10136*6777b538SAndroid Build Coastguard Worker // Tests that we delete an entry when the request is cancelled if the response
10137*6777b538SAndroid Build Coastguard Worker // has an "Accept-Ranges: none" header.
TEST_F(HttpCacheTest,DoomOnDestruction3)10138*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, DoomOnDestruction3) {
10139*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10140*6777b538SAndroid Build Coastguard Worker 
10141*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10142*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
10143*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10144*6777b538SAndroid Build Coastguard Worker       "Content-Length: 22\n"
10145*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: none\n"
10146*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n";
10147*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10148*6777b538SAndroid Build Coastguard Worker 
10149*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
10150*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
10151*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
10152*6777b538SAndroid Build Coastguard Worker 
10153*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10154*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
10155*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
10156*6777b538SAndroid Build Coastguard Worker   }
10157*6777b538SAndroid Build Coastguard Worker 
10158*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10159*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10160*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10161*6777b538SAndroid Build Coastguard Worker 
10162*6777b538SAndroid Build Coastguard Worker   // Make sure that the entry has some data stored.
10163*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
10164*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(10);
10165*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10166*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
10167*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
10168*6777b538SAndroid Build Coastguard Worker   }
10169*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(buf->size(), rv);
10170*6777b538SAndroid Build Coastguard Worker 
10171*6777b538SAndroid Build Coastguard Worker   // Destroy the transaction.
10172*6777b538SAndroid Build Coastguard Worker   c.reset();
10173*6777b538SAndroid Build Coastguard Worker 
10174*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10175*6777b538SAndroid Build Coastguard Worker 
10176*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10177*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10178*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
10179*6777b538SAndroid Build Coastguard Worker }
10180*6777b538SAndroid Build Coastguard Worker 
10181*6777b538SAndroid Build Coastguard Worker // Tests that we mark an entry as incomplete when the request is cancelled.
TEST_F(HttpCacheTest,SetTruncatedFlag)10182*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SetTruncatedFlag) {
10183*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10184*6777b538SAndroid Build Coastguard Worker 
10185*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10186*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
10187*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10188*6777b538SAndroid Build Coastguard Worker       "Content-Length: 22\n"
10189*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n";
10190*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10191*6777b538SAndroid Build Coastguard Worker 
10192*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
10193*6777b538SAndroid Build Coastguard Worker 
10194*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
10195*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
10196*6777b538SAndroid Build Coastguard Worker 
10197*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10198*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
10199*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
10200*6777b538SAndroid Build Coastguard Worker   }
10201*6777b538SAndroid Build Coastguard Worker 
10202*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10203*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10204*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10205*6777b538SAndroid Build Coastguard Worker 
10206*6777b538SAndroid Build Coastguard Worker   // Make sure that the entry has some data stored.
10207*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
10208*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(10);
10209*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10210*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
10211*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
10212*6777b538SAndroid Build Coastguard Worker   }
10213*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(buf->size(), rv);
10214*6777b538SAndroid Build Coastguard Worker 
10215*6777b538SAndroid Build Coastguard Worker   // We want to cancel the request when the transaction is busy.
10216*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10217*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10218*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(c->callback.have_result());
10219*6777b538SAndroid Build Coastguard Worker 
10220*6777b538SAndroid Build Coastguard Worker   // Destroy the transaction.
10221*6777b538SAndroid Build Coastguard Worker   c->trans.reset();
10222*6777b538SAndroid Build Coastguard Worker 
10223*6777b538SAndroid Build Coastguard Worker   // Make sure that we don't invoke the callback. We may have an issue if the
10224*6777b538SAndroid Build Coastguard Worker   // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
10225*6777b538SAndroid Build Coastguard Worker   // could end up with the transaction being deleted twice if we send any
10226*6777b538SAndroid Build Coastguard Worker   // notification from the transaction destructor (see http://crbug.com/31723).
10227*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(c->callback.have_result());
10228*6777b538SAndroid Build Coastguard Worker 
10229*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
10230*6777b538SAndroid Build Coastguard Worker   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 0);
10231*6777b538SAndroid Build Coastguard Worker }
10232*6777b538SAndroid Build Coastguard Worker 
10233*6777b538SAndroid Build Coastguard Worker // Tests that we do not mark an entry as truncated when the request is
10234*6777b538SAndroid Build Coastguard Worker // cancelled.
TEST_F(HttpCacheTest,DontSetTruncatedFlagForGarbledResponseCode)10235*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, DontSetTruncatedFlagForGarbledResponseCode) {
10236*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10237*6777b538SAndroid Build Coastguard Worker 
10238*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10239*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
10240*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10241*6777b538SAndroid Build Coastguard Worker       "Content-Length: 22\n"
10242*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n";
10243*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 2";
10244*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10245*6777b538SAndroid Build Coastguard Worker 
10246*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
10247*6777b538SAndroid Build Coastguard Worker 
10248*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
10249*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
10250*6777b538SAndroid Build Coastguard Worker 
10251*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10252*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
10253*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
10254*6777b538SAndroid Build Coastguard Worker   }
10255*6777b538SAndroid Build Coastguard Worker 
10256*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10257*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10258*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10259*6777b538SAndroid Build Coastguard Worker 
10260*6777b538SAndroid Build Coastguard Worker   // Make sure that the entry has some data stored.
10261*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
10262*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(10);
10263*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10264*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
10265*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
10266*6777b538SAndroid Build Coastguard Worker   }
10267*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(buf->size(), rv);
10268*6777b538SAndroid Build Coastguard Worker 
10269*6777b538SAndroid Build Coastguard Worker   // We want to cancel the request when the transaction is busy.
10270*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10271*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10272*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(c->callback.have_result());
10273*6777b538SAndroid Build Coastguard Worker 
10274*6777b538SAndroid Build Coastguard Worker   MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
10275*6777b538SAndroid Build Coastguard Worker 
10276*6777b538SAndroid Build Coastguard Worker   // Destroy the transaction.
10277*6777b538SAndroid Build Coastguard Worker   c->trans.reset();
10278*6777b538SAndroid Build Coastguard Worker   MockHttpCache::SetTestMode(0);
10279*6777b538SAndroid Build Coastguard Worker 
10280*6777b538SAndroid Build Coastguard Worker   // Make sure that we don't invoke the callback. We may have an issue if the
10281*6777b538SAndroid Build Coastguard Worker   // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
10282*6777b538SAndroid Build Coastguard Worker   // could end up with the transaction being deleted twice if we send any
10283*6777b538SAndroid Build Coastguard Worker   // notification from the transaction destructor (see http://crbug.com/31723).
10284*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(c->callback.have_result());
10285*6777b538SAndroid Build Coastguard Worker 
10286*6777b538SAndroid Build Coastguard Worker   // Verify that the entry is deleted as well, since the response status is
10287*6777b538SAndroid Build Coastguard Worker   // garbled. Note that the entry will be deleted after the pending Read is
10288*6777b538SAndroid Build Coastguard Worker   // complete.
10289*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
10290*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
10291*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10292*6777b538SAndroid Build Coastguard Worker }
10293*6777b538SAndroid Build Coastguard Worker 
10294*6777b538SAndroid Build Coastguard Worker // Tests that we don't mark an entry as truncated when we read everything.
TEST_F(HttpCacheTest,DontSetTruncatedFlag)10295*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, DontSetTruncatedFlag) {
10296*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10297*6777b538SAndroid Build Coastguard Worker 
10298*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10299*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
10300*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10301*6777b538SAndroid Build Coastguard Worker       "Content-Length: 22\n"
10302*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n";
10303*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10304*6777b538SAndroid Build Coastguard Worker 
10305*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
10306*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
10307*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
10308*6777b538SAndroid Build Coastguard Worker 
10309*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10310*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10311*6777b538SAndroid Build Coastguard Worker 
10312*6777b538SAndroid Build Coastguard Worker   // Read everything.
10313*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
10314*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(22);
10315*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10316*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
10317*6777b538SAndroid Build Coastguard Worker 
10318*6777b538SAndroid Build Coastguard Worker   // Destroy the transaction.
10319*6777b538SAndroid Build Coastguard Worker   c->trans.reset();
10320*6777b538SAndroid Build Coastguard Worker 
10321*6777b538SAndroid Build Coastguard Worker   // Verify that the entry is not marked as truncated.
10322*6777b538SAndroid Build Coastguard Worker   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 0);
10323*6777b538SAndroid Build Coastguard Worker }
10324*6777b538SAndroid Build Coastguard Worker 
10325*6777b538SAndroid Build Coastguard Worker // Tests that sparse entries don't set the truncate flag.
TEST_F(HttpCacheTest,RangeGET_DontTruncate)10326*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_DontTruncate) {
10327*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10328*6777b538SAndroid Build Coastguard Worker 
10329*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10330*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 0-19\r\n" EXTRA_HEADER;
10331*6777b538SAndroid Build Coastguard Worker 
10332*6777b538SAndroid Build Coastguard Worker   auto request = std::make_unique<MockHttpRequest>(transaction);
10333*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
10334*6777b538SAndroid Build Coastguard Worker 
10335*6777b538SAndroid Build Coastguard Worker   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
10336*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsOk());
10337*6777b538SAndroid Build Coastguard Worker 
10338*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback cb;
10339*6777b538SAndroid Build Coastguard Worker   rv = trans->Start(request.get(), cb.callback(), NetLogWithSource());
10340*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cb.GetResult(rv));
10341*6777b538SAndroid Build Coastguard Worker 
10342*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<IOBufferWithSize>(10);
10343*6777b538SAndroid Build Coastguard Worker   rv = trans->Read(buf.get(), 10, cb.callback());
10344*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, cb.GetResult(rv));
10345*6777b538SAndroid Build Coastguard Worker 
10346*6777b538SAndroid Build Coastguard Worker   // Should not trigger any DCHECK.
10347*6777b538SAndroid Build Coastguard Worker   trans.reset();
10348*6777b538SAndroid Build Coastguard Worker   VerifyTruncatedFlag(&cache, request->CacheKey(), false, 0);
10349*6777b538SAndroid Build Coastguard Worker }
10350*6777b538SAndroid Build Coastguard Worker 
10351*6777b538SAndroid Build Coastguard Worker // Tests that sparse entries don't set the truncate flag (when the byte range
10352*6777b538SAndroid Build Coastguard Worker //  starts after 0).
TEST_F(HttpCacheTest,RangeGET_DontTruncate2)10353*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_DontTruncate2) {
10354*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10355*6777b538SAndroid Build Coastguard Worker 
10356*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10357*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
10358*6777b538SAndroid Build Coastguard Worker 
10359*6777b538SAndroid Build Coastguard Worker   auto request = std::make_unique<MockHttpRequest>(transaction);
10360*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
10361*6777b538SAndroid Build Coastguard Worker 
10362*6777b538SAndroid Build Coastguard Worker   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
10363*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsOk());
10364*6777b538SAndroid Build Coastguard Worker 
10365*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback cb;
10366*6777b538SAndroid Build Coastguard Worker   rv = trans->Start(request.get(), cb.callback(), NetLogWithSource());
10367*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cb.GetResult(rv));
10368*6777b538SAndroid Build Coastguard Worker 
10369*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<IOBufferWithSize>(10);
10370*6777b538SAndroid Build Coastguard Worker   rv = trans->Read(buf.get(), 10, cb.callback());
10371*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, cb.GetResult(rv));
10372*6777b538SAndroid Build Coastguard Worker 
10373*6777b538SAndroid Build Coastguard Worker   // Should not trigger any DCHECK.
10374*6777b538SAndroid Build Coastguard Worker   trans.reset();
10375*6777b538SAndroid Build Coastguard Worker   VerifyTruncatedFlag(&cache, request->CacheKey(), false, 0);
10376*6777b538SAndroid Build Coastguard Worker }
10377*6777b538SAndroid Build Coastguard Worker 
10378*6777b538SAndroid Build Coastguard Worker // Tests that we can continue with a request that was interrupted.
TEST_F(HttpCacheTest,GET_IncompleteResource)10379*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_IncompleteResource) {
10380*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10381*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10382*6777b538SAndroid Build Coastguard Worker 
10383*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(
10384*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
10385*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10386*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
10387*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
10388*6777b538SAndroid Build Coastguard Worker       "Content-Length: 80\n");
10389*6777b538SAndroid Build Coastguard Worker   CreateTruncatedEntry(raw_headers, &cache);
10390*6777b538SAndroid Build Coastguard Worker 
10391*6777b538SAndroid Build Coastguard Worker   // Now make a regular request.
10392*6777b538SAndroid Build Coastguard Worker   std::string headers;
10393*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
10394*6777b538SAndroid Build Coastguard Worker   transaction.data = kFullRangeData;
10395*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10396*6777b538SAndroid Build Coastguard Worker 
10397*6777b538SAndroid Build Coastguard Worker   // We update the headers with the ones received while revalidating.
10398*6777b538SAndroid Build Coastguard Worker   std::string expected_headers(
10399*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
10400*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10401*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
10402*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
10403*6777b538SAndroid Build Coastguard Worker       "Content-Length: 80\n");
10404*6777b538SAndroid Build Coastguard Worker 
10405*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_headers, headers);
10406*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10407*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
10408*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10409*6777b538SAndroid Build Coastguard Worker 
10410*6777b538SAndroid Build Coastguard Worker   // Verify that the disk entry was updated.
10411*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10412*6777b538SAndroid Build Coastguard Worker   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 80);
10413*6777b538SAndroid Build Coastguard Worker }
10414*6777b538SAndroid Build Coastguard Worker 
10415*6777b538SAndroid Build Coastguard Worker // Tests the handling of no-store when revalidating a truncated entry.
TEST_F(HttpCacheTest,GET_IncompleteResource_NoStore)10416*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_IncompleteResource_NoStore) {
10417*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10418*6777b538SAndroid Build Coastguard Worker   {
10419*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10420*6777b538SAndroid Build Coastguard Worker 
10421*6777b538SAndroid Build Coastguard Worker     std::string raw_headers(
10422*6777b538SAndroid Build Coastguard Worker         "HTTP/1.1 200 OK\n"
10423*6777b538SAndroid Build Coastguard Worker         "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10424*6777b538SAndroid Build Coastguard Worker         "ETag: \"foo\"\n"
10425*6777b538SAndroid Build Coastguard Worker         "Accept-Ranges: bytes\n"
10426*6777b538SAndroid Build Coastguard Worker         "Content-Length: 80\n");
10427*6777b538SAndroid Build Coastguard Worker     CreateTruncatedEntry(raw_headers, &cache);
10428*6777b538SAndroid Build Coastguard Worker   }
10429*6777b538SAndroid Build Coastguard Worker 
10430*6777b538SAndroid Build Coastguard Worker   // Now make a regular request.
10431*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10432*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
10433*6777b538SAndroid Build Coastguard Worker   std::string response_headers(transaction.response_headers);
10434*6777b538SAndroid Build Coastguard Worker   response_headers += ("Cache-Control: no-store\n");
10435*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = response_headers.c_str();
10436*6777b538SAndroid Build Coastguard Worker   transaction.data = kFullRangeData;
10437*6777b538SAndroid Build Coastguard Worker 
10438*6777b538SAndroid Build Coastguard Worker   std::string headers;
10439*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10440*6777b538SAndroid Build Coastguard Worker 
10441*6777b538SAndroid Build Coastguard Worker   // We update the headers with the ones received while revalidating.
10442*6777b538SAndroid Build Coastguard Worker   std::string expected_headers(
10443*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
10444*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10445*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
10446*6777b538SAndroid Build Coastguard Worker       "Cache-Control: no-store\n"
10447*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
10448*6777b538SAndroid Build Coastguard Worker       "Content-Length: 80\n");
10449*6777b538SAndroid Build Coastguard Worker 
10450*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_headers, headers);
10451*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10452*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
10453*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10454*6777b538SAndroid Build Coastguard Worker 
10455*6777b538SAndroid Build Coastguard Worker   // Verify that the disk entry was deleted.
10456*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
10457*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10458*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10459*6777b538SAndroid Build Coastguard Worker }
10460*6777b538SAndroid Build Coastguard Worker 
10461*6777b538SAndroid Build Coastguard Worker // Tests cancelling a request after the server sent no-store.
TEST_F(HttpCacheTest,GET_IncompleteResource_Cancel)10462*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_IncompleteResource_Cancel) {
10463*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10464*6777b538SAndroid Build Coastguard Worker   {
10465*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10466*6777b538SAndroid Build Coastguard Worker     std::string raw_headers(
10467*6777b538SAndroid Build Coastguard Worker         "HTTP/1.1 200 OK\n"
10468*6777b538SAndroid Build Coastguard Worker         "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10469*6777b538SAndroid Build Coastguard Worker         "ETag: \"foo\"\n"
10470*6777b538SAndroid Build Coastguard Worker         "Accept-Ranges: bytes\n"
10471*6777b538SAndroid Build Coastguard Worker         "Content-Length: 80\n");
10472*6777b538SAndroid Build Coastguard Worker     CreateTruncatedEntry(raw_headers, &cache);
10473*6777b538SAndroid Build Coastguard Worker   }
10474*6777b538SAndroid Build Coastguard Worker 
10475*6777b538SAndroid Build Coastguard Worker   // Now make a regular request.
10476*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10477*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
10478*6777b538SAndroid Build Coastguard Worker   std::string response_headers(transaction.response_headers);
10479*6777b538SAndroid Build Coastguard Worker   response_headers += ("Cache-Control: no-store\n");
10480*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = response_headers.c_str();
10481*6777b538SAndroid Build Coastguard Worker   transaction.data = kFullRangeData;
10482*6777b538SAndroid Build Coastguard Worker 
10483*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10484*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
10485*6777b538SAndroid Build Coastguard Worker 
10486*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
10487*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
10488*6777b538SAndroid Build Coastguard Worker 
10489*6777b538SAndroid Build Coastguard Worker   // Queue another request to this transaction. We have to start this request
10490*6777b538SAndroid Build Coastguard Worker   // before the first one gets the response from the server and dooms the entry,
10491*6777b538SAndroid Build Coastguard Worker   // otherwise it will just create a new entry without being queued to the first
10492*6777b538SAndroid Build Coastguard Worker   // request.
10493*6777b538SAndroid Build Coastguard Worker   auto pending = std::make_unique<Context>();
10494*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&pending->trans), IsOk());
10495*6777b538SAndroid Build Coastguard Worker 
10496*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10497*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING,
10498*6777b538SAndroid Build Coastguard Worker             pending->trans->Start(&request, pending->callback.callback(),
10499*6777b538SAndroid Build Coastguard Worker                                   NetLogWithSource()));
10500*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10501*6777b538SAndroid Build Coastguard Worker 
10502*6777b538SAndroid Build Coastguard Worker   // Make sure that the entry has some data stored.
10503*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
10504*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(5);
10505*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10506*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, c->callback.GetResult(rv));
10507*6777b538SAndroid Build Coastguard Worker 
10508*6777b538SAndroid Build Coastguard Worker   // Since |pending| is currently validating the already written headers
10509*6777b538SAndroid Build Coastguard Worker   // it will be restarted as well.
10510*6777b538SAndroid Build Coastguard Worker   c.reset();
10511*6777b538SAndroid Build Coastguard Worker   pending.reset();
10512*6777b538SAndroid Build Coastguard Worker 
10513*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10514*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
10515*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10516*6777b538SAndroid Build Coastguard Worker 
10517*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
10518*6777b538SAndroid Build Coastguard Worker }
10519*6777b538SAndroid Build Coastguard Worker 
10520*6777b538SAndroid Build Coastguard Worker // Tests that we delete truncated entries if the server changes its mind midway.
TEST_F(HttpCacheTest,GET_IncompleteResource2)10521*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_IncompleteResource2) {
10522*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10523*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10524*6777b538SAndroid Build Coastguard Worker   // Content-length will be intentionally bad.
10525*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(
10526*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
10527*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10528*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
10529*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
10530*6777b538SAndroid Build Coastguard Worker       "Content-Length: 50\n");
10531*6777b538SAndroid Build Coastguard Worker   CreateTruncatedEntry(raw_headers, &cache);
10532*6777b538SAndroid Build Coastguard Worker 
10533*6777b538SAndroid Build Coastguard Worker   // Now make a regular request. We expect the code to fail the validation and
10534*6777b538SAndroid Build Coastguard Worker   // retry the request without using byte ranges.
10535*6777b538SAndroid Build Coastguard Worker   std::string headers;
10536*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_TransactionOK);
10537*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
10538*6777b538SAndroid Build Coastguard Worker   transaction.data = "Not a range";
10539*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10540*6777b538SAndroid Build Coastguard Worker 
10541*6777b538SAndroid Build Coastguard Worker   // The server will return 200 instead of a byte range.
10542*6777b538SAndroid Build Coastguard Worker   std::string expected_headers(
10543*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
10544*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
10545*6777b538SAndroid Build Coastguard Worker 
10546*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_headers, headers);
10547*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10548*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
10549*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10550*6777b538SAndroid Build Coastguard Worker 
10551*6777b538SAndroid Build Coastguard Worker   // Verify that the disk entry was deleted.
10552*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
10553*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10554*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10555*6777b538SAndroid Build Coastguard Worker }
10556*6777b538SAndroid Build Coastguard Worker 
10557*6777b538SAndroid Build Coastguard Worker // Tests that we always validate a truncated request.
TEST_F(HttpCacheTest,GET_IncompleteResource3)10558*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_IncompleteResource3) {
10559*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10560*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10561*6777b538SAndroid Build Coastguard Worker 
10562*6777b538SAndroid Build Coastguard Worker   // This should not require validation for 10 hours.
10563*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(
10564*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
10565*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10566*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
10567*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age= 36000\n"
10568*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
10569*6777b538SAndroid Build Coastguard Worker       "Content-Length: 80\n");
10570*6777b538SAndroid Build Coastguard Worker   CreateTruncatedEntry(raw_headers, &cache);
10571*6777b538SAndroid Build Coastguard Worker 
10572*6777b538SAndroid Build Coastguard Worker   // Now make a regular request.
10573*6777b538SAndroid Build Coastguard Worker   std::string headers;
10574*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_TransactionOK);
10575*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
10576*6777b538SAndroid Build Coastguard Worker   transaction.data = kFullRangeData;
10577*6777b538SAndroid Build Coastguard Worker 
10578*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
10579*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
10580*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
10581*6777b538SAndroid Build Coastguard Worker 
10582*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10583*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10584*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10585*6777b538SAndroid Build Coastguard Worker 
10586*6777b538SAndroid Build Coastguard Worker   // We should have checked with the server before finishing Start().
10587*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10588*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
10589*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10590*6777b538SAndroid Build Coastguard Worker }
10591*6777b538SAndroid Build Coastguard Worker 
10592*6777b538SAndroid Build Coastguard Worker // Tests that we handle 401s for truncated resources.
TEST_F(HttpCacheTest,GET_IncompleteResourceWithAuth)10593*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_IncompleteResourceWithAuth) {
10594*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10595*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10596*6777b538SAndroid Build Coastguard Worker 
10597*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(
10598*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
10599*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10600*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
10601*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
10602*6777b538SAndroid Build Coastguard Worker       "Content-Length: 80\n");
10603*6777b538SAndroid Build Coastguard Worker   CreateTruncatedEntry(raw_headers, &cache);
10604*6777b538SAndroid Build Coastguard Worker 
10605*6777b538SAndroid Build Coastguard Worker   // Now make a regular request.
10606*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_TransactionOK);
10607*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n" EXTRA_HEADER;
10608*6777b538SAndroid Build Coastguard Worker   transaction.data = kFullRangeData;
10609*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer handler;
10610*6777b538SAndroid Build Coastguard Worker 
10611*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
10612*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
10613*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
10614*6777b538SAndroid Build Coastguard Worker 
10615*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10616*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10617*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10618*6777b538SAndroid Build Coastguard Worker 
10619*6777b538SAndroid Build Coastguard Worker   const HttpResponseInfo* response = c->trans->GetResponseInfo();
10620*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(response);
10621*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(401, response->headers->response_code());
10622*6777b538SAndroid Build Coastguard Worker   rv = c->trans->RestartWithAuth(AuthCredentials(), c->callback.callback());
10623*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10624*6777b538SAndroid Build Coastguard Worker   response = c->trans->GetResponseInfo();
10625*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(response);
10626*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(200, response->headers->response_code());
10627*6777b538SAndroid Build Coastguard Worker 
10628*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(c->trans.get(), transaction);
10629*6777b538SAndroid Build Coastguard Worker   c.reset();  // The destructor could delete the entry.
10630*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10631*6777b538SAndroid Build Coastguard Worker 
10632*6777b538SAndroid Build Coastguard Worker   // Verify that the entry was deleted.
10633*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
10634*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10635*6777b538SAndroid Build Coastguard Worker   entry->Close();
10636*6777b538SAndroid Build Coastguard Worker }
10637*6777b538SAndroid Build Coastguard Worker 
10638*6777b538SAndroid Build Coastguard Worker // Test that the transaction won't retry failed partial requests
10639*6777b538SAndroid Build Coastguard Worker // after it starts reading data.  http://crbug.com/474835
TEST_F(HttpCacheTest,TransactionRetryLimit)10640*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, TransactionRetryLimit) {
10641*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10642*6777b538SAndroid Build Coastguard Worker 
10643*6777b538SAndroid Build Coastguard Worker   // Cache 0-9, so that we have data to read before failing.
10644*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10645*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
10646*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 00-09 ";
10647*6777b538SAndroid Build Coastguard Worker 
10648*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
10649*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
10650*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10651*6777b538SAndroid Build Coastguard Worker 
10652*6777b538SAndroid Build Coastguard Worker   // And now read from the cache and the network.  10-19 will get a
10653*6777b538SAndroid Build Coastguard Worker   // 401, but will have already returned 0-9.
10654*6777b538SAndroid Build Coastguard Worker   // We do not set X-Require-Mock-Auth because that causes the mock
10655*6777b538SAndroid Build Coastguard Worker   // network transaction to become IsReadyToRestartForAuth().
10656*6777b538SAndroid Build Coastguard Worker   transaction.request_headers =
10657*6777b538SAndroid Build Coastguard Worker       "Range: bytes = 0-79\r\n"
10658*6777b538SAndroid Build Coastguard Worker       "X-Require-Mock-Auth-Alt: dummy\r\n" EXTRA_HEADER;
10659*6777b538SAndroid Build Coastguard Worker 
10660*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
10661*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
10662*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
10663*6777b538SAndroid Build Coastguard Worker 
10664*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10665*6777b538SAndroid Build Coastguard Worker 
10666*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10667*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
10668*6777b538SAndroid Build Coastguard Worker     rv = c->callback.WaitForResult();
10669*6777b538SAndroid Build Coastguard Worker   }
10670*6777b538SAndroid Build Coastguard Worker   std::string content;
10671*6777b538SAndroid Build Coastguard Worker   rv = ReadTransaction(c->trans.get(), &content);
10672*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_CACHE_AUTH_FAILURE_AFTER_READ));
10673*6777b538SAndroid Build Coastguard Worker }
10674*6777b538SAndroid Build Coastguard Worker 
10675*6777b538SAndroid Build Coastguard Worker // Tests that we cache a 200 response to the validation request.
TEST_F(HttpCacheTest,GET_IncompleteResource4)10676*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_IncompleteResource4) {
10677*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10678*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10679*6777b538SAndroid Build Coastguard Worker 
10680*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(
10681*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
10682*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10683*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
10684*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
10685*6777b538SAndroid Build Coastguard Worker       "Content-Length: 80\n");
10686*6777b538SAndroid Build Coastguard Worker   CreateTruncatedEntry(raw_headers, &cache);
10687*6777b538SAndroid Build Coastguard Worker 
10688*6777b538SAndroid Build Coastguard Worker   // Now make a regular request.
10689*6777b538SAndroid Build Coastguard Worker   std::string headers;
10690*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
10691*6777b538SAndroid Build Coastguard Worker   transaction.data = "Not a range";
10692*6777b538SAndroid Build Coastguard Worker   RangeTransactionServer handler;
10693*6777b538SAndroid Build Coastguard Worker   handler.set_bad_200(true);
10694*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10695*6777b538SAndroid Build Coastguard Worker 
10696*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10697*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
10698*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10699*6777b538SAndroid Build Coastguard Worker 
10700*6777b538SAndroid Build Coastguard Worker   // Verify that the disk entry was updated.
10701*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10702*6777b538SAndroid Build Coastguard Worker   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 11);
10703*6777b538SAndroid Build Coastguard Worker }
10704*6777b538SAndroid Build Coastguard Worker 
10705*6777b538SAndroid Build Coastguard Worker // Tests that when we cancel a request that was interrupted, we mark it again
10706*6777b538SAndroid Build Coastguard Worker // as truncated.
TEST_F(HttpCacheTest,GET_CancelIncompleteResource)10707*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GET_CancelIncompleteResource) {
10708*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10709*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10710*6777b538SAndroid Build Coastguard Worker 
10711*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(
10712*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
10713*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10714*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
10715*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
10716*6777b538SAndroid Build Coastguard Worker       "Content-Length: 80\n");
10717*6777b538SAndroid Build Coastguard Worker   CreateTruncatedEntry(raw_headers, &cache);
10718*6777b538SAndroid Build Coastguard Worker 
10719*6777b538SAndroid Build Coastguard Worker   // Now make a regular request.
10720*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
10721*6777b538SAndroid Build Coastguard Worker 
10722*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10723*6777b538SAndroid Build Coastguard Worker   auto c = std::make_unique<Context>();
10724*6777b538SAndroid Build Coastguard Worker   int rv = cache.CreateTransaction(&c->trans);
10725*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsOk());
10726*6777b538SAndroid Build Coastguard Worker 
10727*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10728*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10729*6777b538SAndroid Build Coastguard Worker 
10730*6777b538SAndroid Build Coastguard Worker   // Read 20 bytes from the cache, and 10 from the net.
10731*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<IOBufferWithSize>(100);
10732*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), 20, c->callback.callback());
10733*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20, c->callback.GetResult(rv));
10734*6777b538SAndroid Build Coastguard Worker   rv = c->trans->Read(buf.get(), 10, c->callback.callback());
10735*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, c->callback.GetResult(rv));
10736*6777b538SAndroid Build Coastguard Worker 
10737*6777b538SAndroid Build Coastguard Worker   // At this point, we are already reading so canceling the request should leave
10738*6777b538SAndroid Build Coastguard Worker   // a truncated one.
10739*6777b538SAndroid Build Coastguard Worker   c.reset();
10740*6777b538SAndroid Build Coastguard Worker 
10741*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10742*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
10743*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10744*6777b538SAndroid Build Coastguard Worker 
10745*6777b538SAndroid Build Coastguard Worker   // Verify that the disk entry was updated: now we have 30 bytes.
10746*6777b538SAndroid Build Coastguard Worker   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 30);
10747*6777b538SAndroid Build Coastguard Worker }
10748*6777b538SAndroid Build Coastguard Worker 
10749*6777b538SAndroid Build Coastguard Worker // Tests that we can handle range requests when we have a truncated entry.
TEST_F(HttpCacheTest,RangeGET_IncompleteResource)10750*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_IncompleteResource) {
10751*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10752*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10753*6777b538SAndroid Build Coastguard Worker 
10754*6777b538SAndroid Build Coastguard Worker   // Content-length will be intentionally bogus.
10755*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(
10756*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
10757*6777b538SAndroid Build Coastguard Worker       "Last-Modified: something\n"
10758*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
10759*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
10760*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n");
10761*6777b538SAndroid Build Coastguard Worker   CreateTruncatedEntry(raw_headers, &cache);
10762*6777b538SAndroid Build Coastguard Worker 
10763*6777b538SAndroid Build Coastguard Worker   // Now make a range request.
10764*6777b538SAndroid Build Coastguard Worker   std::string headers;
10765*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
10766*6777b538SAndroid Build Coastguard Worker                                  &headers);
10767*6777b538SAndroid Build Coastguard Worker 
10768*6777b538SAndroid Build Coastguard Worker   Verify206Response(headers, 40, 49);
10769*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10770*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
10771*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
10772*6777b538SAndroid Build Coastguard Worker }
10773*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SyncRead)10774*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SyncRead) {
10775*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10776*6777b538SAndroid Build Coastguard Worker 
10777*6777b538SAndroid Build Coastguard Worker   // This test ensures that a read that completes synchronously does not cause
10778*6777b538SAndroid Build Coastguard Worker   // any problems.
10779*6777b538SAndroid Build Coastguard Worker 
10780*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10781*6777b538SAndroid Build Coastguard Worker   transaction.test_mode |=
10782*6777b538SAndroid Build Coastguard Worker       (TEST_MODE_SYNC_CACHE_START | TEST_MODE_SYNC_CACHE_READ |
10783*6777b538SAndroid Build Coastguard Worker        TEST_MODE_SYNC_CACHE_WRITE);
10784*6777b538SAndroid Build Coastguard Worker 
10785*6777b538SAndroid Build Coastguard Worker   MockHttpRequest r1(transaction), r2(transaction), r3(transaction);
10786*6777b538SAndroid Build Coastguard Worker 
10787*6777b538SAndroid Build Coastguard Worker   TestTransactionConsumer c1(DEFAULT_PRIORITY, cache.http_cache()),
10788*6777b538SAndroid Build Coastguard Worker       c2(DEFAULT_PRIORITY, cache.http_cache()),
10789*6777b538SAndroid Build Coastguard Worker       c3(DEFAULT_PRIORITY, cache.http_cache());
10790*6777b538SAndroid Build Coastguard Worker 
10791*6777b538SAndroid Build Coastguard Worker   c1.Start(&r1, NetLogWithSource());
10792*6777b538SAndroid Build Coastguard Worker 
10793*6777b538SAndroid Build Coastguard Worker   r2.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
10794*6777b538SAndroid Build Coastguard Worker   c2.Start(&r2, NetLogWithSource());
10795*6777b538SAndroid Build Coastguard Worker 
10796*6777b538SAndroid Build Coastguard Worker   r3.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
10797*6777b538SAndroid Build Coastguard Worker   c3.Start(&r3, NetLogWithSource());
10798*6777b538SAndroid Build Coastguard Worker 
10799*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(c1.is_done());
10800*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(c2.is_done());
10801*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(c3.is_done());
10802*6777b538SAndroid Build Coastguard Worker 
10803*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c1.error(), IsOk());
10804*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c2.error(), IsOk());
10805*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(c3.error(), IsOk());
10806*6777b538SAndroid Build Coastguard Worker }
10807*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,ValidationResultsIn200)10808*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ValidationResultsIn200) {
10809*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10810*6777b538SAndroid Build Coastguard Worker 
10811*6777b538SAndroid Build Coastguard Worker   // This test ensures that a conditional request, which results in a 200
10812*6777b538SAndroid Build Coastguard Worker   // instead of a 304, properly truncates the existing response data.
10813*6777b538SAndroid Build Coastguard Worker 
10814*6777b538SAndroid Build Coastguard Worker   // write to the cache
10815*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
10816*6777b538SAndroid Build Coastguard Worker 
10817*6777b538SAndroid Build Coastguard Worker   // force this transaction to validate the cache
10818*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kETagGET_Transaction);
10819*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_VALIDATE_CACHE;
10820*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
10821*6777b538SAndroid Build Coastguard Worker 
10822*6777b538SAndroid Build Coastguard Worker   // read from the cache
10823*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
10824*6777b538SAndroid Build Coastguard Worker }
10825*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,CachedRedirect)10826*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CachedRedirect) {
10827*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10828*6777b538SAndroid Build Coastguard Worker 
10829*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
10830*6777b538SAndroid Build Coastguard Worker   kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
10831*6777b538SAndroid Build Coastguard Worker   kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
10832*6777b538SAndroid Build Coastguard Worker 
10833*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kTestTransaction);
10834*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
10835*6777b538SAndroid Build Coastguard Worker 
10836*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
10837*6777b538SAndroid Build Coastguard Worker   {
10838*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
10839*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
10840*6777b538SAndroid Build Coastguard Worker 
10841*6777b538SAndroid Build Coastguard Worker     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
10842*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING) {
10843*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
10844*6777b538SAndroid Build Coastguard Worker     }
10845*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(rv, IsOk());
10846*6777b538SAndroid Build Coastguard Worker 
10847*6777b538SAndroid Build Coastguard Worker     const HttpResponseInfo* info = trans->GetResponseInfo();
10848*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(info);
10849*6777b538SAndroid Build Coastguard Worker 
10850*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(info->headers->response_code(), 301);
10851*6777b538SAndroid Build Coastguard Worker 
10852*6777b538SAndroid Build Coastguard Worker     std::string location;
10853*6777b538SAndroid Build Coastguard Worker     info->headers->EnumerateHeader(nullptr, "Location", &location);
10854*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(location, "http://www.bar.com/");
10855*6777b538SAndroid Build Coastguard Worker 
10856*6777b538SAndroid Build Coastguard Worker     // Mark the transaction as completed so it is cached.
10857*6777b538SAndroid Build Coastguard Worker     trans->DoneReading();
10858*6777b538SAndroid Build Coastguard Worker 
10859*6777b538SAndroid Build Coastguard Worker     // Destroy transaction when going out of scope. We have not actually
10860*6777b538SAndroid Build Coastguard Worker     // read the response body -- want to test that it is still getting cached.
10861*6777b538SAndroid Build Coastguard Worker   }
10862*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10863*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10864*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10865*6777b538SAndroid Build Coastguard Worker 
10866*6777b538SAndroid Build Coastguard Worker   // Active entries in the cache are not retired synchronously. Make
10867*6777b538SAndroid Build Coastguard Worker   // sure the next run hits the MockHttpCache and open_count is
10868*6777b538SAndroid Build Coastguard Worker   // correct.
10869*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
10870*6777b538SAndroid Build Coastguard Worker 
10871*6777b538SAndroid Build Coastguard Worker   // Read from the cache.
10872*6777b538SAndroid Build Coastguard Worker   {
10873*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
10874*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
10875*6777b538SAndroid Build Coastguard Worker 
10876*6777b538SAndroid Build Coastguard Worker     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
10877*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING) {
10878*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
10879*6777b538SAndroid Build Coastguard Worker     }
10880*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(rv, IsOk());
10881*6777b538SAndroid Build Coastguard Worker 
10882*6777b538SAndroid Build Coastguard Worker     const HttpResponseInfo* info = trans->GetResponseInfo();
10883*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(info);
10884*6777b538SAndroid Build Coastguard Worker 
10885*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(info->headers->response_code(), 301);
10886*6777b538SAndroid Build Coastguard Worker 
10887*6777b538SAndroid Build Coastguard Worker     std::string location;
10888*6777b538SAndroid Build Coastguard Worker     info->headers->EnumerateHeader(nullptr, "Location", &location);
10889*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(location, "http://www.bar.com/");
10890*6777b538SAndroid Build Coastguard Worker 
10891*6777b538SAndroid Build Coastguard Worker     // Mark the transaction as completed so it is cached.
10892*6777b538SAndroid Build Coastguard Worker     trans->DoneReading();
10893*6777b538SAndroid Build Coastguard Worker 
10894*6777b538SAndroid Build Coastguard Worker     // Destroy transaction when going out of scope. We have not actually
10895*6777b538SAndroid Build Coastguard Worker     // read the response body -- want to test that it is still getting cached.
10896*6777b538SAndroid Build Coastguard Worker   }
10897*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10898*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
10899*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10900*6777b538SAndroid Build Coastguard Worker }
10901*6777b538SAndroid Build Coastguard Worker 
10902*6777b538SAndroid Build Coastguard Worker // Verify that no-cache resources are stored in cache, but are not fetched from
10903*6777b538SAndroid Build Coastguard Worker // cache during normal loads.
TEST_F(HttpCacheTest,CacheControlNoCacheNormalLoad)10904*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheControlNoCacheNormalLoad) {
10905*6777b538SAndroid Build Coastguard Worker   for (bool use_memory_entry_data : {false, true}) {
10906*6777b538SAndroid Build Coastguard Worker     MockHttpCache cache;
10907*6777b538SAndroid Build Coastguard Worker     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
10908*6777b538SAndroid Build Coastguard Worker 
10909*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kSimpleGET_Transaction);
10910*6777b538SAndroid Build Coastguard Worker     transaction.response_headers = "cache-control: no-cache\n";
10911*6777b538SAndroid Build Coastguard Worker 
10912*6777b538SAndroid Build Coastguard Worker     // Initial load.
10913*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
10914*6777b538SAndroid Build Coastguard Worker 
10915*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
10916*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache.disk_cache()->open_count());
10917*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
10918*6777b538SAndroid Build Coastguard Worker 
10919*6777b538SAndroid Build Coastguard Worker     // Try loading again; it should result in a network fetch.
10920*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
10921*6777b538SAndroid Build Coastguard Worker 
10922*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache.network_layer()->transaction_count());
10923*6777b538SAndroid Build Coastguard Worker     if (use_memory_entry_data) {
10924*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(0, cache.disk_cache()->open_count());
10925*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(2, cache.disk_cache()->create_count());
10926*6777b538SAndroid Build Coastguard Worker     } else {
10927*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(1, cache.disk_cache()->open_count());
10928*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(1, cache.disk_cache()->create_count());
10929*6777b538SAndroid Build Coastguard Worker     }
10930*6777b538SAndroid Build Coastguard Worker 
10931*6777b538SAndroid Build Coastguard Worker     disk_cache::Entry* entry;
10932*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(transaction);
10933*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10934*6777b538SAndroid Build Coastguard Worker     entry->Close();
10935*6777b538SAndroid Build Coastguard Worker   }
10936*6777b538SAndroid Build Coastguard Worker }
10937*6777b538SAndroid Build Coastguard Worker 
10938*6777b538SAndroid Build Coastguard Worker // Verify that no-cache resources are stored in cache and fetched from cache
10939*6777b538SAndroid Build Coastguard Worker // when the LOAD_SKIP_CACHE_VALIDATION flag is set.
TEST_F(HttpCacheTest,CacheControlNoCacheHistoryLoad)10940*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheControlNoCacheHistoryLoad) {
10941*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10942*6777b538SAndroid Build Coastguard Worker 
10943*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10944*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "cache-control: no-cache\n";
10945*6777b538SAndroid Build Coastguard Worker 
10946*6777b538SAndroid Build Coastguard Worker   // Initial load.
10947*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
10948*6777b538SAndroid Build Coastguard Worker 
10949*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10950*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10951*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10952*6777b538SAndroid Build Coastguard Worker 
10953*6777b538SAndroid Build Coastguard Worker   // Try loading again with LOAD_SKIP_CACHE_VALIDATION.
10954*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_SKIP_CACHE_VALIDATION;
10955*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
10956*6777b538SAndroid Build Coastguard Worker 
10957*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10958*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
10959*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10960*6777b538SAndroid Build Coastguard Worker 
10961*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
10962*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10963*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10964*6777b538SAndroid Build Coastguard Worker   entry->Close();
10965*6777b538SAndroid Build Coastguard Worker }
10966*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,CacheControlNoStore)10967*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheControlNoStore) {
10968*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10969*6777b538SAndroid Build Coastguard Worker 
10970*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10971*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "cache-control: no-store\n";
10972*6777b538SAndroid Build Coastguard Worker 
10973*6777b538SAndroid Build Coastguard Worker   // initial load
10974*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
10975*6777b538SAndroid Build Coastguard Worker 
10976*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10977*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10978*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
10979*6777b538SAndroid Build Coastguard Worker 
10980*6777b538SAndroid Build Coastguard Worker   // try loading again; it should result in a network fetch
10981*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
10982*6777b538SAndroid Build Coastguard Worker 
10983*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10984*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
10985*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
10986*6777b538SAndroid Build Coastguard Worker 
10987*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
10988*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
10989*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10990*6777b538SAndroid Build Coastguard Worker }
10991*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,CacheControlNoStore2)10992*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheControlNoStore2) {
10993*6777b538SAndroid Build Coastguard Worker   // this test is similar to the above test, except that the initial response
10994*6777b538SAndroid Build Coastguard Worker   // is cachable, but when it is validated, no-store is received causing the
10995*6777b538SAndroid Build Coastguard Worker   // cached document to be deleted.
10996*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
10997*6777b538SAndroid Build Coastguard Worker 
10998*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kETagGET_Transaction);
10999*6777b538SAndroid Build Coastguard Worker 
11000*6777b538SAndroid Build Coastguard Worker   // initial load
11001*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11002*6777b538SAndroid Build Coastguard Worker 
11003*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11004*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
11005*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
11006*6777b538SAndroid Build Coastguard Worker 
11007*6777b538SAndroid Build Coastguard Worker   // try loading again; it should result in a network fetch
11008*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_VALIDATE_CACHE;
11009*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "cache-control: no-store\n";
11010*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11011*6777b538SAndroid Build Coastguard Worker 
11012*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11013*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
11014*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
11015*6777b538SAndroid Build Coastguard Worker 
11016*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
11017*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
11018*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11019*6777b538SAndroid Build Coastguard Worker }
11020*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,CacheControlNoStore3)11021*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheControlNoStore3) {
11022*6777b538SAndroid Build Coastguard Worker   // this test is similar to the above test, except that the response is a 304
11023*6777b538SAndroid Build Coastguard Worker   // instead of a 200.  this should never happen in practice, but it seems like
11024*6777b538SAndroid Build Coastguard Worker   // a good thing to verify that we still destroy the cache entry.
11025*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11026*6777b538SAndroid Build Coastguard Worker 
11027*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kETagGET_Transaction);
11028*6777b538SAndroid Build Coastguard Worker 
11029*6777b538SAndroid Build Coastguard Worker   // initial load
11030*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11031*6777b538SAndroid Build Coastguard Worker 
11032*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11033*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
11034*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
11035*6777b538SAndroid Build Coastguard Worker 
11036*6777b538SAndroid Build Coastguard Worker   // try loading again; it should result in a network fetch
11037*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_VALIDATE_CACHE;
11038*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "cache-control: no-store\n";
11039*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 304 Not Modified";
11040*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11041*6777b538SAndroid Build Coastguard Worker 
11042*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11043*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
11044*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
11045*6777b538SAndroid Build Coastguard Worker 
11046*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
11047*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
11048*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11049*6777b538SAndroid Build Coastguard Worker }
11050*6777b538SAndroid Build Coastguard Worker 
11051*6777b538SAndroid Build Coastguard Worker // Ensure that we don't cache requests served over bad HTTPS.
TEST_F(HttpCacheTest,SimpleGET_SSLError)11052*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SimpleGET_SSLError) {
11053*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11054*6777b538SAndroid Build Coastguard Worker 
11055*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction = kSimpleGET_Transaction;
11056*6777b538SAndroid Build Coastguard Worker   transaction.cert_status = CERT_STATUS_REVOKED;
11057*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(transaction);
11058*6777b538SAndroid Build Coastguard Worker 
11059*6777b538SAndroid Build Coastguard Worker   // write to the cache
11060*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11061*6777b538SAndroid Build Coastguard Worker 
11062*6777b538SAndroid Build Coastguard Worker   // Test that it was not cached.
11063*6777b538SAndroid Build Coastguard Worker   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
11064*6777b538SAndroid Build Coastguard Worker 
11065*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
11066*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
11067*6777b538SAndroid Build Coastguard Worker 
11068*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
11069*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11070*6777b538SAndroid Build Coastguard Worker 
11071*6777b538SAndroid Build Coastguard Worker   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11072*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
11073*6777b538SAndroid Build Coastguard Worker     rv = callback.WaitForResult();
11074*6777b538SAndroid Build Coastguard Worker   }
11075*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
11076*6777b538SAndroid Build Coastguard Worker }
11077*6777b538SAndroid Build Coastguard Worker 
11078*6777b538SAndroid Build Coastguard Worker // Ensure that we don't crash by if left-behind transactions.
TEST_F(HttpCacheTest,OutlivedTransactions)11079*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, OutlivedTransactions) {
11080*6777b538SAndroid Build Coastguard Worker   auto cache = std::make_unique<MockHttpCache>();
11081*6777b538SAndroid Build Coastguard Worker 
11082*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
11083*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cache->CreateTransaction(&trans), IsOk());
11084*6777b538SAndroid Build Coastguard Worker 
11085*6777b538SAndroid Build Coastguard Worker   cache.reset();
11086*6777b538SAndroid Build Coastguard Worker   trans.reset();
11087*6777b538SAndroid Build Coastguard Worker }
11088*6777b538SAndroid Build Coastguard Worker 
11089*6777b538SAndroid Build Coastguard Worker // Test that the disabled mode works.
TEST_F(HttpCacheTest,CacheDisabledMode)11090*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheDisabledMode) {
11091*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11092*6777b538SAndroid Build Coastguard Worker 
11093*6777b538SAndroid Build Coastguard Worker   // write to the cache
11094*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11095*6777b538SAndroid Build Coastguard Worker 
11096*6777b538SAndroid Build Coastguard Worker   // go into disabled mode
11097*6777b538SAndroid Build Coastguard Worker   cache.http_cache()->set_mode(HttpCache::DISABLE);
11098*6777b538SAndroid Build Coastguard Worker 
11099*6777b538SAndroid Build Coastguard Worker   // force this transaction to write to the cache again
11100*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
11101*6777b538SAndroid Build Coastguard Worker 
11102*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11103*6777b538SAndroid Build Coastguard Worker 
11104*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11105*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
11106*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
11107*6777b538SAndroid Build Coastguard Worker }
11108*6777b538SAndroid Build Coastguard Worker 
11109*6777b538SAndroid Build Coastguard Worker // Other tests check that the response headers of the cached response
11110*6777b538SAndroid Build Coastguard Worker // get updated on 304. Here we specifically check that the
11111*6777b538SAndroid Build Coastguard Worker // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
11112*6777b538SAndroid Build Coastguard Worker // fields also gets updated.
11113*6777b538SAndroid Build Coastguard Worker // http://crbug.com/20594.
TEST_F(HttpCacheTest,UpdatesRequestResponseTimeOn304)11114*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, UpdatesRequestResponseTimeOn304) {
11115*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11116*6777b538SAndroid Build Coastguard Worker 
11117*6777b538SAndroid Build Coastguard Worker   const char kUrl[] = "http://foobar";
11118*6777b538SAndroid Build Coastguard Worker   const char kData[] = "body";
11119*6777b538SAndroid Build Coastguard Worker 
11120*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_network_response(kUrl);
11121*6777b538SAndroid Build Coastguard Worker 
11122*6777b538SAndroid Build Coastguard Worker   // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
11123*6777b538SAndroid Build Coastguard Worker 
11124*6777b538SAndroid Build Coastguard Worker   MockTransaction request = {nullptr};
11125*6777b538SAndroid Build Coastguard Worker   request.url = kUrl;
11126*6777b538SAndroid Build Coastguard Worker   request.method = "GET";
11127*6777b538SAndroid Build Coastguard Worker   request.request_headers = "\r\n";
11128*6777b538SAndroid Build Coastguard Worker   request.data = kData;
11129*6777b538SAndroid Build Coastguard Worker 
11130*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse1 = {
11131*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
11132*6777b538SAndroid Build Coastguard Worker       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
11133*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
11134*6777b538SAndroid Build Coastguard Worker       kData};
11135*6777b538SAndroid Build Coastguard Worker 
11136*6777b538SAndroid Build Coastguard Worker   kNetResponse1.AssignTo(&mock_network_response);
11137*6777b538SAndroid Build Coastguard Worker 
11138*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), request);
11139*6777b538SAndroid Build Coastguard Worker 
11140*6777b538SAndroid Build Coastguard Worker   // Request |kUrl| again, this time validating the cache and getting
11141*6777b538SAndroid Build Coastguard Worker   // a 304 back.
11142*6777b538SAndroid Build Coastguard Worker 
11143*6777b538SAndroid Build Coastguard Worker   request.load_flags = LOAD_VALIDATE_CACHE;
11144*6777b538SAndroid Build Coastguard Worker 
11145*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse2 = {
11146*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 304 Not Modified", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n", ""};
11147*6777b538SAndroid Build Coastguard Worker 
11148*6777b538SAndroid Build Coastguard Worker   kNetResponse2.AssignTo(&mock_network_response);
11149*6777b538SAndroid Build Coastguard Worker 
11150*6777b538SAndroid Build Coastguard Worker   base::Time request_time = base::Time() + base::Hours(1234);
11151*6777b538SAndroid Build Coastguard Worker   base::Time response_time = base::Time() + base::Hours(1235);
11152*6777b538SAndroid Build Coastguard Worker 
11153*6777b538SAndroid Build Coastguard Worker   mock_network_response.request_time = request_time;
11154*6777b538SAndroid Build Coastguard Worker   mock_network_response.response_time = response_time;
11155*6777b538SAndroid Build Coastguard Worker 
11156*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
11157*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
11158*6777b538SAndroid Build Coastguard Worker 
11159*6777b538SAndroid Build Coastguard Worker   // The request and response times should have been updated.
11160*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(request_time.ToInternalValue(),
11161*6777b538SAndroid Build Coastguard Worker             response.request_time.ToInternalValue());
11162*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(response_time.ToInternalValue(),
11163*6777b538SAndroid Build Coastguard Worker             response.response_time.ToInternalValue());
11164*6777b538SAndroid Build Coastguard Worker 
11165*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
11166*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
11167*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
11168*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
11169*6777b538SAndroid Build Coastguard Worker       ToSimpleString(response.headers));
11170*6777b538SAndroid Build Coastguard Worker }
11171*6777b538SAndroid Build Coastguard Worker 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCacheWithNetworkIsolationKey)11172*6777b538SAndroid Build Coastguard Worker TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
11173*6777b538SAndroid Build Coastguard Worker        SplitCacheWithNetworkIsolationKey) {
11174*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11175*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
11176*6777b538SAndroid Build Coastguard Worker 
11177*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_a(GURL("http://a.com"));
11178*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_b(GURL("http://b.com"));
11179*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_data(GURL("data:text/html,<body>Hello World</body>"));
11180*6777b538SAndroid Build Coastguard Worker 
11181*6777b538SAndroid Build Coastguard Worker   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11182*6777b538SAndroid Build Coastguard Worker   // Request with a.com as the top frame and subframe origins. This should
11183*6777b538SAndroid Build Coastguard Worker   // result in a cache miss.
11184*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11185*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11186*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11187*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11188*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11189*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11190*6777b538SAndroid Build Coastguard Worker 
11191*6777b538SAndroid Build Coastguard Worker   // The second request should result in a cache hit.
11192*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11193*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11194*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
11195*6777b538SAndroid Build Coastguard Worker 
11196*6777b538SAndroid Build Coastguard Worker   // Now request with b.com as the subframe origin. It should result in a cache
11197*6777b538SAndroid Build Coastguard Worker   // miss.
11198*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_b);
11199*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11200*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateCrossSite(site_a);
11201*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11202*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11203*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11204*6777b538SAndroid Build Coastguard Worker 
11205*6777b538SAndroid Build Coastguard Worker   // The second request should result in a cache hit.
11206*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11207*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11208*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
11209*6777b538SAndroid Build Coastguard Worker 
11210*6777b538SAndroid Build Coastguard Worker   // Another request with a.com as the top frame and subframe origin should
11211*6777b538SAndroid Build Coastguard Worker   // still result in a cache hit.
11212*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11213*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11214*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11215*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11216*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11217*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
11218*6777b538SAndroid Build Coastguard Worker 
11219*6777b538SAndroid Build Coastguard Worker   // Now make a request with an opaque subframe site. It shouldn't cause
11220*6777b538SAndroid Build Coastguard Worker   // anything to be added to the cache when the NIK makes use of the frame site.
11221*6777b538SAndroid Build Coastguard Worker   // Note that we will use `site_b` as the top-level site so that this resource
11222*6777b538SAndroid Build Coastguard Worker   // won't be in the cache at first regardless of the NIK partitioning scheme.
11223*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_data);
11224*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11225*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateCrossSite(site_b);
11226*6777b538SAndroid Build Coastguard Worker   switch (GetParam()) {
11227*6777b538SAndroid Build Coastguard Worker     case SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled:
11228*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(std::nullopt,
11229*6777b538SAndroid Build Coastguard Worker                 trans_info.network_isolation_key.ToCacheKeyString());
11230*6777b538SAndroid Build Coastguard Worker       break;
11231*6777b538SAndroid Build Coastguard Worker     case SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled:
11232*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ("http://b.com _1",
11233*6777b538SAndroid Build Coastguard Worker                 trans_info.network_isolation_key.ToCacheKeyString().value());
11234*6777b538SAndroid Build Coastguard Worker       break;
11235*6777b538SAndroid Build Coastguard Worker     case SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled:
11236*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ("http://b.com _opaque",
11237*6777b538SAndroid Build Coastguard Worker                 trans_info.network_isolation_key.ToCacheKeyString().value());
11238*6777b538SAndroid Build Coastguard Worker       break;
11239*6777b538SAndroid Build Coastguard Worker     case SplitCacheTestCase::kSplitCacheDisabled:
11240*6777b538SAndroid Build Coastguard Worker       NOTREACHED_NORETURN();
11241*6777b538SAndroid Build Coastguard Worker   }
11242*6777b538SAndroid Build Coastguard Worker 
11243*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11244*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11245*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11246*6777b538SAndroid Build Coastguard Worker 
11247*6777b538SAndroid Build Coastguard Worker   // On the second request, expect a cache miss if the NIK uses the frame site.
11248*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11249*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11250*6777b538SAndroid Build Coastguard Worker   switch (GetParam()) {
11251*6777b538SAndroid Build Coastguard Worker     case SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled:
11252*6777b538SAndroid Build Coastguard Worker       EXPECT_FALSE(response.was_cached);
11253*6777b538SAndroid Build Coastguard Worker       break;
11254*6777b538SAndroid Build Coastguard Worker     case SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled:
11255*6777b538SAndroid Build Coastguard Worker     case SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled:
11256*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(response.was_cached);
11257*6777b538SAndroid Build Coastguard Worker       break;
11258*6777b538SAndroid Build Coastguard Worker     case SplitCacheTestCase::kSplitCacheDisabled:
11259*6777b538SAndroid Build Coastguard Worker       NOTREACHED_NORETURN();
11260*6777b538SAndroid Build Coastguard Worker   }
11261*6777b538SAndroid Build Coastguard Worker 
11262*6777b538SAndroid Build Coastguard Worker   // Verify that a post transaction with a data stream uses a separate key.
11263*6777b538SAndroid Build Coastguard Worker   const int64_t kUploadId = 1;  // Just a dummy value.
11264*6777b538SAndroid Build Coastguard Worker 
11265*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11266*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
11267*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
11268*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
11269*6777b538SAndroid Build Coastguard Worker                                               kUploadId);
11270*6777b538SAndroid Build Coastguard Worker 
11271*6777b538SAndroid Build Coastguard Worker   MockHttpRequest post_info = MockHttpRequest(kSimplePOST_Transaction);
11272*6777b538SAndroid Build Coastguard Worker   post_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11273*6777b538SAndroid Build Coastguard Worker   post_info.network_anonymization_key =
11274*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11275*6777b538SAndroid Build Coastguard Worker   post_info.upload_data_stream = &upload_data_stream;
11276*6777b538SAndroid Build Coastguard Worker 
11277*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimplePOST_Transaction,
11278*6777b538SAndroid Build Coastguard Worker                                 post_info, &response);
11279*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11280*6777b538SAndroid Build Coastguard Worker }
11281*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyCSS)11282*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyCSS) {
11283*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histograms;
11284*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11285*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
11286*6777b538SAndroid Build Coastguard Worker 
11287*6777b538SAndroid Build Coastguard Worker   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11288*6777b538SAndroid Build Coastguard Worker   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11289*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_a(origin_a);
11290*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_b(origin_b);
11291*6777b538SAndroid Build Coastguard Worker 
11292*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11293*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "Content-Type: text/css\n";
11294*6777b538SAndroid Build Coastguard Worker 
11295*6777b538SAndroid Build Coastguard Worker   MockHttpRequest trans_info = MockHttpRequest(transaction);
11296*6777b538SAndroid Build Coastguard Worker 
11297*6777b538SAndroid Build Coastguard Worker   // Requesting with the same top-frame site should not count as third-party
11298*6777b538SAndroid Build Coastguard Worker   // but should still be recorded as CSS
11299*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11300*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11301*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11302*6777b538SAndroid Build Coastguard Worker   trans_info.possibly_top_frame_origin = origin_a;
11303*6777b538SAndroid Build Coastguard Worker 
11304*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11305*6777b538SAndroid Build Coastguard Worker                                 &response);
11306*6777b538SAndroid Build Coastguard Worker 
11307*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11308*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.CSS", 1);
11309*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.CSSThirdParty", 0);
11310*6777b538SAndroid Build Coastguard Worker 
11311*6777b538SAndroid Build Coastguard Worker   // Requesting with a different top-frame site should count as third-party
11312*6777b538SAndroid Build Coastguard Worker   // and recorded as CSS
11313*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11314*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11315*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11316*6777b538SAndroid Build Coastguard Worker   trans_info.possibly_top_frame_origin = origin_b;
11317*6777b538SAndroid Build Coastguard Worker 
11318*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11319*6777b538SAndroid Build Coastguard Worker                                 &response);
11320*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11321*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.CSS", 2);
11322*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.CSSThirdParty", 1);
11323*6777b538SAndroid Build Coastguard Worker }
11324*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyJavaScript)11325*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyJavaScript) {
11326*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histograms;
11327*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11328*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
11329*6777b538SAndroid Build Coastguard Worker 
11330*6777b538SAndroid Build Coastguard Worker   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11331*6777b538SAndroid Build Coastguard Worker   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11332*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_a(origin_a);
11333*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_b(origin_b);
11334*6777b538SAndroid Build Coastguard Worker 
11335*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11336*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "Content-Type: application/javascript\n";
11337*6777b538SAndroid Build Coastguard Worker 
11338*6777b538SAndroid Build Coastguard Worker   MockHttpRequest trans_info = MockHttpRequest(transaction);
11339*6777b538SAndroid Build Coastguard Worker 
11340*6777b538SAndroid Build Coastguard Worker   // Requesting with the same top-frame site should not count as third-party
11341*6777b538SAndroid Build Coastguard Worker   // but should still be recorded as JavaScript
11342*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11343*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11344*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11345*6777b538SAndroid Build Coastguard Worker   trans_info.possibly_top_frame_origin = origin_a;
11346*6777b538SAndroid Build Coastguard Worker 
11347*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11348*6777b538SAndroid Build Coastguard Worker                                 &response);
11349*6777b538SAndroid Build Coastguard Worker 
11350*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11351*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScript", 1);
11352*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScriptThirdParty", 0);
11353*6777b538SAndroid Build Coastguard Worker 
11354*6777b538SAndroid Build Coastguard Worker   // Requesting with a different top-frame site should count as third-party
11355*6777b538SAndroid Build Coastguard Worker   // and recorded as JavaScript
11356*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11357*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11358*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11359*6777b538SAndroid Build Coastguard Worker   trans_info.possibly_top_frame_origin = origin_b;
11360*6777b538SAndroid Build Coastguard Worker 
11361*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11362*6777b538SAndroid Build Coastguard Worker                                 &response);
11363*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11364*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScript", 2);
11365*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScriptThirdParty", 1);
11366*6777b538SAndroid Build Coastguard Worker }
11367*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyFont)11368*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyFont) {
11369*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histograms;
11370*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11371*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
11372*6777b538SAndroid Build Coastguard Worker 
11373*6777b538SAndroid Build Coastguard Worker   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11374*6777b538SAndroid Build Coastguard Worker   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11375*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_a(origin_a);
11376*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_b(origin_b);
11377*6777b538SAndroid Build Coastguard Worker 
11378*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11379*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "Content-Type: font/otf\n";
11380*6777b538SAndroid Build Coastguard Worker 
11381*6777b538SAndroid Build Coastguard Worker   MockHttpRequest trans_info = MockHttpRequest(transaction);
11382*6777b538SAndroid Build Coastguard Worker 
11383*6777b538SAndroid Build Coastguard Worker   // Requesting with the same top-frame site should not count as third-party
11384*6777b538SAndroid Build Coastguard Worker   // but should still be recorded as a font
11385*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11386*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11387*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11388*6777b538SAndroid Build Coastguard Worker   trans_info.possibly_top_frame_origin = origin_a;
11389*6777b538SAndroid Build Coastguard Worker 
11390*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11391*6777b538SAndroid Build Coastguard Worker                                 &response);
11392*6777b538SAndroid Build Coastguard Worker 
11393*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11394*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.Font", 1);
11395*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.FontThirdParty", 0);
11396*6777b538SAndroid Build Coastguard Worker 
11397*6777b538SAndroid Build Coastguard Worker   // Requesting with a different top-frame site should count as third-party
11398*6777b538SAndroid Build Coastguard Worker   // and recorded as a font
11399*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11400*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11401*6777b538SAndroid Build Coastguard Worker       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11402*6777b538SAndroid Build Coastguard Worker   trans_info.possibly_top_frame_origin = origin_b;
11403*6777b538SAndroid Build Coastguard Worker 
11404*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11405*6777b538SAndroid Build Coastguard Worker                                 &response);
11406*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11407*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.Font", 2);
11408*6777b538SAndroid Build Coastguard Worker   histograms.ExpectTotalCount("HttpCache.Pattern.FontThirdParty", 1);
11409*6777b538SAndroid Build Coastguard Worker }
11410*6777b538SAndroid Build Coastguard Worker 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCache)11411*6777b538SAndroid Build Coastguard Worker TEST_P(HttpCacheTest_SplitCacheFeatureEnabled, SplitCache) {
11412*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11413*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
11414*6777b538SAndroid Build Coastguard Worker 
11415*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_a(GURL("http://a.com"));
11416*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_b(GURL("http://b.com"));
11417*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_data(GURL("data:text/html,<body>Hello World</body>"));
11418*6777b538SAndroid Build Coastguard Worker 
11419*6777b538SAndroid Build Coastguard Worker   // A request without a top frame origin shouldn't result in anything being
11420*6777b538SAndroid Build Coastguard Worker   // added to the cache.
11421*6777b538SAndroid Build Coastguard Worker   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11422*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = net::NetworkIsolationKey();
11423*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key = net::NetworkAnonymizationKey();
11424*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11425*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11426*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11427*6777b538SAndroid Build Coastguard Worker 
11428*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11429*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11430*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11431*6777b538SAndroid Build Coastguard Worker 
11432*6777b538SAndroid Build Coastguard Worker   // Now request with a.com as the top frame origin. This should initially
11433*6777b538SAndroid Build Coastguard Worker   // result in a cache miss since the cached resource has a different top frame
11434*6777b538SAndroid Build Coastguard Worker   // origin.
11435*6777b538SAndroid Build Coastguard Worker   net::NetworkIsolationKey key_a(site_a, site_a);
11436*6777b538SAndroid Build Coastguard Worker   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11437*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = key_a;
11438*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key = nak_a;
11439*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11440*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11441*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11442*6777b538SAndroid Build Coastguard Worker 
11443*6777b538SAndroid Build Coastguard Worker   // The second request should result in a cache hit.
11444*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11445*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11446*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
11447*6777b538SAndroid Build Coastguard Worker 
11448*6777b538SAndroid Build Coastguard Worker   // If the same resource with the same NIK is for a subframe document resource,
11449*6777b538SAndroid Build Coastguard Worker   // it should not be a cache hit.
11450*6777b538SAndroid Build Coastguard Worker   MockHttpRequest subframe_document_trans_info = trans_info;
11451*6777b538SAndroid Build Coastguard Worker   subframe_document_trans_info.is_subframe_document_resource = true;
11452*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11453*6777b538SAndroid Build Coastguard Worker                                 subframe_document_trans_info, &response);
11454*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11455*6777b538SAndroid Build Coastguard Worker 
11456*6777b538SAndroid Build Coastguard Worker   // Same request again should be a cache hit.
11457*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11458*6777b538SAndroid Build Coastguard Worker                                 subframe_document_trans_info, &response);
11459*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
11460*6777b538SAndroid Build Coastguard Worker 
11461*6777b538SAndroid Build Coastguard Worker   // Now request with b.com as the top frame origin. It should be a cache miss.
11462*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11463*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11464*6777b538SAndroid Build Coastguard Worker       NetworkAnonymizationKey::CreateSameSite(site_b);
11465*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11466*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11467*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11468*6777b538SAndroid Build Coastguard Worker 
11469*6777b538SAndroid Build Coastguard Worker   // The second request should be a cache hit.
11470*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11471*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11472*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
11473*6777b538SAndroid Build Coastguard Worker 
11474*6777b538SAndroid Build Coastguard Worker   // Another request for a.com should still result in a cache hit.
11475*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = key_a;
11476*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key = nak_a;
11477*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11478*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11479*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
11480*6777b538SAndroid Build Coastguard Worker 
11481*6777b538SAndroid Build Coastguard Worker   // Now make a request with an opaque top frame origin. It shouldn't result in
11482*6777b538SAndroid Build Coastguard Worker   // a cache hit.
11483*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(site_data, site_data);
11484*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11485*6777b538SAndroid Build Coastguard Worker       NetworkAnonymizationKey::CreateSameSite(site_data);
11486*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::nullopt, trans_info.network_isolation_key.ToCacheKeyString());
11487*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11488*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11489*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11490*6777b538SAndroid Build Coastguard Worker 
11491*6777b538SAndroid Build Coastguard Worker   // On the second request, it still shouldn't result in a cache hit.
11492*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11493*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11494*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11495*6777b538SAndroid Build Coastguard Worker 
11496*6777b538SAndroid Build Coastguard Worker   // Verify that a post transaction with a data stream uses a separate key.
11497*6777b538SAndroid Build Coastguard Worker   const int64_t kUploadId = 1;  // Just a dummy value.
11498*6777b538SAndroid Build Coastguard Worker 
11499*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11500*6777b538SAndroid Build Coastguard Worker   element_readers.push_back(
11501*6777b538SAndroid Build Coastguard Worker       std::make_unique<UploadBytesElementReader>("hello", 5));
11502*6777b538SAndroid Build Coastguard Worker   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
11503*6777b538SAndroid Build Coastguard Worker                                               kUploadId);
11504*6777b538SAndroid Build Coastguard Worker 
11505*6777b538SAndroid Build Coastguard Worker   MockHttpRequest post_info = MockHttpRequest(kSimplePOST_Transaction);
11506*6777b538SAndroid Build Coastguard Worker   post_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11507*6777b538SAndroid Build Coastguard Worker   post_info.network_anonymization_key =
11508*6777b538SAndroid Build Coastguard Worker       NetworkAnonymizationKey::CreateSameSite(site_a);
11509*6777b538SAndroid Build Coastguard Worker   post_info.upload_data_stream = &upload_data_stream;
11510*6777b538SAndroid Build Coastguard Worker 
11511*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimplePOST_Transaction,
11512*6777b538SAndroid Build Coastguard Worker                                 post_info, &response);
11513*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11514*6777b538SAndroid Build Coastguard Worker }
11515*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SplitCacheEnabledByDefault)11516*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SplitCacheEnabledByDefault) {
11517*6777b538SAndroid Build Coastguard Worker   HttpCache::ClearGlobalsForTesting();
11518*6777b538SAndroid Build Coastguard Worker   HttpCache::SplitCacheFeatureEnableByDefault();
11519*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(HttpCache::IsSplitCacheEnabled());
11520*6777b538SAndroid Build Coastguard Worker 
11521*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11522*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
11523*6777b538SAndroid Build Coastguard Worker 
11524*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_a(GURL("http://a.com"));
11525*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_b(GURL("http://b.com"));
11526*6777b538SAndroid Build Coastguard Worker   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11527*6777b538SAndroid Build Coastguard Worker   net::NetworkIsolationKey key_a(site_a, site_a);
11528*6777b538SAndroid Build Coastguard Worker   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11529*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = key_a;
11530*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key = nak_a;
11531*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11532*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11533*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11534*6777b538SAndroid Build Coastguard Worker 
11535*6777b538SAndroid Build Coastguard Worker   // Subsequent requests with the same NIK and different NIK will be a cache hit
11536*6777b538SAndroid Build Coastguard Worker   // and miss respectively.
11537*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11538*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11539*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
11540*6777b538SAndroid Build Coastguard Worker 
11541*6777b538SAndroid Build Coastguard Worker   net::NetworkIsolationKey key_b(site_b, site_b);
11542*6777b538SAndroid Build Coastguard Worker   auto nak_b = net::NetworkAnonymizationKey::CreateSameSite(site_b);
11543*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = key_b;
11544*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key = nak_b;
11545*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11546*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11547*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11548*6777b538SAndroid Build Coastguard Worker }
11549*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SplitCacheEnabledByDefaultButOverridden)11550*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SplitCacheEnabledByDefaultButOverridden) {
11551*6777b538SAndroid Build Coastguard Worker   HttpCache::ClearGlobalsForTesting();
11552*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList feature_list;
11553*6777b538SAndroid Build Coastguard Worker   feature_list.InitAndDisableFeature(
11554*6777b538SAndroid Build Coastguard Worker       net::features::kSplitCacheByNetworkIsolationKey);
11555*6777b538SAndroid Build Coastguard Worker 
11556*6777b538SAndroid Build Coastguard Worker   // Enabling it here should have no effect as it is already overridden.
11557*6777b538SAndroid Build Coastguard Worker   HttpCache::SplitCacheFeatureEnableByDefault();
11558*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(HttpCache::IsSplitCacheEnabled());
11559*6777b538SAndroid Build Coastguard Worker }
11560*6777b538SAndroid Build Coastguard Worker 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCacheUsesRegistrableDomain)11561*6777b538SAndroid Build Coastguard Worker TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
11562*6777b538SAndroid Build Coastguard Worker        SplitCacheUsesRegistrableDomain) {
11563*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11564*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
11565*6777b538SAndroid Build Coastguard Worker   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11566*6777b538SAndroid Build Coastguard Worker 
11567*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_a(GURL("http://a.foo.com"));
11568*6777b538SAndroid Build Coastguard Worker   SchemefulSite site_b(GURL("http://b.foo.com"));
11569*6777b538SAndroid Build Coastguard Worker 
11570*6777b538SAndroid Build Coastguard Worker   net::NetworkIsolationKey key_a(site_a, site_a);
11571*6777b538SAndroid Build Coastguard Worker   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11572*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = key_a;
11573*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key = nak_a;
11574*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11575*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11576*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11577*6777b538SAndroid Build Coastguard Worker 
11578*6777b538SAndroid Build Coastguard Worker   // The second request with a different origin but the same registrable domain
11579*6777b538SAndroid Build Coastguard Worker   // should be a cache hit.
11580*6777b538SAndroid Build Coastguard Worker   net::NetworkIsolationKey key_b(site_b, site_b);
11581*6777b538SAndroid Build Coastguard Worker   auto nak_b = net::NetworkAnonymizationKey::CreateSameSite(site_b);
11582*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = key_b;
11583*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key = nak_b;
11584*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11585*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11586*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
11587*6777b538SAndroid Build Coastguard Worker 
11588*6777b538SAndroid Build Coastguard Worker   // Request with a different registrable domain. It should be a cache miss.
11589*6777b538SAndroid Build Coastguard Worker   SchemefulSite new_site_a(GURL("http://a.bar.com"));
11590*6777b538SAndroid Build Coastguard Worker   net::NetworkIsolationKey new_key_a(new_site_a, new_site_a);
11591*6777b538SAndroid Build Coastguard Worker   auto new_nak_a = net::NetworkAnonymizationKey::CreateSameSite(new_site_a);
11592*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = new_key_a;
11593*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key = new_nak_a;
11594*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11595*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11596*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11597*6777b538SAndroid Build Coastguard Worker }
11598*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,NonSplitCache)11599*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, NonSplitCache) {
11600*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList feature_list;
11601*6777b538SAndroid Build Coastguard Worker   feature_list.InitAndDisableFeature(
11602*6777b538SAndroid Build Coastguard Worker       net::features::kSplitCacheByNetworkIsolationKey);
11603*6777b538SAndroid Build Coastguard Worker 
11604*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11605*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
11606*6777b538SAndroid Build Coastguard Worker 
11607*6777b538SAndroid Build Coastguard Worker   // A request without a top frame is added to the cache normally.
11608*6777b538SAndroid Build Coastguard Worker   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11609*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey();
11610*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key = NetworkAnonymizationKey();
11611*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11612*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11613*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
11614*6777b538SAndroid Build Coastguard Worker 
11615*6777b538SAndroid Build Coastguard Worker   // The second request should result in a cache hit.
11616*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11617*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11618*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
11619*6777b538SAndroid Build Coastguard Worker 
11620*6777b538SAndroid Build Coastguard Worker   // Now request with a.com as the top frame origin. The same cached object
11621*6777b538SAndroid Build Coastguard Worker   // should be used.
11622*6777b538SAndroid Build Coastguard Worker   const SchemefulSite kSiteA(GURL("http://a.com/"));
11623*6777b538SAndroid Build Coastguard Worker   trans_info.network_isolation_key = NetworkIsolationKey(kSiteA, kSiteA);
11624*6777b538SAndroid Build Coastguard Worker   trans_info.network_anonymization_key =
11625*6777b538SAndroid Build Coastguard Worker       NetworkAnonymizationKey::CreateSameSite(kSiteA);
11626*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11627*6777b538SAndroid Build Coastguard Worker                                 trans_info, &response);
11628*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
11629*6777b538SAndroid Build Coastguard Worker }
11630*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SkipVaryCheck)11631*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SkipVaryCheck) {
11632*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11633*6777b538SAndroid Build Coastguard Worker 
11634*6777b538SAndroid Build Coastguard Worker   // Write a simple vary transaction to the cache.
11635*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
11636*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11637*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "accept-encoding: gzip\r\n";
11638*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
11639*6777b538SAndroid Build Coastguard Worker       "Vary: accept-encoding\n"
11640*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=10000\n";
11641*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11642*6777b538SAndroid Build Coastguard Worker 
11643*6777b538SAndroid Build Coastguard Worker   // Change the request headers so that the request doesn't match due to vary.
11644*6777b538SAndroid Build Coastguard Worker   // The request should fail.
11645*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11646*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "accept-encoding: foo\r\n";
11647*6777b538SAndroid Build Coastguard Worker   transaction.start_return_code = ERR_CACHE_MISS;
11648*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11649*6777b538SAndroid Build Coastguard Worker 
11650*6777b538SAndroid Build Coastguard Worker   // Change the load flags to ignore vary checks, the request should now hit.
11651*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_VARY_CHECK;
11652*6777b538SAndroid Build Coastguard Worker   transaction.start_return_code = OK;
11653*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11654*6777b538SAndroid Build Coastguard Worker }
11655*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SkipVaryCheckStar)11656*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SkipVaryCheckStar) {
11657*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11658*6777b538SAndroid Build Coastguard Worker 
11659*6777b538SAndroid Build Coastguard Worker   // Write a simple vary:* transaction to the cache.
11660*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
11661*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11662*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "accept-encoding: gzip\r\n";
11663*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
11664*6777b538SAndroid Build Coastguard Worker       "Vary: *\n"
11665*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=10000\n";
11666*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11667*6777b538SAndroid Build Coastguard Worker 
11668*6777b538SAndroid Build Coastguard Worker   // The request shouldn't match even with the same request headers due to the
11669*6777b538SAndroid Build Coastguard Worker   // Vary: *. The request should fail.
11670*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11671*6777b538SAndroid Build Coastguard Worker   transaction.start_return_code = ERR_CACHE_MISS;
11672*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11673*6777b538SAndroid Build Coastguard Worker 
11674*6777b538SAndroid Build Coastguard Worker   // Change the load flags to ignore vary checks, the request should now hit.
11675*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_VARY_CHECK;
11676*6777b538SAndroid Build Coastguard Worker   transaction.start_return_code = OK;
11677*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11678*6777b538SAndroid Build Coastguard Worker }
11679*6777b538SAndroid Build Coastguard Worker 
11680*6777b538SAndroid Build Coastguard Worker // Tests that we only return valid entries with LOAD_ONLY_FROM_CACHE
11681*6777b538SAndroid Build Coastguard Worker // transactions unless LOAD_SKIP_CACHE_VALIDATION is set.
TEST_F(HttpCacheTest,ValidLoadOnlyFromCache)11682*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, ValidLoadOnlyFromCache) {
11683*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11684*6777b538SAndroid Build Coastguard Worker   base::SimpleTestClock clock;
11685*6777b538SAndroid Build Coastguard Worker   cache.http_cache()->SetClockForTesting(&clock);
11686*6777b538SAndroid Build Coastguard Worker   cache.network_layer()->SetClock(&clock);
11687*6777b538SAndroid Build Coastguard Worker 
11688*6777b538SAndroid Build Coastguard Worker   // Write a resource that will expire in 100 seconds.
11689*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11690*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "Cache-Control: max-age=100\n";
11691*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11692*6777b538SAndroid Build Coastguard Worker 
11693*6777b538SAndroid Build Coastguard Worker   // Move forward in time such that the cached response is no longer valid.
11694*6777b538SAndroid Build Coastguard Worker   clock.Advance(base::Seconds(101));
11695*6777b538SAndroid Build Coastguard Worker 
11696*6777b538SAndroid Build Coastguard Worker   // Skipping cache validation should still return a response.
11697*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
11698*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11699*6777b538SAndroid Build Coastguard Worker 
11700*6777b538SAndroid Build Coastguard Worker   // If the cache entry is checked for validitiy, it should fail.
11701*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11702*6777b538SAndroid Build Coastguard Worker   transaction.start_return_code = ERR_CACHE_MISS;
11703*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11704*6777b538SAndroid Build Coastguard Worker }
11705*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,InvalidLoadFlagCombination)11706*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, InvalidLoadFlagCombination) {
11707*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11708*6777b538SAndroid Build Coastguard Worker 
11709*6777b538SAndroid Build Coastguard Worker   // Put the resource in the cache.
11710*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11711*6777b538SAndroid Build Coastguard Worker 
11712*6777b538SAndroid Build Coastguard Worker   // Now try to fetch it again, but with a flag combination disallowing both
11713*6777b538SAndroid Build Coastguard Worker   // cache and network access.
11714*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11715*6777b538SAndroid Build Coastguard Worker   // DevTools relies on this combination of flags for "disable cache" mode
11716*6777b538SAndroid Build Coastguard Worker   // when a resource is only supposed to be loaded from cache.
11717*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_BYPASS_CACHE;
11718*6777b538SAndroid Build Coastguard Worker   transaction.start_return_code = ERR_CACHE_MISS;
11719*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11720*6777b538SAndroid Build Coastguard Worker }
11721*6777b538SAndroid Build Coastguard Worker 
11722*6777b538SAndroid Build Coastguard Worker // Tests that we don't mark entries as truncated when a filter detects the end
11723*6777b538SAndroid Build Coastguard Worker // of the stream.
TEST_F(HttpCacheTest,FilterCompletion)11724*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, FilterCompletion) {
11725*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11726*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
11727*6777b538SAndroid Build Coastguard Worker 
11728*6777b538SAndroid Build Coastguard Worker   {
11729*6777b538SAndroid Build Coastguard Worker     MockHttpRequest request(kSimpleGET_Transaction);
11730*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
11731*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11732*6777b538SAndroid Build Coastguard Worker 
11733*6777b538SAndroid Build Coastguard Worker     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11734*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.GetResult(rv), IsOk());
11735*6777b538SAndroid Build Coastguard Worker 
11736*6777b538SAndroid Build Coastguard Worker     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11737*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 256, callback.callback());
11738*6777b538SAndroid Build Coastguard Worker     EXPECT_GT(callback.GetResult(rv), 0);
11739*6777b538SAndroid Build Coastguard Worker 
11740*6777b538SAndroid Build Coastguard Worker     // Now make sure that the entry is preserved.
11741*6777b538SAndroid Build Coastguard Worker     trans->DoneReading();
11742*6777b538SAndroid Build Coastguard Worker   }
11743*6777b538SAndroid Build Coastguard Worker 
11744*6777b538SAndroid Build Coastguard Worker   // Make sure that the ActiveEntry is gone.
11745*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
11746*6777b538SAndroid Build Coastguard Worker 
11747*6777b538SAndroid Build Coastguard Worker   // Read from the cache.
11748*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11749*6777b538SAndroid Build Coastguard Worker 
11750*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11751*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
11752*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
11753*6777b538SAndroid Build Coastguard Worker }
11754*6777b538SAndroid Build Coastguard Worker 
11755*6777b538SAndroid Build Coastguard Worker // Tests that we don't mark entries as truncated and release the cache
11756*6777b538SAndroid Build Coastguard Worker // entry when DoneReading() is called before any Read() calls, such as
11757*6777b538SAndroid Build Coastguard Worker // for a redirect.
TEST_F(HttpCacheTest,DoneReading)11758*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, DoneReading) {
11759*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11760*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
11761*6777b538SAndroid Build Coastguard Worker 
11762*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11763*6777b538SAndroid Build Coastguard Worker   transaction.data = "";
11764*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
11765*6777b538SAndroid Build Coastguard Worker 
11766*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
11767*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11768*6777b538SAndroid Build Coastguard Worker 
11769*6777b538SAndroid Build Coastguard Worker   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11770*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.GetResult(rv), IsOk());
11771*6777b538SAndroid Build Coastguard Worker 
11772*6777b538SAndroid Build Coastguard Worker   trans->DoneReading();
11773*6777b538SAndroid Build Coastguard Worker   // Leave the transaction around.
11774*6777b538SAndroid Build Coastguard Worker 
11775*6777b538SAndroid Build Coastguard Worker   // Make sure that the ActiveEntry is gone.
11776*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
11777*6777b538SAndroid Build Coastguard Worker 
11778*6777b538SAndroid Build Coastguard Worker   // Read from the cache. This should not deadlock.
11779*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), transaction);
11780*6777b538SAndroid Build Coastguard Worker 
11781*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11782*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
11783*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
11784*6777b538SAndroid Build Coastguard Worker }
11785*6777b538SAndroid Build Coastguard Worker 
11786*6777b538SAndroid Build Coastguard Worker // Tests that we stop caching when told.
TEST_F(HttpCacheTest,StopCachingDeletesEntry)11787*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, StopCachingDeletesEntry) {
11788*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11789*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
11790*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
11791*6777b538SAndroid Build Coastguard Worker 
11792*6777b538SAndroid Build Coastguard Worker   {
11793*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
11794*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11795*6777b538SAndroid Build Coastguard Worker 
11796*6777b538SAndroid Build Coastguard Worker     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11797*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.GetResult(rv), IsOk());
11798*6777b538SAndroid Build Coastguard Worker 
11799*6777b538SAndroid Build Coastguard Worker     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11800*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 10, callback.callback());
11801*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(10, callback.GetResult(rv));
11802*6777b538SAndroid Build Coastguard Worker 
11803*6777b538SAndroid Build Coastguard Worker     trans->StopCaching();
11804*6777b538SAndroid Build Coastguard Worker 
11805*6777b538SAndroid Build Coastguard Worker     // We should be able to keep reading.
11806*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 256, callback.callback());
11807*6777b538SAndroid Build Coastguard Worker     EXPECT_GT(callback.GetResult(rv), 0);
11808*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 256, callback.callback());
11809*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, callback.GetResult(rv));
11810*6777b538SAndroid Build Coastguard Worker   }
11811*6777b538SAndroid Build Coastguard Worker 
11812*6777b538SAndroid Build Coastguard Worker   // Make sure that the ActiveEntry is gone.
11813*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
11814*6777b538SAndroid Build Coastguard Worker 
11815*6777b538SAndroid Build Coastguard Worker   // Verify that the entry is gone.
11816*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11817*6777b538SAndroid Build Coastguard Worker 
11818*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11819*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
11820*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
11821*6777b538SAndroid Build Coastguard Worker }
11822*6777b538SAndroid Build Coastguard Worker 
11823*6777b538SAndroid Build Coastguard Worker // Tests that we stop caching when told, even if DoneReading is called
11824*6777b538SAndroid Build Coastguard Worker // after StopCaching.
TEST_F(HttpCacheTest,StopCachingThenDoneReadingDeletesEntry)11825*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, StopCachingThenDoneReadingDeletesEntry) {
11826*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11827*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
11828*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
11829*6777b538SAndroid Build Coastguard Worker 
11830*6777b538SAndroid Build Coastguard Worker   {
11831*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
11832*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11833*6777b538SAndroid Build Coastguard Worker 
11834*6777b538SAndroid Build Coastguard Worker     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11835*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.GetResult(rv), IsOk());
11836*6777b538SAndroid Build Coastguard Worker 
11837*6777b538SAndroid Build Coastguard Worker     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11838*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 10, callback.callback());
11839*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(10, callback.GetResult(rv));
11840*6777b538SAndroid Build Coastguard Worker 
11841*6777b538SAndroid Build Coastguard Worker     trans->StopCaching();
11842*6777b538SAndroid Build Coastguard Worker 
11843*6777b538SAndroid Build Coastguard Worker     // We should be able to keep reading.
11844*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 256, callback.callback());
11845*6777b538SAndroid Build Coastguard Worker     EXPECT_GT(callback.GetResult(rv), 0);
11846*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 256, callback.callback());
11847*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, callback.GetResult(rv));
11848*6777b538SAndroid Build Coastguard Worker 
11849*6777b538SAndroid Build Coastguard Worker     // We should be able to call DoneReading.
11850*6777b538SAndroid Build Coastguard Worker     trans->DoneReading();
11851*6777b538SAndroid Build Coastguard Worker   }
11852*6777b538SAndroid Build Coastguard Worker 
11853*6777b538SAndroid Build Coastguard Worker   // Make sure that the ActiveEntry is gone.
11854*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
11855*6777b538SAndroid Build Coastguard Worker 
11856*6777b538SAndroid Build Coastguard Worker   // Verify that the entry is gone.
11857*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11858*6777b538SAndroid Build Coastguard Worker 
11859*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11860*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
11861*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
11862*6777b538SAndroid Build Coastguard Worker }
11863*6777b538SAndroid Build Coastguard Worker 
11864*6777b538SAndroid Build Coastguard Worker // Tests that we stop caching when told, when using auth.
TEST_F(HttpCacheTest,StopCachingWithAuthDeletesEntry)11865*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, StopCachingWithAuthDeletesEntry) {
11866*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11867*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
11868*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
11869*6777b538SAndroid Build Coastguard Worker   mock_transaction.status = "HTTP/1.1 401 Unauthorized";
11870*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(mock_transaction);
11871*6777b538SAndroid Build Coastguard Worker 
11872*6777b538SAndroid Build Coastguard Worker   {
11873*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
11874*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11875*6777b538SAndroid Build Coastguard Worker 
11876*6777b538SAndroid Build Coastguard Worker     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11877*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.GetResult(rv), IsOk());
11878*6777b538SAndroid Build Coastguard Worker 
11879*6777b538SAndroid Build Coastguard Worker     trans->StopCaching();
11880*6777b538SAndroid Build Coastguard Worker   }
11881*6777b538SAndroid Build Coastguard Worker 
11882*6777b538SAndroid Build Coastguard Worker   // Make sure that the ActiveEntry is gone.
11883*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
11884*6777b538SAndroid Build Coastguard Worker 
11885*6777b538SAndroid Build Coastguard Worker   // Verify that the entry is gone.
11886*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11887*6777b538SAndroid Build Coastguard Worker 
11888*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11889*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
11890*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
11891*6777b538SAndroid Build Coastguard Worker }
11892*6777b538SAndroid Build Coastguard Worker 
11893*6777b538SAndroid Build Coastguard Worker // Tests that when we are told to stop caching we don't throw away valid data.
TEST_F(HttpCacheTest,StopCachingSavesEntry)11894*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, StopCachingSavesEntry) {
11895*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11896*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
11897*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
11898*6777b538SAndroid Build Coastguard Worker 
11899*6777b538SAndroid Build Coastguard Worker   {
11900*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
11901*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11902*6777b538SAndroid Build Coastguard Worker 
11903*6777b538SAndroid Build Coastguard Worker     // Force a response that can be resumed.
11904*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
11905*6777b538SAndroid Build Coastguard Worker     mock_transaction.response_headers =
11906*6777b538SAndroid Build Coastguard Worker         "Cache-Control: max-age=10000\n"
11907*6777b538SAndroid Build Coastguard Worker         "Content-Length: 42\n"
11908*6777b538SAndroid Build Coastguard Worker         "Etag: \"foo\"\n";
11909*6777b538SAndroid Build Coastguard Worker 
11910*6777b538SAndroid Build Coastguard Worker     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11911*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.GetResult(rv), IsOk());
11912*6777b538SAndroid Build Coastguard Worker 
11913*6777b538SAndroid Build Coastguard Worker     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11914*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 10, callback.callback());
11915*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(callback.GetResult(rv), 10);
11916*6777b538SAndroid Build Coastguard Worker 
11917*6777b538SAndroid Build Coastguard Worker     trans->StopCaching();
11918*6777b538SAndroid Build Coastguard Worker 
11919*6777b538SAndroid Build Coastguard Worker     // We should be able to keep reading.
11920*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 256, callback.callback());
11921*6777b538SAndroid Build Coastguard Worker     EXPECT_GT(callback.GetResult(rv), 0);
11922*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 256, callback.callback());
11923*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(callback.GetResult(rv), 0);
11924*6777b538SAndroid Build Coastguard Worker   }
11925*6777b538SAndroid Build Coastguard Worker 
11926*6777b538SAndroid Build Coastguard Worker   // Verify that the entry is marked as incomplete.
11927*6777b538SAndroid Build Coastguard Worker   // VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
11928*6777b538SAndroid Build Coastguard Worker   // Verify that the entry is doomed.
11929*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->IsDiskEntryDoomed(request.CacheKey());
11930*6777b538SAndroid Build Coastguard Worker }
11931*6777b538SAndroid Build Coastguard Worker 
11932*6777b538SAndroid Build Coastguard Worker // Tests that we handle truncated enries when StopCaching is called.
TEST_F(HttpCacheTest,StopCachingTruncatedEntry)11933*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, StopCachingTruncatedEntry) {
11934*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
11935*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
11936*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kRangeGET_TransactionOK);
11937*6777b538SAndroid Build Coastguard Worker   request.extra_headers.Clear();
11938*6777b538SAndroid Build Coastguard Worker   request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
11939*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
11940*6777b538SAndroid Build Coastguard Worker 
11941*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(
11942*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
11943*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
11944*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
11945*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
11946*6777b538SAndroid Build Coastguard Worker       "Content-Length: 80\n");
11947*6777b538SAndroid Build Coastguard Worker   CreateTruncatedEntry(raw_headers, &cache);
11948*6777b538SAndroid Build Coastguard Worker 
11949*6777b538SAndroid Build Coastguard Worker   {
11950*6777b538SAndroid Build Coastguard Worker     // Now make a regular request.
11951*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<HttpTransaction> trans;
11952*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11953*6777b538SAndroid Build Coastguard Worker 
11954*6777b538SAndroid Build Coastguard Worker     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11955*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(callback.GetResult(rv), IsOk());
11956*6777b538SAndroid Build Coastguard Worker 
11957*6777b538SAndroid Build Coastguard Worker     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11958*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 10, callback.callback());
11959*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(callback.GetResult(rv), 10);
11960*6777b538SAndroid Build Coastguard Worker 
11961*6777b538SAndroid Build Coastguard Worker     // This is actually going to do nothing.
11962*6777b538SAndroid Build Coastguard Worker     trans->StopCaching();
11963*6777b538SAndroid Build Coastguard Worker 
11964*6777b538SAndroid Build Coastguard Worker     // We should be able to keep reading.
11965*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 256, callback.callback());
11966*6777b538SAndroid Build Coastguard Worker     EXPECT_GT(callback.GetResult(rv), 0);
11967*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 256, callback.callback());
11968*6777b538SAndroid Build Coastguard Worker     EXPECT_GT(callback.GetResult(rv), 0);
11969*6777b538SAndroid Build Coastguard Worker     rv = trans->Read(buf.get(), 256, callback.callback());
11970*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(callback.GetResult(rv), 0);
11971*6777b538SAndroid Build Coastguard Worker   }
11972*6777b538SAndroid Build Coastguard Worker 
11973*6777b538SAndroid Build Coastguard Worker   // Verify that the disk entry was updated.
11974*6777b538SAndroid Build Coastguard Worker   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 80);
11975*6777b538SAndroid Build Coastguard Worker }
11976*6777b538SAndroid Build Coastguard Worker 
11977*6777b538SAndroid Build Coastguard Worker namespace {
11978*6777b538SAndroid Build Coastguard Worker 
11979*6777b538SAndroid Build Coastguard Worker enum class TransactionPhase {
11980*6777b538SAndroid Build Coastguard Worker   BEFORE_FIRST_READ,
11981*6777b538SAndroid Build Coastguard Worker   AFTER_FIRST_READ,
11982*6777b538SAndroid Build Coastguard Worker   AFTER_NETWORK_READ
11983*6777b538SAndroid Build Coastguard Worker };
11984*6777b538SAndroid Build Coastguard Worker 
11985*6777b538SAndroid Build Coastguard Worker using CacheInitializer = void (*)(MockHttpCache*);
11986*6777b538SAndroid Build Coastguard Worker using HugeCacheTestConfiguration =
11987*6777b538SAndroid Build Coastguard Worker     std::pair<TransactionPhase, CacheInitializer>;
11988*6777b538SAndroid Build Coastguard Worker 
11989*6777b538SAndroid Build Coastguard Worker class HttpCacheHugeResourceTest
11990*6777b538SAndroid Build Coastguard Worker     : public ::testing::TestWithParam<HugeCacheTestConfiguration>,
11991*6777b538SAndroid Build Coastguard Worker       public WithTaskEnvironment {
11992*6777b538SAndroid Build Coastguard Worker  public:
11993*6777b538SAndroid Build Coastguard Worker   static std::list<HugeCacheTestConfiguration> GetTestModes();
11994*6777b538SAndroid Build Coastguard Worker   static std::list<HugeCacheTestConfiguration> kTestModes;
11995*6777b538SAndroid Build Coastguard Worker 
11996*6777b538SAndroid Build Coastguard Worker   // CacheInitializer callbacks. These are used to initialize the cache
11997*6777b538SAndroid Build Coastguard Worker   // depending on the test run configuration.
11998*6777b538SAndroid Build Coastguard Worker 
11999*6777b538SAndroid Build Coastguard Worker   // Initializes a cache containing a truncated entry containing the first 20
12000*6777b538SAndroid Build Coastguard Worker   // bytes of the reponse body.
12001*6777b538SAndroid Build Coastguard Worker   static void SetupTruncatedCacheEntry(MockHttpCache* cache);
12002*6777b538SAndroid Build Coastguard Worker 
12003*6777b538SAndroid Build Coastguard Worker   // Initializes a cache containing a sparse entry. The first 10 bytes are
12004*6777b538SAndroid Build Coastguard Worker   // present in the cache.
12005*6777b538SAndroid Build Coastguard Worker   static void SetupPrefixSparseCacheEntry(MockHttpCache* cache);
12006*6777b538SAndroid Build Coastguard Worker 
12007*6777b538SAndroid Build Coastguard Worker   // Initializes a cache containing a sparse entry. The 10 bytes at offset
12008*6777b538SAndroid Build Coastguard Worker   // 99990 are present in the cache.
12009*6777b538SAndroid Build Coastguard Worker   static void SetupInfixSparseCacheEntry(MockHttpCache* cache);
12010*6777b538SAndroid Build Coastguard Worker 
12011*6777b538SAndroid Build Coastguard Worker  protected:
12012*6777b538SAndroid Build Coastguard Worker   static void LargeResourceTransactionHandler(
12013*6777b538SAndroid Build Coastguard Worker       const net::HttpRequestInfo* request,
12014*6777b538SAndroid Build Coastguard Worker       std::string* response_status,
12015*6777b538SAndroid Build Coastguard Worker       std::string* response_headers,
12016*6777b538SAndroid Build Coastguard Worker       std::string* response_data);
12017*6777b538SAndroid Build Coastguard Worker   static int LargeBufferReader(int64_t content_length,
12018*6777b538SAndroid Build Coastguard Worker                                int64_t offset,
12019*6777b538SAndroid Build Coastguard Worker                                net::IOBuffer* buf,
12020*6777b538SAndroid Build Coastguard Worker                                int buf_len);
12021*6777b538SAndroid Build Coastguard Worker 
12022*6777b538SAndroid Build Coastguard Worker   static void SetFlagOnBeforeNetworkStart(bool* started, bool* /* defer */);
12023*6777b538SAndroid Build Coastguard Worker 
12024*6777b538SAndroid Build Coastguard Worker   // Size of resource to be tested.
12025*6777b538SAndroid Build Coastguard Worker   static const int64_t kTotalSize = 5000LL * 1000 * 1000;
12026*6777b538SAndroid Build Coastguard Worker };
12027*6777b538SAndroid Build Coastguard Worker 
12028*6777b538SAndroid Build Coastguard Worker const int64_t HttpCacheHugeResourceTest::kTotalSize;
12029*6777b538SAndroid Build Coastguard Worker 
12030*6777b538SAndroid Build Coastguard Worker // static
LargeResourceTransactionHandler(const net::HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)12031*6777b538SAndroid Build Coastguard Worker void HttpCacheHugeResourceTest::LargeResourceTransactionHandler(
12032*6777b538SAndroid Build Coastguard Worker     const net::HttpRequestInfo* request,
12033*6777b538SAndroid Build Coastguard Worker     std::string* response_status,
12034*6777b538SAndroid Build Coastguard Worker     std::string* response_headers,
12035*6777b538SAndroid Build Coastguard Worker     std::string* response_data) {
12036*6777b538SAndroid Build Coastguard Worker   std::string if_range;
12037*6777b538SAndroid Build Coastguard Worker   if (!request->extra_headers.GetHeader(net::HttpRequestHeaders::kIfRange,
12038*6777b538SAndroid Build Coastguard Worker                                         &if_range)) {
12039*6777b538SAndroid Build Coastguard Worker     // If there were no range headers in the request, we are going to just
12040*6777b538SAndroid Build Coastguard Worker     // return the entire response body.
12041*6777b538SAndroid Build Coastguard Worker     *response_status = "HTTP/1.1 200 Success";
12042*6777b538SAndroid Build Coastguard Worker     *response_headers = base::StringPrintf("Content-Length: %" PRId64
12043*6777b538SAndroid Build Coastguard Worker                                            "\n"
12044*6777b538SAndroid Build Coastguard Worker                                            "ETag: \"foo\"\n"
12045*6777b538SAndroid Build Coastguard Worker                                            "Accept-Ranges: bytes\n",
12046*6777b538SAndroid Build Coastguard Worker                                            kTotalSize);
12047*6777b538SAndroid Build Coastguard Worker     return;
12048*6777b538SAndroid Build Coastguard Worker   }
12049*6777b538SAndroid Build Coastguard Worker 
12050*6777b538SAndroid Build Coastguard Worker   // From this point on, we should be processing a valid byte-range request.
12051*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("\"foo\"", if_range);
12052*6777b538SAndroid Build Coastguard Worker 
12053*6777b538SAndroid Build Coastguard Worker   std::string range_header;
12054*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(request->extra_headers.GetHeader(net::HttpRequestHeaders::kRange,
12055*6777b538SAndroid Build Coastguard Worker                                                &range_header));
12056*6777b538SAndroid Build Coastguard Worker   std::vector<net::HttpByteRange> ranges;
12057*6777b538SAndroid Build Coastguard Worker 
12058*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(net::HttpUtil::ParseRangeHeader(range_header, &ranges));
12059*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, ranges.size());
12060*6777b538SAndroid Build Coastguard Worker 
12061*6777b538SAndroid Build Coastguard Worker   net::HttpByteRange range = ranges[0];
12062*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(range.HasFirstBytePosition());
12063*6777b538SAndroid Build Coastguard Worker   int64_t last_byte_position =
12064*6777b538SAndroid Build Coastguard Worker       range.HasLastBytePosition() ? range.last_byte_position() : kTotalSize - 1;
12065*6777b538SAndroid Build Coastguard Worker 
12066*6777b538SAndroid Build Coastguard Worker   *response_status = "HTTP/1.1 206 Partial";
12067*6777b538SAndroid Build Coastguard Worker   *response_headers = base::StringPrintf(
12068*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes %" PRId64 "-%" PRId64 "/%" PRId64
12069*6777b538SAndroid Build Coastguard Worker       "\n"
12070*6777b538SAndroid Build Coastguard Worker       "Content-Length: %" PRId64 "\n",
12071*6777b538SAndroid Build Coastguard Worker       range.first_byte_position(), last_byte_position, kTotalSize,
12072*6777b538SAndroid Build Coastguard Worker       last_byte_position - range.first_byte_position() + 1);
12073*6777b538SAndroid Build Coastguard Worker }
12074*6777b538SAndroid Build Coastguard Worker 
12075*6777b538SAndroid Build Coastguard Worker // static
LargeBufferReader(int64_t content_length,int64_t offset,net::IOBuffer * buf,int buf_len)12076*6777b538SAndroid Build Coastguard Worker int HttpCacheHugeResourceTest::LargeBufferReader(int64_t content_length,
12077*6777b538SAndroid Build Coastguard Worker                                                  int64_t offset,
12078*6777b538SAndroid Build Coastguard Worker                                                  net::IOBuffer* buf,
12079*6777b538SAndroid Build Coastguard Worker                                                  int buf_len) {
12080*6777b538SAndroid Build Coastguard Worker   // This test involves reading multiple gigabytes of data. To make it run in a
12081*6777b538SAndroid Build Coastguard Worker   // reasonable amount of time, we are going to skip filling the buffer with
12082*6777b538SAndroid Build Coastguard Worker   // data. Instead the test relies on verifying that the count of bytes expected
12083*6777b538SAndroid Build Coastguard Worker   // at the end is correct.
12084*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(0, content_length);
12085*6777b538SAndroid Build Coastguard Worker   EXPECT_LE(offset, content_length);
12086*6777b538SAndroid Build Coastguard Worker   int num = std::min(static_cast<int64_t>(buf_len), content_length - offset);
12087*6777b538SAndroid Build Coastguard Worker   return num;
12088*6777b538SAndroid Build Coastguard Worker }
12089*6777b538SAndroid Build Coastguard Worker 
12090*6777b538SAndroid Build Coastguard Worker // static
SetFlagOnBeforeNetworkStart(bool * started,bool *)12091*6777b538SAndroid Build Coastguard Worker void HttpCacheHugeResourceTest::SetFlagOnBeforeNetworkStart(bool* started,
12092*6777b538SAndroid Build Coastguard Worker                                                             bool* /* defer */) {
12093*6777b538SAndroid Build Coastguard Worker   *started = true;
12094*6777b538SAndroid Build Coastguard Worker }
12095*6777b538SAndroid Build Coastguard Worker 
12096*6777b538SAndroid Build Coastguard Worker // static
SetupTruncatedCacheEntry(MockHttpCache * cache)12097*6777b538SAndroid Build Coastguard Worker void HttpCacheHugeResourceTest::SetupTruncatedCacheEntry(MockHttpCache* cache) {
12098*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
12099*6777b538SAndroid Build Coastguard Worker   std::string cached_headers = base::StringPrintf(
12100*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
12101*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12102*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
12103*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
12104*6777b538SAndroid Build Coastguard Worker       "Content-Length: %" PRId64 "\n",
12105*6777b538SAndroid Build Coastguard Worker       kTotalSize);
12106*6777b538SAndroid Build Coastguard Worker   CreateTruncatedEntry(cached_headers, cache);
12107*6777b538SAndroid Build Coastguard Worker }
12108*6777b538SAndroid Build Coastguard Worker 
12109*6777b538SAndroid Build Coastguard Worker // static
SetupPrefixSparseCacheEntry(MockHttpCache * cache)12110*6777b538SAndroid Build Coastguard Worker void HttpCacheHugeResourceTest::SetupPrefixSparseCacheEntry(
12111*6777b538SAndroid Build Coastguard Worker     MockHttpCache* cache) {
12112*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
12113*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
12114*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
12115*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
12116*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12117*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
12118*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
12119*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes 0-9/5000000000\n"
12120*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n";
12121*6777b538SAndroid Build Coastguard Worker   std::string headers;
12122*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers);
12123*6777b538SAndroid Build Coastguard Worker }
12124*6777b538SAndroid Build Coastguard Worker 
12125*6777b538SAndroid Build Coastguard Worker // static
SetupInfixSparseCacheEntry(MockHttpCache * cache)12126*6777b538SAndroid Build Coastguard Worker void HttpCacheHugeResourceTest::SetupInfixSparseCacheEntry(
12127*6777b538SAndroid Build Coastguard Worker     MockHttpCache* cache) {
12128*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
12129*6777b538SAndroid Build Coastguard Worker   transaction.handler = MockTransactionHandler();
12130*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 99990-99999\r\n" EXTRA_HEADER;
12131*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
12132*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12133*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
12134*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
12135*6777b538SAndroid Build Coastguard Worker       "Content-Range: bytes 99990-99999/5000000000\n"
12136*6777b538SAndroid Build Coastguard Worker       "Content-Length: 10\n";
12137*6777b538SAndroid Build Coastguard Worker   std::string headers;
12138*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers);
12139*6777b538SAndroid Build Coastguard Worker }
12140*6777b538SAndroid Build Coastguard Worker 
12141*6777b538SAndroid Build Coastguard Worker // static
12142*6777b538SAndroid Build Coastguard Worker std::list<HugeCacheTestConfiguration>
GetTestModes()12143*6777b538SAndroid Build Coastguard Worker HttpCacheHugeResourceTest::GetTestModes() {
12144*6777b538SAndroid Build Coastguard Worker   std::list<HugeCacheTestConfiguration> test_modes;
12145*6777b538SAndroid Build Coastguard Worker   const TransactionPhase kTransactionPhases[] = {
12146*6777b538SAndroid Build Coastguard Worker       TransactionPhase::BEFORE_FIRST_READ, TransactionPhase::AFTER_FIRST_READ,
12147*6777b538SAndroid Build Coastguard Worker       TransactionPhase::AFTER_NETWORK_READ};
12148*6777b538SAndroid Build Coastguard Worker   const CacheInitializer kInitializers[] = {&SetupTruncatedCacheEntry,
12149*6777b538SAndroid Build Coastguard Worker                                             &SetupPrefixSparseCacheEntry,
12150*6777b538SAndroid Build Coastguard Worker                                             &SetupInfixSparseCacheEntry};
12151*6777b538SAndroid Build Coastguard Worker 
12152*6777b538SAndroid Build Coastguard Worker   for (const auto phase : kTransactionPhases) {
12153*6777b538SAndroid Build Coastguard Worker     for (const auto initializer : kInitializers) {
12154*6777b538SAndroid Build Coastguard Worker       test_modes.emplace_back(phase, initializer);
12155*6777b538SAndroid Build Coastguard Worker     }
12156*6777b538SAndroid Build Coastguard Worker   }
12157*6777b538SAndroid Build Coastguard Worker 
12158*6777b538SAndroid Build Coastguard Worker   return test_modes;
12159*6777b538SAndroid Build Coastguard Worker }
12160*6777b538SAndroid Build Coastguard Worker 
12161*6777b538SAndroid Build Coastguard Worker // static
12162*6777b538SAndroid Build Coastguard Worker std::list<HugeCacheTestConfiguration> HttpCacheHugeResourceTest::kTestModes =
12163*6777b538SAndroid Build Coastguard Worker     HttpCacheHugeResourceTest::GetTestModes();
12164*6777b538SAndroid Build Coastguard Worker 
12165*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
12166*6777b538SAndroid Build Coastguard Worker     _,
12167*6777b538SAndroid Build Coastguard Worker     HttpCacheHugeResourceTest,
12168*6777b538SAndroid Build Coastguard Worker     ::testing::ValuesIn(HttpCacheHugeResourceTest::kTestModes));
12169*6777b538SAndroid Build Coastguard Worker 
12170*6777b538SAndroid Build Coastguard Worker }  // namespace
12171*6777b538SAndroid Build Coastguard Worker 
12172*6777b538SAndroid Build Coastguard Worker // Test what happens when StopCaching() is called while reading a huge resource
12173*6777b538SAndroid Build Coastguard Worker // fetched via GET. Various combinations of cache state and when StopCaching()
12174*6777b538SAndroid Build Coastguard Worker // is called is controlled by the parameter passed into the test via the
12175*6777b538SAndroid Build Coastguard Worker // INSTANTIATE_TEST_SUITE_P invocation above.
TEST_P(HttpCacheHugeResourceTest,StopCachingFollowedByReadForHugeTruncatedResource)12176*6777b538SAndroid Build Coastguard Worker TEST_P(HttpCacheHugeResourceTest,
12177*6777b538SAndroid Build Coastguard Worker        StopCachingFollowedByReadForHugeTruncatedResource) {
12178*6777b538SAndroid Build Coastguard Worker   // This test is going to be repeated for all combinations of TransactionPhase
12179*6777b538SAndroid Build Coastguard Worker   // and CacheInitializers returned by GetTestModes().
12180*6777b538SAndroid Build Coastguard Worker   const TransactionPhase stop_caching_phase = GetParam().first;
12181*6777b538SAndroid Build Coastguard Worker   const CacheInitializer cache_initializer = GetParam().second;
12182*6777b538SAndroid Build Coastguard Worker 
12183*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12184*6777b538SAndroid Build Coastguard Worker   (*cache_initializer)(&cache);
12185*6777b538SAndroid Build Coastguard Worker 
12186*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
12187*6777b538SAndroid Build Coastguard Worker   transaction.url = kRangeGET_TransactionOK.url;
12188*6777b538SAndroid Build Coastguard Worker   transaction.handler = base::BindRepeating(&LargeResourceTransactionHandler);
12189*6777b538SAndroid Build Coastguard Worker   transaction.read_handler = base::BindRepeating(&LargeBufferReader);
12190*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(transaction);
12191*6777b538SAndroid Build Coastguard Worker 
12192*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction);
12193*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback callback;
12194*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<net::HttpTransaction> http_transaction;
12195*6777b538SAndroid Build Coastguard Worker   int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY,
12196*6777b538SAndroid Build Coastguard Worker                                                  &http_transaction);
12197*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, rv);
12198*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(http_transaction.get());
12199*6777b538SAndroid Build Coastguard Worker 
12200*6777b538SAndroid Build Coastguard Worker   bool network_transaction_started = false;
12201*6777b538SAndroid Build Coastguard Worker   if (stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) {
12202*6777b538SAndroid Build Coastguard Worker     http_transaction->SetBeforeNetworkStartCallback(base::BindOnce(
12203*6777b538SAndroid Build Coastguard Worker         &SetFlagOnBeforeNetworkStart, &network_transaction_started));
12204*6777b538SAndroid Build Coastguard Worker   }
12205*6777b538SAndroid Build Coastguard Worker 
12206*6777b538SAndroid Build Coastguard Worker   rv = http_transaction->Start(&request, callback.callback(),
12207*6777b538SAndroid Build Coastguard Worker                                NetLogWithSource());
12208*6777b538SAndroid Build Coastguard Worker   rv = callback.GetResult(rv);
12209*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, rv);
12210*6777b538SAndroid Build Coastguard Worker 
12211*6777b538SAndroid Build Coastguard Worker   if (stop_caching_phase == TransactionPhase::BEFORE_FIRST_READ) {
12212*6777b538SAndroid Build Coastguard Worker     http_transaction->StopCaching();
12213*6777b538SAndroid Build Coastguard Worker   }
12214*6777b538SAndroid Build Coastguard Worker 
12215*6777b538SAndroid Build Coastguard Worker   int64_t total_bytes_received = 0;
12216*6777b538SAndroid Build Coastguard Worker 
12217*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTotalSize,
12218*6777b538SAndroid Build Coastguard Worker             http_transaction->GetResponseInfo()->headers->GetContentLength());
12219*6777b538SAndroid Build Coastguard Worker   do {
12220*6777b538SAndroid Build Coastguard Worker     // This test simulates reading gigabytes of data. Buffer size is set to 10MB
12221*6777b538SAndroid Build Coastguard Worker     // to reduce the number of reads and speed up the test.
12222*6777b538SAndroid Build Coastguard Worker     const int kBufferSize = 1024 * 1024 * 10;
12223*6777b538SAndroid Build Coastguard Worker     scoped_refptr<net::IOBuffer> buf =
12224*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
12225*6777b538SAndroid Build Coastguard Worker     rv = http_transaction->Read(buf.get(), kBufferSize, callback.callback());
12226*6777b538SAndroid Build Coastguard Worker     rv = callback.GetResult(rv);
12227*6777b538SAndroid Build Coastguard Worker 
12228*6777b538SAndroid Build Coastguard Worker     if (stop_caching_phase == TransactionPhase::AFTER_FIRST_READ &&
12229*6777b538SAndroid Build Coastguard Worker         total_bytes_received == 0) {
12230*6777b538SAndroid Build Coastguard Worker       http_transaction->StopCaching();
12231*6777b538SAndroid Build Coastguard Worker     }
12232*6777b538SAndroid Build Coastguard Worker 
12233*6777b538SAndroid Build Coastguard Worker     if (rv > 0) {
12234*6777b538SAndroid Build Coastguard Worker       total_bytes_received += rv;
12235*6777b538SAndroid Build Coastguard Worker     }
12236*6777b538SAndroid Build Coastguard Worker 
12237*6777b538SAndroid Build Coastguard Worker     if (network_transaction_started &&
12238*6777b538SAndroid Build Coastguard Worker         stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) {
12239*6777b538SAndroid Build Coastguard Worker       http_transaction->StopCaching();
12240*6777b538SAndroid Build Coastguard Worker       network_transaction_started = false;
12241*6777b538SAndroid Build Coastguard Worker     }
12242*6777b538SAndroid Build Coastguard Worker   } while (rv > 0);
12243*6777b538SAndroid Build Coastguard Worker 
12244*6777b538SAndroid Build Coastguard Worker   // The only verification we are going to do is that the received resource has
12245*6777b538SAndroid Build Coastguard Worker   // the correct size. This is sufficient to verify that the state machine
12246*6777b538SAndroid Build Coastguard Worker   // didn't terminate abruptly due to the StopCaching() call.
12247*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTotalSize, total_bytes_received);
12248*6777b538SAndroid Build Coastguard Worker }
12249*6777b538SAndroid Build Coastguard Worker 
12250*6777b538SAndroid Build Coastguard Worker // Tests that we detect truncated resources from the net when there is
12251*6777b538SAndroid Build Coastguard Worker // a Content-Length header.
TEST_F(HttpCacheTest,TruncatedByContentLength)12252*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, TruncatedByContentLength) {
12253*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12254*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
12255*6777b538SAndroid Build Coastguard Worker 
12256*6777b538SAndroid Build Coastguard Worker   {
12257*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kSimpleGET_Transaction);
12258*6777b538SAndroid Build Coastguard Worker     transaction.response_headers =
12259*6777b538SAndroid Build Coastguard Worker         "Cache-Control: max-age=10000\n"
12260*6777b538SAndroid Build Coastguard Worker         "Content-Length: 100\n";
12261*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
12262*6777b538SAndroid Build Coastguard Worker   }
12263*6777b538SAndroid Build Coastguard Worker 
12264*6777b538SAndroid Build Coastguard Worker   // Read from the cache.
12265*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
12266*6777b538SAndroid Build Coastguard Worker 
12267*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12268*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
12269*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.disk_cache()->create_count());
12270*6777b538SAndroid Build Coastguard Worker }
12271*6777b538SAndroid Build Coastguard Worker 
12272*6777b538SAndroid Build Coastguard Worker // Tests that we actually flag entries as truncated when we detect an error
12273*6777b538SAndroid Build Coastguard Worker // from the net.
TEST_F(HttpCacheTest,TruncatedByContentLength2)12274*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, TruncatedByContentLength2) {
12275*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12276*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
12277*6777b538SAndroid Build Coastguard Worker 
12278*6777b538SAndroid Build Coastguard Worker   {
12279*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction transaction(kSimpleGET_Transaction);
12280*6777b538SAndroid Build Coastguard Worker     transaction.response_headers =
12281*6777b538SAndroid Build Coastguard Worker         "Cache-Control: max-age=10000\n"
12282*6777b538SAndroid Build Coastguard Worker         "Content-Length: 100\n"
12283*6777b538SAndroid Build Coastguard Worker         "Etag: \"foo\"\n";
12284*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
12285*6777b538SAndroid Build Coastguard Worker   }
12286*6777b538SAndroid Build Coastguard Worker 
12287*6777b538SAndroid Build Coastguard Worker   // Verify that the entry is marked as incomplete.
12288*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kSimpleGET_Transaction);
12289*6777b538SAndroid Build Coastguard Worker   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 0);
12290*6777b538SAndroid Build Coastguard Worker }
12291*6777b538SAndroid Build Coastguard Worker 
12292*6777b538SAndroid Build Coastguard Worker // Make sure that calling SetPriority on a cache transaction passes on
12293*6777b538SAndroid Build Coastguard Worker // its priority updates to its underlying network transaction.
TEST_F(HttpCacheTest,SetPriority)12294*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SetPriority) {
12295*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12296*6777b538SAndroid Build Coastguard Worker 
12297*6777b538SAndroid Build Coastguard Worker   HttpRequestInfo info;
12298*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
12299*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.http_cache()->CreateTransaction(IDLE, &trans), IsOk());
12300*6777b538SAndroid Build Coastguard Worker 
12301*6777b538SAndroid Build Coastguard Worker   // Shouldn't crash, but doesn't do anything either.
12302*6777b538SAndroid Build Coastguard Worker   trans->SetPriority(LOW);
12303*6777b538SAndroid Build Coastguard Worker 
12304*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.network_layer()->last_transaction());
12305*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(DEFAULT_PRIORITY,
12306*6777b538SAndroid Build Coastguard Worker             cache.network_layer()->last_create_transaction_priority());
12307*6777b538SAndroid Build Coastguard Worker 
12308*6777b538SAndroid Build Coastguard Worker   info.url = GURL(kSimpleGET_Transaction.url);
12309*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
12310*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING,
12311*6777b538SAndroid Build Coastguard Worker             trans->Start(&info, callback.callback(), NetLogWithSource()));
12312*6777b538SAndroid Build Coastguard Worker 
12313*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.network_layer()->last_transaction());
12314*6777b538SAndroid Build Coastguard Worker   if (cache.network_layer()->last_transaction()) {
12315*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
12316*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOW, cache.network_layer()->last_transaction()->priority());
12317*6777b538SAndroid Build Coastguard Worker   }
12318*6777b538SAndroid Build Coastguard Worker 
12319*6777b538SAndroid Build Coastguard Worker   trans->SetPriority(HIGHEST);
12320*6777b538SAndroid Build Coastguard Worker 
12321*6777b538SAndroid Build Coastguard Worker   if (cache.network_layer()->last_transaction()) {
12322*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
12323*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(HIGHEST, cache.network_layer()->last_transaction()->priority());
12324*6777b538SAndroid Build Coastguard Worker   }
12325*6777b538SAndroid Build Coastguard Worker 
12326*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
12327*6777b538SAndroid Build Coastguard Worker }
12328*6777b538SAndroid Build Coastguard Worker 
12329*6777b538SAndroid Build Coastguard Worker // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
12330*6777b538SAndroid Build Coastguard Worker // transaction passes on its argument to the underlying network transaction.
TEST_F(HttpCacheTest,SetWebSocketHandshakeStreamCreateHelper)12331*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SetWebSocketHandshakeStreamCreateHelper) {
12332*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12333*6777b538SAndroid Build Coastguard Worker   HttpRequestInfo info;
12334*6777b538SAndroid Build Coastguard Worker 
12335*6777b538SAndroid Build Coastguard Worker   FakeWebSocketHandshakeStreamCreateHelper create_helper;
12336*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
12337*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.http_cache()->CreateTransaction(IDLE, &trans), IsOk());
12338*6777b538SAndroid Build Coastguard Worker 
12339*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.network_layer()->last_transaction());
12340*6777b538SAndroid Build Coastguard Worker 
12341*6777b538SAndroid Build Coastguard Worker   info.url = GURL(kSimpleGET_Transaction.url);
12342*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
12343*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING,
12344*6777b538SAndroid Build Coastguard Worker             trans->Start(&info, callback.callback(), NetLogWithSource()));
12345*6777b538SAndroid Build Coastguard Worker 
12346*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache.network_layer()->last_transaction());
12347*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.network_layer()
12348*6777b538SAndroid Build Coastguard Worker                    ->last_transaction()
12349*6777b538SAndroid Build Coastguard Worker                    ->websocket_handshake_stream_create_helper());
12350*6777b538SAndroid Build Coastguard Worker   trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
12351*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(&create_helper, cache.network_layer()
12352*6777b538SAndroid Build Coastguard Worker                                 ->last_transaction()
12353*6777b538SAndroid Build Coastguard Worker                                 ->websocket_handshake_stream_create_helper());
12354*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
12355*6777b538SAndroid Build Coastguard Worker }
12356*6777b538SAndroid Build Coastguard Worker 
12357*6777b538SAndroid Build Coastguard Worker // Make sure that a cache transaction passes on its priority to
12358*6777b538SAndroid Build Coastguard Worker // newly-created network transactions.
TEST_F(HttpCacheTest,SetPriorityNewTransaction)12359*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SetPriorityNewTransaction) {
12360*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12361*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
12362*6777b538SAndroid Build Coastguard Worker 
12363*6777b538SAndroid Build Coastguard Worker   std::string raw_headers(
12364*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK\n"
12365*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12366*6777b538SAndroid Build Coastguard Worker       "ETag: \"foo\"\n"
12367*6777b538SAndroid Build Coastguard Worker       "Accept-Ranges: bytes\n"
12368*6777b538SAndroid Build Coastguard Worker       "Content-Length: 80\n");
12369*6777b538SAndroid Build Coastguard Worker   CreateTruncatedEntry(raw_headers, &cache);
12370*6777b538SAndroid Build Coastguard Worker 
12371*6777b538SAndroid Build Coastguard Worker   // Now make a regular request.
12372*6777b538SAndroid Build Coastguard Worker   std::string headers;
12373*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kRangeGET_TransactionOK);
12374*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = EXTRA_HEADER;
12375*6777b538SAndroid Build Coastguard Worker   transaction.data = kFullRangeData;
12376*6777b538SAndroid Build Coastguard Worker 
12377*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
12378*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(cache.http_cache()->CreateTransaction(MEDIUM, &trans), IsOk());
12379*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(DEFAULT_PRIORITY,
12380*6777b538SAndroid Build Coastguard Worker             cache.network_layer()->last_create_transaction_priority());
12381*6777b538SAndroid Build Coastguard Worker 
12382*6777b538SAndroid Build Coastguard Worker   MockHttpRequest info(transaction);
12383*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
12384*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_IO_PENDING,
12385*6777b538SAndroid Build Coastguard Worker             trans->Start(&info, callback.callback(), NetLogWithSource()));
12386*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
12387*6777b538SAndroid Build Coastguard Worker 
12388*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MEDIUM, cache.network_layer()->last_create_transaction_priority());
12389*6777b538SAndroid Build Coastguard Worker 
12390*6777b538SAndroid Build Coastguard Worker   trans->SetPriority(HIGHEST);
12391*6777b538SAndroid Build Coastguard Worker   // Should trigger a new network transaction and pick up the new
12392*6777b538SAndroid Build Coastguard Worker   // priority.
12393*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(trans.get(), transaction);
12394*6777b538SAndroid Build Coastguard Worker 
12395*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(HIGHEST, cache.network_layer()->last_create_transaction_priority());
12396*6777b538SAndroid Build Coastguard Worker }
12397*6777b538SAndroid Build Coastguard Worker 
12398*6777b538SAndroid Build Coastguard Worker namespace {
12399*6777b538SAndroid Build Coastguard Worker 
RunTransactionAndGetNetworkBytes(MockHttpCache * cache,const MockTransaction & trans_info,int64_t * sent_bytes,int64_t * received_bytes)12400*6777b538SAndroid Build Coastguard Worker void RunTransactionAndGetNetworkBytes(MockHttpCache* cache,
12401*6777b538SAndroid Build Coastguard Worker                                       const MockTransaction& trans_info,
12402*6777b538SAndroid Build Coastguard Worker                                       int64_t* sent_bytes,
12403*6777b538SAndroid Build Coastguard Worker                                       int64_t* received_bytes) {
12404*6777b538SAndroid Build Coastguard Worker   RunTransactionTestBase(
12405*6777b538SAndroid Build Coastguard Worker       cache->http_cache(), trans_info, MockHttpRequest(trans_info), nullptr,
12406*6777b538SAndroid Build Coastguard Worker       NetLogWithSource(), nullptr, sent_bytes, received_bytes, nullptr);
12407*6777b538SAndroid Build Coastguard Worker }
12408*6777b538SAndroid Build Coastguard Worker 
12409*6777b538SAndroid Build Coastguard Worker }  // namespace
12410*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,NetworkBytesCacheMissAndThenHit)12411*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, NetworkBytesCacheMissAndThenHit) {
12412*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12413*6777b538SAndroid Build Coastguard Worker 
12414*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction(kSimpleGET_Transaction);
12415*6777b538SAndroid Build Coastguard Worker   int64_t sent, received;
12416*6777b538SAndroid Build Coastguard Worker   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12417*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12418*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12419*6777b538SAndroid Build Coastguard Worker 
12420*6777b538SAndroid Build Coastguard Worker   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12421*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, sent);
12422*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, received);
12423*6777b538SAndroid Build Coastguard Worker }
12424*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,NetworkBytesConditionalRequest304)12425*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, NetworkBytesConditionalRequest304) {
12426*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12427*6777b538SAndroid Build Coastguard Worker 
12428*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kETagGET_Transaction);
12429*6777b538SAndroid Build Coastguard Worker   int64_t sent, received;
12430*6777b538SAndroid Build Coastguard Worker   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12431*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12432*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12433*6777b538SAndroid Build Coastguard Worker 
12434*6777b538SAndroid Build Coastguard Worker   transaction.load_flags = LOAD_VALIDATE_CACHE;
12435*6777b538SAndroid Build Coastguard Worker   transaction.handler = kETagGetConditionalRequestHandler;
12436*6777b538SAndroid Build Coastguard Worker   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12437*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12438*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12439*6777b538SAndroid Build Coastguard Worker }
12440*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,NetworkBytesConditionalRequest200)12441*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, NetworkBytesConditionalRequest200) {
12442*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12443*6777b538SAndroid Build Coastguard Worker 
12444*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
12445*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: bar\r\n";
12446*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
12447*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
12448*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
12449*6777b538SAndroid Build Coastguard Worker       "Etag: \"foopy\"\n"
12450*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n"
12451*6777b538SAndroid Build Coastguard Worker       "Vary: Foo\n";
12452*6777b538SAndroid Build Coastguard Worker   int64_t sent, received;
12453*6777b538SAndroid Build Coastguard Worker   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12454*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12455*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12456*6777b538SAndroid Build Coastguard Worker 
12457*6777b538SAndroid Build Coastguard Worker   RevalidationServer server;
12458*6777b538SAndroid Build Coastguard Worker   transaction.handler = server.GetHandlerCallback();
12459*6777b538SAndroid Build Coastguard Worker 
12460*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Foo: none\r\n";
12461*6777b538SAndroid Build Coastguard Worker   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12462*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12463*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12464*6777b538SAndroid Build Coastguard Worker }
12465*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,NetworkBytesRange)12466*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, NetworkBytesRange) {
12467*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12468*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
12469*6777b538SAndroid Build Coastguard Worker 
12470*6777b538SAndroid Build Coastguard Worker   // Read bytes 40-49 from the network.
12471*6777b538SAndroid Build Coastguard Worker   int64_t sent, received;
12472*6777b538SAndroid Build Coastguard Worker   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12473*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12474*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12475*6777b538SAndroid Build Coastguard Worker 
12476*6777b538SAndroid Build Coastguard Worker   // Read bytes 40-49 from the cache.
12477*6777b538SAndroid Build Coastguard Worker   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12478*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, sent);
12479*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, received);
12480*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
12481*6777b538SAndroid Build Coastguard Worker 
12482*6777b538SAndroid Build Coastguard Worker   // Read bytes 30-39 from the network.
12483*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
12484*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 30-39 ";
12485*6777b538SAndroid Build Coastguard Worker   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12486*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12487*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12488*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
12489*6777b538SAndroid Build Coastguard Worker 
12490*6777b538SAndroid Build Coastguard Worker   // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
12491*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
12492*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
12493*6777b538SAndroid Build Coastguard Worker   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12494*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes * 2, sent);
12495*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes * 2, received);
12496*6777b538SAndroid Build Coastguard Worker }
12497*6777b538SAndroid Build Coastguard Worker 
12498*6777b538SAndroid Build Coastguard Worker class HttpCachePrefetchValidationTest : public TestWithTaskEnvironment {
12499*6777b538SAndroid Build Coastguard Worker  protected:
12500*6777b538SAndroid Build Coastguard Worker   static const int kNumSecondsPerMinute = 60;
12501*6777b538SAndroid Build Coastguard Worker   static const int kMaxAgeSecs = 100;
12502*6777b538SAndroid Build Coastguard Worker   static const int kRequireValidationSecs = kMaxAgeSecs + 1;
12503*6777b538SAndroid Build Coastguard Worker 
HttpCachePrefetchValidationTest()12504*6777b538SAndroid Build Coastguard Worker   HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction) {
12505*6777b538SAndroid Build Coastguard Worker     DCHECK_LT(kMaxAgeSecs, prefetch_reuse_mins() * kNumSecondsPerMinute);
12506*6777b538SAndroid Build Coastguard Worker 
12507*6777b538SAndroid Build Coastguard Worker     cache_.http_cache()->SetClockForTesting(&clock_);
12508*6777b538SAndroid Build Coastguard Worker     cache_.network_layer()->SetClock(&clock_);
12509*6777b538SAndroid Build Coastguard Worker 
12510*6777b538SAndroid Build Coastguard Worker     transaction_.response_headers = "Cache-Control: max-age=100\n";
12511*6777b538SAndroid Build Coastguard Worker   }
12512*6777b538SAndroid Build Coastguard Worker 
TransactionRequiredNetwork(int load_flags)12513*6777b538SAndroid Build Coastguard Worker   bool TransactionRequiredNetwork(int load_flags) {
12514*6777b538SAndroid Build Coastguard Worker     int pre_transaction_count = transaction_count();
12515*6777b538SAndroid Build Coastguard Worker     transaction_.load_flags = load_flags;
12516*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache_.http_cache(), transaction_);
12517*6777b538SAndroid Build Coastguard Worker     return pre_transaction_count != transaction_count();
12518*6777b538SAndroid Build Coastguard Worker   }
12519*6777b538SAndroid Build Coastguard Worker 
AdvanceTime(int seconds)12520*6777b538SAndroid Build Coastguard Worker   void AdvanceTime(int seconds) { clock_.Advance(base::Seconds(seconds)); }
12521*6777b538SAndroid Build Coastguard Worker 
prefetch_reuse_mins()12522*6777b538SAndroid Build Coastguard Worker   int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins; }
12523*6777b538SAndroid Build Coastguard Worker 
12524*6777b538SAndroid Build Coastguard Worker   // How many times this test has sent requests to the (fake) origin
12525*6777b538SAndroid Build Coastguard Worker   // server. Every test case needs to make at least one request to initialise
12526*6777b538SAndroid Build Coastguard Worker   // the cache.
transaction_count()12527*6777b538SAndroid Build Coastguard Worker   int transaction_count() {
12528*6777b538SAndroid Build Coastguard Worker     return cache_.network_layer()->transaction_count();
12529*6777b538SAndroid Build Coastguard Worker   }
12530*6777b538SAndroid Build Coastguard Worker 
12531*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache_;
12532*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction_;
12533*6777b538SAndroid Build Coastguard Worker   std::string response_headers_;
12534*6777b538SAndroid Build Coastguard Worker   base::SimpleTestClock clock_;
12535*6777b538SAndroid Build Coastguard Worker };
12536*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationShortlyAfterPrefetch)12537*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCachePrefetchValidationTest, SkipValidationShortlyAfterPrefetch) {
12538*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12539*6777b538SAndroid Build Coastguard Worker   AdvanceTime(kRequireValidationSecs);
12540*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12541*6777b538SAndroid Build Coastguard Worker }
12542*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCachePrefetchValidationTest,ValidateLongAfterPrefetch)12543*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCachePrefetchValidationTest, ValidateLongAfterPrefetch) {
12544*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12545*6777b538SAndroid Build Coastguard Worker   AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute);
12546*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12547*6777b538SAndroid Build Coastguard Worker }
12548*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnceOnly)12549*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceOnly) {
12550*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12551*6777b538SAndroid Build Coastguard Worker   AdvanceTime(kRequireValidationSecs);
12552*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12553*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12554*6777b538SAndroid Build Coastguard Worker }
12555*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnceReadOnly)12556*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceReadOnly) {
12557*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12558*6777b538SAndroid Build Coastguard Worker   AdvanceTime(kRequireValidationSecs);
12559*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE |
12560*6777b538SAndroid Build Coastguard Worker                                           LOAD_SKIP_CACHE_VALIDATION));
12561*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12562*6777b538SAndroid Build Coastguard Worker }
12563*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCachePrefetchValidationTest,BypassCacheOverwritesPrefetch)12564*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCachePrefetchValidationTest, BypassCacheOverwritesPrefetch) {
12565*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12566*6777b538SAndroid Build Coastguard Worker   AdvanceTime(kRequireValidationSecs);
12567*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE));
12568*6777b538SAndroid Build Coastguard Worker   AdvanceTime(kRequireValidationSecs);
12569*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12570*6777b538SAndroid Build Coastguard Worker }
12571*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnExistingEntryThatNeedsValidation)12572*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCachePrefetchValidationTest,
12573*6777b538SAndroid Build Coastguard Worker        SkipValidationOnExistingEntryThatNeedsValidation) {
12574*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12575*6777b538SAndroid Build Coastguard Worker   AdvanceTime(kRequireValidationSecs);
12576*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12577*6777b538SAndroid Build Coastguard Worker   AdvanceTime(kRequireValidationSecs);
12578*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12579*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12580*6777b538SAndroid Build Coastguard Worker }
12581*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnExistingEntryThatDoesNotNeedValidation)12582*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCachePrefetchValidationTest,
12583*6777b538SAndroid Build Coastguard Worker        SkipValidationOnExistingEntryThatDoesNotNeedValidation) {
12584*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12585*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
12586*6777b538SAndroid Build Coastguard Worker   AdvanceTime(kRequireValidationSecs);
12587*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12588*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12589*6777b538SAndroid Build Coastguard Worker }
12590*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCachePrefetchValidationTest,PrefetchMultipleTimes)12591*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCachePrefetchValidationTest, PrefetchMultipleTimes) {
12592*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12593*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
12594*6777b538SAndroid Build Coastguard Worker   AdvanceTime(kRequireValidationSecs);
12595*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12596*6777b538SAndroid Build Coastguard Worker }
12597*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCachePrefetchValidationTest,ValidateOnDelayedSecondPrefetch)12598*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCachePrefetchValidationTest, ValidateOnDelayedSecondPrefetch) {
12599*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12600*6777b538SAndroid Build Coastguard Worker   AdvanceTime(kRequireValidationSecs);
12601*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12602*6777b538SAndroid Build Coastguard Worker   AdvanceTime(kRequireValidationSecs);
12603*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12604*6777b538SAndroid Build Coastguard Worker }
12605*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,StaleContentNotUsedWhenLoadFlagNotSet)12606*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, StaleContentNotUsedWhenLoadFlagNotSet) {
12607*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12608*6777b538SAndroid Build Coastguard Worker 
12609*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction stale_while_revalidate_transaction(
12610*6777b538SAndroid Build Coastguard Worker       kSimpleGET_Transaction);
12611*6777b538SAndroid Build Coastguard Worker 
12612*6777b538SAndroid Build Coastguard Worker   stale_while_revalidate_transaction.response_headers =
12613*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12614*6777b538SAndroid Build Coastguard Worker       "Age: 10801\n"
12615*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12616*6777b538SAndroid Build Coastguard Worker 
12617*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
12618*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12619*6777b538SAndroid Build Coastguard Worker 
12620*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12621*6777b538SAndroid Build Coastguard Worker 
12622*6777b538SAndroid Build Coastguard Worker   // Send the request again and check that it is sent to the network again.
12623*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
12624*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(
12625*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12626*6777b538SAndroid Build Coastguard Worker 
12627*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12628*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.async_revalidation_requested);
12629*6777b538SAndroid Build Coastguard Worker }
12630*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,StaleContentUsedWhenLoadFlagSetAndUsableThenTimesout)12631*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, StaleContentUsedWhenLoadFlagSetAndUsableThenTimesout) {
12632*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12633*6777b538SAndroid Build Coastguard Worker   base::SimpleTestClock clock;
12634*6777b538SAndroid Build Coastguard Worker   cache.http_cache()->SetClockForTesting(&clock);
12635*6777b538SAndroid Build Coastguard Worker   cache.network_layer()->SetClock(&clock);
12636*6777b538SAndroid Build Coastguard Worker   clock.Advance(base::Seconds(10));
12637*6777b538SAndroid Build Coastguard Worker 
12638*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction stale_while_revalidate_transaction(
12639*6777b538SAndroid Build Coastguard Worker       kSimpleGET_Transaction);
12640*6777b538SAndroid Build Coastguard Worker   stale_while_revalidate_transaction.load_flags |=
12641*6777b538SAndroid Build Coastguard Worker       LOAD_SUPPORT_ASYNC_REVALIDATION;
12642*6777b538SAndroid Build Coastguard Worker   stale_while_revalidate_transaction.response_headers =
12643*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12644*6777b538SAndroid Build Coastguard Worker       "Age: 10801\n"
12645*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12646*6777b538SAndroid Build Coastguard Worker 
12647*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
12648*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12649*6777b538SAndroid Build Coastguard Worker 
12650*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12651*6777b538SAndroid Build Coastguard Worker 
12652*6777b538SAndroid Build Coastguard Worker   // Send the request again and check that it is not sent to the network again.
12653*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
12654*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(
12655*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12656*6777b538SAndroid Build Coastguard Worker 
12657*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12658*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.async_revalidation_requested);
12659*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.stale_revalidate_timeout.is_null());
12660*6777b538SAndroid Build Coastguard Worker 
12661*6777b538SAndroid Build Coastguard Worker   // Move forward in time such that the stale response is no longer valid.
12662*6777b538SAndroid Build Coastguard Worker   clock.SetNow(response_info.stale_revalidate_timeout);
12663*6777b538SAndroid Build Coastguard Worker   clock.Advance(base::Seconds(1));
12664*6777b538SAndroid Build Coastguard Worker 
12665*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(
12666*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12667*6777b538SAndroid Build Coastguard Worker 
12668*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12669*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.async_revalidation_requested);
12670*6777b538SAndroid Build Coastguard Worker }
12671*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,StaleContentUsedWhenLoadFlagSetAndUsable)12672*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, StaleContentUsedWhenLoadFlagSetAndUsable) {
12673*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12674*6777b538SAndroid Build Coastguard Worker   base::SimpleTestClock clock;
12675*6777b538SAndroid Build Coastguard Worker   cache.http_cache()->SetClockForTesting(&clock);
12676*6777b538SAndroid Build Coastguard Worker   cache.network_layer()->SetClock(&clock);
12677*6777b538SAndroid Build Coastguard Worker   clock.Advance(base::Seconds(10));
12678*6777b538SAndroid Build Coastguard Worker 
12679*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction stale_while_revalidate_transaction(
12680*6777b538SAndroid Build Coastguard Worker       kSimpleGET_Transaction);
12681*6777b538SAndroid Build Coastguard Worker   stale_while_revalidate_transaction.load_flags |=
12682*6777b538SAndroid Build Coastguard Worker       LOAD_SUPPORT_ASYNC_REVALIDATION;
12683*6777b538SAndroid Build Coastguard Worker   stale_while_revalidate_transaction.response_headers =
12684*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12685*6777b538SAndroid Build Coastguard Worker       "Age: 10801\n"
12686*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12687*6777b538SAndroid Build Coastguard Worker 
12688*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
12689*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12690*6777b538SAndroid Build Coastguard Worker 
12691*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12692*6777b538SAndroid Build Coastguard Worker 
12693*6777b538SAndroid Build Coastguard Worker   // Send the request again and check that it is not sent to the network again.
12694*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
12695*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(
12696*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12697*6777b538SAndroid Build Coastguard Worker 
12698*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12699*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.async_revalidation_requested);
12700*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.stale_revalidate_timeout.is_null());
12701*6777b538SAndroid Build Coastguard Worker   base::Time revalidation_timeout = response_info.stale_revalidate_timeout;
12702*6777b538SAndroid Build Coastguard Worker   clock.Advance(base::Seconds(1));
12703*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(clock.Now() < revalidation_timeout);
12704*6777b538SAndroid Build Coastguard Worker 
12705*6777b538SAndroid Build Coastguard Worker   // Fetch the resource again inside the revalidation timeout window.
12706*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(
12707*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12708*6777b538SAndroid Build Coastguard Worker 
12709*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12710*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.async_revalidation_requested);
12711*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.stale_revalidate_timeout.is_null());
12712*6777b538SAndroid Build Coastguard Worker   // Expect that the original revalidation timeout hasn't changed.
12713*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(revalidation_timeout == response_info.stale_revalidate_timeout);
12714*6777b538SAndroid Build Coastguard Worker 
12715*6777b538SAndroid Build Coastguard Worker   // mask of async revalidation flag.
12716*6777b538SAndroid Build Coastguard Worker   stale_while_revalidate_transaction.load_flags &=
12717*6777b538SAndroid Build Coastguard Worker       ~LOAD_SUPPORT_ASYNC_REVALIDATION;
12718*6777b538SAndroid Build Coastguard Worker   stale_while_revalidate_transaction.status = "HTTP/1.1 304 Not Modified";
12719*6777b538SAndroid Build Coastguard Worker   // Write 304 to the cache.
12720*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(
12721*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12722*6777b538SAndroid Build Coastguard Worker 
12723*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12724*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.async_revalidation_requested);
12725*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.stale_revalidate_timeout.is_null());
12726*6777b538SAndroid Build Coastguard Worker }
12727*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,StaleContentNotUsedWhenUnusable)12728*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, StaleContentNotUsedWhenUnusable) {
12729*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12730*6777b538SAndroid Build Coastguard Worker 
12731*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction stale_while_revalidate_transaction(
12732*6777b538SAndroid Build Coastguard Worker       kSimpleGET_Transaction);
12733*6777b538SAndroid Build Coastguard Worker   stale_while_revalidate_transaction.load_flags |=
12734*6777b538SAndroid Build Coastguard Worker       LOAD_SUPPORT_ASYNC_REVALIDATION;
12735*6777b538SAndroid Build Coastguard Worker   stale_while_revalidate_transaction.response_headers =
12736*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12737*6777b538SAndroid Build Coastguard Worker       "Age: 10801\n"
12738*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0,stale-while-revalidate=1800\n";
12739*6777b538SAndroid Build Coastguard Worker 
12740*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
12741*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12742*6777b538SAndroid Build Coastguard Worker 
12743*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12744*6777b538SAndroid Build Coastguard Worker 
12745*6777b538SAndroid Build Coastguard Worker   // Send the request again and check that it is sent to the network again.
12746*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
12747*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(
12748*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12749*6777b538SAndroid Build Coastguard Worker 
12750*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12751*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.async_revalidation_requested);
12752*6777b538SAndroid Build Coastguard Worker }
12753*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,StaleContentWriteError)12754*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, StaleContentWriteError) {
12755*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12756*6777b538SAndroid Build Coastguard Worker   base::SimpleTestClock clock;
12757*6777b538SAndroid Build Coastguard Worker   cache.http_cache()->SetClockForTesting(&clock);
12758*6777b538SAndroid Build Coastguard Worker   cache.network_layer()->SetClock(&clock);
12759*6777b538SAndroid Build Coastguard Worker   clock.Advance(base::Seconds(10));
12760*6777b538SAndroid Build Coastguard Worker 
12761*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction stale_while_revalidate_transaction(
12762*6777b538SAndroid Build Coastguard Worker       kSimpleGET_Transaction);
12763*6777b538SAndroid Build Coastguard Worker   stale_while_revalidate_transaction.load_flags |=
12764*6777b538SAndroid Build Coastguard Worker       LOAD_SUPPORT_ASYNC_REVALIDATION;
12765*6777b538SAndroid Build Coastguard Worker   stale_while_revalidate_transaction.response_headers =
12766*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12767*6777b538SAndroid Build Coastguard Worker       "Age: 10801\n"
12768*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12769*6777b538SAndroid Build Coastguard Worker 
12770*6777b538SAndroid Build Coastguard Worker   // Write to the cache.
12771*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12772*6777b538SAndroid Build Coastguard Worker 
12773*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12774*6777b538SAndroid Build Coastguard Worker 
12775*6777b538SAndroid Build Coastguard Worker   // Send the request again but inject a write fault. Should still work
12776*6777b538SAndroid Build Coastguard Worker   // (and not dereference any null pointers).
12777*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_WRITE);
12778*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
12779*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(
12780*6777b538SAndroid Build Coastguard Worker       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12781*6777b538SAndroid Build Coastguard Worker 
12782*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12783*6777b538SAndroid Build Coastguard Worker }
12784*6777b538SAndroid Build Coastguard Worker 
12785*6777b538SAndroid Build Coastguard Worker // Tests that we allow multiple simultaneous, non-overlapping transactions to
12786*6777b538SAndroid Build Coastguard Worker // take place on a sparse entry.
TEST_F(HttpCacheTest,RangeGET_MultipleRequests)12787*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_MultipleRequests) {
12788*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12789*6777b538SAndroid Build Coastguard Worker 
12790*6777b538SAndroid Build Coastguard Worker   // Create a transaction for bytes 0-9.
12791*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(kRangeGET_TransactionOK);
12792*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
12793*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
12794*6777b538SAndroid Build Coastguard Worker   transaction.data = "rg: 00-09 ";
12795*6777b538SAndroid Build Coastguard Worker 
12796*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
12797*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
12798*6777b538SAndroid Build Coastguard Worker   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
12799*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsOk());
12800*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(trans.get());
12801*6777b538SAndroid Build Coastguard Worker 
12802*6777b538SAndroid Build Coastguard Worker   // Start our transaction.
12803*6777b538SAndroid Build Coastguard Worker   trans->Start(&request, callback.callback(), NetLogWithSource());
12804*6777b538SAndroid Build Coastguard Worker 
12805*6777b538SAndroid Build Coastguard Worker   // A second transaction on a different part of the file (the default
12806*6777b538SAndroid Build Coastguard Worker   // kRangeGET_TransactionOK requests 40-49) should not be blocked by
12807*6777b538SAndroid Build Coastguard Worker   // the already pending transaction.
12808*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
12809*6777b538SAndroid Build Coastguard Worker 
12810*6777b538SAndroid Build Coastguard Worker   // Let the first transaction complete.
12811*6777b538SAndroid Build Coastguard Worker   callback.WaitForResult();
12812*6777b538SAndroid Build Coastguard Worker }
12813*6777b538SAndroid Build Coastguard Worker 
12814*6777b538SAndroid Build Coastguard Worker // Verify that a range request can be satisfied from a completely cached
12815*6777b538SAndroid Build Coastguard Worker // resource with the LOAD_ONLY_FROM_CACHE flag set. Currently it's not
12816*6777b538SAndroid Build Coastguard Worker // implemented so it returns ERR_CACHE_MISS. See also
12817*6777b538SAndroid Build Coastguard Worker // HttpCacheTest.RangeGET_OK_LoadOnlyFromCache.
12818*6777b538SAndroid Build Coastguard Worker // TODO(ricea): Update this test if it is implemented in future.
TEST_F(HttpCacheTest,RangeGET_Previous200_LoadOnlyFromCache)12819*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RangeGET_Previous200_LoadOnlyFromCache) {
12820*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12821*6777b538SAndroid Build Coastguard Worker 
12822*6777b538SAndroid Build Coastguard Worker   // Store the whole thing with status 200.
12823*6777b538SAndroid Build Coastguard Worker   {
12824*6777b538SAndroid Build Coastguard Worker     MockTransaction transaction(kETagGET_Transaction);
12825*6777b538SAndroid Build Coastguard Worker     transaction.url = kRangeGET_TransactionOK.url;
12826*6777b538SAndroid Build Coastguard Worker     transaction.data = kFullRangeData;
12827*6777b538SAndroid Build Coastguard Worker     ScopedMockTransaction scoped_transaction(transaction);
12828*6777b538SAndroid Build Coastguard Worker     RunTransactionTest(cache.http_cache(), transaction);
12829*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.network_layer()->transaction_count());
12830*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache.disk_cache()->open_count());
12831*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, cache.disk_cache()->create_count());
12832*6777b538SAndroid Build Coastguard Worker   }
12833*6777b538SAndroid Build Coastguard Worker 
12834*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
12835*6777b538SAndroid Build Coastguard Worker 
12836*6777b538SAndroid Build Coastguard Worker   // Now see that we use the stored entry.
12837*6777b538SAndroid Build Coastguard Worker   MockTransaction transaction2(kRangeGET_TransactionOK);
12838*6777b538SAndroid Build Coastguard Worker   transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
12839*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(transaction2);
12840*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
12841*6777b538SAndroid Build Coastguard Worker 
12842*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpTransaction> trans;
12843*6777b538SAndroid Build Coastguard Worker   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
12844*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsOk());
12845*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(trans);
12846*6777b538SAndroid Build Coastguard Worker 
12847*6777b538SAndroid Build Coastguard Worker   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12848*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
12849*6777b538SAndroid Build Coastguard Worker     rv = callback.WaitForResult();
12850*6777b538SAndroid Build Coastguard Worker   }
12851*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_CACHE_MISS));
12852*6777b538SAndroid Build Coastguard Worker 
12853*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12854*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
12855*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
12856*6777b538SAndroid Build Coastguard Worker }
12857*6777b538SAndroid Build Coastguard Worker 
12858*6777b538SAndroid Build Coastguard Worker // Makes sure that a request stops using the cache when the response headers
12859*6777b538SAndroid Build Coastguard Worker // with "Cache-Control: no-store" arrives. That means that another request for
12860*6777b538SAndroid Build Coastguard Worker // the same URL can be processed before the response body of the original
12861*6777b538SAndroid Build Coastguard Worker // request arrives.
TEST_F(HttpCacheTest,NoStoreResponseShouldNotBlockFollowingRequests)12862*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, NoStoreResponseShouldNotBlockFollowingRequests) {
12863*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12864*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
12865*6777b538SAndroid Build Coastguard Worker   mock_transaction.response_headers = "Cache-Control: no-store\n";
12866*6777b538SAndroid Build Coastguard Worker   MockHttpRequest request(mock_transaction);
12867*6777b538SAndroid Build Coastguard Worker 
12868*6777b538SAndroid Build Coastguard Worker   auto first = std::make_unique<Context>();
12869*6777b538SAndroid Build Coastguard Worker   first->result = cache.CreateTransaction(&first->trans);
12870*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(first->result, IsOk());
12871*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
12872*6777b538SAndroid Build Coastguard Worker   first->result = first->trans->Start(&request, first->callback.callback(),
12873*6777b538SAndroid Build Coastguard Worker                                       NetLogWithSource());
12874*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, first->trans->GetLoadState());
12875*6777b538SAndroid Build Coastguard Worker 
12876*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
12877*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
12878*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(first->trans->GetResponseInfo());
12879*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(first->trans->GetResponseInfo()->headers->HasHeaderValue(
12880*6777b538SAndroid Build Coastguard Worker       "Cache-Control", "no-store"));
12881*6777b538SAndroid Build Coastguard Worker   // Here we have read the response header but not read the response body yet.
12882*6777b538SAndroid Build Coastguard Worker 
12883*6777b538SAndroid Build Coastguard Worker   // Let us create the second (read) transaction.
12884*6777b538SAndroid Build Coastguard Worker   auto second = std::make_unique<Context>();
12885*6777b538SAndroid Build Coastguard Worker   second->result = cache.CreateTransaction(&second->trans);
12886*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(second->result, IsOk());
12887*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
12888*6777b538SAndroid Build Coastguard Worker   second->result = second->trans->Start(&request, second->callback.callback(),
12889*6777b538SAndroid Build Coastguard Worker                                         NetLogWithSource());
12890*6777b538SAndroid Build Coastguard Worker 
12891*6777b538SAndroid Build Coastguard Worker   // Here the second transaction proceeds without reading the first body.
12892*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState());
12893*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
12894*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
12895*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(second->trans->GetResponseInfo());
12896*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue(
12897*6777b538SAndroid Build Coastguard Worker       "Cache-Control", "no-store"));
12898*6777b538SAndroid Build Coastguard Worker   ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction);
12899*6777b538SAndroid Build Coastguard Worker }
12900*6777b538SAndroid Build Coastguard Worker 
12901*6777b538SAndroid Build Coastguard Worker // Tests that serving a response entirely from cache replays the previous
12902*6777b538SAndroid Build Coastguard Worker // SSLInfo.
TEST_F(HttpCacheTest,CachePreservesSSLInfo)12903*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CachePreservesSSLInfo) {
12904*6777b538SAndroid Build Coastguard Worker   static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
12905*6777b538SAndroid Build Coastguard Worker   int status = 0;
12906*6777b538SAndroid Build Coastguard Worker   SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
12907*6777b538SAndroid Build Coastguard Worker                                     &status);
12908*6777b538SAndroid Build Coastguard Worker   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status);
12909*6777b538SAndroid Build Coastguard Worker 
12910*6777b538SAndroid Build Coastguard Worker   scoped_refptr<X509Certificate> cert =
12911*6777b538SAndroid Build Coastguard Worker       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12912*6777b538SAndroid Build Coastguard Worker 
12913*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12914*6777b538SAndroid Build Coastguard Worker 
12915*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
12916*6777b538SAndroid Build Coastguard Worker   transaction.cert = cert;
12917*6777b538SAndroid Build Coastguard Worker   transaction.ssl_connection_status = status;
12918*6777b538SAndroid Build Coastguard Worker 
12919*6777b538SAndroid Build Coastguard Worker   // Fetch the resource.
12920*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
12921*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
12922*6777b538SAndroid Build Coastguard Worker                                      &response_info);
12923*6777b538SAndroid Build Coastguard Worker 
12924*6777b538SAndroid Build Coastguard Worker   // The request should have hit the network and a cache entry created.
12925*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12926*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
12927*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
12928*6777b538SAndroid Build Coastguard Worker 
12929*6777b538SAndroid Build Coastguard Worker   // The expected SSL state was reported.
12930*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(transaction.ssl_connection_status,
12931*6777b538SAndroid Build Coastguard Worker             response_info.ssl_info.connection_status);
12932*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cert->EqualsIncludingChain(response_info.ssl_info.cert.get()));
12933*6777b538SAndroid Build Coastguard Worker 
12934*6777b538SAndroid Build Coastguard Worker   // Fetch the resource again.
12935*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
12936*6777b538SAndroid Build Coastguard Worker                                      &response_info);
12937*6777b538SAndroid Build Coastguard Worker 
12938*6777b538SAndroid Build Coastguard Worker   // The request should have been reused without hitting the network.
12939*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12940*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
12941*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
12942*6777b538SAndroid Build Coastguard Worker 
12943*6777b538SAndroid Build Coastguard Worker   // The SSL state was preserved.
12944*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(status, response_info.ssl_info.connection_status);
12945*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cert->EqualsIncludingChain(response_info.ssl_info.cert.get()));
12946*6777b538SAndroid Build Coastguard Worker }
12947*6777b538SAndroid Build Coastguard Worker 
12948*6777b538SAndroid Build Coastguard Worker // Tests that SSLInfo gets updated when revalidating a cached response.
TEST_F(HttpCacheTest,RevalidationUpdatesSSLInfo)12949*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, RevalidationUpdatesSSLInfo) {
12950*6777b538SAndroid Build Coastguard Worker   static const uint16_t kTLS_RSA_WITH_RC4_128_MD5 = 0x0004;
12951*6777b538SAndroid Build Coastguard Worker   static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
12952*6777b538SAndroid Build Coastguard Worker 
12953*6777b538SAndroid Build Coastguard Worker   int status1 = 0;
12954*6777b538SAndroid Build Coastguard Worker   SSLConnectionStatusSetCipherSuite(kTLS_RSA_WITH_RC4_128_MD5, &status1);
12955*6777b538SAndroid Build Coastguard Worker   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1, &status1);
12956*6777b538SAndroid Build Coastguard Worker   int status2 = 0;
12957*6777b538SAndroid Build Coastguard Worker   SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
12958*6777b538SAndroid Build Coastguard Worker                                     &status2);
12959*6777b538SAndroid Build Coastguard Worker   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status2);
12960*6777b538SAndroid Build Coastguard Worker 
12961*6777b538SAndroid Build Coastguard Worker   scoped_refptr<X509Certificate> cert1 =
12962*6777b538SAndroid Build Coastguard Worker       ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
12963*6777b538SAndroid Build Coastguard Worker   scoped_refptr<X509Certificate> cert2 =
12964*6777b538SAndroid Build Coastguard Worker       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12965*6777b538SAndroid Build Coastguard Worker 
12966*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
12967*6777b538SAndroid Build Coastguard Worker 
12968*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
12969*6777b538SAndroid Build Coastguard Worker   transaction.cert = cert1;
12970*6777b538SAndroid Build Coastguard Worker   transaction.ssl_connection_status = status1;
12971*6777b538SAndroid Build Coastguard Worker 
12972*6777b538SAndroid Build Coastguard Worker   // Fetch the resource.
12973*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
12974*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
12975*6777b538SAndroid Build Coastguard Worker                                      &response_info);
12976*6777b538SAndroid Build Coastguard Worker 
12977*6777b538SAndroid Build Coastguard Worker   // The request should have hit the network and a cache entry created.
12978*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12979*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache.disk_cache()->open_count());
12980*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
12981*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.was_cached);
12982*6777b538SAndroid Build Coastguard Worker 
12983*6777b538SAndroid Build Coastguard Worker   // The expected SSL state was reported.
12984*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(status1, response_info.ssl_info.connection_status);
12985*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cert1->EqualsIncludingChain(response_info.ssl_info.cert.get()));
12986*6777b538SAndroid Build Coastguard Worker 
12987*6777b538SAndroid Build Coastguard Worker   // The server deploys a more modern configuration but reports 304 on the
12988*6777b538SAndroid Build Coastguard Worker   // revalidation attempt.
12989*6777b538SAndroid Build Coastguard Worker   transaction.status = "HTTP/1.1 304 Not Modified";
12990*6777b538SAndroid Build Coastguard Worker   transaction.cert = cert2;
12991*6777b538SAndroid Build Coastguard Worker   transaction.ssl_connection_status = status2;
12992*6777b538SAndroid Build Coastguard Worker 
12993*6777b538SAndroid Build Coastguard Worker   // Fetch the resource again, forcing a revalidation.
12994*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = "Cache-Control: max-age=0\r\n";
12995*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
12996*6777b538SAndroid Build Coastguard Worker                                      &response_info);
12997*6777b538SAndroid Build Coastguard Worker 
12998*6777b538SAndroid Build Coastguard Worker   // The request should have been successfully revalidated.
12999*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, cache.network_layer()->transaction_count());
13000*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->open_count());
13001*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, cache.disk_cache()->create_count());
13002*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.was_cached);
13003*6777b538SAndroid Build Coastguard Worker 
13004*6777b538SAndroid Build Coastguard Worker   // The new SSL state is reported.
13005*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(status2, response_info.ssl_info.connection_status);
13006*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cert2->EqualsIncludingChain(response_info.ssl_info.cert.get()));
13007*6777b538SAndroid Build Coastguard Worker }
13008*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,CacheEntryStatusOther)13009*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheEntryStatusOther) {
13010*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13011*6777b538SAndroid Build Coastguard Worker 
13012*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
13013*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), kRangeGET_Transaction,
13014*6777b538SAndroid Build Coastguard Worker                                      &response_info);
13015*6777b538SAndroid Build Coastguard Worker 
13016*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.was_cached);
13017*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.network_accessed);
13018*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CacheEntryStatus::ENTRY_OTHER, response_info.cache_entry_status);
13019*6777b538SAndroid Build Coastguard Worker }
13020*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,CacheEntryStatusNotInCache)13021*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheEntryStatusNotInCache) {
13022*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13023*6777b538SAndroid Build Coastguard Worker 
13024*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
13025*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
13026*6777b538SAndroid Build Coastguard Worker                                      &response_info);
13027*6777b538SAndroid Build Coastguard Worker 
13028*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.was_cached);
13029*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.network_accessed);
13030*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CacheEntryStatus::ENTRY_NOT_IN_CACHE,
13031*6777b538SAndroid Build Coastguard Worker             response_info.cache_entry_status);
13032*6777b538SAndroid Build Coastguard Worker }
13033*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,CacheEntryStatusUsed)13034*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheEntryStatusUsed) {
13035*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13036*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
13037*6777b538SAndroid Build Coastguard Worker 
13038*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
13039*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
13040*6777b538SAndroid Build Coastguard Worker                                      &response_info);
13041*6777b538SAndroid Build Coastguard Worker 
13042*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.was_cached);
13043*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.network_accessed);
13044*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CacheEntryStatus::ENTRY_USED, response_info.cache_entry_status);
13045*6777b538SAndroid Build Coastguard Worker }
13046*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,CacheEntryStatusValidated)13047*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheEntryStatusValidated) {
13048*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13049*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
13050*6777b538SAndroid Build Coastguard Worker 
13051*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction still_valid(kETagGET_Transaction);
13052*6777b538SAndroid Build Coastguard Worker   still_valid.load_flags = LOAD_VALIDATE_CACHE;  // Force a validation.
13053*6777b538SAndroid Build Coastguard Worker   still_valid.handler = kETagGetConditionalRequestHandler;
13054*6777b538SAndroid Build Coastguard Worker 
13055*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
13056*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), still_valid,
13057*6777b538SAndroid Build Coastguard Worker                                      &response_info);
13058*6777b538SAndroid Build Coastguard Worker 
13059*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.was_cached);
13060*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.network_accessed);
13061*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CacheEntryStatus::ENTRY_VALIDATED,
13062*6777b538SAndroid Build Coastguard Worker             response_info.cache_entry_status);
13063*6777b538SAndroid Build Coastguard Worker }
13064*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,CacheEntryStatusUpdated)13065*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheEntryStatusUpdated) {
13066*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13067*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
13068*6777b538SAndroid Build Coastguard Worker 
13069*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction update(kETagGET_Transaction);
13070*6777b538SAndroid Build Coastguard Worker   update.load_flags = LOAD_VALIDATE_CACHE;  // Force a validation.
13071*6777b538SAndroid Build Coastguard Worker 
13072*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
13073*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), update,
13074*6777b538SAndroid Build Coastguard Worker                                      &response_info);
13075*6777b538SAndroid Build Coastguard Worker 
13076*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.was_cached);
13077*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.network_accessed);
13078*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CacheEntryStatus::ENTRY_UPDATED, response_info.cache_entry_status);
13079*6777b538SAndroid Build Coastguard Worker }
13080*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,CacheEntryStatusCantConditionalize)13081*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, CacheEntryStatusCantConditionalize) {
13082*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13083*6777b538SAndroid Build Coastguard Worker   cache.FailConditionalizations();
13084*6777b538SAndroid Build Coastguard Worker   RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
13085*6777b538SAndroid Build Coastguard Worker 
13086*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
13087*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(),
13088*6777b538SAndroid Build Coastguard Worker                                      kTypicalGET_Transaction, &response_info);
13089*6777b538SAndroid Build Coastguard Worker 
13090*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response_info.was_cached);
13091*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response_info.network_accessed);
13092*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE,
13093*6777b538SAndroid Build Coastguard Worker             response_info.cache_entry_status);
13094*6777b538SAndroid Build Coastguard Worker }
13095*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpSplitCacheKeyTest,GetResourceURLFromHttpCacheKey)13096*6777b538SAndroid Build Coastguard Worker TEST_F(HttpSplitCacheKeyTest, GetResourceURLFromHttpCacheKey) {
13097*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList feature_list;
13098*6777b538SAndroid Build Coastguard Worker   feature_list.InitAndEnableFeature(
13099*6777b538SAndroid Build Coastguard Worker       net::features::kSplitCacheByNetworkIsolationKey);
13100*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13101*6777b538SAndroid Build Coastguard Worker   std::string urls[] = {"http://www.a.com/", "https://b.com/example.html",
13102*6777b538SAndroid Build Coastguard Worker                         "http://example.com/Some Path/Some Leaf?some query"};
13103*6777b538SAndroid Build Coastguard Worker 
13104*6777b538SAndroid Build Coastguard Worker   for (const std::string& url : urls) {
13105*6777b538SAndroid Build Coastguard Worker     std::string key = ComputeCacheKey(url);
13106*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(GURL(url).spec(), HttpCache::GetResourceURLFromHttpCacheKey(key));
13107*6777b538SAndroid Build Coastguard Worker   }
13108*6777b538SAndroid Build Coastguard Worker }
13109*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,GetResourceURLFromHttpCacheKey)13110*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, GetResourceURLFromHttpCacheKey) {
13111*6777b538SAndroid Build Coastguard Worker   const struct {
13112*6777b538SAndroid Build Coastguard Worker     std::string input;
13113*6777b538SAndroid Build Coastguard Worker     std::string output;
13114*6777b538SAndroid Build Coastguard Worker   } kTestCase[] = {
13115*6777b538SAndroid Build Coastguard Worker       // Valid input:
13116*6777b538SAndroid Build Coastguard Worker       {"0/0/https://a.com/", "https://a.com/"},
13117*6777b538SAndroid Build Coastguard Worker       {"0/0/https://a.com/path", "https://a.com/path"},
13118*6777b538SAndroid Build Coastguard Worker       {"0/0/https://a.com/?query", "https://a.com/?query"},
13119*6777b538SAndroid Build Coastguard Worker       {"0/0/https://a.com/#fragment", "https://a.com/#fragment"},
13120*6777b538SAndroid Build Coastguard Worker       {"0/0/_dk_s_ https://a.com/", "https://a.com/"},
13121*6777b538SAndroid Build Coastguard Worker       {"0/0/_dk_https://a.com https://b.com https://c.com/", "https://c.com/"},
13122*6777b538SAndroid Build Coastguard Worker       {"0/0/_dk_shttps://a.com https://b.com https://c.com/", "https://c.com/"},
13123*6777b538SAndroid Build Coastguard Worker 
13124*6777b538SAndroid Build Coastguard Worker       // Invalid input, producing garbage, without crashing.
13125*6777b538SAndroid Build Coastguard Worker       {"", ""},
13126*6777b538SAndroid Build Coastguard Worker       {"0/a.com", "0/a.com"},
13127*6777b538SAndroid Build Coastguard Worker       {"https://a.com/", "a.com/"},
13128*6777b538SAndroid Build Coastguard Worker       {"0/https://a.com/", "/a.com/"},
13129*6777b538SAndroid Build Coastguard Worker   };
13130*6777b538SAndroid Build Coastguard Worker 
13131*6777b538SAndroid Build Coastguard Worker   for (const auto& test : kTestCase) {
13132*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test.output,
13133*6777b538SAndroid Build Coastguard Worker               HttpCache::GetResourceURLFromHttpCacheKey(test.input));
13134*6777b538SAndroid Build Coastguard Worker   }
13135*6777b538SAndroid Build Coastguard Worker }
13136*6777b538SAndroid Build Coastguard Worker 
13137*6777b538SAndroid Build Coastguard Worker class TestCompletionCallbackForHttpCache : public TestCompletionCallbackBase {
13138*6777b538SAndroid Build Coastguard Worker  public:
13139*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache() = default;
13140*6777b538SAndroid Build Coastguard Worker   ~TestCompletionCallbackForHttpCache() override = default;
13141*6777b538SAndroid Build Coastguard Worker 
callback()13142*6777b538SAndroid Build Coastguard Worker   CompletionRepeatingCallback callback() {
13143*6777b538SAndroid Build Coastguard Worker     return base::BindRepeating(&TestCompletionCallbackForHttpCache::SetResult,
13144*6777b538SAndroid Build Coastguard Worker                                base::Unretained(this));
13145*6777b538SAndroid Build Coastguard Worker   }
13146*6777b538SAndroid Build Coastguard Worker 
results()13147*6777b538SAndroid Build Coastguard Worker   const std::vector<int>& results() { return results_; }
13148*6777b538SAndroid Build Coastguard Worker 
13149*6777b538SAndroid Build Coastguard Worker  private:
13150*6777b538SAndroid Build Coastguard Worker   std::vector<int> results_;
13151*6777b538SAndroid Build Coastguard Worker 
13152*6777b538SAndroid Build Coastguard Worker  protected:
SetResult(int result)13153*6777b538SAndroid Build Coastguard Worker   void SetResult(int result) override {
13154*6777b538SAndroid Build Coastguard Worker     results_.push_back(result);
13155*6777b538SAndroid Build Coastguard Worker     DidSetResult();
13156*6777b538SAndroid Build Coastguard Worker   }
13157*6777b538SAndroid Build Coastguard Worker };
13158*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByOpen)13159*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByOpen) {
13160*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13161*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13162*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13163*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13164*6777b538SAndroid Build Coastguard Worker 
13165*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13166*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13167*6777b538SAndroid Build Coastguard Worker 
13168*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to DoomEntry and OpenEntry
13169*6777b538SAndroid Build Coastguard Worker   // below require that it exists.
13170*6777b538SAndroid Build Coastguard Worker   cache.backend();
13171*6777b538SAndroid Build Coastguard Worker 
13172*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13173*6777b538SAndroid Build Coastguard Worker   // functions.
13174*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13175*6777b538SAndroid Build Coastguard Worker 
13176*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13177*6777b538SAndroid Build Coastguard Worker 
13178*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(true);
13179*6777b538SAndroid Build Coastguard Worker 
13180*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13181*6777b538SAndroid Build Coastguard Worker   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13182*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13183*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(false);
13184*6777b538SAndroid Build Coastguard Worker   rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13185*6777b538SAndroid Build Coastguard Worker                  transaction.get());
13186*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13187*6777b538SAndroid Build Coastguard Worker 
13188*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13189*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13190*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13191*6777b538SAndroid Build Coastguard Worker 
13192*6777b538SAndroid Build Coastguard Worker   // Verify that DoomEntry failed correctly.
13193*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13194*6777b538SAndroid Build Coastguard Worker   // Verify that OpenEntry fails with the same code.
13195*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_DOOM_FAILURE);
13196*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry1, nullptr);
13197*6777b538SAndroid Build Coastguard Worker }
13198*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByCreate)13199*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByCreate) {
13200*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13201*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13202*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13203*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13204*6777b538SAndroid Build Coastguard Worker 
13205*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13206*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13207*6777b538SAndroid Build Coastguard Worker 
13208*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to DoomEntry and CreateEntry
13209*6777b538SAndroid Build Coastguard Worker   // below require that it exists.
13210*6777b538SAndroid Build Coastguard Worker   cache.backend();
13211*6777b538SAndroid Build Coastguard Worker 
13212*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13213*6777b538SAndroid Build Coastguard Worker   // functions.
13214*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13215*6777b538SAndroid Build Coastguard Worker 
13216*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13217*6777b538SAndroid Build Coastguard Worker 
13218*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(true);
13219*6777b538SAndroid Build Coastguard Worker 
13220*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13221*6777b538SAndroid Build Coastguard Worker   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13222*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13223*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(false);
13224*6777b538SAndroid Build Coastguard Worker   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13225*6777b538SAndroid Build Coastguard Worker                    transaction.get());
13226*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13227*6777b538SAndroid Build Coastguard Worker 
13228*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13229*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13230*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13231*6777b538SAndroid Build Coastguard Worker 
13232*6777b538SAndroid Build Coastguard Worker   // Verify that DoomEntry failed correctly.
13233*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13234*6777b538SAndroid Build Coastguard Worker   // Verify that CreateEntry requests a restart (CACHE_RACE).
13235*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13236*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry1, nullptr);
13237*6777b538SAndroid Build Coastguard Worker }
13238*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByDoom)13239*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByDoom) {
13240*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13241*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13242*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13243*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13244*6777b538SAndroid Build Coastguard Worker 
13245*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13246*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13247*6777b538SAndroid Build Coastguard Worker 
13248*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to DoomEntry below require that
13249*6777b538SAndroid Build Coastguard Worker   // it exists.
13250*6777b538SAndroid Build Coastguard Worker   cache.backend();
13251*6777b538SAndroid Build Coastguard Worker 
13252*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13253*6777b538SAndroid Build Coastguard Worker   // functions.
13254*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13255*6777b538SAndroid Build Coastguard Worker 
13256*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(true);
13257*6777b538SAndroid Build Coastguard Worker 
13258*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13259*6777b538SAndroid Build Coastguard Worker   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13260*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13261*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(false);
13262*6777b538SAndroid Build Coastguard Worker   rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13263*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13264*6777b538SAndroid Build Coastguard Worker 
13265*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13266*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13267*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13268*6777b538SAndroid Build Coastguard Worker 
13269*6777b538SAndroid Build Coastguard Worker   // Verify that DoomEntry failed correctly.
13270*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13271*6777b538SAndroid Build Coastguard Worker   // Verify that the second DoomEntry requests a restart (CACHE_RACE).
13272*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13273*6777b538SAndroid Build Coastguard Worker }
13274*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,FailedOpenFollowedByCreate)13275*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, FailedOpenFollowedByCreate) {
13276*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13277*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13278*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13279*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13280*6777b538SAndroid Build Coastguard Worker 
13281*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13282*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13283*6777b538SAndroid Build Coastguard Worker 
13284*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to OpenEntry and CreateEntry
13285*6777b538SAndroid Build Coastguard Worker   // below require that it exists.
13286*6777b538SAndroid Build Coastguard Worker   cache.backend();
13287*6777b538SAndroid Build Coastguard Worker 
13288*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13289*6777b538SAndroid Build Coastguard Worker   // functions.
13290*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13291*6777b538SAndroid Build Coastguard Worker 
13292*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13293*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry2 = nullptr;
13294*6777b538SAndroid Build Coastguard Worker 
13295*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(true);
13296*6777b538SAndroid Build Coastguard Worker 
13297*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13298*6777b538SAndroid Build Coastguard Worker   int rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13299*6777b538SAndroid Build Coastguard Worker                      transaction.get());
13300*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13301*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(false);
13302*6777b538SAndroid Build Coastguard Worker   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13303*6777b538SAndroid Build Coastguard Worker                    transaction.get());
13304*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13305*6777b538SAndroid Build Coastguard Worker 
13306*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13307*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13308*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13309*6777b538SAndroid Build Coastguard Worker 
13310*6777b538SAndroid Build Coastguard Worker   // Verify that OpenEntry failed correctly.
13311*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_FAILURE);
13312*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry1, nullptr);
13313*6777b538SAndroid Build Coastguard Worker   // Verify that the CreateEntry requests a restart (CACHE_RACE).
13314*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13315*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry2, nullptr);
13316*6777b538SAndroid Build Coastguard Worker }
13317*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByOpen)13318*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByOpen) {
13319*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13320*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13321*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13322*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13323*6777b538SAndroid Build Coastguard Worker 
13324*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13325*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13326*6777b538SAndroid Build Coastguard Worker 
13327*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to CreateEntry and OpenEntry
13328*6777b538SAndroid Build Coastguard Worker   // below require that it exists.
13329*6777b538SAndroid Build Coastguard Worker   cache.backend();
13330*6777b538SAndroid Build Coastguard Worker 
13331*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13332*6777b538SAndroid Build Coastguard Worker   // functions.
13333*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13334*6777b538SAndroid Build Coastguard Worker 
13335*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13336*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry2 = nullptr;
13337*6777b538SAndroid Build Coastguard Worker 
13338*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(true);
13339*6777b538SAndroid Build Coastguard Worker 
13340*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13341*6777b538SAndroid Build Coastguard Worker   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13342*6777b538SAndroid Build Coastguard Worker                        transaction.get());
13343*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13344*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(false);
13345*6777b538SAndroid Build Coastguard Worker   rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry2,
13346*6777b538SAndroid Build Coastguard Worker                  transaction.get());
13347*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13348*6777b538SAndroid Build Coastguard Worker 
13349*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13350*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13351*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13352*6777b538SAndroid Build Coastguard Worker 
13353*6777b538SAndroid Build Coastguard Worker   // Verify that CreateEntry failed correctly.
13354*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13355*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry1, nullptr);
13356*6777b538SAndroid Build Coastguard Worker   // Verify that the OpenEntry requests a restart (CACHE_RACE).
13357*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13358*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry2, nullptr);
13359*6777b538SAndroid Build Coastguard Worker }
13360*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByCreate)13361*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByCreate) {
13362*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13363*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13364*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13365*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13366*6777b538SAndroid Build Coastguard Worker 
13367*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13368*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13369*6777b538SAndroid Build Coastguard Worker 
13370*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to CreateEntry below require
13371*6777b538SAndroid Build Coastguard Worker   // that it exists.
13372*6777b538SAndroid Build Coastguard Worker   cache.backend();
13373*6777b538SAndroid Build Coastguard Worker 
13374*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13375*6777b538SAndroid Build Coastguard Worker   // functions.
13376*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13377*6777b538SAndroid Build Coastguard Worker 
13378*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13379*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry2 = nullptr;
13380*6777b538SAndroid Build Coastguard Worker 
13381*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(true);
13382*6777b538SAndroid Build Coastguard Worker 
13383*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13384*6777b538SAndroid Build Coastguard Worker   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13385*6777b538SAndroid Build Coastguard Worker                        transaction.get());
13386*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13387*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(false);
13388*6777b538SAndroid Build Coastguard Worker   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13389*6777b538SAndroid Build Coastguard Worker                    transaction.get());
13390*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13391*6777b538SAndroid Build Coastguard Worker 
13392*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13393*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13394*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13395*6777b538SAndroid Build Coastguard Worker 
13396*6777b538SAndroid Build Coastguard Worker   // Verify the CreateEntry(s) failed.
13397*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13398*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry1, nullptr);
13399*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13400*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry2, nullptr);
13401*6777b538SAndroid Build Coastguard Worker }
13402*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,CreateFollowedByCreate)13403*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, CreateFollowedByCreate) {
13404*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13405*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13406*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13407*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13408*6777b538SAndroid Build Coastguard Worker 
13409*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13410*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13411*6777b538SAndroid Build Coastguard Worker 
13412*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to CreateEntry below require
13413*6777b538SAndroid Build Coastguard Worker   // that it exists.
13414*6777b538SAndroid Build Coastguard Worker   cache.backend();
13415*6777b538SAndroid Build Coastguard Worker 
13416*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13417*6777b538SAndroid Build Coastguard Worker   // functions.
13418*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13419*6777b538SAndroid Build Coastguard Worker 
13420*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13421*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry2 = nullptr;
13422*6777b538SAndroid Build Coastguard Worker 
13423*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13424*6777b538SAndroid Build Coastguard Worker   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13425*6777b538SAndroid Build Coastguard Worker                        transaction.get());
13426*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13427*6777b538SAndroid Build Coastguard Worker   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13428*6777b538SAndroid Build Coastguard Worker                    transaction.get());
13429*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13430*6777b538SAndroid Build Coastguard Worker 
13431*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13432*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13433*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13434*6777b538SAndroid Build Coastguard Worker 
13435*6777b538SAndroid Build Coastguard Worker   // Verify that the first CreateEntry succeeded.
13436*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], OK);
13437*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(entry1, nullptr);
13438*6777b538SAndroid Build Coastguard Worker   // Verify that the second CreateEntry failed.
13439*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13440*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry2, nullptr);
13441*6777b538SAndroid Build Coastguard Worker }
13442*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,OperationFollowedByDoom)13443*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, OperationFollowedByDoom) {
13444*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13445*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13446*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13447*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13448*6777b538SAndroid Build Coastguard Worker 
13449*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13450*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13451*6777b538SAndroid Build Coastguard Worker 
13452*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to CreateEntry and DoomEntry
13453*6777b538SAndroid Build Coastguard Worker   // below require that it exists.
13454*6777b538SAndroid Build Coastguard Worker   cache.backend();
13455*6777b538SAndroid Build Coastguard Worker 
13456*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13457*6777b538SAndroid Build Coastguard Worker   // functions.
13458*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13459*6777b538SAndroid Build Coastguard Worker 
13460*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13461*6777b538SAndroid Build Coastguard Worker 
13462*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13463*6777b538SAndroid Build Coastguard Worker   // For this test all we need is some operation followed by a doom, a create
13464*6777b538SAndroid Build Coastguard Worker   // fulfills that requirement.
13465*6777b538SAndroid Build Coastguard Worker   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13466*6777b538SAndroid Build Coastguard Worker                        transaction.get());
13467*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13468*6777b538SAndroid Build Coastguard Worker   rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13469*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13470*6777b538SAndroid Build Coastguard Worker 
13471*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13472*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13473*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13474*6777b538SAndroid Build Coastguard Worker 
13475*6777b538SAndroid Build Coastguard Worker   // Verify that the CreateEntry succeeded.
13476*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], OK);
13477*6777b538SAndroid Build Coastguard Worker   // Verify that the DoomEntry requests a restart (CACHE_RACE).
13478*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13479*6777b538SAndroid Build Coastguard Worker }
13480*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,CreateFollowedByOpenOrCreate)13481*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, CreateFollowedByOpenOrCreate) {
13482*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13483*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13484*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13485*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13486*6777b538SAndroid Build Coastguard Worker 
13487*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13488*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13489*6777b538SAndroid Build Coastguard Worker 
13490*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to CreateEntry and
13491*6777b538SAndroid Build Coastguard Worker   // OpenOrCreateEntry below require that it exists.
13492*6777b538SAndroid Build Coastguard Worker   cache.backend();
13493*6777b538SAndroid Build Coastguard Worker 
13494*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13495*6777b538SAndroid Build Coastguard Worker   // functions.
13496*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13497*6777b538SAndroid Build Coastguard Worker 
13498*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13499*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry2 = nullptr;
13500*6777b538SAndroid Build Coastguard Worker 
13501*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13502*6777b538SAndroid Build Coastguard Worker   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13503*6777b538SAndroid Build Coastguard Worker                        transaction.get());
13504*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13505*6777b538SAndroid Build Coastguard Worker   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13506*6777b538SAndroid Build Coastguard Worker                          transaction.get());
13507*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13508*6777b538SAndroid Build Coastguard Worker 
13509*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13510*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13511*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13512*6777b538SAndroid Build Coastguard Worker 
13513*6777b538SAndroid Build Coastguard Worker   // Verify that the CreateEntry succeeded.
13514*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], OK);
13515*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(entry1, nullptr);
13516*6777b538SAndroid Build Coastguard Worker   // Verify that OpenOrCreateEntry succeeded.
13517*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], OK);
13518*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(entry2, nullptr);
13519*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry1->GetEntry(), entry2->GetEntry());
13520*6777b538SAndroid Build Coastguard Worker }
13521*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByOpenOrCreate)13522*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByOpenOrCreate) {
13523*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13524*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13525*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13526*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13527*6777b538SAndroid Build Coastguard Worker 
13528*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13529*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13530*6777b538SAndroid Build Coastguard Worker 
13531*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to CreateEntry and
13532*6777b538SAndroid Build Coastguard Worker   // OpenOrCreateEntry below require that it exists.
13533*6777b538SAndroid Build Coastguard Worker   cache.backend();
13534*6777b538SAndroid Build Coastguard Worker 
13535*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13536*6777b538SAndroid Build Coastguard Worker   // functions.
13537*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13538*6777b538SAndroid Build Coastguard Worker 
13539*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13540*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry2 = nullptr;
13541*6777b538SAndroid Build Coastguard Worker 
13542*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(true);
13543*6777b538SAndroid Build Coastguard Worker 
13544*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13545*6777b538SAndroid Build Coastguard Worker   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13546*6777b538SAndroid Build Coastguard Worker                        transaction.get());
13547*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13548*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(false);
13549*6777b538SAndroid Build Coastguard Worker   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13550*6777b538SAndroid Build Coastguard Worker                          transaction.get());
13551*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13552*6777b538SAndroid Build Coastguard Worker 
13553*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13554*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13555*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13556*6777b538SAndroid Build Coastguard Worker 
13557*6777b538SAndroid Build Coastguard Worker   // Verify that CreateEntry failed correctly.
13558*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13559*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry1, nullptr);
13560*6777b538SAndroid Build Coastguard Worker   // Verify that the OpenOrCreateEntry requests a restart (CACHE_RACE).
13561*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13562*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry2, nullptr);
13563*6777b538SAndroid Build Coastguard Worker }
13564*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,OpenFollowedByOpenOrCreate)13565*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, OpenFollowedByOpenOrCreate) {
13566*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13567*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13568*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13569*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13570*6777b538SAndroid Build Coastguard Worker 
13571*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13572*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13573*6777b538SAndroid Build Coastguard Worker 
13574*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to OpenEntry and
13575*6777b538SAndroid Build Coastguard Worker   // OpenOrCreateEntry below require that it exists.
13576*6777b538SAndroid Build Coastguard Worker   cache.backend();
13577*6777b538SAndroid Build Coastguard Worker 
13578*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13579*6777b538SAndroid Build Coastguard Worker   // functions.
13580*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13581*6777b538SAndroid Build Coastguard Worker 
13582*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry0 = nullptr;
13583*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13584*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry2 = nullptr;
13585*6777b538SAndroid Build Coastguard Worker 
13586*6777b538SAndroid Build Coastguard Worker   // First need to create and entry so we can open it.
13587*6777b538SAndroid Build Coastguard Worker   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry0,
13588*6777b538SAndroid Build Coastguard Worker                        transaction.get());
13589*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13590*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13591*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), static_cast<size_t>(1));
13592*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], OK);
13593*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(entry0, nullptr);
13594*6777b538SAndroid Build Coastguard Worker   // Manually Deactivate() `entry0` because OpenEntry() fails if there is an
13595*6777b538SAndroid Build Coastguard Worker   // existing active entry.
13596*6777b538SAndroid Build Coastguard Worker   entry0.reset();
13597*6777b538SAndroid Build Coastguard Worker 
13598*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13599*6777b538SAndroid Build Coastguard Worker   rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13600*6777b538SAndroid Build Coastguard Worker                  transaction.get());
13601*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13602*6777b538SAndroid Build Coastguard Worker   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13603*6777b538SAndroid Build Coastguard Worker                          transaction.get());
13604*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13605*6777b538SAndroid Build Coastguard Worker 
13606*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13607*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13608*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 3u);
13609*6777b538SAndroid Build Coastguard Worker 
13610*6777b538SAndroid Build Coastguard Worker   // Verify that the OpenEntry succeeded.
13611*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], OK);
13612*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(entry1, nullptr);
13613*6777b538SAndroid Build Coastguard Worker   // Verify that OpenOrCreateEntry succeeded.
13614*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[2], OK);
13615*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(entry2, nullptr);
13616*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry1->GetEntry(), entry2->GetEntry());
13617*6777b538SAndroid Build Coastguard Worker }
13618*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,FailedOpenFollowedByOpenOrCreate)13619*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, FailedOpenFollowedByOpenOrCreate) {
13620*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13621*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13622*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13623*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13624*6777b538SAndroid Build Coastguard Worker 
13625*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13626*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13627*6777b538SAndroid Build Coastguard Worker 
13628*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to OpenEntry and
13629*6777b538SAndroid Build Coastguard Worker   // OpenOrCreateEntry below require that it exists.
13630*6777b538SAndroid Build Coastguard Worker   cache.backend();
13631*6777b538SAndroid Build Coastguard Worker 
13632*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13633*6777b538SAndroid Build Coastguard Worker   // functions.
13634*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13635*6777b538SAndroid Build Coastguard Worker 
13636*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13637*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry2 = nullptr;
13638*6777b538SAndroid Build Coastguard Worker 
13639*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(true);
13640*6777b538SAndroid Build Coastguard Worker 
13641*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13642*6777b538SAndroid Build Coastguard Worker   int rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13643*6777b538SAndroid Build Coastguard Worker                      transaction.get());
13644*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13645*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(false);
13646*6777b538SAndroid Build Coastguard Worker   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13647*6777b538SAndroid Build Coastguard Worker                          transaction.get());
13648*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13649*6777b538SAndroid Build Coastguard Worker 
13650*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13651*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13652*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13653*6777b538SAndroid Build Coastguard Worker 
13654*6777b538SAndroid Build Coastguard Worker   // Verify that OpenEntry failed correctly.
13655*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_FAILURE);
13656*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry1, nullptr);
13657*6777b538SAndroid Build Coastguard Worker   // Verify that the OpenOrCreateEntry requests a restart (CACHE_RACE).
13658*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13659*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry2, nullptr);
13660*6777b538SAndroid Build Coastguard Worker }
13661*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,OpenOrCreateFollowedByCreate)13662*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, OpenOrCreateFollowedByCreate) {
13663*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13664*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13665*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13666*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13667*6777b538SAndroid Build Coastguard Worker 
13668*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13669*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13670*6777b538SAndroid Build Coastguard Worker 
13671*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to OpenOrCreateEntry and
13672*6777b538SAndroid Build Coastguard Worker   // CreateEntry below require that it exists.
13673*6777b538SAndroid Build Coastguard Worker   cache.backend();
13674*6777b538SAndroid Build Coastguard Worker 
13675*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13676*6777b538SAndroid Build Coastguard Worker   // functions.
13677*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13678*6777b538SAndroid Build Coastguard Worker 
13679*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13680*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry2 = nullptr;
13681*6777b538SAndroid Build Coastguard Worker 
13682*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13683*6777b538SAndroid Build Coastguard Worker   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13684*6777b538SAndroid Build Coastguard Worker                              transaction.get());
13685*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13686*6777b538SAndroid Build Coastguard Worker   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13687*6777b538SAndroid Build Coastguard Worker                    transaction.get());
13688*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13689*6777b538SAndroid Build Coastguard Worker 
13690*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13691*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13692*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13693*6777b538SAndroid Build Coastguard Worker 
13694*6777b538SAndroid Build Coastguard Worker   // Verify that the OpenOrCreateEntry succeeded.
13695*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], OK);
13696*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(entry1, nullptr);
13697*6777b538SAndroid Build Coastguard Worker   // Verify that CreateEntry failed.
13698*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13699*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry2, nullptr);
13700*6777b538SAndroid Build Coastguard Worker }
13701*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,OpenOrCreateFollowedByOpenOrCreate)13702*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, OpenOrCreateFollowedByOpenOrCreate) {
13703*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13704*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13705*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13706*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13707*6777b538SAndroid Build Coastguard Worker 
13708*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13709*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13710*6777b538SAndroid Build Coastguard Worker 
13711*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to OpenOrCreateEntry below
13712*6777b538SAndroid Build Coastguard Worker   // require that it exists.
13713*6777b538SAndroid Build Coastguard Worker   cache.backend();
13714*6777b538SAndroid Build Coastguard Worker 
13715*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13716*6777b538SAndroid Build Coastguard Worker   // functions.
13717*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13718*6777b538SAndroid Build Coastguard Worker 
13719*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13720*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry2 = nullptr;
13721*6777b538SAndroid Build Coastguard Worker 
13722*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13723*6777b538SAndroid Build Coastguard Worker   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13724*6777b538SAndroid Build Coastguard Worker                              transaction.get());
13725*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13726*6777b538SAndroid Build Coastguard Worker   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13727*6777b538SAndroid Build Coastguard Worker                          transaction.get());
13728*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13729*6777b538SAndroid Build Coastguard Worker 
13730*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13731*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13732*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13733*6777b538SAndroid Build Coastguard Worker 
13734*6777b538SAndroid Build Coastguard Worker   // Verify that the OpenOrCreateEntry succeeded.
13735*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], OK);
13736*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(entry1, nullptr);
13737*6777b538SAndroid Build Coastguard Worker   // Verify that the other succeeded.
13738*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], OK);
13739*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(entry2, nullptr);
13740*6777b538SAndroid Build Coastguard Worker }
13741*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheIOCallbackTest,FailedOpenOrCreateFollowedByOpenOrCreate)13742*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheIOCallbackTest, FailedOpenOrCreateFollowedByOpenOrCreate) {
13743*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13744*6777b538SAndroid Build Coastguard Worker   TestCompletionCallbackForHttpCache cb;
13745*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Transaction> transaction =
13746*6777b538SAndroid Build Coastguard Worker       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13747*6777b538SAndroid Build Coastguard Worker 
13748*6777b538SAndroid Build Coastguard Worker   transaction->SetIOCallBackForTest(cb.callback());
13749*6777b538SAndroid Build Coastguard Worker   transaction->SetCacheIOCallBackForTest(cb.callback());
13750*6777b538SAndroid Build Coastguard Worker 
13751*6777b538SAndroid Build Coastguard Worker   // Create the backend here as our direct calls to OpenOrCreateEntry below
13752*6777b538SAndroid Build Coastguard Worker   // require that it exists.
13753*6777b538SAndroid Build Coastguard Worker   cache.backend();
13754*6777b538SAndroid Build Coastguard Worker 
13755*6777b538SAndroid Build Coastguard Worker   // Need a mock transaction in order to use some of MockHttpCache's
13756*6777b538SAndroid Build Coastguard Worker   // functions.
13757*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13758*6777b538SAndroid Build Coastguard Worker 
13759*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry1 = nullptr;
13760*6777b538SAndroid Build Coastguard Worker   scoped_refptr<ActiveEntry> entry2 = nullptr;
13761*6777b538SAndroid Build Coastguard Worker 
13762*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(true);
13763*6777b538SAndroid Build Coastguard Worker 
13764*6777b538SAndroid Build Coastguard Worker   // Queue up our operations.
13765*6777b538SAndroid Build Coastguard Worker   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13766*6777b538SAndroid Build Coastguard Worker                              transaction.get());
13767*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13768*6777b538SAndroid Build Coastguard Worker   cache.disk_cache()->set_force_fail_callback_later(false);
13769*6777b538SAndroid Build Coastguard Worker   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13770*6777b538SAndroid Build Coastguard Worker                          transaction.get());
13771*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(rv, ERR_IO_PENDING);
13772*6777b538SAndroid Build Coastguard Worker 
13773*6777b538SAndroid Build Coastguard Worker   // Wait for all the results to arrive.
13774*6777b538SAndroid Build Coastguard Worker   cb.GetResult(rv);
13775*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results().size(), 2u);
13776*6777b538SAndroid Build Coastguard Worker 
13777*6777b538SAndroid Build Coastguard Worker   // Verify that the OpenOrCreateEntry failed.
13778*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_OR_CREATE_FAILURE);
13779*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry1, nullptr);
13780*6777b538SAndroid Build Coastguard Worker   // Verify that the other failed.
13781*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cb.results()[1], ERR_CACHE_OPEN_OR_CREATE_FAILURE);
13782*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(entry2, nullptr);
13783*6777b538SAndroid Build Coastguard Worker }
13784*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,DnsAliasesNoRevalidation)13785*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, DnsAliasesNoRevalidation) {
13786*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13787*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
13788*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13789*6777b538SAndroid Build Coastguard Worker   transaction.dns_aliases = {"alias1", "alias2"};
13790*6777b538SAndroid Build Coastguard Worker 
13791*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13792*6777b538SAndroid Build Coastguard Worker                                      &response);
13793*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
13794*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
13795*6777b538SAndroid Build Coastguard Worker 
13796*6777b538SAndroid Build Coastguard Worker   // The second request result in a cache hit and the response used without
13797*6777b538SAndroid Build Coastguard Worker   // revalidation. Set the transaction alias list to empty to verify that the
13798*6777b538SAndroid Build Coastguard Worker   // cached aliases are being used.
13799*6777b538SAndroid Build Coastguard Worker   transaction.dns_aliases = {};
13800*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13801*6777b538SAndroid Build Coastguard Worker                                      &response);
13802*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
13803*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
13804*6777b538SAndroid Build Coastguard Worker }
13805*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,NoDnsAliasesNoRevalidation)13806*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, NoDnsAliasesNoRevalidation) {
13807*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13808*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
13809*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13810*6777b538SAndroid Build Coastguard Worker   transaction.dns_aliases = {};
13811*6777b538SAndroid Build Coastguard Worker 
13812*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13813*6777b538SAndroid Build Coastguard Worker                                      &response);
13814*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
13815*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.dns_aliases.empty());
13816*6777b538SAndroid Build Coastguard Worker 
13817*6777b538SAndroid Build Coastguard Worker   // The second request should result in a cache hit and the response used
13818*6777b538SAndroid Build Coastguard Worker   // without revalidation. Set the transaction alias list to nonempty to verify
13819*6777b538SAndroid Build Coastguard Worker   // that the cached aliases are being used.
13820*6777b538SAndroid Build Coastguard Worker   transaction.dns_aliases = {"alias"};
13821*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13822*6777b538SAndroid Build Coastguard Worker                                      &response);
13823*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
13824*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.dns_aliases.empty());
13825*6777b538SAndroid Build Coastguard Worker }
13826*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,DnsAliasesRevalidation)13827*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, DnsAliasesRevalidation) {
13828*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13829*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
13830*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kTypicalGET_Transaction);
13831*6777b538SAndroid Build Coastguard Worker   transaction.response_headers =
13832*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
13833*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
13834*6777b538SAndroid Build Coastguard Worker       "Cache-Control: max-age=0\n";
13835*6777b538SAndroid Build Coastguard Worker   transaction.dns_aliases = {"alias1", "alias2"};
13836*6777b538SAndroid Build Coastguard Worker 
13837*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13838*6777b538SAndroid Build Coastguard Worker                                      &response);
13839*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
13840*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
13841*6777b538SAndroid Build Coastguard Worker 
13842*6777b538SAndroid Build Coastguard Worker   // On the second request, the cache should be revalidated. Change the aliases
13843*6777b538SAndroid Build Coastguard Worker   // to be sure that the new aliases are being used, and have the response be
13844*6777b538SAndroid Build Coastguard Worker   // cached for next time.
13845*6777b538SAndroid Build Coastguard Worker   transaction.response_headers = "Cache-Control: max-age=10000\n";
13846*6777b538SAndroid Build Coastguard Worker   transaction.dns_aliases = {"alias3", "alias4"};
13847*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13848*6777b538SAndroid Build Coastguard Worker                                      &response);
13849*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
13850*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias3", "alias4"));
13851*6777b538SAndroid Build Coastguard Worker 
13852*6777b538SAndroid Build Coastguard Worker   transaction.dns_aliases = {"alias5", "alias6"};
13853*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13854*6777b538SAndroid Build Coastguard Worker                                      &response);
13855*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
13856*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias3", "alias4"));
13857*6777b538SAndroid Build Coastguard Worker }
13858*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldBypass_NoId)13859*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldBypass_NoId) {
13860*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13861*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
13862*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13863*6777b538SAndroid Build Coastguard Worker 
13864*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13865*6777b538SAndroid Build Coastguard Worker                                      &response);
13866*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
13867*6777b538SAndroid Build Coastguard Worker 
13868*6777b538SAndroid Build Coastguard Worker   transaction.fps_cache_filter = {5};
13869*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13870*6777b538SAndroid Build Coastguard Worker                                      &response);
13871*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
13872*6777b538SAndroid Build Coastguard Worker }
13873*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldBypass_IdTooSmall)13874*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldBypass_IdTooSmall) {
13875*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13876*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
13877*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13878*6777b538SAndroid Build Coastguard Worker   const int64_t kBrowserRunId = 4;
13879*6777b538SAndroid Build Coastguard Worker   transaction.browser_run_id = {kBrowserRunId};
13880*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13881*6777b538SAndroid Build Coastguard Worker                                      &response);
13882*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
13883*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.browser_run_id.has_value());
13884*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kBrowserRunId, response.browser_run_id.value());
13885*6777b538SAndroid Build Coastguard Worker 
13886*6777b538SAndroid Build Coastguard Worker   transaction.fps_cache_filter = {5};
13887*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13888*6777b538SAndroid Build Coastguard Worker                                      &response);
13889*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
13890*6777b538SAndroid Build Coastguard Worker }
13891*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldNotBypass)13892*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldNotBypass) {
13893*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13894*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
13895*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13896*6777b538SAndroid Build Coastguard Worker   const int64_t kBrowserRunId = 5;
13897*6777b538SAndroid Build Coastguard Worker   transaction.browser_run_id = {kBrowserRunId};
13898*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13899*6777b538SAndroid Build Coastguard Worker                                      &response);
13900*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
13901*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.browser_run_id.has_value());
13902*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kBrowserRunId, response.browser_run_id.value());
13903*6777b538SAndroid Build Coastguard Worker 
13904*6777b538SAndroid Build Coastguard Worker   transaction.fps_cache_filter = {5};
13905*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13906*6777b538SAndroid Build Coastguard Worker                                      &response);
13907*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
13908*6777b538SAndroid Build Coastguard Worker }
13909*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldNotBypass_NoFilter)13910*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldNotBypass_NoFilter) {
13911*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13912*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
13913*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13914*6777b538SAndroid Build Coastguard Worker 
13915*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13916*6777b538SAndroid Build Coastguard Worker                                      &response);
13917*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(response.was_cached);
13918*6777b538SAndroid Build Coastguard Worker 
13919*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13920*6777b538SAndroid Build Coastguard Worker                                      &response);
13921*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(response.was_cached);
13922*6777b538SAndroid Build Coastguard Worker }
13923*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpCacheTest,SecurityHeadersAreCopiedToConditionalizedResponse)13924*6777b538SAndroid Build Coastguard Worker TEST_F(HttpCacheTest, SecurityHeadersAreCopiedToConditionalizedResponse) {
13925*6777b538SAndroid Build Coastguard Worker   MockHttpCache cache;
13926*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response;
13927*6777b538SAndroid Build Coastguard Worker   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13928*6777b538SAndroid Build Coastguard Worker 
13929*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse1 = {
13930*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 200 OK",
13931*6777b538SAndroid Build Coastguard Worker       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
13932*6777b538SAndroid Build Coastguard Worker       "Server: server1\n"
13933*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n"
13934*6777b538SAndroid Build Coastguard Worker       "Cross-Origin-Resource-Policy: cross-origin\n",
13935*6777b538SAndroid Build Coastguard Worker       "body1"};
13936*6777b538SAndroid Build Coastguard Worker 
13937*6777b538SAndroid Build Coastguard Worker   static const Response kNetResponse2 = {
13938*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 304 Not Modified",
13939*6777b538SAndroid Build Coastguard Worker       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
13940*6777b538SAndroid Build Coastguard Worker       "Server: server2\n"
13941*6777b538SAndroid Build Coastguard Worker       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
13942*6777b538SAndroid Build Coastguard Worker       ""};
13943*6777b538SAndroid Build Coastguard Worker 
13944*6777b538SAndroid Build Coastguard Worker   kNetResponse1.AssignTo(&transaction);
13945*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13946*6777b538SAndroid Build Coastguard Worker                                      &response);
13947*6777b538SAndroid Build Coastguard Worker 
13948*6777b538SAndroid Build Coastguard Worker   // On the second request, the cache is revalidated.
13949*6777b538SAndroid Build Coastguard Worker   const char kExtraRequestHeaders[] =
13950*6777b538SAndroid Build Coastguard Worker       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
13951*6777b538SAndroid Build Coastguard Worker   transaction.request_headers = kExtraRequestHeaders;
13952*6777b538SAndroid Build Coastguard Worker   kNetResponse2.AssignTo(&transaction);
13953*6777b538SAndroid Build Coastguard Worker   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13954*6777b538SAndroid Build Coastguard Worker                                      &response);
13955*6777b538SAndroid Build Coastguard Worker 
13956*6777b538SAndroid Build Coastguard Worker   // Verify that the CORP header was carried over to the response.
13957*6777b538SAndroid Build Coastguard Worker   std::string response_corp_header;
13958*6777b538SAndroid Build Coastguard Worker   response.headers->GetNormalizedHeader("Cross-Origin-Resource-Policy",
13959*6777b538SAndroid Build Coastguard Worker                                         &response_corp_header);
13960*6777b538SAndroid Build Coastguard Worker 
13961*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(304, response.headers->response_code());
13962*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("cross-origin", response_corp_header);
13963*6777b538SAndroid Build Coastguard Worker }
13964*6777b538SAndroid Build Coastguard Worker 
13965*6777b538SAndroid Build Coastguard Worker }  // namespace net
13966