xref: /aosp_15_r20/external/cronet/net/disk_cache/entry_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 <utility>
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/files/file.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/metrics/field_trial.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/metrics/field_trial_param_associator.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/test/metrics/histogram_tester.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
20*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
21*6777b538SAndroid Build Coastguard Worker #include "net/base/completion_once_callback.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/base/io_buffer.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/base/request_priority.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/base/test_completion_callback.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/blockfile/backend_impl.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/blockfile/entry_impl.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/cache_util.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/disk_cache_test_base.h"
30*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/disk_cache_test_util.h"
31*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/memory/mem_entry_impl.h"
32*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/simple/simple_backend_impl.h"
33*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/simple/simple_entry_format.h"
34*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/simple/simple_entry_impl.h"
35*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/simple/simple_histogram_enums.h"
36*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/simple/simple_synchronous_entry.h"
37*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/simple/simple_test_util.h"
38*6777b538SAndroid Build Coastguard Worker #include "net/disk_cache/simple/simple_util.h"
39*6777b538SAndroid Build Coastguard Worker #include "net/test/gtest_util.h"
40*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
41*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker using net::test::IsError;
44*6777b538SAndroid Build Coastguard Worker using net::test::IsOk;
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker using base::Time;
47*6777b538SAndroid Build Coastguard Worker using disk_cache::EntryResult;
48*6777b538SAndroid Build Coastguard Worker using disk_cache::EntryResultCallback;
49*6777b538SAndroid Build Coastguard Worker using disk_cache::RangeResult;
50*6777b538SAndroid Build Coastguard Worker using disk_cache::ScopedEntryPtr;
51*6777b538SAndroid Build Coastguard Worker 
52*6777b538SAndroid Build Coastguard Worker // Tests that can run with different types of caches.
53*6777b538SAndroid Build Coastguard Worker class DiskCacheEntryTest : public DiskCacheTestWithCache {
54*6777b538SAndroid Build Coastguard Worker  public:
55*6777b538SAndroid Build Coastguard Worker   void InternalSyncIOBackground(disk_cache::Entry* entry);
56*6777b538SAndroid Build Coastguard Worker   void ExternalSyncIOBackground(disk_cache::Entry* entry);
57*6777b538SAndroid Build Coastguard Worker 
58*6777b538SAndroid Build Coastguard Worker  protected:
59*6777b538SAndroid Build Coastguard Worker   void InternalSyncIO();
60*6777b538SAndroid Build Coastguard Worker   void InternalAsyncIO();
61*6777b538SAndroid Build Coastguard Worker   void ExternalSyncIO();
62*6777b538SAndroid Build Coastguard Worker   void ExternalAsyncIO();
63*6777b538SAndroid Build Coastguard Worker   void ReleaseBuffer(int stream_index);
64*6777b538SAndroid Build Coastguard Worker   void StreamAccess();
65*6777b538SAndroid Build Coastguard Worker   void GetKey();
66*6777b538SAndroid Build Coastguard Worker   void GetTimes(int stream_index);
67*6777b538SAndroid Build Coastguard Worker   void GrowData(int stream_index);
68*6777b538SAndroid Build Coastguard Worker   void TruncateData(int stream_index);
69*6777b538SAndroid Build Coastguard Worker   void ZeroLengthIO(int stream_index);
70*6777b538SAndroid Build Coastguard Worker   void Buffering();
71*6777b538SAndroid Build Coastguard Worker   void SizeAtCreate();
72*6777b538SAndroid Build Coastguard Worker   void SizeChanges(int stream_index);
73*6777b538SAndroid Build Coastguard Worker   void ReuseEntry(int size, int stream_index);
74*6777b538SAndroid Build Coastguard Worker   void InvalidData(int stream_index);
75*6777b538SAndroid Build Coastguard Worker   void ReadWriteDestroyBuffer(int stream_index);
76*6777b538SAndroid Build Coastguard Worker   void DoomNormalEntry();
77*6777b538SAndroid Build Coastguard Worker   void DoomEntryNextToOpenEntry();
78*6777b538SAndroid Build Coastguard Worker   void DoomedEntry(int stream_index);
79*6777b538SAndroid Build Coastguard Worker   void BasicSparseIO();
80*6777b538SAndroid Build Coastguard Worker   void HugeSparseIO();
81*6777b538SAndroid Build Coastguard Worker   void GetAvailableRangeTest();
82*6777b538SAndroid Build Coastguard Worker   void CouldBeSparse();
83*6777b538SAndroid Build Coastguard Worker   void UpdateSparseEntry();
84*6777b538SAndroid Build Coastguard Worker   void DoomSparseEntry();
85*6777b538SAndroid Build Coastguard Worker   void PartialSparseEntry();
86*6777b538SAndroid Build Coastguard Worker   void SparseInvalidArg();
87*6777b538SAndroid Build Coastguard Worker   void SparseClipEnd(int64_t max_index, bool expected_unsupported);
88*6777b538SAndroid Build Coastguard Worker   bool SimpleCacheMakeBadChecksumEntry(const std::string& key, int data_size);
89*6777b538SAndroid Build Coastguard Worker   bool SimpleCacheThirdStreamFileExists(const char* key);
90*6777b538SAndroid Build Coastguard Worker   void SyncDoomEntry(const char* key);
91*6777b538SAndroid Build Coastguard Worker   void CreateEntryWithHeaderBodyAndSideData(const std::string& key,
92*6777b538SAndroid Build Coastguard Worker                                             int data_size);
93*6777b538SAndroid Build Coastguard Worker   void TruncateFileFromEnd(int file_index,
94*6777b538SAndroid Build Coastguard Worker                            const std::string& key,
95*6777b538SAndroid Build Coastguard Worker                            int data_size,
96*6777b538SAndroid Build Coastguard Worker                            int truncate_size);
97*6777b538SAndroid Build Coastguard Worker   void UseAfterBackendDestruction();
98*6777b538SAndroid Build Coastguard Worker   void CloseSparseAfterBackendDestruction();
99*6777b538SAndroid Build Coastguard Worker   void LastUsedTimePersists();
100*6777b538SAndroid Build Coastguard Worker   void TruncateBackwards();
101*6777b538SAndroid Build Coastguard Worker   void ZeroWriteBackwards();
102*6777b538SAndroid Build Coastguard Worker   void SparseOffset64Bit();
103*6777b538SAndroid Build Coastguard Worker };
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker // This part of the test runs on the background thread.
InternalSyncIOBackground(disk_cache::Entry * entry)106*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::InternalSyncIOBackground(disk_cache::Entry* entry) {
107*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 10;
108*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
109*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
110*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, entry->ReadData(0, 0, buffer1.get(), kSize1,
111*6777b538SAndroid Build Coastguard Worker                                net::CompletionOnceCallback()));
112*6777b538SAndroid Build Coastguard Worker   base::strlcpy(buffer1->data(), "the data", kSize1);
113*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, entry->WriteData(0, 0, buffer1.get(), kSize1,
114*6777b538SAndroid Build Coastguard Worker                                  net::CompletionOnceCallback(), false));
115*6777b538SAndroid Build Coastguard Worker   memset(buffer1->data(), 0, kSize1);
116*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, entry->ReadData(0, 0, buffer1.get(), kSize1,
117*6777b538SAndroid Build Coastguard Worker                                 net::CompletionOnceCallback()));
118*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("the data", buffer1->data());
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker   const int kSize2 = 5000;
121*6777b538SAndroid Build Coastguard Worker   const int kSize3 = 10000;
122*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize2);
123*6777b538SAndroid Build Coastguard Worker   auto buffer3 = base::MakeRefCounted<net::IOBufferWithSize>(kSize3);
124*6777b538SAndroid Build Coastguard Worker   memset(buffer3->data(), 0, kSize3);
125*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize2, false);
126*6777b538SAndroid Build Coastguard Worker   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
127*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5000, entry->WriteData(1, 1500, buffer2.get(), kSize2,
128*6777b538SAndroid Build Coastguard Worker                                    net::CompletionOnceCallback(), false));
129*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize2);
130*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4989, entry->ReadData(1, 1511, buffer2.get(), kSize2,
131*6777b538SAndroid Build Coastguard Worker                                   net::CompletionOnceCallback()));
132*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("big data goes here", buffer2->data());
133*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5000, entry->ReadData(1, 0, buffer2.get(), kSize2,
134*6777b538SAndroid Build Coastguard Worker                                   net::CompletionOnceCallback()));
135*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 1500));
136*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1500, entry->ReadData(1, 5000, buffer2.get(), kSize2,
137*6777b538SAndroid Build Coastguard Worker                                   net::CompletionOnceCallback()));
138*6777b538SAndroid Build Coastguard Worker 
139*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, entry->ReadData(1, 6500, buffer2.get(), kSize2,
140*6777b538SAndroid Build Coastguard Worker                                net::CompletionOnceCallback()));
141*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(6500, entry->ReadData(1, 0, buffer3.get(), kSize3,
142*6777b538SAndroid Build Coastguard Worker                                   net::CompletionOnceCallback()));
143*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(8192, entry->WriteData(1, 0, buffer3.get(), 8192,
144*6777b538SAndroid Build Coastguard Worker                                    net::CompletionOnceCallback(), false));
145*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(8192, entry->ReadData(1, 0, buffer3.get(), kSize3,
146*6777b538SAndroid Build Coastguard Worker                                   net::CompletionOnceCallback()));
147*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(8192, entry->GetDataSize(1));
148*6777b538SAndroid Build Coastguard Worker 
149*6777b538SAndroid Build Coastguard Worker   // We need to delete the memory buffer on this thread.
150*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, entry->WriteData(0, 0, nullptr, 0, net::CompletionOnceCallback(),
151*6777b538SAndroid Build Coastguard Worker                                 true));
152*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, entry->WriteData(1, 0, nullptr, 0, net::CompletionOnceCallback(),
153*6777b538SAndroid Build Coastguard Worker                                 true));
154*6777b538SAndroid Build Coastguard Worker }
155*6777b538SAndroid Build Coastguard Worker 
156*6777b538SAndroid Build Coastguard Worker // We need to support synchronous IO even though it is not a supported operation
157*6777b538SAndroid Build Coastguard Worker // from the point of view of the disk cache's public interface, because we use
158*6777b538SAndroid Build Coastguard Worker // it internally, not just by a few tests, but as part of the implementation
159*6777b538SAndroid Build Coastguard Worker // (see sparse_control.cc, for example).
InternalSyncIO()160*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::InternalSyncIO() {
161*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
162*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("the first key", &entry), IsOk());
163*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(nullptr != entry);
164*6777b538SAndroid Build Coastguard Worker 
165*6777b538SAndroid Build Coastguard Worker   // The bulk of the test runs from within the callback, on the cache thread.
166*6777b538SAndroid Build Coastguard Worker   RunTaskForTest(base::BindOnce(&DiskCacheEntryTest::InternalSyncIOBackground,
167*6777b538SAndroid Build Coastguard Worker                                 base::Unretained(this), entry));
168*6777b538SAndroid Build Coastguard Worker 
169*6777b538SAndroid Build Coastguard Worker   entry->Doom();
170*6777b538SAndroid Build Coastguard Worker   entry->Close();
171*6777b538SAndroid Build Coastguard Worker   FlushQueueForTest();
172*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache_->GetEntryCount());
173*6777b538SAndroid Build Coastguard Worker }
174*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,InternalSyncIO)175*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, InternalSyncIO) {
176*6777b538SAndroid Build Coastguard Worker   InitCache();
177*6777b538SAndroid Build Coastguard Worker   InternalSyncIO();
178*6777b538SAndroid Build Coastguard Worker }
179*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyInternalSyncIO)180*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyInternalSyncIO) {
181*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
182*6777b538SAndroid Build Coastguard Worker   InitCache();
183*6777b538SAndroid Build Coastguard Worker   InternalSyncIO();
184*6777b538SAndroid Build Coastguard Worker }
185*6777b538SAndroid Build Coastguard Worker 
InternalAsyncIO()186*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::InternalAsyncIO() {
187*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
188*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("the first key", &entry), IsOk());
189*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(nullptr != entry);
190*6777b538SAndroid Build Coastguard Worker 
191*6777b538SAndroid Build Coastguard Worker   // Avoid using internal buffers for the test. We have to write something to
192*6777b538SAndroid Build Coastguard Worker   // the entry and close it so that we flush the internal buffer to disk. After
193*6777b538SAndroid Build Coastguard Worker   // that, IO operations will be really hitting the disk. We don't care about
194*6777b538SAndroid Build Coastguard Worker   // the content, so just extending the entry is enough (all extensions zero-
195*6777b538SAndroid Build Coastguard Worker   // fill any holes).
196*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, 0, 15 * 1024, nullptr, 0, false));
197*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, 1, 15 * 1024, nullptr, 0, false));
198*6777b538SAndroid Build Coastguard Worker   entry->Close();
199*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry("the first key", &entry), IsOk());
200*6777b538SAndroid Build Coastguard Worker 
201*6777b538SAndroid Build Coastguard Worker   MessageLoopHelper helper;
202*6777b538SAndroid Build Coastguard Worker   // Let's verify that each IO goes to the right callback object.
203*6777b538SAndroid Build Coastguard Worker   CallbackTest callback1(&helper, false);
204*6777b538SAndroid Build Coastguard Worker   CallbackTest callback2(&helper, false);
205*6777b538SAndroid Build Coastguard Worker   CallbackTest callback3(&helper, false);
206*6777b538SAndroid Build Coastguard Worker   CallbackTest callback4(&helper, false);
207*6777b538SAndroid Build Coastguard Worker   CallbackTest callback5(&helper, false);
208*6777b538SAndroid Build Coastguard Worker   CallbackTest callback6(&helper, false);
209*6777b538SAndroid Build Coastguard Worker   CallbackTest callback7(&helper, false);
210*6777b538SAndroid Build Coastguard Worker   CallbackTest callback8(&helper, false);
211*6777b538SAndroid Build Coastguard Worker   CallbackTest callback9(&helper, false);
212*6777b538SAndroid Build Coastguard Worker   CallbackTest callback10(&helper, false);
213*6777b538SAndroid Build Coastguard Worker   CallbackTest callback11(&helper, false);
214*6777b538SAndroid Build Coastguard Worker   CallbackTest callback12(&helper, false);
215*6777b538SAndroid Build Coastguard Worker   CallbackTest callback13(&helper, false);
216*6777b538SAndroid Build Coastguard Worker 
217*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 10;
218*6777b538SAndroid Build Coastguard Worker   const int kSize2 = 5000;
219*6777b538SAndroid Build Coastguard Worker   const int kSize3 = 10000;
220*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
221*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize2);
222*6777b538SAndroid Build Coastguard Worker   auto buffer3 = base::MakeRefCounted<net::IOBufferWithSize>(kSize3);
223*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
224*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize2, false);
225*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer3->data(), kSize3, false);
226*6777b538SAndroid Build Coastguard Worker 
227*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, entry->ReadData(0, 15 * 1024, buffer1.get(), kSize1,
228*6777b538SAndroid Build Coastguard Worker                                base::BindOnce(&CallbackTest::Run,
229*6777b538SAndroid Build Coastguard Worker                                               base::Unretained(&callback1))));
230*6777b538SAndroid Build Coastguard Worker   base::strlcpy(buffer1->data(), "the data", kSize1);
231*6777b538SAndroid Build Coastguard Worker   int expected = 0;
232*6777b538SAndroid Build Coastguard Worker   int ret = entry->WriteData(
233*6777b538SAndroid Build Coastguard Worker       0, 0, buffer1.get(), kSize1,
234*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback2)), false);
235*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
236*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
237*6777b538SAndroid Build Coastguard Worker     expected++;
238*6777b538SAndroid Build Coastguard Worker 
239*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
240*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize2);
241*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
242*6777b538SAndroid Build Coastguard Worker       0, 0, buffer2.get(), kSize1,
243*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback3)));
244*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
245*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
246*6777b538SAndroid Build Coastguard Worker     expected++;
247*6777b538SAndroid Build Coastguard Worker 
248*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
249*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("the data", buffer2->data());
250*6777b538SAndroid Build Coastguard Worker 
251*6777b538SAndroid Build Coastguard Worker   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
252*6777b538SAndroid Build Coastguard Worker   ret = entry->WriteData(
253*6777b538SAndroid Build Coastguard Worker       1, 1500, buffer2.get(), kSize2,
254*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback4)), true);
255*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
256*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
257*6777b538SAndroid Build Coastguard Worker     expected++;
258*6777b538SAndroid Build Coastguard Worker 
259*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
260*6777b538SAndroid Build Coastguard Worker   memset(buffer3->data(), 0, kSize3);
261*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
262*6777b538SAndroid Build Coastguard Worker       1, 1511, buffer3.get(), kSize2,
263*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback5)));
264*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(4989 == ret || net::ERR_IO_PENDING == ret);
265*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
266*6777b538SAndroid Build Coastguard Worker     expected++;
267*6777b538SAndroid Build Coastguard Worker 
268*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
269*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("big data goes here", buffer3->data());
270*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
271*6777b538SAndroid Build Coastguard Worker       1, 0, buffer2.get(), kSize2,
272*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback6)));
273*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
274*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
275*6777b538SAndroid Build Coastguard Worker     expected++;
276*6777b538SAndroid Build Coastguard Worker 
277*6777b538SAndroid Build Coastguard Worker   memset(buffer3->data(), 0, kSize3);
278*6777b538SAndroid Build Coastguard Worker 
279*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
280*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 1500));
281*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
282*6777b538SAndroid Build Coastguard Worker       1, 5000, buffer2.get(), kSize2,
283*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback7)));
284*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(1500 == ret || net::ERR_IO_PENDING == ret);
285*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
286*6777b538SAndroid Build Coastguard Worker     expected++;
287*6777b538SAndroid Build Coastguard Worker 
288*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
289*6777b538SAndroid Build Coastguard Worker       1, 0, buffer3.get(), kSize3,
290*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback9)));
291*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(6500 == ret || net::ERR_IO_PENDING == ret);
292*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
293*6777b538SAndroid Build Coastguard Worker     expected++;
294*6777b538SAndroid Build Coastguard Worker 
295*6777b538SAndroid Build Coastguard Worker   ret = entry->WriteData(
296*6777b538SAndroid Build Coastguard Worker       1, 0, buffer3.get(), 8192,
297*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback10)), true);
298*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(8192 == ret || net::ERR_IO_PENDING == ret);
299*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
300*6777b538SAndroid Build Coastguard Worker     expected++;
301*6777b538SAndroid Build Coastguard Worker 
302*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
303*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
304*6777b538SAndroid Build Coastguard Worker       1, 0, buffer3.get(), kSize3,
305*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback11)));
306*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(8192 == ret || net::ERR_IO_PENDING == ret);
307*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
308*6777b538SAndroid Build Coastguard Worker     expected++;
309*6777b538SAndroid Build Coastguard Worker 
310*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(8192, entry->GetDataSize(1));
311*6777b538SAndroid Build Coastguard Worker 
312*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
313*6777b538SAndroid Build Coastguard Worker       0, 0, buffer1.get(), kSize1,
314*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback12)));
315*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
316*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
317*6777b538SAndroid Build Coastguard Worker     expected++;
318*6777b538SAndroid Build Coastguard Worker 
319*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
320*6777b538SAndroid Build Coastguard Worker       1, 0, buffer2.get(), kSize2,
321*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback13)));
322*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
323*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
324*6777b538SAndroid Build Coastguard Worker     expected++;
325*6777b538SAndroid Build Coastguard Worker 
326*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
327*6777b538SAndroid Build Coastguard Worker 
328*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(helper.callback_reused_error());
329*6777b538SAndroid Build Coastguard Worker 
330*6777b538SAndroid Build Coastguard Worker   entry->Doom();
331*6777b538SAndroid Build Coastguard Worker   entry->Close();
332*6777b538SAndroid Build Coastguard Worker   FlushQueueForTest();
333*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache_->GetEntryCount());
334*6777b538SAndroid Build Coastguard Worker }
335*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,InternalAsyncIO)336*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, InternalAsyncIO) {
337*6777b538SAndroid Build Coastguard Worker   InitCache();
338*6777b538SAndroid Build Coastguard Worker   InternalAsyncIO();
339*6777b538SAndroid Build Coastguard Worker }
340*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyInternalAsyncIO)341*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyInternalAsyncIO) {
342*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
343*6777b538SAndroid Build Coastguard Worker   InitCache();
344*6777b538SAndroid Build Coastguard Worker   InternalAsyncIO();
345*6777b538SAndroid Build Coastguard Worker }
346*6777b538SAndroid Build Coastguard Worker 
347*6777b538SAndroid Build Coastguard Worker // This part of the test runs on the background thread.
ExternalSyncIOBackground(disk_cache::Entry * entry)348*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::ExternalSyncIOBackground(disk_cache::Entry* entry) {
349*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 17000;
350*6777b538SAndroid Build Coastguard Worker   const int kSize2 = 25000;
351*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
352*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize2);
353*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
354*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize2, false);
355*6777b538SAndroid Build Coastguard Worker   base::strlcpy(buffer1->data(), "the data", kSize1);
356*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(17000, entry->WriteData(0, 0, buffer1.get(), kSize1,
357*6777b538SAndroid Build Coastguard Worker                                     net::CompletionOnceCallback(), false));
358*6777b538SAndroid Build Coastguard Worker   memset(buffer1->data(), 0, kSize1);
359*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(17000, entry->ReadData(0, 0, buffer1.get(), kSize1,
360*6777b538SAndroid Build Coastguard Worker                                    net::CompletionOnceCallback()));
361*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("the data", buffer1->data());
362*6777b538SAndroid Build Coastguard Worker 
363*6777b538SAndroid Build Coastguard Worker   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
364*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(25000, entry->WriteData(1, 10000, buffer2.get(), kSize2,
365*6777b538SAndroid Build Coastguard Worker                                     net::CompletionOnceCallback(), false));
366*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize2);
367*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(24989, entry->ReadData(1, 10011, buffer2.get(), kSize2,
368*6777b538SAndroid Build Coastguard Worker                                    net::CompletionOnceCallback()));
369*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("big data goes here", buffer2->data());
370*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(25000, entry->ReadData(1, 0, buffer2.get(), kSize2,
371*6777b538SAndroid Build Coastguard Worker                                    net::CompletionOnceCallback()));
372*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5000, entry->ReadData(1, 30000, buffer2.get(), kSize2,
373*6777b538SAndroid Build Coastguard Worker                                   net::CompletionOnceCallback()));
374*6777b538SAndroid Build Coastguard Worker 
375*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, entry->ReadData(1, 35000, buffer2.get(), kSize2,
376*6777b538SAndroid Build Coastguard Worker                                net::CompletionOnceCallback()));
377*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(17000, entry->ReadData(1, 0, buffer1.get(), kSize1,
378*6777b538SAndroid Build Coastguard Worker                                    net::CompletionOnceCallback()));
379*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(17000, entry->WriteData(1, 20000, buffer1.get(), kSize1,
380*6777b538SAndroid Build Coastguard Worker                                     net::CompletionOnceCallback(), false));
381*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(37000, entry->GetDataSize(1));
382*6777b538SAndroid Build Coastguard Worker 
383*6777b538SAndroid Build Coastguard Worker   // We need to delete the memory buffer on this thread.
384*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, entry->WriteData(0, 0, nullptr, 0, net::CompletionOnceCallback(),
385*6777b538SAndroid Build Coastguard Worker                                 true));
386*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, entry->WriteData(1, 0, nullptr, 0, net::CompletionOnceCallback(),
387*6777b538SAndroid Build Coastguard Worker                                 true));
388*6777b538SAndroid Build Coastguard Worker }
389*6777b538SAndroid Build Coastguard Worker 
ExternalSyncIO()390*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::ExternalSyncIO() {
391*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
392*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("the first key", &entry), IsOk());
393*6777b538SAndroid Build Coastguard Worker 
394*6777b538SAndroid Build Coastguard Worker   // The bulk of the test runs from within the callback, on the cache thread.
395*6777b538SAndroid Build Coastguard Worker   RunTaskForTest(base::BindOnce(&DiskCacheEntryTest::ExternalSyncIOBackground,
396*6777b538SAndroid Build Coastguard Worker                                 base::Unretained(this), entry));
397*6777b538SAndroid Build Coastguard Worker 
398*6777b538SAndroid Build Coastguard Worker   entry->Doom();
399*6777b538SAndroid Build Coastguard Worker   entry->Close();
400*6777b538SAndroid Build Coastguard Worker   FlushQueueForTest();
401*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache_->GetEntryCount());
402*6777b538SAndroid Build Coastguard Worker }
403*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,ExternalSyncIO)404*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, ExternalSyncIO) {
405*6777b538SAndroid Build Coastguard Worker   InitCache();
406*6777b538SAndroid Build Coastguard Worker   ExternalSyncIO();
407*6777b538SAndroid Build Coastguard Worker }
408*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,ExternalSyncIONoBuffer)409*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, ExternalSyncIONoBuffer) {
410*6777b538SAndroid Build Coastguard Worker   InitCache();
411*6777b538SAndroid Build Coastguard Worker   cache_impl_->SetFlags(disk_cache::kNoBuffering);
412*6777b538SAndroid Build Coastguard Worker   ExternalSyncIO();
413*6777b538SAndroid Build Coastguard Worker }
414*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyExternalSyncIO)415*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyExternalSyncIO) {
416*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
417*6777b538SAndroid Build Coastguard Worker   InitCache();
418*6777b538SAndroid Build Coastguard Worker   ExternalSyncIO();
419*6777b538SAndroid Build Coastguard Worker }
420*6777b538SAndroid Build Coastguard Worker 
ExternalAsyncIO()421*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::ExternalAsyncIO() {
422*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
423*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("the first key", &entry), IsOk());
424*6777b538SAndroid Build Coastguard Worker 
425*6777b538SAndroid Build Coastguard Worker   int expected = 0;
426*6777b538SAndroid Build Coastguard Worker 
427*6777b538SAndroid Build Coastguard Worker   MessageLoopHelper helper;
428*6777b538SAndroid Build Coastguard Worker   // Let's verify that each IO goes to the right callback object.
429*6777b538SAndroid Build Coastguard Worker   CallbackTest callback1(&helper, false);
430*6777b538SAndroid Build Coastguard Worker   CallbackTest callback2(&helper, false);
431*6777b538SAndroid Build Coastguard Worker   CallbackTest callback3(&helper, false);
432*6777b538SAndroid Build Coastguard Worker   CallbackTest callback4(&helper, false);
433*6777b538SAndroid Build Coastguard Worker   CallbackTest callback5(&helper, false);
434*6777b538SAndroid Build Coastguard Worker   CallbackTest callback6(&helper, false);
435*6777b538SAndroid Build Coastguard Worker   CallbackTest callback7(&helper, false);
436*6777b538SAndroid Build Coastguard Worker   CallbackTest callback8(&helper, false);
437*6777b538SAndroid Build Coastguard Worker   CallbackTest callback9(&helper, false);
438*6777b538SAndroid Build Coastguard Worker 
439*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 17000;
440*6777b538SAndroid Build Coastguard Worker   const int kSize2 = 25000;
441*6777b538SAndroid Build Coastguard Worker   const int kSize3 = 25000;
442*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
443*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize2);
444*6777b538SAndroid Build Coastguard Worker   auto buffer3 = base::MakeRefCounted<net::IOBufferWithSize>(kSize3);
445*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
446*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize2, false);
447*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer3->data(), kSize3, false);
448*6777b538SAndroid Build Coastguard Worker   base::strlcpy(buffer1->data(), "the data", kSize1);
449*6777b538SAndroid Build Coastguard Worker   int ret = entry->WriteData(
450*6777b538SAndroid Build Coastguard Worker       0, 0, buffer1.get(), kSize1,
451*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback1)), false);
452*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
453*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
454*6777b538SAndroid Build Coastguard Worker     expected++;
455*6777b538SAndroid Build Coastguard Worker 
456*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
457*6777b538SAndroid Build Coastguard Worker 
458*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize1);
459*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
460*6777b538SAndroid Build Coastguard Worker       0, 0, buffer2.get(), kSize1,
461*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback2)));
462*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
463*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
464*6777b538SAndroid Build Coastguard Worker     expected++;
465*6777b538SAndroid Build Coastguard Worker 
466*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
467*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("the data", buffer2->data());
468*6777b538SAndroid Build Coastguard Worker 
469*6777b538SAndroid Build Coastguard Worker   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
470*6777b538SAndroid Build Coastguard Worker   ret = entry->WriteData(
471*6777b538SAndroid Build Coastguard Worker       1, 10000, buffer2.get(), kSize2,
472*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback3)), false);
473*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(25000 == ret || net::ERR_IO_PENDING == ret);
474*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
475*6777b538SAndroid Build Coastguard Worker     expected++;
476*6777b538SAndroid Build Coastguard Worker 
477*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
478*6777b538SAndroid Build Coastguard Worker 
479*6777b538SAndroid Build Coastguard Worker   memset(buffer3->data(), 0, kSize3);
480*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
481*6777b538SAndroid Build Coastguard Worker       1, 10011, buffer3.get(), kSize3,
482*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback4)));
483*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(24989 == ret || net::ERR_IO_PENDING == ret);
484*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
485*6777b538SAndroid Build Coastguard Worker     expected++;
486*6777b538SAndroid Build Coastguard Worker 
487*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
488*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("big data goes here", buffer3->data());
489*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
490*6777b538SAndroid Build Coastguard Worker       1, 0, buffer2.get(), kSize2,
491*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback5)));
492*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(25000 == ret || net::ERR_IO_PENDING == ret);
493*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
494*6777b538SAndroid Build Coastguard Worker     expected++;
495*6777b538SAndroid Build Coastguard Worker 
496*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
497*6777b538SAndroid Build Coastguard Worker   memset(buffer3->data(), 0, kSize3);
498*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 10000));
499*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
500*6777b538SAndroid Build Coastguard Worker       1, 30000, buffer2.get(), kSize2,
501*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback6)));
502*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
503*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
504*6777b538SAndroid Build Coastguard Worker     expected++;
505*6777b538SAndroid Build Coastguard Worker 
506*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
507*6777b538SAndroid Build Coastguard Worker       1, 35000, buffer2.get(), kSize2,
508*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback7)));
509*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(0 == ret || net::ERR_IO_PENDING == ret);
510*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
511*6777b538SAndroid Build Coastguard Worker     expected++;
512*6777b538SAndroid Build Coastguard Worker 
513*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
514*6777b538SAndroid Build Coastguard Worker       1, 0, buffer1.get(), kSize1,
515*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback8)));
516*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
517*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
518*6777b538SAndroid Build Coastguard Worker     expected++;
519*6777b538SAndroid Build Coastguard Worker   ret = entry->WriteData(
520*6777b538SAndroid Build Coastguard Worker       1, 20000, buffer3.get(), kSize1,
521*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback9)), false);
522*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
523*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
524*6777b538SAndroid Build Coastguard Worker     expected++;
525*6777b538SAndroid Build Coastguard Worker 
526*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
527*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(37000, entry->GetDataSize(1));
528*6777b538SAndroid Build Coastguard Worker 
529*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(helper.callback_reused_error());
530*6777b538SAndroid Build Coastguard Worker 
531*6777b538SAndroid Build Coastguard Worker   entry->Doom();
532*6777b538SAndroid Build Coastguard Worker   entry->Close();
533*6777b538SAndroid Build Coastguard Worker   FlushQueueForTest();
534*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache_->GetEntryCount());
535*6777b538SAndroid Build Coastguard Worker }
536*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,ExternalAsyncIO)537*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, ExternalAsyncIO) {
538*6777b538SAndroid Build Coastguard Worker   InitCache();
539*6777b538SAndroid Build Coastguard Worker   ExternalAsyncIO();
540*6777b538SAndroid Build Coastguard Worker }
541*6777b538SAndroid Build Coastguard Worker 
542*6777b538SAndroid Build Coastguard Worker // TODO(http://crbug.com/497101): This test is flaky.
543*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_IOS)
544*6777b538SAndroid Build Coastguard Worker #define MAYBE_ExternalAsyncIONoBuffer DISABLED_ExternalAsyncIONoBuffer
545*6777b538SAndroid Build Coastguard Worker #else
546*6777b538SAndroid Build Coastguard Worker #define MAYBE_ExternalAsyncIONoBuffer ExternalAsyncIONoBuffer
547*6777b538SAndroid Build Coastguard Worker #endif
TEST_F(DiskCacheEntryTest,MAYBE_ExternalAsyncIONoBuffer)548*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MAYBE_ExternalAsyncIONoBuffer) {
549*6777b538SAndroid Build Coastguard Worker   InitCache();
550*6777b538SAndroid Build Coastguard Worker   cache_impl_->SetFlags(disk_cache::kNoBuffering);
551*6777b538SAndroid Build Coastguard Worker   ExternalAsyncIO();
552*6777b538SAndroid Build Coastguard Worker }
553*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyExternalAsyncIO)554*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyExternalAsyncIO) {
555*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
556*6777b538SAndroid Build Coastguard Worker   InitCache();
557*6777b538SAndroid Build Coastguard Worker   ExternalAsyncIO();
558*6777b538SAndroid Build Coastguard Worker }
559*6777b538SAndroid Build Coastguard Worker 
560*6777b538SAndroid Build Coastguard Worker // Tests that IOBuffers are not referenced after IO completes.
ReleaseBuffer(int stream_index)561*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::ReleaseBuffer(int stream_index) {
562*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
563*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("the first key", &entry), IsOk());
564*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(nullptr != entry);
565*6777b538SAndroid Build Coastguard Worker 
566*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 1024;
567*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
568*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kBufferSize, false);
569*6777b538SAndroid Build Coastguard Worker 
570*6777b538SAndroid Build Coastguard Worker   net::ReleaseBufferCompletionCallback cb(buffer.get());
571*6777b538SAndroid Build Coastguard Worker   int rv = entry->WriteData(
572*6777b538SAndroid Build Coastguard Worker       stream_index, 0, buffer.get(), kBufferSize, cb.callback(), false);
573*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kBufferSize, cb.GetResult(rv));
574*6777b538SAndroid Build Coastguard Worker   entry->Close();
575*6777b538SAndroid Build Coastguard Worker }
576*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,ReleaseBuffer)577*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, ReleaseBuffer) {
578*6777b538SAndroid Build Coastguard Worker   InitCache();
579*6777b538SAndroid Build Coastguard Worker   cache_impl_->SetFlags(disk_cache::kNoBuffering);
580*6777b538SAndroid Build Coastguard Worker   ReleaseBuffer(0);
581*6777b538SAndroid Build Coastguard Worker }
582*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyReleaseBuffer)583*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyReleaseBuffer) {
584*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
585*6777b538SAndroid Build Coastguard Worker   InitCache();
586*6777b538SAndroid Build Coastguard Worker   ReleaseBuffer(0);
587*6777b538SAndroid Build Coastguard Worker }
588*6777b538SAndroid Build Coastguard Worker 
StreamAccess()589*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::StreamAccess() {
590*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
591*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("the first key", &entry), IsOk());
592*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(nullptr != entry);
593*6777b538SAndroid Build Coastguard Worker 
594*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 1024;
595*6777b538SAndroid Build Coastguard Worker   const int kNumStreams = 3;
596*6777b538SAndroid Build Coastguard Worker   scoped_refptr<net::IOBuffer> reference_buffers[kNumStreams];
597*6777b538SAndroid Build Coastguard Worker   for (auto& reference_buffer : reference_buffers) {
598*6777b538SAndroid Build Coastguard Worker     reference_buffer = base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
599*6777b538SAndroid Build Coastguard Worker     CacheTestFillBuffer(reference_buffer->data(), kBufferSize, false);
600*6777b538SAndroid Build Coastguard Worker   }
601*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
602*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumStreams; i++) {
603*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(
604*6777b538SAndroid Build Coastguard Worker         kBufferSize,
605*6777b538SAndroid Build Coastguard Worker         WriteData(entry, i, 0, reference_buffers[i].get(), kBufferSize, false));
606*6777b538SAndroid Build Coastguard Worker     memset(buffer1->data(), 0, kBufferSize);
607*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kBufferSize, ReadData(entry, i, 0, buffer1.get(), kBufferSize));
608*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(
609*6777b538SAndroid Build Coastguard Worker         0, memcmp(reference_buffers[i]->data(), buffer1->data(), kBufferSize));
610*6777b538SAndroid Build Coastguard Worker   }
611*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_INVALID_ARGUMENT,
612*6777b538SAndroid Build Coastguard Worker             ReadData(entry, kNumStreams, 0, buffer1.get(), kBufferSize));
613*6777b538SAndroid Build Coastguard Worker   entry->Close();
614*6777b538SAndroid Build Coastguard Worker 
615*6777b538SAndroid Build Coastguard Worker   // Open the entry and read it in chunks, including a read past the end.
616*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry("the first key", &entry), IsOk());
617*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(nullptr != entry);
618*6777b538SAndroid Build Coastguard Worker   const int kReadBufferSize = 600;
619*6777b538SAndroid Build Coastguard Worker   const int kFinalReadSize = kBufferSize - kReadBufferSize;
620*6777b538SAndroid Build Coastguard Worker   static_assert(kFinalReadSize < kReadBufferSize,
621*6777b538SAndroid Build Coastguard Worker                 "should be exactly two reads");
622*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kReadBufferSize);
623*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumStreams; i++) {
624*6777b538SAndroid Build Coastguard Worker     memset(buffer2->data(), 0, kReadBufferSize);
625*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kReadBufferSize,
626*6777b538SAndroid Build Coastguard Worker               ReadData(entry, i, 0, buffer2.get(), kReadBufferSize));
627*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(
628*6777b538SAndroid Build Coastguard Worker         0,
629*6777b538SAndroid Build Coastguard Worker         memcmp(reference_buffers[i]->data(), buffer2->data(), kReadBufferSize));
630*6777b538SAndroid Build Coastguard Worker 
631*6777b538SAndroid Build Coastguard Worker     memset(buffer2->data(), 0, kReadBufferSize);
632*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(
633*6777b538SAndroid Build Coastguard Worker         kFinalReadSize,
634*6777b538SAndroid Build Coastguard Worker         ReadData(entry, i, kReadBufferSize, buffer2.get(), kReadBufferSize));
635*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0,
636*6777b538SAndroid Build Coastguard Worker               memcmp(reference_buffers[i]->data() + kReadBufferSize,
637*6777b538SAndroid Build Coastguard Worker                      buffer2->data(),
638*6777b538SAndroid Build Coastguard Worker                      kFinalReadSize));
639*6777b538SAndroid Build Coastguard Worker   }
640*6777b538SAndroid Build Coastguard Worker 
641*6777b538SAndroid Build Coastguard Worker   entry->Close();
642*6777b538SAndroid Build Coastguard Worker }
643*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,StreamAccess)644*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, StreamAccess) {
645*6777b538SAndroid Build Coastguard Worker   InitCache();
646*6777b538SAndroid Build Coastguard Worker   StreamAccess();
647*6777b538SAndroid Build Coastguard Worker }
648*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyStreamAccess)649*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyStreamAccess) {
650*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
651*6777b538SAndroid Build Coastguard Worker   InitCache();
652*6777b538SAndroid Build Coastguard Worker   StreamAccess();
653*6777b538SAndroid Build Coastguard Worker }
654*6777b538SAndroid Build Coastguard Worker 
GetKey()655*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::GetKey() {
656*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
657*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
658*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
659*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(key, entry->GetKey()) << "short key";
660*6777b538SAndroid Build Coastguard Worker   entry->Close();
661*6777b538SAndroid Build Coastguard Worker 
662*6777b538SAndroid Build Coastguard Worker   int seed = static_cast<int>(Time::Now().ToInternalValue());
663*6777b538SAndroid Build Coastguard Worker   srand(seed);
664*6777b538SAndroid Build Coastguard Worker   char key_buffer[20000];
665*6777b538SAndroid Build Coastguard Worker 
666*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(key_buffer, 3000, true);
667*6777b538SAndroid Build Coastguard Worker   key_buffer[1000] = '\0';
668*6777b538SAndroid Build Coastguard Worker 
669*6777b538SAndroid Build Coastguard Worker   key = key_buffer;
670*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
671*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(key == entry->GetKey()) << "1000 bytes key";
672*6777b538SAndroid Build Coastguard Worker   entry->Close();
673*6777b538SAndroid Build Coastguard Worker 
674*6777b538SAndroid Build Coastguard Worker   key_buffer[1000] = 'p';
675*6777b538SAndroid Build Coastguard Worker   key_buffer[3000] = '\0';
676*6777b538SAndroid Build Coastguard Worker   key = key_buffer;
677*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
678*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(key == entry->GetKey()) << "medium size key";
679*6777b538SAndroid Build Coastguard Worker   entry->Close();
680*6777b538SAndroid Build Coastguard Worker 
681*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(key_buffer, sizeof(key_buffer), true);
682*6777b538SAndroid Build Coastguard Worker   key_buffer[19999] = '\0';
683*6777b538SAndroid Build Coastguard Worker 
684*6777b538SAndroid Build Coastguard Worker   key = key_buffer;
685*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
686*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(key == entry->GetKey()) << "long key";
687*6777b538SAndroid Build Coastguard Worker   entry->Close();
688*6777b538SAndroid Build Coastguard Worker 
689*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(key_buffer, 0x4000, true);
690*6777b538SAndroid Build Coastguard Worker   key_buffer[0x4000] = '\0';
691*6777b538SAndroid Build Coastguard Worker 
692*6777b538SAndroid Build Coastguard Worker   key = key_buffer;
693*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
694*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(key == entry->GetKey()) << "16KB key";
695*6777b538SAndroid Build Coastguard Worker   entry->Close();
696*6777b538SAndroid Build Coastguard Worker }
697*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,GetKey)698*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, GetKey) {
699*6777b538SAndroid Build Coastguard Worker   InitCache();
700*6777b538SAndroid Build Coastguard Worker   GetKey();
701*6777b538SAndroid Build Coastguard Worker }
702*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyGetKey)703*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyGetKey) {
704*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
705*6777b538SAndroid Build Coastguard Worker   InitCache();
706*6777b538SAndroid Build Coastguard Worker   GetKey();
707*6777b538SAndroid Build Coastguard Worker }
708*6777b538SAndroid Build Coastguard Worker 
GetTimes(int stream_index)709*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::GetTimes(int stream_index) {
710*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
711*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
712*6777b538SAndroid Build Coastguard Worker 
713*6777b538SAndroid Build Coastguard Worker   Time t1 = Time::Now();
714*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
715*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry->GetLastModified() >= t1);
716*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry->GetLastModified() == entry->GetLastUsed());
717*6777b538SAndroid Build Coastguard Worker 
718*6777b538SAndroid Build Coastguard Worker   AddDelay();
719*6777b538SAndroid Build Coastguard Worker   Time t2 = Time::Now();
720*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(t2 > t1);
721*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, stream_index, 200, nullptr, 0, false));
722*6777b538SAndroid Build Coastguard Worker   if (type_ == net::APP_CACHE) {
723*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(entry->GetLastModified() < t2);
724*6777b538SAndroid Build Coastguard Worker   } else {
725*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(entry->GetLastModified() >= t2);
726*6777b538SAndroid Build Coastguard Worker   }
727*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry->GetLastModified() == entry->GetLastUsed());
728*6777b538SAndroid Build Coastguard Worker 
729*6777b538SAndroid Build Coastguard Worker   AddDelay();
730*6777b538SAndroid Build Coastguard Worker   Time t3 = Time::Now();
731*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(t3 > t2);
732*6777b538SAndroid Build Coastguard Worker   const int kSize = 200;
733*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
734*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, stream_index, 0, buffer.get(), kSize));
735*6777b538SAndroid Build Coastguard Worker   if (type_ == net::APP_CACHE) {
736*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(entry->GetLastUsed() < t2);
737*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(entry->GetLastModified() < t2);
738*6777b538SAndroid Build Coastguard Worker   } else if (type_ == net::SHADER_CACHE) {
739*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(entry->GetLastUsed() < t3);
740*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(entry->GetLastModified() < t3);
741*6777b538SAndroid Build Coastguard Worker   } else {
742*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(entry->GetLastUsed() >= t3);
743*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(entry->GetLastModified() < t3);
744*6777b538SAndroid Build Coastguard Worker   }
745*6777b538SAndroid Build Coastguard Worker   entry->Close();
746*6777b538SAndroid Build Coastguard Worker }
747*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,GetTimes)748*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, GetTimes) {
749*6777b538SAndroid Build Coastguard Worker   InitCache();
750*6777b538SAndroid Build Coastguard Worker   GetTimes(0);
751*6777b538SAndroid Build Coastguard Worker }
752*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyGetTimes)753*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyGetTimes) {
754*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
755*6777b538SAndroid Build Coastguard Worker   InitCache();
756*6777b538SAndroid Build Coastguard Worker   GetTimes(0);
757*6777b538SAndroid Build Coastguard Worker }
758*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,AppCacheGetTimes)759*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, AppCacheGetTimes) {
760*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
761*6777b538SAndroid Build Coastguard Worker   InitCache();
762*6777b538SAndroid Build Coastguard Worker   GetTimes(0);
763*6777b538SAndroid Build Coastguard Worker }
764*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,ShaderCacheGetTimes)765*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, ShaderCacheGetTimes) {
766*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::SHADER_CACHE);
767*6777b538SAndroid Build Coastguard Worker   InitCache();
768*6777b538SAndroid Build Coastguard Worker   GetTimes(0);
769*6777b538SAndroid Build Coastguard Worker }
770*6777b538SAndroid Build Coastguard Worker 
GrowData(int stream_index)771*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::GrowData(int stream_index) {
772*6777b538SAndroid Build Coastguard Worker   std::string key1("the first key");
773*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
774*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key1, &entry), IsOk());
775*6777b538SAndroid Build Coastguard Worker 
776*6777b538SAndroid Build Coastguard Worker   const int kSize = 20000;
777*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
778*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
779*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize, false);
780*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize);
781*6777b538SAndroid Build Coastguard Worker 
782*6777b538SAndroid Build Coastguard Worker   base::strlcpy(buffer1->data(), "the data", kSize);
783*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, WriteData(entry, stream_index, 0, buffer1.get(), 10, false));
784*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, ReadData(entry, stream_index, 0, buffer2.get(), 10));
785*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("the data", buffer2->data());
786*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, entry->GetDataSize(stream_index));
787*6777b538SAndroid Build Coastguard Worker 
788*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2000,
789*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 0, buffer1.get(), 2000, false));
790*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2000, entry->GetDataSize(stream_index));
791*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2000, ReadData(entry, stream_index, 0, buffer2.get(), 2000));
792*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 2000));
793*6777b538SAndroid Build Coastguard Worker 
794*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000,
795*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 0, buffer1.get(), kSize, false));
796*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
797*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, ReadData(entry, stream_index, 0, buffer2.get(), kSize));
798*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), kSize));
799*6777b538SAndroid Build Coastguard Worker   entry->Close();
800*6777b538SAndroid Build Coastguard Worker 
801*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize);
802*6777b538SAndroid Build Coastguard Worker   std::string key2("Second key");
803*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key2, &entry), IsOk());
804*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, WriteData(entry, stream_index, 0, buffer1.get(), 10, false));
805*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, entry->GetDataSize(stream_index));
806*6777b538SAndroid Build Coastguard Worker   entry->Close();
807*6777b538SAndroid Build Coastguard Worker 
808*6777b538SAndroid Build Coastguard Worker   // Go from an internal address to a bigger block size.
809*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key2, &entry), IsOk());
810*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2000,
811*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 0, buffer1.get(), 2000, false));
812*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2000, entry->GetDataSize(stream_index));
813*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2000, ReadData(entry, stream_index, 0, buffer2.get(), 2000));
814*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 2000));
815*6777b538SAndroid Build Coastguard Worker   entry->Close();
816*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize);
817*6777b538SAndroid Build Coastguard Worker 
818*6777b538SAndroid Build Coastguard Worker   // Go from an internal address to an external one.
819*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key2, &entry), IsOk());
820*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000,
821*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 0, buffer1.get(), kSize, false));
822*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
823*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, ReadData(entry, stream_index, 0, buffer2.get(), kSize));
824*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), kSize));
825*6777b538SAndroid Build Coastguard Worker   entry->Close();
826*6777b538SAndroid Build Coastguard Worker 
827*6777b538SAndroid Build Coastguard Worker   // Double check the size from disk.
828*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key2, &entry), IsOk());
829*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
830*6777b538SAndroid Build Coastguard Worker 
831*6777b538SAndroid Build Coastguard Worker   // Now extend the entry without actual data.
832*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, stream_index, 45500, buffer1.get(), 0, false));
833*6777b538SAndroid Build Coastguard Worker   entry->Close();
834*6777b538SAndroid Build Coastguard Worker 
835*6777b538SAndroid Build Coastguard Worker   // And check again from disk.
836*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key2, &entry), IsOk());
837*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(45500, entry->GetDataSize(stream_index));
838*6777b538SAndroid Build Coastguard Worker   entry->Close();
839*6777b538SAndroid Build Coastguard Worker }
840*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,GrowData)841*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, GrowData) {
842*6777b538SAndroid Build Coastguard Worker   InitCache();
843*6777b538SAndroid Build Coastguard Worker   GrowData(0);
844*6777b538SAndroid Build Coastguard Worker }
845*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,GrowDataNoBuffer)846*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, GrowDataNoBuffer) {
847*6777b538SAndroid Build Coastguard Worker   InitCache();
848*6777b538SAndroid Build Coastguard Worker   cache_impl_->SetFlags(disk_cache::kNoBuffering);
849*6777b538SAndroid Build Coastguard Worker   GrowData(0);
850*6777b538SAndroid Build Coastguard Worker }
851*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyGrowData)852*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyGrowData) {
853*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
854*6777b538SAndroid Build Coastguard Worker   InitCache();
855*6777b538SAndroid Build Coastguard Worker   GrowData(0);
856*6777b538SAndroid Build Coastguard Worker }
857*6777b538SAndroid Build Coastguard Worker 
TruncateData(int stream_index)858*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::TruncateData(int stream_index) {
859*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
860*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
861*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
862*6777b538SAndroid Build Coastguard Worker 
863*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 20000;
864*6777b538SAndroid Build Coastguard Worker   const int kSize2 = 20000;
865*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
866*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize2);
867*6777b538SAndroid Build Coastguard Worker 
868*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
869*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize2);
870*6777b538SAndroid Build Coastguard Worker 
871*6777b538SAndroid Build Coastguard Worker   // Simple truncation:
872*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(200, WriteData(entry, stream_index, 0, buffer1.get(), 200, false));
873*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(200, entry->GetDataSize(stream_index));
874*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100, WriteData(entry, stream_index, 0, buffer1.get(), 100, false));
875*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(200, entry->GetDataSize(stream_index));
876*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100, WriteData(entry, stream_index, 0, buffer1.get(), 100, true));
877*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100, entry->GetDataSize(stream_index));
878*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, stream_index, 50, buffer1.get(), 0, true));
879*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(50, entry->GetDataSize(stream_index));
880*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, stream_index, 0, buffer1.get(), 0, true));
881*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, entry->GetDataSize(stream_index));
882*6777b538SAndroid Build Coastguard Worker   entry->Close();
883*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
884*6777b538SAndroid Build Coastguard Worker 
885*6777b538SAndroid Build Coastguard Worker   // Go to an external file.
886*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000,
887*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 0, buffer1.get(), 20000, true));
888*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
889*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, ReadData(entry, stream_index, 0, buffer2.get(), 20000));
890*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 20000));
891*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize2);
892*6777b538SAndroid Build Coastguard Worker 
893*6777b538SAndroid Build Coastguard Worker   // External file truncation
894*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(18000,
895*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 0, buffer1.get(), 18000, false));
896*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
897*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(18000,
898*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 0, buffer1.get(), 18000, true));
899*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(18000, entry->GetDataSize(stream_index));
900*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, stream_index, 17500, buffer1.get(), 0, true));
901*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(17500, entry->GetDataSize(stream_index));
902*6777b538SAndroid Build Coastguard Worker 
903*6777b538SAndroid Build Coastguard Worker   // And back to an internal block.
904*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(600,
905*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 1000, buffer1.get(), 600, true));
906*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1600, entry->GetDataSize(stream_index));
907*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(600, ReadData(entry, stream_index, 1000, buffer2.get(), 600));
908*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 600));
909*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1000, ReadData(entry, stream_index, 0, buffer2.get(), 1000));
910*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 1000))
911*6777b538SAndroid Build Coastguard Worker       << "Preserves previous data";
912*6777b538SAndroid Build Coastguard Worker 
913*6777b538SAndroid Build Coastguard Worker   // Go from external file to zero length.
914*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000,
915*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 0, buffer1.get(), 20000, true));
916*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
917*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, stream_index, 0, buffer1.get(), 0, true));
918*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, entry->GetDataSize(stream_index));
919*6777b538SAndroid Build Coastguard Worker 
920*6777b538SAndroid Build Coastguard Worker   entry->Close();
921*6777b538SAndroid Build Coastguard Worker }
922*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,TruncateData)923*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, TruncateData) {
924*6777b538SAndroid Build Coastguard Worker   InitCache();
925*6777b538SAndroid Build Coastguard Worker   TruncateData(0);
926*6777b538SAndroid Build Coastguard Worker }
927*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,TruncateDataNoBuffer)928*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, TruncateDataNoBuffer) {
929*6777b538SAndroid Build Coastguard Worker   InitCache();
930*6777b538SAndroid Build Coastguard Worker   cache_impl_->SetFlags(disk_cache::kNoBuffering);
931*6777b538SAndroid Build Coastguard Worker   TruncateData(0);
932*6777b538SAndroid Build Coastguard Worker }
933*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyTruncateData)934*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyTruncateData) {
935*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
936*6777b538SAndroid Build Coastguard Worker   InitCache();
937*6777b538SAndroid Build Coastguard Worker   TruncateData(0);
938*6777b538SAndroid Build Coastguard Worker }
939*6777b538SAndroid Build Coastguard Worker 
ZeroLengthIO(int stream_index)940*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::ZeroLengthIO(int stream_index) {
941*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
942*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
943*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
944*6777b538SAndroid Build Coastguard Worker 
945*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, ReadData(entry, stream_index, 0, nullptr, 0));
946*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, stream_index, 0, nullptr, 0, false));
947*6777b538SAndroid Build Coastguard Worker 
948*6777b538SAndroid Build Coastguard Worker   // This write should extend the entry.
949*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, stream_index, 1000, nullptr, 0, false));
950*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, ReadData(entry, stream_index, 500, nullptr, 0));
951*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, ReadData(entry, stream_index, 2000, nullptr, 0));
952*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1000, entry->GetDataSize(stream_index));
953*6777b538SAndroid Build Coastguard Worker 
954*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, stream_index, 100000, nullptr, 0, true));
955*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, ReadData(entry, stream_index, 50000, nullptr, 0));
956*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100000, entry->GetDataSize(stream_index));
957*6777b538SAndroid Build Coastguard Worker 
958*6777b538SAndroid Build Coastguard Worker   // Let's verify the actual content.
959*6777b538SAndroid Build Coastguard Worker   const int kSize = 20;
960*6777b538SAndroid Build Coastguard Worker   const char zeros[kSize] = {};
961*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
962*6777b538SAndroid Build Coastguard Worker 
963*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
964*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, stream_index, 500, buffer.get(), kSize));
965*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize));
966*6777b538SAndroid Build Coastguard Worker 
967*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
968*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, stream_index, 5000, buffer.get(), kSize));
969*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize));
970*6777b538SAndroid Build Coastguard Worker 
971*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
972*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, stream_index, 50000, buffer.get(), kSize));
973*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize));
974*6777b538SAndroid Build Coastguard Worker 
975*6777b538SAndroid Build Coastguard Worker   entry->Close();
976*6777b538SAndroid Build Coastguard Worker }
977*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,ZeroLengthIO)978*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, ZeroLengthIO) {
979*6777b538SAndroid Build Coastguard Worker   InitCache();
980*6777b538SAndroid Build Coastguard Worker   ZeroLengthIO(0);
981*6777b538SAndroid Build Coastguard Worker }
982*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,ZeroLengthIONoBuffer)983*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, ZeroLengthIONoBuffer) {
984*6777b538SAndroid Build Coastguard Worker   InitCache();
985*6777b538SAndroid Build Coastguard Worker   cache_impl_->SetFlags(disk_cache::kNoBuffering);
986*6777b538SAndroid Build Coastguard Worker   ZeroLengthIO(0);
987*6777b538SAndroid Build Coastguard Worker }
988*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyZeroLengthIO)989*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyZeroLengthIO) {
990*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
991*6777b538SAndroid Build Coastguard Worker   InitCache();
992*6777b538SAndroid Build Coastguard Worker   ZeroLengthIO(0);
993*6777b538SAndroid Build Coastguard Worker }
994*6777b538SAndroid Build Coastguard Worker 
995*6777b538SAndroid Build Coastguard Worker // Tests that we handle the content correctly when buffering, a feature of the
996*6777b538SAndroid Build Coastguard Worker // standard cache that permits fast responses to certain reads.
Buffering()997*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::Buffering() {
998*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
999*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1000*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1001*6777b538SAndroid Build Coastguard Worker 
1002*6777b538SAndroid Build Coastguard Worker   const int kSize = 200;
1003*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1004*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1005*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize, true);
1006*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1007*6777b538SAndroid Build Coastguard Worker 
1008*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer1.get(), kSize, false));
1009*6777b538SAndroid Build Coastguard Worker   entry->Close();
1010*6777b538SAndroid Build Coastguard Worker 
1011*6777b538SAndroid Build Coastguard Worker   // Write a little more and read what we wrote before.
1012*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1013*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 5000, buffer1.get(), kSize, false));
1014*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 1, 0, buffer2.get(), kSize));
1015*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1016*6777b538SAndroid Build Coastguard Worker 
1017*6777b538SAndroid Build Coastguard Worker   // Now go to an external file.
1018*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 18000, buffer1.get(), kSize, false));
1019*6777b538SAndroid Build Coastguard Worker   entry->Close();
1020*6777b538SAndroid Build Coastguard Worker 
1021*6777b538SAndroid Build Coastguard Worker   // Write something else and verify old data.
1022*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1023*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 10000, buffer1.get(), kSize, false));
1024*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1025*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 1, 5000, buffer2.get(), kSize));
1026*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1027*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1028*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 1, 0, buffer2.get(), kSize));
1029*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1030*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1031*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 1, 18000, buffer2.get(), kSize));
1032*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1033*6777b538SAndroid Build Coastguard Worker 
1034*6777b538SAndroid Build Coastguard Worker   // Extend the file some more.
1035*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 23000, buffer1.get(), kSize, false));
1036*6777b538SAndroid Build Coastguard Worker   entry->Close();
1037*6777b538SAndroid Build Coastguard Worker 
1038*6777b538SAndroid Build Coastguard Worker   // And now make sure that we can deal with data in both places (ram/disk).
1039*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1040*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 17000, buffer1.get(), kSize, false));
1041*6777b538SAndroid Build Coastguard Worker 
1042*6777b538SAndroid Build Coastguard Worker   // We should not overwrite the data at 18000 with this.
1043*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 19000, buffer1.get(), kSize, false));
1044*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1045*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 1, 18000, buffer2.get(), kSize));
1046*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1047*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1048*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 1, 17000, buffer2.get(), kSize));
1049*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1050*6777b538SAndroid Build Coastguard Worker 
1051*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 22900, buffer1.get(), kSize, false));
1052*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1053*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100, ReadData(entry, 1, 23000, buffer2.get(), kSize));
1054*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + 100, 100));
1055*6777b538SAndroid Build Coastguard Worker 
1056*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1057*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100, ReadData(entry, 1, 23100, buffer2.get(), kSize));
1058*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + 100, 100));
1059*6777b538SAndroid Build Coastguard Worker 
1060*6777b538SAndroid Build Coastguard Worker   // Extend the file again and read before without closing the entry.
1061*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 25000, buffer1.get(), kSize, false));
1062*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 45000, buffer1.get(), kSize, false));
1063*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1064*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 1, 25000, buffer2.get(), kSize));
1065*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1066*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1067*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 1, 45000, buffer2.get(), kSize));
1068*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1069*6777b538SAndroid Build Coastguard Worker 
1070*6777b538SAndroid Build Coastguard Worker   entry->Close();
1071*6777b538SAndroid Build Coastguard Worker }
1072*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,Buffering)1073*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, Buffering) {
1074*6777b538SAndroid Build Coastguard Worker   InitCache();
1075*6777b538SAndroid Build Coastguard Worker   Buffering();
1076*6777b538SAndroid Build Coastguard Worker }
1077*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,BufferingNoBuffer)1078*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, BufferingNoBuffer) {
1079*6777b538SAndroid Build Coastguard Worker   InitCache();
1080*6777b538SAndroid Build Coastguard Worker   cache_impl_->SetFlags(disk_cache::kNoBuffering);
1081*6777b538SAndroid Build Coastguard Worker   Buffering();
1082*6777b538SAndroid Build Coastguard Worker }
1083*6777b538SAndroid Build Coastguard Worker 
1084*6777b538SAndroid Build Coastguard Worker // Checks that entries are zero length when created.
SizeAtCreate()1085*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::SizeAtCreate() {
1086*6777b538SAndroid Build Coastguard Worker   const char key[]  = "the first key";
1087*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1088*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1089*6777b538SAndroid Build Coastguard Worker 
1090*6777b538SAndroid Build Coastguard Worker   const int kNumStreams = 3;
1091*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumStreams; ++i)
1092*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, entry->GetDataSize(i));
1093*6777b538SAndroid Build Coastguard Worker   entry->Close();
1094*6777b538SAndroid Build Coastguard Worker }
1095*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SizeAtCreate)1096*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SizeAtCreate) {
1097*6777b538SAndroid Build Coastguard Worker   InitCache();
1098*6777b538SAndroid Build Coastguard Worker   SizeAtCreate();
1099*6777b538SAndroid Build Coastguard Worker }
1100*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlySizeAtCreate)1101*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlySizeAtCreate) {
1102*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
1103*6777b538SAndroid Build Coastguard Worker   InitCache();
1104*6777b538SAndroid Build Coastguard Worker   SizeAtCreate();
1105*6777b538SAndroid Build Coastguard Worker }
1106*6777b538SAndroid Build Coastguard Worker 
1107*6777b538SAndroid Build Coastguard Worker // Some extra tests to make sure that buffering works properly when changing
1108*6777b538SAndroid Build Coastguard Worker // the entry size.
SizeChanges(int stream_index)1109*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::SizeChanges(int stream_index) {
1110*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1111*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1112*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1113*6777b538SAndroid Build Coastguard Worker 
1114*6777b538SAndroid Build Coastguard Worker   const int kSize = 200;
1115*6777b538SAndroid Build Coastguard Worker   const char zeros[kSize] = {};
1116*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1117*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1118*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize, true);
1119*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1120*6777b538SAndroid Build Coastguard Worker 
1121*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize,
1122*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 0, buffer1.get(), kSize, true));
1123*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize,
1124*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 17000, buffer1.get(), kSize, true));
1125*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize,
1126*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 23000, buffer1.get(), kSize, true));
1127*6777b538SAndroid Build Coastguard Worker   entry->Close();
1128*6777b538SAndroid Build Coastguard Worker 
1129*6777b538SAndroid Build Coastguard Worker   // Extend the file and read between the old size and the new write.
1130*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1131*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(23000 + kSize, entry->GetDataSize(stream_index));
1132*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize,
1133*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 25000, buffer1.get(), kSize, true));
1134*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(25000 + kSize, entry->GetDataSize(stream_index));
1135*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, stream_index, 24000, buffer2.get(), kSize));
1136*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, kSize));
1137*6777b538SAndroid Build Coastguard Worker 
1138*6777b538SAndroid Build Coastguard Worker   // Read at the end of the old file size.
1139*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
1140*6777b538SAndroid Build Coastguard Worker       kSize,
1141*6777b538SAndroid Build Coastguard Worker       ReadData(entry, stream_index, 23000 + kSize - 35, buffer2.get(), kSize));
1142*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + kSize - 35, 35));
1143*6777b538SAndroid Build Coastguard Worker 
1144*6777b538SAndroid Build Coastguard Worker   // Read slightly before the last write.
1145*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1146*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, stream_index, 24900, buffer2.get(), kSize));
1147*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
1148*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
1149*6777b538SAndroid Build Coastguard Worker 
1150*6777b538SAndroid Build Coastguard Worker   // Extend the entry a little more.
1151*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize,
1152*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 26000, buffer1.get(), kSize, true));
1153*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(26000 + kSize, entry->GetDataSize(stream_index));
1154*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, true);
1155*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, stream_index, 25900, buffer2.get(), kSize));
1156*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
1157*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
1158*6777b538SAndroid Build Coastguard Worker 
1159*6777b538SAndroid Build Coastguard Worker   // And now reduce the size.
1160*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize,
1161*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 25000, buffer1.get(), kSize, true));
1162*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(25000 + kSize, entry->GetDataSize(stream_index));
1163*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
1164*6777b538SAndroid Build Coastguard Worker       28,
1165*6777b538SAndroid Build Coastguard Worker       ReadData(entry, stream_index, 25000 + kSize - 28, buffer2.get(), kSize));
1166*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + kSize - 28, 28));
1167*6777b538SAndroid Build Coastguard Worker 
1168*6777b538SAndroid Build Coastguard Worker   // Reduce the size with a buffer that is not extending the size.
1169*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize,
1170*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 24000, buffer1.get(), kSize, false));
1171*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(25000 + kSize, entry->GetDataSize(stream_index));
1172*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize,
1173*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 24500, buffer1.get(), kSize, true));
1174*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(24500 + kSize, entry->GetDataSize(stream_index));
1175*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, stream_index, 23900, buffer2.get(), kSize));
1176*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
1177*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
1178*6777b538SAndroid Build Coastguard Worker 
1179*6777b538SAndroid Build Coastguard Worker   // And now reduce the size below the old size.
1180*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize,
1181*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 19000, buffer1.get(), kSize, true));
1182*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(19000 + kSize, entry->GetDataSize(stream_index));
1183*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, stream_index, 18900, buffer2.get(), kSize));
1184*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
1185*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
1186*6777b538SAndroid Build Coastguard Worker 
1187*6777b538SAndroid Build Coastguard Worker   // Verify that the actual file is truncated.
1188*6777b538SAndroid Build Coastguard Worker   entry->Close();
1189*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1190*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(19000 + kSize, entry->GetDataSize(stream_index));
1191*6777b538SAndroid Build Coastguard Worker 
1192*6777b538SAndroid Build Coastguard Worker   // Extend the newly opened file with a zero length write, expect zero fill.
1193*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
1194*6777b538SAndroid Build Coastguard Worker       0,
1195*6777b538SAndroid Build Coastguard Worker       WriteData(entry, stream_index, 20000 + kSize, buffer1.get(), 0, false));
1196*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize,
1197*6777b538SAndroid Build Coastguard Worker             ReadData(entry, stream_index, 19000 + kSize, buffer1.get(), kSize));
1198*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer1->data(), zeros, kSize));
1199*6777b538SAndroid Build Coastguard Worker 
1200*6777b538SAndroid Build Coastguard Worker   entry->Close();
1201*6777b538SAndroid Build Coastguard Worker }
1202*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SizeChanges)1203*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SizeChanges) {
1204*6777b538SAndroid Build Coastguard Worker   InitCache();
1205*6777b538SAndroid Build Coastguard Worker   SizeChanges(1);
1206*6777b538SAndroid Build Coastguard Worker }
1207*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SizeChangesNoBuffer)1208*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SizeChangesNoBuffer) {
1209*6777b538SAndroid Build Coastguard Worker   InitCache();
1210*6777b538SAndroid Build Coastguard Worker   cache_impl_->SetFlags(disk_cache::kNoBuffering);
1211*6777b538SAndroid Build Coastguard Worker   SizeChanges(1);
1212*6777b538SAndroid Build Coastguard Worker }
1213*6777b538SAndroid Build Coastguard Worker 
1214*6777b538SAndroid Build Coastguard Worker // Write more than the total cache capacity but to a single entry. |size| is the
1215*6777b538SAndroid Build Coastguard Worker // amount of bytes to write each time.
ReuseEntry(int size,int stream_index)1216*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::ReuseEntry(int size, int stream_index) {
1217*6777b538SAndroid Build Coastguard Worker   std::string key1("the first key");
1218*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1219*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key1, &entry), IsOk());
1220*6777b538SAndroid Build Coastguard Worker 
1221*6777b538SAndroid Build Coastguard Worker   entry->Close();
1222*6777b538SAndroid Build Coastguard Worker   std::string key2("the second key");
1223*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key2, &entry), IsOk());
1224*6777b538SAndroid Build Coastguard Worker 
1225*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(size);
1226*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), size, false);
1227*6777b538SAndroid Build Coastguard Worker 
1228*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 15; i++) {
1229*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, WriteData(entry, stream_index, 0, buffer.get(), 0, true));
1230*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(size,
1231*6777b538SAndroid Build Coastguard Worker               WriteData(entry, stream_index, 0, buffer.get(), size, false));
1232*6777b538SAndroid Build Coastguard Worker     entry->Close();
1233*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(OpenEntry(key2, &entry), IsOk());
1234*6777b538SAndroid Build Coastguard Worker   }
1235*6777b538SAndroid Build Coastguard Worker 
1236*6777b538SAndroid Build Coastguard Worker   entry->Close();
1237*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, OpenEntry(key1, &entry)) << "have not evicted this entry";
1238*6777b538SAndroid Build Coastguard Worker   entry->Close();
1239*6777b538SAndroid Build Coastguard Worker }
1240*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,ReuseExternalEntry)1241*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, ReuseExternalEntry) {
1242*6777b538SAndroid Build Coastguard Worker   SetMaxSize(200 * 1024);
1243*6777b538SAndroid Build Coastguard Worker   InitCache();
1244*6777b538SAndroid Build Coastguard Worker   ReuseEntry(20 * 1024, 0);
1245*6777b538SAndroid Build Coastguard Worker }
1246*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyReuseExternalEntry)1247*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyReuseExternalEntry) {
1248*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
1249*6777b538SAndroid Build Coastguard Worker   SetMaxSize(200 * 1024);
1250*6777b538SAndroid Build Coastguard Worker   InitCache();
1251*6777b538SAndroid Build Coastguard Worker   ReuseEntry(20 * 1024, 0);
1252*6777b538SAndroid Build Coastguard Worker }
1253*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,ReuseInternalEntry)1254*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, ReuseInternalEntry) {
1255*6777b538SAndroid Build Coastguard Worker   SetMaxSize(100 * 1024);
1256*6777b538SAndroid Build Coastguard Worker   InitCache();
1257*6777b538SAndroid Build Coastguard Worker   ReuseEntry(10 * 1024, 0);
1258*6777b538SAndroid Build Coastguard Worker }
1259*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyReuseInternalEntry)1260*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyReuseInternalEntry) {
1261*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
1262*6777b538SAndroid Build Coastguard Worker   SetMaxSize(100 * 1024);
1263*6777b538SAndroid Build Coastguard Worker   InitCache();
1264*6777b538SAndroid Build Coastguard Worker   ReuseEntry(10 * 1024, 0);
1265*6777b538SAndroid Build Coastguard Worker }
1266*6777b538SAndroid Build Coastguard Worker 
1267*6777b538SAndroid Build Coastguard Worker // Reading somewhere that was not written should return zeros.
InvalidData(int stream_index)1268*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::InvalidData(int stream_index) {
1269*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1270*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1271*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1272*6777b538SAndroid Build Coastguard Worker 
1273*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 20000;
1274*6777b538SAndroid Build Coastguard Worker   const int kSize2 = 20000;
1275*6777b538SAndroid Build Coastguard Worker   const int kSize3 = 20000;
1276*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
1277*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize2);
1278*6777b538SAndroid Build Coastguard Worker   auto buffer3 = base::MakeRefCounted<net::IOBufferWithSize>(kSize3);
1279*6777b538SAndroid Build Coastguard Worker 
1280*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
1281*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize2);
1282*6777b538SAndroid Build Coastguard Worker 
1283*6777b538SAndroid Build Coastguard Worker   // Simple data grow:
1284*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(200,
1285*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 400, buffer1.get(), 200, false));
1286*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(600, entry->GetDataSize(stream_index));
1287*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100, ReadData(entry, stream_index, 300, buffer3.get(), 100));
1288*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
1289*6777b538SAndroid Build Coastguard Worker   entry->Close();
1290*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1291*6777b538SAndroid Build Coastguard Worker 
1292*6777b538SAndroid Build Coastguard Worker   // The entry is now on disk. Load it and extend it.
1293*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(200,
1294*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 800, buffer1.get(), 200, false));
1295*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1000, entry->GetDataSize(stream_index));
1296*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100, ReadData(entry, stream_index, 700, buffer3.get(), 100));
1297*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
1298*6777b538SAndroid Build Coastguard Worker   entry->Close();
1299*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1300*6777b538SAndroid Build Coastguard Worker 
1301*6777b538SAndroid Build Coastguard Worker   // This time using truncate.
1302*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(200,
1303*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 1800, buffer1.get(), 200, true));
1304*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2000, entry->GetDataSize(stream_index));
1305*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100, ReadData(entry, stream_index, 1500, buffer3.get(), 100));
1306*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
1307*6777b538SAndroid Build Coastguard Worker 
1308*6777b538SAndroid Build Coastguard Worker   // Go to an external file.
1309*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(200,
1310*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 19800, buffer1.get(), 200, false));
1311*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
1312*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4000, ReadData(entry, stream_index, 14000, buffer3.get(), 4000));
1313*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 4000));
1314*6777b538SAndroid Build Coastguard Worker 
1315*6777b538SAndroid Build Coastguard Worker   // And back to an internal block.
1316*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(600,
1317*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 1000, buffer1.get(), 600, true));
1318*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1600, entry->GetDataSize(stream_index));
1319*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(600, ReadData(entry, stream_index, 1000, buffer3.get(), 600));
1320*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer3->data(), buffer1->data(), 600));
1321*6777b538SAndroid Build Coastguard Worker 
1322*6777b538SAndroid Build Coastguard Worker   // Extend it again.
1323*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(600,
1324*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 2000, buffer1.get(), 600, false));
1325*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2600, entry->GetDataSize(stream_index));
1326*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(200, ReadData(entry, stream_index, 1800, buffer3.get(), 200));
1327*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 200));
1328*6777b538SAndroid Build Coastguard Worker 
1329*6777b538SAndroid Build Coastguard Worker   // And again (with truncation flag).
1330*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(600,
1331*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 3000, buffer1.get(), 600, true));
1332*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3600, entry->GetDataSize(stream_index));
1333*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(200, ReadData(entry, stream_index, 2800, buffer3.get(), 200));
1334*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 200));
1335*6777b538SAndroid Build Coastguard Worker 
1336*6777b538SAndroid Build Coastguard Worker   entry->Close();
1337*6777b538SAndroid Build Coastguard Worker }
1338*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,InvalidData)1339*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, InvalidData) {
1340*6777b538SAndroid Build Coastguard Worker   InitCache();
1341*6777b538SAndroid Build Coastguard Worker   InvalidData(0);
1342*6777b538SAndroid Build Coastguard Worker }
1343*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,InvalidDataNoBuffer)1344*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, InvalidDataNoBuffer) {
1345*6777b538SAndroid Build Coastguard Worker   InitCache();
1346*6777b538SAndroid Build Coastguard Worker   cache_impl_->SetFlags(disk_cache::kNoBuffering);
1347*6777b538SAndroid Build Coastguard Worker   InvalidData(0);
1348*6777b538SAndroid Build Coastguard Worker }
1349*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyInvalidData)1350*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyInvalidData) {
1351*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
1352*6777b538SAndroid Build Coastguard Worker   InitCache();
1353*6777b538SAndroid Build Coastguard Worker   InvalidData(0);
1354*6777b538SAndroid Build Coastguard Worker }
1355*6777b538SAndroid Build Coastguard Worker 
1356*6777b538SAndroid Build Coastguard Worker // Tests that the cache preserves the buffer of an IO operation.
ReadWriteDestroyBuffer(int stream_index)1357*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::ReadWriteDestroyBuffer(int stream_index) {
1358*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1359*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1360*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1361*6777b538SAndroid Build Coastguard Worker 
1362*6777b538SAndroid Build Coastguard Worker   const int kSize = 200;
1363*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1364*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
1365*6777b538SAndroid Build Coastguard Worker 
1366*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
1367*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING,
1368*6777b538SAndroid Build Coastguard Worker             entry->WriteData(
1369*6777b538SAndroid Build Coastguard Worker                 stream_index, 0, buffer.get(), kSize, cb.callback(), false));
1370*6777b538SAndroid Build Coastguard Worker 
1371*6777b538SAndroid Build Coastguard Worker   // Release our reference to the buffer.
1372*6777b538SAndroid Build Coastguard Worker   buffer = nullptr;
1373*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, cb.WaitForResult());
1374*6777b538SAndroid Build Coastguard Worker 
1375*6777b538SAndroid Build Coastguard Worker   // And now test with a Read().
1376*6777b538SAndroid Build Coastguard Worker   buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1377*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
1378*6777b538SAndroid Build Coastguard Worker 
1379*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
1380*6777b538SAndroid Build Coastguard Worker       net::ERR_IO_PENDING,
1381*6777b538SAndroid Build Coastguard Worker       entry->ReadData(stream_index, 0, buffer.get(), kSize, cb.callback()));
1382*6777b538SAndroid Build Coastguard Worker   buffer = nullptr;
1383*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, cb.WaitForResult());
1384*6777b538SAndroid Build Coastguard Worker 
1385*6777b538SAndroid Build Coastguard Worker   entry->Close();
1386*6777b538SAndroid Build Coastguard Worker }
1387*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,ReadWriteDestroyBuffer)1388*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, ReadWriteDestroyBuffer) {
1389*6777b538SAndroid Build Coastguard Worker   InitCache();
1390*6777b538SAndroid Build Coastguard Worker   ReadWriteDestroyBuffer(0);
1391*6777b538SAndroid Build Coastguard Worker }
1392*6777b538SAndroid Build Coastguard Worker 
DoomNormalEntry()1393*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::DoomNormalEntry() {
1394*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1395*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1396*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1397*6777b538SAndroid Build Coastguard Worker   entry->Doom();
1398*6777b538SAndroid Build Coastguard Worker   entry->Close();
1399*6777b538SAndroid Build Coastguard Worker 
1400*6777b538SAndroid Build Coastguard Worker   const int kSize = 20000;
1401*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1402*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, true);
1403*6777b538SAndroid Build Coastguard Worker   buffer->data()[19999] = '\0';
1404*6777b538SAndroid Build Coastguard Worker 
1405*6777b538SAndroid Build Coastguard Worker   key = buffer->data();
1406*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1407*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, WriteData(entry, 0, 0, buffer.get(), kSize, false));
1408*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20000, WriteData(entry, 1, 0, buffer.get(), kSize, false));
1409*6777b538SAndroid Build Coastguard Worker   entry->Doom();
1410*6777b538SAndroid Build Coastguard Worker   entry->Close();
1411*6777b538SAndroid Build Coastguard Worker 
1412*6777b538SAndroid Build Coastguard Worker   FlushQueueForTest();
1413*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache_->GetEntryCount());
1414*6777b538SAndroid Build Coastguard Worker }
1415*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,DoomEntry)1416*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, DoomEntry) {
1417*6777b538SAndroid Build Coastguard Worker   InitCache();
1418*6777b538SAndroid Build Coastguard Worker   DoomNormalEntry();
1419*6777b538SAndroid Build Coastguard Worker }
1420*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyDoomEntry)1421*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyDoomEntry) {
1422*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
1423*6777b538SAndroid Build Coastguard Worker   InitCache();
1424*6777b538SAndroid Build Coastguard Worker   DoomNormalEntry();
1425*6777b538SAndroid Build Coastguard Worker }
1426*6777b538SAndroid Build Coastguard Worker 
1427*6777b538SAndroid Build Coastguard Worker // Tests dooming an entry that's linked to an open entry.
DoomEntryNextToOpenEntry()1428*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::DoomEntryNextToOpenEntry() {
1429*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1;
1430*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2;
1431*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("fixed", &entry1), IsOk());
1432*6777b538SAndroid Build Coastguard Worker   entry1->Close();
1433*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("foo", &entry1), IsOk());
1434*6777b538SAndroid Build Coastguard Worker   entry1->Close();
1435*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("bar", &entry1), IsOk());
1436*6777b538SAndroid Build Coastguard Worker   entry1->Close();
1437*6777b538SAndroid Build Coastguard Worker 
1438*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry("foo", &entry1), IsOk());
1439*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry("bar", &entry2), IsOk());
1440*6777b538SAndroid Build Coastguard Worker   entry2->Doom();
1441*6777b538SAndroid Build Coastguard Worker   entry2->Close();
1442*6777b538SAndroid Build Coastguard Worker 
1443*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry("foo", &entry2), IsOk());
1444*6777b538SAndroid Build Coastguard Worker   entry2->Doom();
1445*6777b538SAndroid Build Coastguard Worker   entry2->Close();
1446*6777b538SAndroid Build Coastguard Worker   entry1->Close();
1447*6777b538SAndroid Build Coastguard Worker 
1448*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry("fixed", &entry1), IsOk());
1449*6777b538SAndroid Build Coastguard Worker   entry1->Close();
1450*6777b538SAndroid Build Coastguard Worker }
1451*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,DoomEntryNextToOpenEntry)1452*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, DoomEntryNextToOpenEntry) {
1453*6777b538SAndroid Build Coastguard Worker   InitCache();
1454*6777b538SAndroid Build Coastguard Worker   DoomEntryNextToOpenEntry();
1455*6777b538SAndroid Build Coastguard Worker }
1456*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,NewEvictionDoomEntryNextToOpenEntry)1457*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, NewEvictionDoomEntryNextToOpenEntry) {
1458*6777b538SAndroid Build Coastguard Worker   SetNewEviction();
1459*6777b538SAndroid Build Coastguard Worker   InitCache();
1460*6777b538SAndroid Build Coastguard Worker   DoomEntryNextToOpenEntry();
1461*6777b538SAndroid Build Coastguard Worker }
1462*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,AppCacheDoomEntryNextToOpenEntry)1463*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, AppCacheDoomEntryNextToOpenEntry) {
1464*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
1465*6777b538SAndroid Build Coastguard Worker   InitCache();
1466*6777b538SAndroid Build Coastguard Worker   DoomEntryNextToOpenEntry();
1467*6777b538SAndroid Build Coastguard Worker }
1468*6777b538SAndroid Build Coastguard Worker 
1469*6777b538SAndroid Build Coastguard Worker // Verify that basic operations work as expected with doomed entries.
DoomedEntry(int stream_index)1470*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::DoomedEntry(int stream_index) {
1471*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1472*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1473*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1474*6777b538SAndroid Build Coastguard Worker   entry->Doom();
1475*6777b538SAndroid Build Coastguard Worker 
1476*6777b538SAndroid Build Coastguard Worker   FlushQueueForTest();
1477*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache_->GetEntryCount());
1478*6777b538SAndroid Build Coastguard Worker   Time initial = Time::Now();
1479*6777b538SAndroid Build Coastguard Worker   AddDelay();
1480*6777b538SAndroid Build Coastguard Worker 
1481*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 2000;
1482*6777b538SAndroid Build Coastguard Worker   const int kSize2 = 2000;
1483*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
1484*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize2);
1485*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
1486*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize2);
1487*6777b538SAndroid Build Coastguard Worker 
1488*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2000,
1489*6777b538SAndroid Build Coastguard Worker             WriteData(entry, stream_index, 0, buffer1.get(), 2000, false));
1490*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2000, ReadData(entry, stream_index, 0, buffer2.get(), 2000));
1491*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize1));
1492*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(key, entry->GetKey());
1493*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(initial < entry->GetLastModified());
1494*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(initial < entry->GetLastUsed());
1495*6777b538SAndroid Build Coastguard Worker 
1496*6777b538SAndroid Build Coastguard Worker   entry->Close();
1497*6777b538SAndroid Build Coastguard Worker }
1498*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,DoomedEntry)1499*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, DoomedEntry) {
1500*6777b538SAndroid Build Coastguard Worker   InitCache();
1501*6777b538SAndroid Build Coastguard Worker   DoomedEntry(0);
1502*6777b538SAndroid Build Coastguard Worker }
1503*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyDoomedEntry)1504*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyDoomedEntry) {
1505*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
1506*6777b538SAndroid Build Coastguard Worker   InitCache();
1507*6777b538SAndroid Build Coastguard Worker   DoomedEntry(0);
1508*6777b538SAndroid Build Coastguard Worker }
1509*6777b538SAndroid Build Coastguard Worker 
1510*6777b538SAndroid Build Coastguard Worker // Tests that we discard entries if the data is missing.
TEST_F(DiskCacheEntryTest,MissingData)1511*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MissingData) {
1512*6777b538SAndroid Build Coastguard Worker   InitCache();
1513*6777b538SAndroid Build Coastguard Worker 
1514*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1515*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1516*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1517*6777b538SAndroid Build Coastguard Worker 
1518*6777b538SAndroid Build Coastguard Worker   // Write to an external file.
1519*6777b538SAndroid Build Coastguard Worker   const int kSize = 20000;
1520*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1521*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
1522*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
1523*6777b538SAndroid Build Coastguard Worker   entry->Close();
1524*6777b538SAndroid Build Coastguard Worker   FlushQueueForTest();
1525*6777b538SAndroid Build Coastguard Worker 
1526*6777b538SAndroid Build Coastguard Worker   disk_cache::Addr address(0x80000001);
1527*6777b538SAndroid Build Coastguard Worker   base::FilePath name = cache_impl_->GetFileName(address);
1528*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::DeleteFile(name));
1529*6777b538SAndroid Build Coastguard Worker 
1530*6777b538SAndroid Build Coastguard Worker   // Attempt to read the data.
1531*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1532*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_FILE_NOT_FOUND,
1533*6777b538SAndroid Build Coastguard Worker             ReadData(entry, 0, 0, buffer.get(), kSize));
1534*6777b538SAndroid Build Coastguard Worker   entry->Close();
1535*6777b538SAndroid Build Coastguard Worker 
1536*6777b538SAndroid Build Coastguard Worker   // The entry should be gone.
1537*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(net::OK, OpenEntry(key, &entry));
1538*6777b538SAndroid Build Coastguard Worker }
1539*6777b538SAndroid Build Coastguard Worker 
1540*6777b538SAndroid Build Coastguard Worker // Test that child entries in a memory cache backend are not visible from
1541*6777b538SAndroid Build Coastguard Worker // enumerations.
TEST_F(DiskCacheEntryTest,MemoryOnlyEnumerationWithSparseEntries)1542*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyEnumerationWithSparseEntries) {
1543*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
1544*6777b538SAndroid Build Coastguard Worker   InitCache();
1545*6777b538SAndroid Build Coastguard Worker 
1546*6777b538SAndroid Build Coastguard Worker   const int kSize = 4096;
1547*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1548*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf->data(), kSize, false);
1549*6777b538SAndroid Build Coastguard Worker 
1550*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1551*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* parent_entry;
1552*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &parent_entry), IsOk());
1553*6777b538SAndroid Build Coastguard Worker 
1554*6777b538SAndroid Build Coastguard Worker   // Writes to the parent entry.
1555*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, parent_entry->WriteSparseData(
1556*6777b538SAndroid Build Coastguard Worker                        0, buf.get(), kSize, net::CompletionOnceCallback()));
1557*6777b538SAndroid Build Coastguard Worker 
1558*6777b538SAndroid Build Coastguard Worker   // This write creates a child entry and writes to it.
1559*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, parent_entry->WriteSparseData(
1560*6777b538SAndroid Build Coastguard Worker                        8192, buf.get(), kSize, net::CompletionOnceCallback()));
1561*6777b538SAndroid Build Coastguard Worker 
1562*6777b538SAndroid Build Coastguard Worker   parent_entry->Close();
1563*6777b538SAndroid Build Coastguard Worker 
1564*6777b538SAndroid Build Coastguard Worker   // Perform the enumerations.
1565*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<TestIterator> iter = CreateIterator();
1566*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
1567*6777b538SAndroid Build Coastguard Worker   int count = 0;
1568*6777b538SAndroid Build Coastguard Worker   while (iter->OpenNextEntry(&entry) == net::OK) {
1569*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(entry != nullptr);
1570*6777b538SAndroid Build Coastguard Worker     ++count;
1571*6777b538SAndroid Build Coastguard Worker     disk_cache::MemEntryImpl* mem_entry =
1572*6777b538SAndroid Build Coastguard Worker         reinterpret_cast<disk_cache::MemEntryImpl*>(entry);
1573*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(disk_cache::MemEntryImpl::EntryType::kParent, mem_entry->type());
1574*6777b538SAndroid Build Coastguard Worker     mem_entry->Close();
1575*6777b538SAndroid Build Coastguard Worker   }
1576*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, count);
1577*6777b538SAndroid Build Coastguard Worker }
1578*6777b538SAndroid Build Coastguard Worker 
1579*6777b538SAndroid Build Coastguard Worker // Writes |buf_1| to offset and reads it back as |buf_2|.
VerifySparseIO(disk_cache::Entry * entry,int64_t offset,net::IOBuffer * buf_1,int size,net::IOBuffer * buf_2)1580*6777b538SAndroid Build Coastguard Worker void VerifySparseIO(disk_cache::Entry* entry,
1581*6777b538SAndroid Build Coastguard Worker                     int64_t offset,
1582*6777b538SAndroid Build Coastguard Worker                     net::IOBuffer* buf_1,
1583*6777b538SAndroid Build Coastguard Worker                     int size,
1584*6777b538SAndroid Build Coastguard Worker                     net::IOBuffer* buf_2) {
1585*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
1586*6777b538SAndroid Build Coastguard Worker 
1587*6777b538SAndroid Build Coastguard Worker   memset(buf_2->data(), 0, size);
1588*6777b538SAndroid Build Coastguard Worker   int ret = entry->ReadSparseData(offset, buf_2, size, cb.callback());
1589*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cb.GetResult(ret));
1590*6777b538SAndroid Build Coastguard Worker 
1591*6777b538SAndroid Build Coastguard Worker   ret = entry->WriteSparseData(offset, buf_1, size, cb.callback());
1592*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(size, cb.GetResult(ret));
1593*6777b538SAndroid Build Coastguard Worker 
1594*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadSparseData(offset, buf_2, size, cb.callback());
1595*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(size, cb.GetResult(ret));
1596*6777b538SAndroid Build Coastguard Worker 
1597*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buf_1->data(), buf_2->data(), size));
1598*6777b538SAndroid Build Coastguard Worker }
1599*6777b538SAndroid Build Coastguard Worker 
1600*6777b538SAndroid Build Coastguard Worker // Reads |size| bytes from |entry| at |offset| and verifies that they are the
1601*6777b538SAndroid Build Coastguard Worker // same as the content of the provided |buffer|.
VerifyContentSparseIO(disk_cache::Entry * entry,int64_t offset,char * buffer,int size)1602*6777b538SAndroid Build Coastguard Worker void VerifyContentSparseIO(disk_cache::Entry* entry,
1603*6777b538SAndroid Build Coastguard Worker                            int64_t offset,
1604*6777b538SAndroid Build Coastguard Worker                            char* buffer,
1605*6777b538SAndroid Build Coastguard Worker                            int size) {
1606*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
1607*6777b538SAndroid Build Coastguard Worker 
1608*6777b538SAndroid Build Coastguard Worker   auto buf_1 = base::MakeRefCounted<net::IOBufferWithSize>(size);
1609*6777b538SAndroid Build Coastguard Worker   memset(buf_1->data(), 0, size);
1610*6777b538SAndroid Build Coastguard Worker   int ret = entry->ReadSparseData(offset, buf_1.get(), size, cb.callback());
1611*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(size, cb.GetResult(ret));
1612*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buf_1->data(), buffer, size));
1613*6777b538SAndroid Build Coastguard Worker }
1614*6777b538SAndroid Build Coastguard Worker 
BasicSparseIO()1615*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::BasicSparseIO() {
1616*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1617*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1618*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1619*6777b538SAndroid Build Coastguard Worker 
1620*6777b538SAndroid Build Coastguard Worker   const int kSize = 2048;
1621*6777b538SAndroid Build Coastguard Worker   auto buf_1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1622*6777b538SAndroid Build Coastguard Worker   auto buf_2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1623*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf_1->data(), kSize, false);
1624*6777b538SAndroid Build Coastguard Worker 
1625*6777b538SAndroid Build Coastguard Worker   // Write at offset 0.
1626*6777b538SAndroid Build Coastguard Worker   VerifySparseIO(entry, 0, buf_1.get(), kSize, buf_2.get());
1627*6777b538SAndroid Build Coastguard Worker 
1628*6777b538SAndroid Build Coastguard Worker   // Write at offset 0x400000 (4 MB).
1629*6777b538SAndroid Build Coastguard Worker   VerifySparseIO(entry, 0x400000, buf_1.get(), kSize, buf_2.get());
1630*6777b538SAndroid Build Coastguard Worker 
1631*6777b538SAndroid Build Coastguard Worker   // Write at offset 0x800000000 (32 GB).
1632*6777b538SAndroid Build Coastguard Worker   VerifySparseIO(entry, 0x800000000LL, buf_1.get(), kSize, buf_2.get());
1633*6777b538SAndroid Build Coastguard Worker 
1634*6777b538SAndroid Build Coastguard Worker   entry->Close();
1635*6777b538SAndroid Build Coastguard Worker 
1636*6777b538SAndroid Build Coastguard Worker   // Check everything again.
1637*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1638*6777b538SAndroid Build Coastguard Worker   VerifyContentSparseIO(entry, 0, buf_1->data(), kSize);
1639*6777b538SAndroid Build Coastguard Worker   VerifyContentSparseIO(entry, 0x400000, buf_1->data(), kSize);
1640*6777b538SAndroid Build Coastguard Worker   VerifyContentSparseIO(entry, 0x800000000LL, buf_1->data(), kSize);
1641*6777b538SAndroid Build Coastguard Worker   entry->Close();
1642*6777b538SAndroid Build Coastguard Worker }
1643*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,BasicSparseIO)1644*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, BasicSparseIO) {
1645*6777b538SAndroid Build Coastguard Worker   InitCache();
1646*6777b538SAndroid Build Coastguard Worker   BasicSparseIO();
1647*6777b538SAndroid Build Coastguard Worker }
1648*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyBasicSparseIO)1649*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyBasicSparseIO) {
1650*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
1651*6777b538SAndroid Build Coastguard Worker   InitCache();
1652*6777b538SAndroid Build Coastguard Worker   BasicSparseIO();
1653*6777b538SAndroid Build Coastguard Worker }
1654*6777b538SAndroid Build Coastguard Worker 
HugeSparseIO()1655*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::HugeSparseIO() {
1656*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1657*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1658*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1659*6777b538SAndroid Build Coastguard Worker 
1660*6777b538SAndroid Build Coastguard Worker   // Write 1.2 MB so that we cover multiple entries.
1661*6777b538SAndroid Build Coastguard Worker   const int kSize = 1200 * 1024;
1662*6777b538SAndroid Build Coastguard Worker   auto buf_1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1663*6777b538SAndroid Build Coastguard Worker   auto buf_2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1664*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf_1->data(), kSize, false);
1665*6777b538SAndroid Build Coastguard Worker 
1666*6777b538SAndroid Build Coastguard Worker   // Write at offset 0x20F0000 (33 MB - 64 KB).
1667*6777b538SAndroid Build Coastguard Worker   VerifySparseIO(entry, 0x20F0000, buf_1.get(), kSize, buf_2.get());
1668*6777b538SAndroid Build Coastguard Worker   entry->Close();
1669*6777b538SAndroid Build Coastguard Worker 
1670*6777b538SAndroid Build Coastguard Worker   // Check it again.
1671*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1672*6777b538SAndroid Build Coastguard Worker   VerifyContentSparseIO(entry, 0x20F0000, buf_1->data(), kSize);
1673*6777b538SAndroid Build Coastguard Worker   entry->Close();
1674*6777b538SAndroid Build Coastguard Worker }
1675*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,HugeSparseIO)1676*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, HugeSparseIO) {
1677*6777b538SAndroid Build Coastguard Worker   InitCache();
1678*6777b538SAndroid Build Coastguard Worker   HugeSparseIO();
1679*6777b538SAndroid Build Coastguard Worker }
1680*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyHugeSparseIO)1681*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyHugeSparseIO) {
1682*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
1683*6777b538SAndroid Build Coastguard Worker   InitCache();
1684*6777b538SAndroid Build Coastguard Worker   HugeSparseIO();
1685*6777b538SAndroid Build Coastguard Worker }
1686*6777b538SAndroid Build Coastguard Worker 
GetAvailableRangeTest()1687*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::GetAvailableRangeTest() {
1688*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1689*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1690*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1691*6777b538SAndroid Build Coastguard Worker 
1692*6777b538SAndroid Build Coastguard Worker   const int kSize = 16 * 1024;
1693*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1694*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf->data(), kSize, false);
1695*6777b538SAndroid Build Coastguard Worker 
1696*6777b538SAndroid Build Coastguard Worker   // Write at offset 0x20F0000 (33 MB - 64 KB), and 0x20F4400 (33 MB - 47 KB).
1697*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F0000, buf.get(), kSize));
1698*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F4400, buf.get(), kSize));
1699*6777b538SAndroid Build Coastguard Worker 
1700*6777b538SAndroid Build Coastguard Worker   // We stop at the first empty block.
1701*6777b538SAndroid Build Coastguard Worker   TestRangeResultCompletionCallback cb;
1702*6777b538SAndroid Build Coastguard Worker   RangeResult result = cb.GetResult(
1703*6777b538SAndroid Build Coastguard Worker       entry->GetAvailableRange(0x20F0000, kSize * 2, cb.callback()));
1704*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1705*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, result.available_len);
1706*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0x20F0000, result.start);
1707*6777b538SAndroid Build Coastguard Worker 
1708*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(0, kSize, cb.callback()));
1709*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1710*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.available_len);
1711*6777b538SAndroid Build Coastguard Worker 
1712*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(
1713*6777b538SAndroid Build Coastguard Worker       entry->GetAvailableRange(0x20F0000 - kSize, kSize, cb.callback()));
1714*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1715*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.available_len);
1716*6777b538SAndroid Build Coastguard Worker 
1717*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(0, 0x2100000, cb.callback()));
1718*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1719*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, result.available_len);
1720*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0x20F0000, result.start);
1721*6777b538SAndroid Build Coastguard Worker 
1722*6777b538SAndroid Build Coastguard Worker   // We should be able to Read based on the results of GetAvailableRange.
1723*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback read_cb;
1724*6777b538SAndroid Build Coastguard Worker   result =
1725*6777b538SAndroid Build Coastguard Worker       cb.GetResult(entry->GetAvailableRange(0x2100000, kSize, cb.callback()));
1726*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1727*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.available_len);
1728*6777b538SAndroid Build Coastguard Worker   int rv =
1729*6777b538SAndroid Build Coastguard Worker       entry->ReadSparseData(result.start, buf.get(), kSize, read_cb.callback());
1730*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, read_cb.GetResult(rv));
1731*6777b538SAndroid Build Coastguard Worker 
1732*6777b538SAndroid Build Coastguard Worker   result =
1733*6777b538SAndroid Build Coastguard Worker       cb.GetResult(entry->GetAvailableRange(0x20F2000, kSize, cb.callback()));
1734*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1735*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0x2000, result.available_len);
1736*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0x20F2000, result.start);
1737*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0x2000, ReadSparseData(entry, result.start, buf.get(), kSize));
1738*6777b538SAndroid Build Coastguard Worker 
1739*6777b538SAndroid Build Coastguard Worker   // Make sure that we respect the |len| argument.
1740*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(
1741*6777b538SAndroid Build Coastguard Worker       entry->GetAvailableRange(0x20F0001 - kSize, kSize, cb.callback()));
1742*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1743*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, result.available_len);
1744*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0x20F0000, result.start);
1745*6777b538SAndroid Build Coastguard Worker 
1746*6777b538SAndroid Build Coastguard Worker   // Use very small ranges. Write at offset 50.
1747*6777b538SAndroid Build Coastguard Worker   const int kTinyLen = 10;
1748*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTinyLen, WriteSparseData(entry, 50, buf.get(), kTinyLen));
1749*6777b538SAndroid Build Coastguard Worker 
1750*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(
1751*6777b538SAndroid Build Coastguard Worker       entry->GetAvailableRange(kTinyLen * 2, kTinyLen, cb.callback()));
1752*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1753*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.available_len);
1754*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTinyLen * 2, result.start);
1755*6777b538SAndroid Build Coastguard Worker 
1756*6777b538SAndroid Build Coastguard Worker   // Get a huge range with maximum boundary
1757*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(
1758*6777b538SAndroid Build Coastguard Worker       0x2100000, std::numeric_limits<int32_t>::max(), cb.callback()));
1759*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1760*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.available_len);
1761*6777b538SAndroid Build Coastguard Worker 
1762*6777b538SAndroid Build Coastguard Worker   entry->Close();
1763*6777b538SAndroid Build Coastguard Worker }
1764*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,GetAvailableRange)1765*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, GetAvailableRange) {
1766*6777b538SAndroid Build Coastguard Worker   InitCache();
1767*6777b538SAndroid Build Coastguard Worker   GetAvailableRangeTest();
1768*6777b538SAndroid Build Coastguard Worker }
1769*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyGetAvailableRange)1770*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyGetAvailableRange) {
1771*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
1772*6777b538SAndroid Build Coastguard Worker   InitCache();
1773*6777b538SAndroid Build Coastguard Worker   GetAvailableRangeTest();
1774*6777b538SAndroid Build Coastguard Worker }
1775*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,GetAvailableRangeBlockFileDiscontinuous)1776*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, GetAvailableRangeBlockFileDiscontinuous) {
1777*6777b538SAndroid Build Coastguard Worker   // crbug.com/791056 --- blockfile problem when there is a sub-KiB write before
1778*6777b538SAndroid Build Coastguard Worker   // a bunch of full 1KiB blocks, and a GetAvailableRange is issued to which
1779*6777b538SAndroid Build Coastguard Worker   // both are a potentially relevant.
1780*6777b538SAndroid Build Coastguard Worker   InitCache();
1781*6777b538SAndroid Build Coastguard Worker 
1782*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1783*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1784*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1785*6777b538SAndroid Build Coastguard Worker 
1786*6777b538SAndroid Build Coastguard Worker   auto buf_2k = base::MakeRefCounted<net::IOBufferWithSize>(2 * 1024);
1787*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf_2k->data(), 2 * 1024, false);
1788*6777b538SAndroid Build Coastguard Worker 
1789*6777b538SAndroid Build Coastguard Worker   const int kSmallSize = 612;  // sub-1k
1790*6777b538SAndroid Build Coastguard Worker   auto buf_small = base::MakeRefCounted<net::IOBufferWithSize>(kSmallSize);
1791*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf_small->data(), kSmallSize, false);
1792*6777b538SAndroid Build Coastguard Worker 
1793*6777b538SAndroid Build Coastguard Worker   // Sets some bits for blocks representing 1K ranges [1024, 3072),
1794*6777b538SAndroid Build Coastguard Worker   // which will be relevant for the next GetAvailableRange call.
1795*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2 * 1024, WriteSparseData(entry, /* offset = */ 1024, buf_2k.get(),
1796*6777b538SAndroid Build Coastguard Worker                                       /* size = */ 2 * 1024));
1797*6777b538SAndroid Build Coastguard Worker 
1798*6777b538SAndroid Build Coastguard Worker   // Now record a partial write from start of the first kb.
1799*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSmallSize, WriteSparseData(entry, /* offset = */ 0,
1800*6777b538SAndroid Build Coastguard Worker                                         buf_small.get(), kSmallSize));
1801*6777b538SAndroid Build Coastguard Worker 
1802*6777b538SAndroid Build Coastguard Worker   // Try to query a range starting from that block 0.
1803*6777b538SAndroid Build Coastguard Worker   // The cache tracks: [0, 612) [1024, 3072).
1804*6777b538SAndroid Build Coastguard Worker   // The request is for: [812, 2059) so response should be [1024, 2059), which
1805*6777b538SAndroid Build Coastguard Worker   // has length = 1035. Previously this return a negative number for rv.
1806*6777b538SAndroid Build Coastguard Worker   TestRangeResultCompletionCallback cb;
1807*6777b538SAndroid Build Coastguard Worker   RangeResult result =
1808*6777b538SAndroid Build Coastguard Worker       cb.GetResult(entry->GetAvailableRange(812, 1247, cb.callback()));
1809*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1810*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1035, result.available_len);
1811*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1024, result.start);
1812*6777b538SAndroid Build Coastguard Worker 
1813*6777b538SAndroid Build Coastguard Worker   // Now query [512, 1536). This matches both [512, 612) and [1024, 1536),
1814*6777b538SAndroid Build Coastguard Worker   // so this should return [512, 612).
1815*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(512, 1024, cb.callback()));
1816*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1817*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100, result.available_len);
1818*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(512, result.start);
1819*6777b538SAndroid Build Coastguard Worker 
1820*6777b538SAndroid Build Coastguard Worker   // Now query next portion, [612, 1636). This now just should produce
1821*6777b538SAndroid Build Coastguard Worker   // [1024, 1636)
1822*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(612, 1024, cb.callback()));
1823*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1824*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(612, result.available_len);
1825*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1024, result.start);
1826*6777b538SAndroid Build Coastguard Worker 
1827*6777b538SAndroid Build Coastguard Worker   // Do a continuous small write, this one at [3072, 3684).
1828*6777b538SAndroid Build Coastguard Worker   // This means the cache tracks [1024, 3072) via bitmaps and [3072, 3684)
1829*6777b538SAndroid Build Coastguard Worker   // as the last write.
1830*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSmallSize, WriteSparseData(entry, /* offset = */ 3072,
1831*6777b538SAndroid Build Coastguard Worker                                         buf_small.get(), kSmallSize));
1832*6777b538SAndroid Build Coastguard Worker 
1833*6777b538SAndroid Build Coastguard Worker   // Query [2048, 4096). Should get [2048, 3684)
1834*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(2048, 2048, cb.callback()));
1835*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1836*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1636, result.available_len);
1837*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2048, result.start);
1838*6777b538SAndroid Build Coastguard Worker 
1839*6777b538SAndroid Build Coastguard Worker   // Now write at [4096, 4708). Since only one sub-kb thing is tracked, this
1840*6777b538SAndroid Build Coastguard Worker   // now tracks  [1024, 3072) via bitmaps and [4096, 4708) as the last write.
1841*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSmallSize, WriteSparseData(entry, /* offset = */ 4096,
1842*6777b538SAndroid Build Coastguard Worker                                         buf_small.get(), kSmallSize));
1843*6777b538SAndroid Build Coastguard Worker 
1844*6777b538SAndroid Build Coastguard Worker   // Query [2048, 4096). Should get [2048, 3072)
1845*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(2048, 2048, cb.callback()));
1846*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1847*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1024, result.available_len);
1848*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2048, result.start);
1849*6777b538SAndroid Build Coastguard Worker 
1850*6777b538SAndroid Build Coastguard Worker   // Query 2K more after that: [3072, 5120). Should get [4096, 4708)
1851*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(3072, 2048, cb.callback()));
1852*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1853*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(612, result.available_len);
1854*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4096, result.start);
1855*6777b538SAndroid Build Coastguard Worker 
1856*6777b538SAndroid Build Coastguard Worker   // Also double-check that offsets within later children are correctly
1857*6777b538SAndroid Build Coastguard Worker   // computed.
1858*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSmallSize, WriteSparseData(entry, /* offset = */ 0x200400,
1859*6777b538SAndroid Build Coastguard Worker                                         buf_small.get(), kSmallSize));
1860*6777b538SAndroid Build Coastguard Worker   result =
1861*6777b538SAndroid Build Coastguard Worker       cb.GetResult(entry->GetAvailableRange(0x100000, 0x200000, cb.callback()));
1862*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1863*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSmallSize, result.available_len);
1864*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0x200400, result.start);
1865*6777b538SAndroid Build Coastguard Worker 
1866*6777b538SAndroid Build Coastguard Worker   entry->Close();
1867*6777b538SAndroid Build Coastguard Worker }
1868*6777b538SAndroid Build Coastguard Worker 
1869*6777b538SAndroid Build Coastguard Worker // Tests that non-sequential writes that are not aligned with the minimum sparse
1870*6777b538SAndroid Build Coastguard Worker // data granularity (1024 bytes) do in fact result in dropped data.
TEST_F(DiskCacheEntryTest,SparseWriteDropped)1871*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SparseWriteDropped) {
1872*6777b538SAndroid Build Coastguard Worker   InitCache();
1873*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1874*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1875*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1876*6777b538SAndroid Build Coastguard Worker 
1877*6777b538SAndroid Build Coastguard Worker   const int kSize = 180;
1878*6777b538SAndroid Build Coastguard Worker   auto buf_1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1879*6777b538SAndroid Build Coastguard Worker   auto buf_2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1880*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf_1->data(), kSize, false);
1881*6777b538SAndroid Build Coastguard Worker 
1882*6777b538SAndroid Build Coastguard Worker   // Do small writes (180 bytes) that get increasingly close to a 1024-byte
1883*6777b538SAndroid Build Coastguard Worker   // boundary. All data should be dropped until a boundary is crossed, at which
1884*6777b538SAndroid Build Coastguard Worker   // point the data after the boundary is saved (at least for a while).
1885*6777b538SAndroid Build Coastguard Worker   int offset = 1024 - 500;
1886*6777b538SAndroid Build Coastguard Worker   int rv = 0;
1887*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
1888*6777b538SAndroid Build Coastguard Worker   TestRangeResultCompletionCallback range_cb;
1889*6777b538SAndroid Build Coastguard Worker   RangeResult result;
1890*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 5; i++) {
1891*6777b538SAndroid Build Coastguard Worker     // Check result of last GetAvailableRange.
1892*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, result.available_len);
1893*6777b538SAndroid Build Coastguard Worker 
1894*6777b538SAndroid Build Coastguard Worker     rv = entry->WriteSparseData(offset, buf_1.get(), kSize, cb.callback());
1895*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kSize, cb.GetResult(rv));
1896*6777b538SAndroid Build Coastguard Worker 
1897*6777b538SAndroid Build Coastguard Worker     result = range_cb.GetResult(
1898*6777b538SAndroid Build Coastguard Worker         entry->GetAvailableRange(offset - 100, kSize, range_cb.callback()));
1899*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::OK, result.net_error);
1900*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, result.available_len);
1901*6777b538SAndroid Build Coastguard Worker 
1902*6777b538SAndroid Build Coastguard Worker     result = range_cb.GetResult(
1903*6777b538SAndroid Build Coastguard Worker         entry->GetAvailableRange(offset, kSize, range_cb.callback()));
1904*6777b538SAndroid Build Coastguard Worker     if (!result.available_len) {
1905*6777b538SAndroid Build Coastguard Worker       rv = entry->ReadSparseData(offset, buf_2.get(), kSize, cb.callback());
1906*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(0, cb.GetResult(rv));
1907*6777b538SAndroid Build Coastguard Worker     }
1908*6777b538SAndroid Build Coastguard Worker     offset += 1024 * i + 100;
1909*6777b538SAndroid Build Coastguard Worker   }
1910*6777b538SAndroid Build Coastguard Worker 
1911*6777b538SAndroid Build Coastguard Worker   // The last write started 100 bytes below a bundary, so there should be 80
1912*6777b538SAndroid Build Coastguard Worker   // bytes after the boundary.
1913*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(80, result.available_len);
1914*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1024 * 7, result.start);
1915*6777b538SAndroid Build Coastguard Worker   rv = entry->ReadSparseData(result.start, buf_2.get(), kSize, cb.callback());
1916*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(80, cb.GetResult(rv));
1917*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buf_1.get()->data() + 100, buf_2.get()->data(), 80));
1918*6777b538SAndroid Build Coastguard Worker 
1919*6777b538SAndroid Build Coastguard Worker   // And even that part is dropped when another write changes the offset.
1920*6777b538SAndroid Build Coastguard Worker   offset = result.start;
1921*6777b538SAndroid Build Coastguard Worker   rv = entry->WriteSparseData(0, buf_1.get(), kSize, cb.callback());
1922*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, cb.GetResult(rv));
1923*6777b538SAndroid Build Coastguard Worker 
1924*6777b538SAndroid Build Coastguard Worker   result = range_cb.GetResult(
1925*6777b538SAndroid Build Coastguard Worker       entry->GetAvailableRange(offset, kSize, range_cb.callback()));
1926*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1927*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.available_len);
1928*6777b538SAndroid Build Coastguard Worker   entry->Close();
1929*6777b538SAndroid Build Coastguard Worker }
1930*6777b538SAndroid Build Coastguard Worker 
1931*6777b538SAndroid Build Coastguard Worker // Tests that small sequential writes are not dropped.
TEST_F(DiskCacheEntryTest,SparseSquentialWriteNotDropped)1932*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SparseSquentialWriteNotDropped) {
1933*6777b538SAndroid Build Coastguard Worker   InitCache();
1934*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1935*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1936*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1937*6777b538SAndroid Build Coastguard Worker 
1938*6777b538SAndroid Build Coastguard Worker   const int kSize = 180;
1939*6777b538SAndroid Build Coastguard Worker   auto buf_1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1940*6777b538SAndroid Build Coastguard Worker   auto buf_2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1941*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf_1->data(), kSize, false);
1942*6777b538SAndroid Build Coastguard Worker 
1943*6777b538SAndroid Build Coastguard Worker   // Any starting offset is fine as long as it is 1024-bytes aligned.
1944*6777b538SAndroid Build Coastguard Worker   int rv = 0;
1945*6777b538SAndroid Build Coastguard Worker   RangeResult result;
1946*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
1947*6777b538SAndroid Build Coastguard Worker   TestRangeResultCompletionCallback range_cb;
1948*6777b538SAndroid Build Coastguard Worker   int64_t offset = 1024 * 11;
1949*6777b538SAndroid Build Coastguard Worker   for (; offset < 20000; offset += kSize) {
1950*6777b538SAndroid Build Coastguard Worker     rv = entry->WriteSparseData(offset, buf_1.get(), kSize, cb.callback());
1951*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kSize, cb.GetResult(rv));
1952*6777b538SAndroid Build Coastguard Worker 
1953*6777b538SAndroid Build Coastguard Worker     result = range_cb.GetResult(
1954*6777b538SAndroid Build Coastguard Worker         entry->GetAvailableRange(offset, kSize, range_cb.callback()));
1955*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::OK, result.net_error);
1956*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kSize, result.available_len);
1957*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(offset, result.start);
1958*6777b538SAndroid Build Coastguard Worker 
1959*6777b538SAndroid Build Coastguard Worker     rv = entry->ReadSparseData(offset, buf_2.get(), kSize, cb.callback());
1960*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kSize, cb.GetResult(rv));
1961*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(buf_1.get()->data(), buf_2.get()->data(), kSize));
1962*6777b538SAndroid Build Coastguard Worker   }
1963*6777b538SAndroid Build Coastguard Worker 
1964*6777b538SAndroid Build Coastguard Worker   entry->Close();
1965*6777b538SAndroid Build Coastguard Worker   FlushQueueForTest();
1966*6777b538SAndroid Build Coastguard Worker 
1967*6777b538SAndroid Build Coastguard Worker   // Verify again the last write made.
1968*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1969*6777b538SAndroid Build Coastguard Worker   offset -= kSize;
1970*6777b538SAndroid Build Coastguard Worker   result = range_cb.GetResult(
1971*6777b538SAndroid Build Coastguard Worker       entry->GetAvailableRange(offset, kSize, range_cb.callback()));
1972*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
1973*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, result.available_len);
1974*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(offset, result.start);
1975*6777b538SAndroid Build Coastguard Worker 
1976*6777b538SAndroid Build Coastguard Worker   rv = entry->ReadSparseData(offset, buf_2.get(), kSize, cb.callback());
1977*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, cb.GetResult(rv));
1978*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buf_1.get()->data(), buf_2.get()->data(), kSize));
1979*6777b538SAndroid Build Coastguard Worker 
1980*6777b538SAndroid Build Coastguard Worker   entry->Close();
1981*6777b538SAndroid Build Coastguard Worker }
1982*6777b538SAndroid Build Coastguard Worker 
CouldBeSparse()1983*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::CouldBeSparse() {
1984*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
1985*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
1986*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
1987*6777b538SAndroid Build Coastguard Worker 
1988*6777b538SAndroid Build Coastguard Worker   const int kSize = 16 * 1024;
1989*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
1990*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf->data(), kSize, false);
1991*6777b538SAndroid Build Coastguard Worker 
1992*6777b538SAndroid Build Coastguard Worker   // Write at offset 0x20F0000 (33 MB - 64 KB).
1993*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F0000, buf.get(), kSize));
1994*6777b538SAndroid Build Coastguard Worker 
1995*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry->CouldBeSparse());
1996*6777b538SAndroid Build Coastguard Worker   entry->Close();
1997*6777b538SAndroid Build Coastguard Worker 
1998*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
1999*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry->CouldBeSparse());
2000*6777b538SAndroid Build Coastguard Worker   entry->Close();
2001*6777b538SAndroid Build Coastguard Worker 
2002*6777b538SAndroid Build Coastguard Worker   // Now verify a regular entry.
2003*6777b538SAndroid Build Coastguard Worker   key.assign("another key");
2004*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2005*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(entry->CouldBeSparse());
2006*6777b538SAndroid Build Coastguard Worker 
2007*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buf.get(), kSize, false));
2008*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 0, buf.get(), kSize, false));
2009*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 2, 0, buf.get(), kSize, false));
2010*6777b538SAndroid Build Coastguard Worker 
2011*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(entry->CouldBeSparse());
2012*6777b538SAndroid Build Coastguard Worker   entry->Close();
2013*6777b538SAndroid Build Coastguard Worker 
2014*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
2015*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(entry->CouldBeSparse());
2016*6777b538SAndroid Build Coastguard Worker   entry->Close();
2017*6777b538SAndroid Build Coastguard Worker }
2018*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,CouldBeSparse)2019*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, CouldBeSparse) {
2020*6777b538SAndroid Build Coastguard Worker   InitCache();
2021*6777b538SAndroid Build Coastguard Worker   CouldBeSparse();
2022*6777b538SAndroid Build Coastguard Worker }
2023*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryCouldBeSparse)2024*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryCouldBeSparse) {
2025*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
2026*6777b538SAndroid Build Coastguard Worker   InitCache();
2027*6777b538SAndroid Build Coastguard Worker   CouldBeSparse();
2028*6777b538SAndroid Build Coastguard Worker }
2029*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyMisalignedSparseIO)2030*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyMisalignedSparseIO) {
2031*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
2032*6777b538SAndroid Build Coastguard Worker   InitCache();
2033*6777b538SAndroid Build Coastguard Worker 
2034*6777b538SAndroid Build Coastguard Worker   const int kSize = 8192;
2035*6777b538SAndroid Build Coastguard Worker   auto buf_1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2036*6777b538SAndroid Build Coastguard Worker   auto buf_2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2037*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf_1->data(), kSize, false);
2038*6777b538SAndroid Build Coastguard Worker 
2039*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
2040*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
2041*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2042*6777b538SAndroid Build Coastguard Worker 
2043*6777b538SAndroid Build Coastguard Worker   // This loop writes back to back starting from offset 0 and 9000.
2044*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kSize; i += 1024) {
2045*6777b538SAndroid Build Coastguard Worker     auto buf_3 =
2046*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<net::WrappedIOBuffer>(buf_1->span().subspan(i));
2047*6777b538SAndroid Build Coastguard Worker     VerifySparseIO(entry, i, buf_3.get(), 1024, buf_2.get());
2048*6777b538SAndroid Build Coastguard Worker     VerifySparseIO(entry, 9000 + i, buf_3.get(), 1024, buf_2.get());
2049*6777b538SAndroid Build Coastguard Worker   }
2050*6777b538SAndroid Build Coastguard Worker 
2051*6777b538SAndroid Build Coastguard Worker   // Make sure we have data written.
2052*6777b538SAndroid Build Coastguard Worker   VerifyContentSparseIO(entry, 0, buf_1->data(), kSize);
2053*6777b538SAndroid Build Coastguard Worker   VerifyContentSparseIO(entry, 9000, buf_1->data(), kSize);
2054*6777b538SAndroid Build Coastguard Worker 
2055*6777b538SAndroid Build Coastguard Worker   // This tests a large write that spans 3 entries from a misaligned offset.
2056*6777b538SAndroid Build Coastguard Worker   VerifySparseIO(entry, 20481, buf_1.get(), 8192, buf_2.get());
2057*6777b538SAndroid Build Coastguard Worker 
2058*6777b538SAndroid Build Coastguard Worker   entry->Close();
2059*6777b538SAndroid Build Coastguard Worker }
2060*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyMisalignedGetAvailableRange)2061*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyMisalignedGetAvailableRange) {
2062*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
2063*6777b538SAndroid Build Coastguard Worker   InitCache();
2064*6777b538SAndroid Build Coastguard Worker 
2065*6777b538SAndroid Build Coastguard Worker   const int kSize = 8192;
2066*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2067*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf->data(), kSize, false);
2068*6777b538SAndroid Build Coastguard Worker 
2069*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
2070*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
2071*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2072*6777b538SAndroid Build Coastguard Worker 
2073*6777b538SAndroid Build Coastguard Worker   // Writes in the middle of an entry.
2074*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1024, entry->WriteSparseData(0, buf.get(), 1024,
2075*6777b538SAndroid Build Coastguard Worker                                          net::CompletionOnceCallback()));
2076*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1024, entry->WriteSparseData(5120, buf.get(), 1024,
2077*6777b538SAndroid Build Coastguard Worker                                          net::CompletionOnceCallback()));
2078*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1024, entry->WriteSparseData(10000, buf.get(), 1024,
2079*6777b538SAndroid Build Coastguard Worker                                          net::CompletionOnceCallback()));
2080*6777b538SAndroid Build Coastguard Worker 
2081*6777b538SAndroid Build Coastguard Worker   // Writes in the middle of an entry and spans 2 child entries.
2082*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(8192, entry->WriteSparseData(50000, buf.get(), 8192,
2083*6777b538SAndroid Build Coastguard Worker                                          net::CompletionOnceCallback()));
2084*6777b538SAndroid Build Coastguard Worker 
2085*6777b538SAndroid Build Coastguard Worker   TestRangeResultCompletionCallback cb;
2086*6777b538SAndroid Build Coastguard Worker   // Test that we stop at a discontinuous child at the second block.
2087*6777b538SAndroid Build Coastguard Worker   RangeResult result =
2088*6777b538SAndroid Build Coastguard Worker       cb.GetResult(entry->GetAvailableRange(0, 10000, cb.callback()));
2089*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2090*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1024, result.available_len);
2091*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.start);
2092*6777b538SAndroid Build Coastguard Worker 
2093*6777b538SAndroid Build Coastguard Worker   // Test that number of bytes is reported correctly when we start from the
2094*6777b538SAndroid Build Coastguard Worker   // middle of a filled region.
2095*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(512, 10000, cb.callback()));
2096*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2097*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(512, result.available_len);
2098*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(512, result.start);
2099*6777b538SAndroid Build Coastguard Worker 
2100*6777b538SAndroid Build Coastguard Worker   // Test that we found bytes in the child of next block.
2101*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(1024, 10000, cb.callback()));
2102*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2103*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1024, result.available_len);
2104*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5120, result.start);
2105*6777b538SAndroid Build Coastguard Worker 
2106*6777b538SAndroid Build Coastguard Worker   // Test that the desired length is respected. It starts within a filled
2107*6777b538SAndroid Build Coastguard Worker   // region.
2108*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(5500, 512, cb.callback()));
2109*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2110*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(512, result.available_len);
2111*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5500, result.start);
2112*6777b538SAndroid Build Coastguard Worker 
2113*6777b538SAndroid Build Coastguard Worker   // Test that the desired length is respected. It starts before a filled
2114*6777b538SAndroid Build Coastguard Worker   // region.
2115*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(5000, 620, cb.callback()));
2116*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2117*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(500, result.available_len);
2118*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5120, result.start);
2119*6777b538SAndroid Build Coastguard Worker 
2120*6777b538SAndroid Build Coastguard Worker   // Test that multiple blocks are scanned.
2121*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(40000, 20000, cb.callback()));
2122*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2123*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(8192, result.available_len);
2124*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(50000, result.start);
2125*6777b538SAndroid Build Coastguard Worker 
2126*6777b538SAndroid Build Coastguard Worker   entry->Close();
2127*6777b538SAndroid Build Coastguard Worker }
2128*6777b538SAndroid Build Coastguard Worker 
UpdateSparseEntry()2129*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::UpdateSparseEntry() {
2130*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
2131*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1;
2132*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry1), IsOk());
2133*6777b538SAndroid Build Coastguard Worker 
2134*6777b538SAndroid Build Coastguard Worker   const int kSize = 2048;
2135*6777b538SAndroid Build Coastguard Worker   auto buf_1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2136*6777b538SAndroid Build Coastguard Worker   auto buf_2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2137*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf_1->data(), kSize, false);
2138*6777b538SAndroid Build Coastguard Worker 
2139*6777b538SAndroid Build Coastguard Worker   // Write at offset 0.
2140*6777b538SAndroid Build Coastguard Worker   VerifySparseIO(entry1, 0, buf_1.get(), kSize, buf_2.get());
2141*6777b538SAndroid Build Coastguard Worker   entry1->Close();
2142*6777b538SAndroid Build Coastguard Worker 
2143*6777b538SAndroid Build Coastguard Worker   // Write at offset 2048.
2144*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry1), IsOk());
2145*6777b538SAndroid Build Coastguard Worker   VerifySparseIO(entry1, 2048, buf_1.get(), kSize, buf_2.get());
2146*6777b538SAndroid Build Coastguard Worker 
2147*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2;
2148*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("the second key", &entry2), IsOk());
2149*6777b538SAndroid Build Coastguard Worker 
2150*6777b538SAndroid Build Coastguard Worker   entry1->Close();
2151*6777b538SAndroid Build Coastguard Worker   entry2->Close();
2152*6777b538SAndroid Build Coastguard Worker   FlushQueueForTest();
2153*6777b538SAndroid Build Coastguard Worker   if (memory_only_ || simple_cache_mode_)
2154*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache_->GetEntryCount());
2155*6777b538SAndroid Build Coastguard Worker   else
2156*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(3, cache_->GetEntryCount());
2157*6777b538SAndroid Build Coastguard Worker }
2158*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,UpdateSparseEntry)2159*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, UpdateSparseEntry) {
2160*6777b538SAndroid Build Coastguard Worker   InitCache();
2161*6777b538SAndroid Build Coastguard Worker   UpdateSparseEntry();
2162*6777b538SAndroid Build Coastguard Worker }
2163*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyUpdateSparseEntry)2164*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyUpdateSparseEntry) {
2165*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
2166*6777b538SAndroid Build Coastguard Worker   InitCache();
2167*6777b538SAndroid Build Coastguard Worker   UpdateSparseEntry();
2168*6777b538SAndroid Build Coastguard Worker }
2169*6777b538SAndroid Build Coastguard Worker 
DoomSparseEntry()2170*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::DoomSparseEntry() {
2171*6777b538SAndroid Build Coastguard Worker   std::string key1("the first key");
2172*6777b538SAndroid Build Coastguard Worker   std::string key2("the second key");
2173*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry *entry1, *entry2;
2174*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key1, &entry1), IsOk());
2175*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key2, &entry2), IsOk());
2176*6777b538SAndroid Build Coastguard Worker 
2177*6777b538SAndroid Build Coastguard Worker   const int kSize = 4 * 1024;
2178*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2179*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf->data(), kSize, false);
2180*6777b538SAndroid Build Coastguard Worker 
2181*6777b538SAndroid Build Coastguard Worker   int64_t offset = 1024;
2182*6777b538SAndroid Build Coastguard Worker   // Write to a bunch of ranges.
2183*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 12; i++) {
2184*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kSize, WriteSparseData(entry1, offset, buf.get(), kSize));
2185*6777b538SAndroid Build Coastguard Worker     // Keep the second map under the default size.
2186*6777b538SAndroid Build Coastguard Worker     if (i < 9)
2187*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(kSize, WriteSparseData(entry2, offset, buf.get(), kSize));
2188*6777b538SAndroid Build Coastguard Worker 
2189*6777b538SAndroid Build Coastguard Worker     offset *= 4;
2190*6777b538SAndroid Build Coastguard Worker   }
2191*6777b538SAndroid Build Coastguard Worker 
2192*6777b538SAndroid Build Coastguard Worker   if (memory_only_ || simple_cache_mode_)
2193*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, cache_->GetEntryCount());
2194*6777b538SAndroid Build Coastguard Worker   else
2195*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(15, cache_->GetEntryCount());
2196*6777b538SAndroid Build Coastguard Worker 
2197*6777b538SAndroid Build Coastguard Worker   // Doom the first entry while it's still open.
2198*6777b538SAndroid Build Coastguard Worker   entry1->Doom();
2199*6777b538SAndroid Build Coastguard Worker   entry1->Close();
2200*6777b538SAndroid Build Coastguard Worker   entry2->Close();
2201*6777b538SAndroid Build Coastguard Worker 
2202*6777b538SAndroid Build Coastguard Worker   // Doom the second entry after it's fully saved.
2203*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(DoomEntry(key2), IsOk());
2204*6777b538SAndroid Build Coastguard Worker 
2205*6777b538SAndroid Build Coastguard Worker   // Make sure we do all needed work. This may fail for entry2 if between Close
2206*6777b538SAndroid Build Coastguard Worker   // and DoomEntry the system decides to remove all traces of the file from the
2207*6777b538SAndroid Build Coastguard Worker   // system cache so we don't see that there is pending IO.
2208*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
2209*6777b538SAndroid Build Coastguard Worker 
2210*6777b538SAndroid Build Coastguard Worker   if (memory_only_) {
2211*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache_->GetEntryCount());
2212*6777b538SAndroid Build Coastguard Worker   } else {
2213*6777b538SAndroid Build Coastguard Worker     if (5 == cache_->GetEntryCount()) {
2214*6777b538SAndroid Build Coastguard Worker       // Most likely we are waiting for the result of reading the sparse info
2215*6777b538SAndroid Build Coastguard Worker       // (it's always async on Posix so it is easy to miss). Unfortunately we
2216*6777b538SAndroid Build Coastguard Worker       // don't have any signal to watch for so we can only wait.
2217*6777b538SAndroid Build Coastguard Worker       base::PlatformThread::Sleep(base::Milliseconds(500));
2218*6777b538SAndroid Build Coastguard Worker       base::RunLoop().RunUntilIdle();
2219*6777b538SAndroid Build Coastguard Worker     }
2220*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, cache_->GetEntryCount());
2221*6777b538SAndroid Build Coastguard Worker   }
2222*6777b538SAndroid Build Coastguard Worker }
2223*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,DoomSparseEntry)2224*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, DoomSparseEntry) {
2225*6777b538SAndroid Build Coastguard Worker   UseCurrentThread();
2226*6777b538SAndroid Build Coastguard Worker   InitCache();
2227*6777b538SAndroid Build Coastguard Worker   DoomSparseEntry();
2228*6777b538SAndroid Build Coastguard Worker }
2229*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyDoomSparseEntry)2230*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyDoomSparseEntry) {
2231*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
2232*6777b538SAndroid Build Coastguard Worker   InitCache();
2233*6777b538SAndroid Build Coastguard Worker   DoomSparseEntry();
2234*6777b538SAndroid Build Coastguard Worker }
2235*6777b538SAndroid Build Coastguard Worker 
2236*6777b538SAndroid Build Coastguard Worker // A TestCompletionCallback wrapper that deletes the cache from within the
2237*6777b538SAndroid Build Coastguard Worker // callback.  The way TestCompletionCallback works means that all tasks (even
2238*6777b538SAndroid Build Coastguard Worker // new ones) are executed by the message loop before returning to the caller so
2239*6777b538SAndroid Build Coastguard Worker // the only way to simulate a race is to execute what we want on the callback.
2240*6777b538SAndroid Build Coastguard Worker class SparseTestCompletionCallback: public net::TestCompletionCallback {
2241*6777b538SAndroid Build Coastguard Worker  public:
SparseTestCompletionCallback(std::unique_ptr<disk_cache::Backend> cache)2242*6777b538SAndroid Build Coastguard Worker   explicit SparseTestCompletionCallback(
2243*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<disk_cache::Backend> cache)
2244*6777b538SAndroid Build Coastguard Worker       : cache_(std::move(cache)) {}
2245*6777b538SAndroid Build Coastguard Worker 
2246*6777b538SAndroid Build Coastguard Worker   SparseTestCompletionCallback(const SparseTestCompletionCallback&) = delete;
2247*6777b538SAndroid Build Coastguard Worker   SparseTestCompletionCallback& operator=(const SparseTestCompletionCallback&) =
2248*6777b538SAndroid Build Coastguard Worker       delete;
2249*6777b538SAndroid Build Coastguard Worker 
2250*6777b538SAndroid Build Coastguard Worker  private:
SetResult(int result)2251*6777b538SAndroid Build Coastguard Worker   void SetResult(int result) override {
2252*6777b538SAndroid Build Coastguard Worker     cache_.reset();
2253*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback::SetResult(result);
2254*6777b538SAndroid Build Coastguard Worker   }
2255*6777b538SAndroid Build Coastguard Worker 
2256*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<disk_cache::Backend> cache_;
2257*6777b538SAndroid Build Coastguard Worker };
2258*6777b538SAndroid Build Coastguard Worker 
2259*6777b538SAndroid Build Coastguard Worker // Tests that we don't crash when the backend is deleted while we are working
2260*6777b538SAndroid Build Coastguard Worker // deleting the sub-entries of a sparse entry.
TEST_F(DiskCacheEntryTest,DoomSparseEntry2)2261*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, DoomSparseEntry2) {
2262*6777b538SAndroid Build Coastguard Worker   UseCurrentThread();
2263*6777b538SAndroid Build Coastguard Worker   InitCache();
2264*6777b538SAndroid Build Coastguard Worker   std::string key("the key");
2265*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
2266*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2267*6777b538SAndroid Build Coastguard Worker 
2268*6777b538SAndroid Build Coastguard Worker   const int kSize = 4 * 1024;
2269*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2270*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf->data(), kSize, false);
2271*6777b538SAndroid Build Coastguard Worker 
2272*6777b538SAndroid Build Coastguard Worker   int64_t offset = 1024;
2273*6777b538SAndroid Build Coastguard Worker   // Write to a bunch of ranges.
2274*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 12; i++) {
2275*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kSize, entry->WriteSparseData(offset, buf.get(), kSize,
2276*6777b538SAndroid Build Coastguard Worker                                             net::CompletionOnceCallback()));
2277*6777b538SAndroid Build Coastguard Worker     offset *= 4;
2278*6777b538SAndroid Build Coastguard Worker   }
2279*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(9, cache_->GetEntryCount());
2280*6777b538SAndroid Build Coastguard Worker 
2281*6777b538SAndroid Build Coastguard Worker   entry->Close();
2282*6777b538SAndroid Build Coastguard Worker   disk_cache::Backend* cache = cache_.get();
2283*6777b538SAndroid Build Coastguard Worker   SparseTestCompletionCallback cb(TakeCache());
2284*6777b538SAndroid Build Coastguard Worker   int rv = cache->DoomEntry(key, net::HIGHEST, cb.callback());
2285*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(net::ERR_IO_PENDING));
2286*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cb.WaitForResult(), IsOk());
2287*6777b538SAndroid Build Coastguard Worker }
2288*6777b538SAndroid Build Coastguard Worker 
PartialSparseEntry()2289*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::PartialSparseEntry() {
2290*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
2291*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
2292*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2293*6777b538SAndroid Build Coastguard Worker 
2294*6777b538SAndroid Build Coastguard Worker   // We should be able to deal with IO that is not aligned to the block size
2295*6777b538SAndroid Build Coastguard Worker   // of a sparse entry, at least to write a big range without leaving holes.
2296*6777b538SAndroid Build Coastguard Worker   const int kSize = 4 * 1024;
2297*6777b538SAndroid Build Coastguard Worker   const int kSmallSize = 128;
2298*6777b538SAndroid Build Coastguard Worker   auto buf1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2299*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf1->data(), kSize, false);
2300*6777b538SAndroid Build Coastguard Worker 
2301*6777b538SAndroid Build Coastguard Worker   // The first write is just to extend the entry. The third write occupies
2302*6777b538SAndroid Build Coastguard Worker   // a 1KB block partially, it may not be written internally depending on the
2303*6777b538SAndroid Build Coastguard Worker   // implementation.
2304*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, 20000, buf1.get(), kSize));
2305*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, 500, buf1.get(), kSize));
2306*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSmallSize,
2307*6777b538SAndroid Build Coastguard Worker             WriteSparseData(entry, 1080321, buf1.get(), kSmallSize));
2308*6777b538SAndroid Build Coastguard Worker   entry->Close();
2309*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
2310*6777b538SAndroid Build Coastguard Worker 
2311*6777b538SAndroid Build Coastguard Worker   auto buf2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2312*6777b538SAndroid Build Coastguard Worker   memset(buf2->data(), 0, kSize);
2313*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, ReadSparseData(entry, 8000, buf2.get(), kSize));
2314*6777b538SAndroid Build Coastguard Worker 
2315*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(500, ReadSparseData(entry, kSize, buf2.get(), kSize));
2316*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500));
2317*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, ReadSparseData(entry, 0, buf2.get(), kSize));
2318*6777b538SAndroid Build Coastguard Worker 
2319*6777b538SAndroid Build Coastguard Worker   // This read should not change anything.
2320*6777b538SAndroid Build Coastguard Worker   if (memory_only_ || simple_cache_mode_)
2321*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(96, ReadSparseData(entry, 24000, buf2.get(), kSize));
2322*6777b538SAndroid Build Coastguard Worker   else
2323*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, ReadSparseData(entry, 24000, buf2.get(), kSize));
2324*6777b538SAndroid Build Coastguard Worker 
2325*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(500, ReadSparseData(entry, kSize, buf2.get(), kSize));
2326*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, ReadSparseData(entry, 99, buf2.get(), kSize));
2327*6777b538SAndroid Build Coastguard Worker 
2328*6777b538SAndroid Build Coastguard Worker   TestRangeResultCompletionCallback cb;
2329*6777b538SAndroid Build Coastguard Worker   RangeResult result;
2330*6777b538SAndroid Build Coastguard Worker   if (memory_only_ || simple_cache_mode_) {
2331*6777b538SAndroid Build Coastguard Worker     result = cb.GetResult(entry->GetAvailableRange(0, 600, cb.callback()));
2332*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::OK, result.net_error);
2333*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(100, result.available_len);
2334*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(500, result.start);
2335*6777b538SAndroid Build Coastguard Worker   } else {
2336*6777b538SAndroid Build Coastguard Worker     result = cb.GetResult(entry->GetAvailableRange(0, 2048, cb.callback()));
2337*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::OK, result.net_error);
2338*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1024, result.available_len);
2339*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1024, result.start);
2340*6777b538SAndroid Build Coastguard Worker   }
2341*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(kSize, kSize, cb.callback()));
2342*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2343*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(500, result.available_len);
2344*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, result.start);
2345*6777b538SAndroid Build Coastguard Worker   result =
2346*6777b538SAndroid Build Coastguard Worker       cb.GetResult(entry->GetAvailableRange(20 * 1024, 10000, cb.callback()));
2347*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2348*6777b538SAndroid Build Coastguard Worker   if (memory_only_ || simple_cache_mode_)
2349*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(3616, result.available_len);
2350*6777b538SAndroid Build Coastguard Worker   else
2351*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(3072, result.available_len);
2352*6777b538SAndroid Build Coastguard Worker 
2353*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(20 * 1024, result.start);
2354*6777b538SAndroid Build Coastguard Worker 
2355*6777b538SAndroid Build Coastguard Worker   // 1. Query before a filled 1KB block.
2356*6777b538SAndroid Build Coastguard Worker   // 2. Query within a filled 1KB block.
2357*6777b538SAndroid Build Coastguard Worker   // 3. Query beyond a filled 1KB block.
2358*6777b538SAndroid Build Coastguard Worker   if (memory_only_ || simple_cache_mode_) {
2359*6777b538SAndroid Build Coastguard Worker     result =
2360*6777b538SAndroid Build Coastguard Worker         cb.GetResult(entry->GetAvailableRange(19400, kSize, cb.callback()));
2361*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::OK, result.net_error);
2362*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(3496, result.available_len);
2363*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(20000, result.start);
2364*6777b538SAndroid Build Coastguard Worker   } else {
2365*6777b538SAndroid Build Coastguard Worker     result =
2366*6777b538SAndroid Build Coastguard Worker         cb.GetResult(entry->GetAvailableRange(19400, kSize, cb.callback()));
2367*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::OK, result.net_error);
2368*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(3016, result.available_len);
2369*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(20480, result.start);
2370*6777b538SAndroid Build Coastguard Worker   }
2371*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(3073, kSize, cb.callback()));
2372*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2373*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1523, result.available_len);
2374*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3073, result.start);
2375*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(4600, kSize, cb.callback()));
2376*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2377*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.available_len);
2378*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4600, result.start);
2379*6777b538SAndroid Build Coastguard Worker 
2380*6777b538SAndroid Build Coastguard Worker   // Now make another write and verify that there is no hole in between.
2381*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, 500 + kSize, buf1.get(), kSize));
2382*6777b538SAndroid Build Coastguard Worker   result = cb.GetResult(entry->GetAvailableRange(1024, 10000, cb.callback()));
2383*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2384*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(7 * 1024 + 500, result.available_len);
2385*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1024, result.start);
2386*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadSparseData(entry, kSize, buf2.get(), kSize));
2387*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500));
2388*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buf2->data() + 500, buf1->data(), kSize - 500));
2389*6777b538SAndroid Build Coastguard Worker 
2390*6777b538SAndroid Build Coastguard Worker   entry->Close();
2391*6777b538SAndroid Build Coastguard Worker }
2392*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,PartialSparseEntry)2393*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, PartialSparseEntry) {
2394*6777b538SAndroid Build Coastguard Worker   InitCache();
2395*6777b538SAndroid Build Coastguard Worker   PartialSparseEntry();
2396*6777b538SAndroid Build Coastguard Worker }
2397*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryPartialSparseEntry)2398*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryPartialSparseEntry) {
2399*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
2400*6777b538SAndroid Build Coastguard Worker   InitCache();
2401*6777b538SAndroid Build Coastguard Worker   PartialSparseEntry();
2402*6777b538SAndroid Build Coastguard Worker }
2403*6777b538SAndroid Build Coastguard Worker 
SparseInvalidArg()2404*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::SparseInvalidArg() {
2405*6777b538SAndroid Build Coastguard Worker   std::string key("key");
2406*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
2407*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2408*6777b538SAndroid Build Coastguard Worker 
2409*6777b538SAndroid Build Coastguard Worker   const int kSize = 2048;
2410*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2411*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf->data(), kSize, false);
2412*6777b538SAndroid Build Coastguard Worker 
2413*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_INVALID_ARGUMENT,
2414*6777b538SAndroid Build Coastguard Worker             WriteSparseData(entry, -1, buf.get(), kSize));
2415*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_INVALID_ARGUMENT,
2416*6777b538SAndroid Build Coastguard Worker             WriteSparseData(entry, 0, buf.get(), -1));
2417*6777b538SAndroid Build Coastguard Worker 
2418*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_INVALID_ARGUMENT,
2419*6777b538SAndroid Build Coastguard Worker             ReadSparseData(entry, -1, buf.get(), kSize));
2420*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_INVALID_ARGUMENT, ReadSparseData(entry, 0, buf.get(), -1));
2421*6777b538SAndroid Build Coastguard Worker 
2422*6777b538SAndroid Build Coastguard Worker   int64_t start_out;
2423*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_INVALID_ARGUMENT,
2424*6777b538SAndroid Build Coastguard Worker             GetAvailableRange(entry, -1, kSize, &start_out));
2425*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_INVALID_ARGUMENT,
2426*6777b538SAndroid Build Coastguard Worker             GetAvailableRange(entry, 0, -1, &start_out));
2427*6777b538SAndroid Build Coastguard Worker 
2428*6777b538SAndroid Build Coastguard Worker   int rv = WriteSparseData(
2429*6777b538SAndroid Build Coastguard Worker       entry, std::numeric_limits<int64_t>::max() - kSize + 1, buf.get(), kSize);
2430*6777b538SAndroid Build Coastguard Worker   // Blockfile rejects anything over 64GiB with
2431*6777b538SAndroid Build Coastguard Worker   // net::ERR_CACHE_OPERATION_NOT_SUPPORTED, which is also OK here, as it's not
2432*6777b538SAndroid Build Coastguard Worker   // an overflow or something else nonsensical.
2433*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(rv == net::ERR_INVALID_ARGUMENT ||
2434*6777b538SAndroid Build Coastguard Worker               rv == net::ERR_CACHE_OPERATION_NOT_SUPPORTED);
2435*6777b538SAndroid Build Coastguard Worker 
2436*6777b538SAndroid Build Coastguard Worker   entry->Close();
2437*6777b538SAndroid Build Coastguard Worker }
2438*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SparseInvalidArg)2439*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SparseInvalidArg) {
2440*6777b538SAndroid Build Coastguard Worker   InitCache();
2441*6777b538SAndroid Build Coastguard Worker   SparseInvalidArg();
2442*6777b538SAndroid Build Coastguard Worker }
2443*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlySparseInvalidArg)2444*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlySparseInvalidArg) {
2445*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
2446*6777b538SAndroid Build Coastguard Worker   InitCache();
2447*6777b538SAndroid Build Coastguard Worker   SparseInvalidArg();
2448*6777b538SAndroid Build Coastguard Worker }
2449*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleSparseInvalidArg)2450*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleSparseInvalidArg) {
2451*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2452*6777b538SAndroid Build Coastguard Worker   InitCache();
2453*6777b538SAndroid Build Coastguard Worker   SparseInvalidArg();
2454*6777b538SAndroid Build Coastguard Worker }
2455*6777b538SAndroid Build Coastguard Worker 
SparseClipEnd(int64_t max_index,bool expect_unsupported)2456*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::SparseClipEnd(int64_t max_index,
2457*6777b538SAndroid Build Coastguard Worker                                        bool expect_unsupported) {
2458*6777b538SAndroid Build Coastguard Worker   std::string key("key");
2459*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
2460*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2461*6777b538SAndroid Build Coastguard Worker 
2462*6777b538SAndroid Build Coastguard Worker   const int kSize = 1024;
2463*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2464*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf->data(), kSize, false);
2465*6777b538SAndroid Build Coastguard Worker 
2466*6777b538SAndroid Build Coastguard Worker   auto read_buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize * 2);
2467*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(read_buf->data(), kSize * 2, false);
2468*6777b538SAndroid Build Coastguard Worker 
2469*6777b538SAndroid Build Coastguard Worker   const int64_t kOffset = max_index - kSize;
2470*6777b538SAndroid Build Coastguard Worker   int rv = WriteSparseData(entry, kOffset, buf.get(), kSize);
2471*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
2472*6777b538SAndroid Build Coastguard Worker       rv, expect_unsupported ? net::ERR_CACHE_OPERATION_NOT_SUPPORTED : kSize);
2473*6777b538SAndroid Build Coastguard Worker 
2474*6777b538SAndroid Build Coastguard Worker   // Try to read further than offset range, should get clipped (if supported).
2475*6777b538SAndroid Build Coastguard Worker   rv = ReadSparseData(entry, kOffset, read_buf.get(), kSize * 2);
2476*6777b538SAndroid Build Coastguard Worker   if (expect_unsupported) {
2477*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(rv, net::ERR_CACHE_OPERATION_NOT_SUPPORTED);
2478*6777b538SAndroid Build Coastguard Worker   } else {
2479*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kSize, rv);
2480*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(buf->data(), read_buf->data(), kSize));
2481*6777b538SAndroid Build Coastguard Worker   }
2482*6777b538SAndroid Build Coastguard Worker 
2483*6777b538SAndroid Build Coastguard Worker   TestRangeResultCompletionCallback cb;
2484*6777b538SAndroid Build Coastguard Worker   RangeResult result = cb.GetResult(
2485*6777b538SAndroid Build Coastguard Worker       entry->GetAvailableRange(kOffset - kSize, kSize * 3, cb.callback()));
2486*6777b538SAndroid Build Coastguard Worker   if (expect_unsupported) {
2487*6777b538SAndroid Build Coastguard Worker     // GetAvailableRange just returns nothing found, not an error.
2488*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::OK, result.net_error);
2489*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(result.available_len, 0);
2490*6777b538SAndroid Build Coastguard Worker   } else {
2491*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::OK, result.net_error);
2492*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kSize, result.available_len);
2493*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kOffset, result.start);
2494*6777b538SAndroid Build Coastguard Worker   }
2495*6777b538SAndroid Build Coastguard Worker 
2496*6777b538SAndroid Build Coastguard Worker   entry->Close();
2497*6777b538SAndroid Build Coastguard Worker }
2498*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SparseClipEnd)2499*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SparseClipEnd) {
2500*6777b538SAndroid Build Coastguard Worker   InitCache();
2501*6777b538SAndroid Build Coastguard Worker 
2502*6777b538SAndroid Build Coastguard Worker   // Blockfile refuses to deal with sparse indices over 64GiB.
2503*6777b538SAndroid Build Coastguard Worker   SparseClipEnd(std::numeric_limits<int64_t>::max(),
2504*6777b538SAndroid Build Coastguard Worker                 /*expected_unsupported=*/true);
2505*6777b538SAndroid Build Coastguard Worker }
2506*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SparseClipEnd2)2507*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SparseClipEnd2) {
2508*6777b538SAndroid Build Coastguard Worker   InitCache();
2509*6777b538SAndroid Build Coastguard Worker 
2510*6777b538SAndroid Build Coastguard Worker   const int64_t kLimit = 64ll * 1024 * 1024 * 1024;
2511*6777b538SAndroid Build Coastguard Worker   // Separate test for blockfile for indices right at the edge of its address
2512*6777b538SAndroid Build Coastguard Worker   // space limit. kLimit must match kMaxEndOffset in sparse_control.cc
2513*6777b538SAndroid Build Coastguard Worker   SparseClipEnd(kLimit, /*expected_unsupported=*/false);
2514*6777b538SAndroid Build Coastguard Worker 
2515*6777b538SAndroid Build Coastguard Worker   // Test with things after kLimit, too, which isn't an issue for backends
2516*6777b538SAndroid Build Coastguard Worker   // supporting the entire 64-bit offset range.
2517*6777b538SAndroid Build Coastguard Worker   std::string key("key2");
2518*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
2519*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2520*6777b538SAndroid Build Coastguard Worker 
2521*6777b538SAndroid Build Coastguard Worker   const int kSize = 1024;
2522*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2523*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf->data(), kSize, false);
2524*6777b538SAndroid Build Coastguard Worker 
2525*6777b538SAndroid Build Coastguard Worker   // Try to write after --- fails.
2526*6777b538SAndroid Build Coastguard Worker   int rv = WriteSparseData(entry, kLimit, buf.get(), kSize);
2527*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, rv);
2528*6777b538SAndroid Build Coastguard Worker 
2529*6777b538SAndroid Build Coastguard Worker   // Similarly for read.
2530*6777b538SAndroid Build Coastguard Worker   rv = ReadSparseData(entry, kLimit, buf.get(), kSize);
2531*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, rv);
2532*6777b538SAndroid Build Coastguard Worker 
2533*6777b538SAndroid Build Coastguard Worker   // GetAvailableRange just returns nothing.
2534*6777b538SAndroid Build Coastguard Worker   TestRangeResultCompletionCallback cb;
2535*6777b538SAndroid Build Coastguard Worker   RangeResult result =
2536*6777b538SAndroid Build Coastguard Worker       cb.GetResult(entry->GetAvailableRange(kLimit, kSize * 3, cb.callback()));
2537*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2538*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.available_len);
2539*6777b538SAndroid Build Coastguard Worker   entry->Close();
2540*6777b538SAndroid Build Coastguard Worker }
2541*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlySparseClipEnd)2542*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlySparseClipEnd) {
2543*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
2544*6777b538SAndroid Build Coastguard Worker   InitCache();
2545*6777b538SAndroid Build Coastguard Worker   SparseClipEnd(std::numeric_limits<int64_t>::max(),
2546*6777b538SAndroid Build Coastguard Worker                 /* expected_unsupported = */ false);
2547*6777b538SAndroid Build Coastguard Worker }
2548*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleSparseClipEnd)2549*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleSparseClipEnd) {
2550*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2551*6777b538SAndroid Build Coastguard Worker   InitCache();
2552*6777b538SAndroid Build Coastguard Worker   SparseClipEnd(std::numeric_limits<int64_t>::max(),
2553*6777b538SAndroid Build Coastguard Worker                 /* expected_unsupported = */ false);
2554*6777b538SAndroid Build Coastguard Worker }
2555*6777b538SAndroid Build Coastguard Worker 
2556*6777b538SAndroid Build Coastguard Worker // Tests that corrupt sparse children are removed automatically.
TEST_F(DiskCacheEntryTest,CleanupSparseEntry)2557*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, CleanupSparseEntry) {
2558*6777b538SAndroid Build Coastguard Worker   InitCache();
2559*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
2560*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
2561*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2562*6777b538SAndroid Build Coastguard Worker 
2563*6777b538SAndroid Build Coastguard Worker   const int kSize = 4 * 1024;
2564*6777b538SAndroid Build Coastguard Worker   auto buf1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2565*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf1->data(), kSize, false);
2566*6777b538SAndroid Build Coastguard Worker 
2567*6777b538SAndroid Build Coastguard Worker   const int k1Meg = 1024 * 1024;
2568*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, 8192, buf1.get(), kSize));
2569*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, k1Meg + 8192, buf1.get(), kSize));
2570*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, 2 * k1Meg + 8192, buf1.get(), kSize));
2571*6777b538SAndroid Build Coastguard Worker   entry->Close();
2572*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache_->GetEntryCount());
2573*6777b538SAndroid Build Coastguard Worker 
2574*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<TestIterator> iter = CreateIterator();
2575*6777b538SAndroid Build Coastguard Worker   int count = 0;
2576*6777b538SAndroid Build Coastguard Worker   std::string child_keys[2];
2577*6777b538SAndroid Build Coastguard Worker   while (iter->OpenNextEntry(&entry) == net::OK) {
2578*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(entry != nullptr);
2579*6777b538SAndroid Build Coastguard Worker     // Writing to an entry will alter the LRU list and invalidate the iterator.
2580*6777b538SAndroid Build Coastguard Worker     if (entry->GetKey() != key && count < 2)
2581*6777b538SAndroid Build Coastguard Worker       child_keys[count++] = entry->GetKey();
2582*6777b538SAndroid Build Coastguard Worker     entry->Close();
2583*6777b538SAndroid Build Coastguard Worker   }
2584*6777b538SAndroid Build Coastguard Worker   for (const auto& child_key : child_keys) {
2585*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(OpenEntry(child_key, &entry), IsOk());
2586*6777b538SAndroid Build Coastguard Worker     // Overwrite the header's magic and signature.
2587*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(12, WriteData(entry, 2, 0, buf1.get(), 12, false));
2588*6777b538SAndroid Build Coastguard Worker     entry->Close();
2589*6777b538SAndroid Build Coastguard Worker   }
2590*6777b538SAndroid Build Coastguard Worker 
2591*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, cache_->GetEntryCount());
2592*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
2593*6777b538SAndroid Build Coastguard Worker 
2594*6777b538SAndroid Build Coastguard Worker   // Two children should be gone. One while reading and one while writing.
2595*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, ReadSparseData(entry, 2 * k1Meg + 8192, buf1.get(), kSize));
2596*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, k1Meg + 16384, buf1.get(), kSize));
2597*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, ReadSparseData(entry, k1Meg + 8192, buf1.get(), kSize));
2598*6777b538SAndroid Build Coastguard Worker 
2599*6777b538SAndroid Build Coastguard Worker   // We never touched this one.
2600*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadSparseData(entry, 8192, buf1.get(), kSize));
2601*6777b538SAndroid Build Coastguard Worker   entry->Close();
2602*6777b538SAndroid Build Coastguard Worker 
2603*6777b538SAndroid Build Coastguard Worker   // We re-created one of the corrupt children.
2604*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, cache_->GetEntryCount());
2605*6777b538SAndroid Build Coastguard Worker }
2606*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,CancelSparseIO)2607*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, CancelSparseIO) {
2608*6777b538SAndroid Build Coastguard Worker   UseCurrentThread();
2609*6777b538SAndroid Build Coastguard Worker   InitCache();
2610*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
2611*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
2612*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2613*6777b538SAndroid Build Coastguard Worker 
2614*6777b538SAndroid Build Coastguard Worker   const int kSize = 40 * 1024;
2615*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
2616*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf->data(), kSize, false);
2617*6777b538SAndroid Build Coastguard Worker 
2618*6777b538SAndroid Build Coastguard Worker   // This will open and write two "real" entries.
2619*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb1, cb2, cb3, cb4;
2620*6777b538SAndroid Build Coastguard Worker   int rv = entry->WriteSparseData(
2621*6777b538SAndroid Build Coastguard Worker       1024 * 1024 - 4096, buf.get(), kSize, cb1.callback());
2622*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(net::ERR_IO_PENDING));
2623*6777b538SAndroid Build Coastguard Worker 
2624*6777b538SAndroid Build Coastguard Worker   TestRangeResultCompletionCallback cb5;
2625*6777b538SAndroid Build Coastguard Worker   RangeResult result =
2626*6777b538SAndroid Build Coastguard Worker       cb5.GetResult(entry->GetAvailableRange(0, kSize, cb5.callback()));
2627*6777b538SAndroid Build Coastguard Worker   if (!cb1.have_result()) {
2628*6777b538SAndroid Build Coastguard Worker     // We may or may not have finished writing to the entry. If we have not,
2629*6777b538SAndroid Build Coastguard Worker     // we cannot start another operation at this time.
2630*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(rv, IsError(net::ERR_CACHE_OPERATION_NOT_SUPPORTED));
2631*6777b538SAndroid Build Coastguard Worker   }
2632*6777b538SAndroid Build Coastguard Worker 
2633*6777b538SAndroid Build Coastguard Worker   // We cancel the pending operation, and register multiple notifications.
2634*6777b538SAndroid Build Coastguard Worker   entry->CancelSparseIO();
2635*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(entry->ReadyForSparseIO(cb2.callback()),
2636*6777b538SAndroid Build Coastguard Worker               IsError(net::ERR_IO_PENDING));
2637*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(entry->ReadyForSparseIO(cb3.callback()),
2638*6777b538SAndroid Build Coastguard Worker               IsError(net::ERR_IO_PENDING));
2639*6777b538SAndroid Build Coastguard Worker   entry->CancelSparseIO();  // Should be a no op at this point.
2640*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(entry->ReadyForSparseIO(cb4.callback()),
2641*6777b538SAndroid Build Coastguard Worker               IsError(net::ERR_IO_PENDING));
2642*6777b538SAndroid Build Coastguard Worker 
2643*6777b538SAndroid Build Coastguard Worker   if (!cb1.have_result()) {
2644*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED,
2645*6777b538SAndroid Build Coastguard Worker               entry->ReadSparseData(result.start, buf.get(), kSize,
2646*6777b538SAndroid Build Coastguard Worker                                     net::CompletionOnceCallback()));
2647*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED,
2648*6777b538SAndroid Build Coastguard Worker               entry->WriteSparseData(result.start, buf.get(), kSize,
2649*6777b538SAndroid Build Coastguard Worker                                      net::CompletionOnceCallback()));
2650*6777b538SAndroid Build Coastguard Worker   }
2651*6777b538SAndroid Build Coastguard Worker 
2652*6777b538SAndroid Build Coastguard Worker   // Now see if we receive all notifications. Note that we should not be able
2653*6777b538SAndroid Build Coastguard Worker   // to write everything (unless the timing of the system is really weird).
2654*6777b538SAndroid Build Coastguard Worker   rv = cb1.WaitForResult();
2655*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(rv == 4096 || rv == kSize);
2656*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cb2.WaitForResult(), IsOk());
2657*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cb3.WaitForResult(), IsOk());
2658*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cb4.WaitForResult(), IsOk());
2659*6777b538SAndroid Build Coastguard Worker 
2660*6777b538SAndroid Build Coastguard Worker   result = cb5.GetResult(
2661*6777b538SAndroid Build Coastguard Worker       entry->GetAvailableRange(result.start, kSize, cb5.callback()));
2662*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error);
2663*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.available_len);
2664*6777b538SAndroid Build Coastguard Worker   entry->Close();
2665*6777b538SAndroid Build Coastguard Worker }
2666*6777b538SAndroid Build Coastguard Worker 
2667*6777b538SAndroid Build Coastguard Worker // Tests that we perform sanity checks on an entry's key. Note that there are
2668*6777b538SAndroid Build Coastguard Worker // other tests that exercise sanity checks by using saved corrupt files.
TEST_F(DiskCacheEntryTest,KeySanityCheck)2669*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, KeySanityCheck) {
2670*6777b538SAndroid Build Coastguard Worker   UseCurrentThread();
2671*6777b538SAndroid Build Coastguard Worker   InitCache();
2672*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
2673*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
2674*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2675*6777b538SAndroid Build Coastguard Worker 
2676*6777b538SAndroid Build Coastguard Worker   disk_cache::EntryImpl* entry_impl =
2677*6777b538SAndroid Build Coastguard Worker       static_cast<disk_cache::EntryImpl*>(entry);
2678*6777b538SAndroid Build Coastguard Worker   disk_cache::EntryStore* store = entry_impl->entry()->Data();
2679*6777b538SAndroid Build Coastguard Worker 
2680*6777b538SAndroid Build Coastguard Worker   // We have reserved space for a short key (one block), let's say that the key
2681*6777b538SAndroid Build Coastguard Worker   // takes more than one block, and remove the NULLs after the actual key.
2682*6777b538SAndroid Build Coastguard Worker   store->key_len = 800;
2683*6777b538SAndroid Build Coastguard Worker   memset(store->key + key.size(), 'k', sizeof(store->key) - key.size());
2684*6777b538SAndroid Build Coastguard Worker   entry_impl->entry()->set_modified();
2685*6777b538SAndroid Build Coastguard Worker   entry->Close();
2686*6777b538SAndroid Build Coastguard Worker 
2687*6777b538SAndroid Build Coastguard Worker   // We have a corrupt entry. Now reload it. We should NOT read beyond the
2688*6777b538SAndroid Build Coastguard Worker   // allocated buffer here.
2689*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(net::OK, OpenEntry(key, &entry));
2690*6777b538SAndroid Build Coastguard Worker   DisableIntegrityCheck();
2691*6777b538SAndroid Build Coastguard Worker }
2692*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,KeySanityCheck2)2693*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, KeySanityCheck2) {
2694*6777b538SAndroid Build Coastguard Worker   UseCurrentThread();
2695*6777b538SAndroid Build Coastguard Worker   InitCache();
2696*6777b538SAndroid Build Coastguard Worker   std::string key("the first key");
2697*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
2698*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2699*6777b538SAndroid Build Coastguard Worker 
2700*6777b538SAndroid Build Coastguard Worker   disk_cache::EntryImpl* entry_impl =
2701*6777b538SAndroid Build Coastguard Worker       static_cast<disk_cache::EntryImpl*>(entry);
2702*6777b538SAndroid Build Coastguard Worker   disk_cache::EntryStore* store = entry_impl->entry()->Data();
2703*6777b538SAndroid Build Coastguard Worker 
2704*6777b538SAndroid Build Coastguard Worker   // Fill in the rest of inline key store with non-nulls. Unlike in
2705*6777b538SAndroid Build Coastguard Worker   // KeySanityCheck, this does not change the length to identify it as
2706*6777b538SAndroid Build Coastguard Worker   // stored under |long_key|.
2707*6777b538SAndroid Build Coastguard Worker   memset(store->key + key.size(), 'k', sizeof(store->key) - key.size());
2708*6777b538SAndroid Build Coastguard Worker   entry_impl->entry()->set_modified();
2709*6777b538SAndroid Build Coastguard Worker   entry->Close();
2710*6777b538SAndroid Build Coastguard Worker 
2711*6777b538SAndroid Build Coastguard Worker   // We have a corrupt entry. Now reload it. We should NOT read beyond the
2712*6777b538SAndroid Build Coastguard Worker   // allocated buffer here.
2713*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(net::OK, OpenEntry(key, &entry));
2714*6777b538SAndroid Build Coastguard Worker   DisableIntegrityCheck();
2715*6777b538SAndroid Build Coastguard Worker }
2716*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,KeySanityCheck3)2717*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, KeySanityCheck3) {
2718*6777b538SAndroid Build Coastguard Worker   const size_t kVeryLong = 40 * 1024;
2719*6777b538SAndroid Build Coastguard Worker   UseCurrentThread();
2720*6777b538SAndroid Build Coastguard Worker   InitCache();
2721*6777b538SAndroid Build Coastguard Worker   std::string key(kVeryLong, 'a');
2722*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
2723*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
2724*6777b538SAndroid Build Coastguard Worker 
2725*6777b538SAndroid Build Coastguard Worker   disk_cache::EntryImpl* entry_impl =
2726*6777b538SAndroid Build Coastguard Worker       static_cast<disk_cache::EntryImpl*>(entry);
2727*6777b538SAndroid Build Coastguard Worker   disk_cache::EntryStore* store = entry_impl->entry()->Data();
2728*6777b538SAndroid Build Coastguard Worker 
2729*6777b538SAndroid Build Coastguard Worker   // Test meaningful when using long keys; and also want this to be
2730*6777b538SAndroid Build Coastguard Worker   // an external file to avoid needing to duplicate offset math here.
2731*6777b538SAndroid Build Coastguard Worker   disk_cache::Addr key_addr(store->long_key);
2732*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(key_addr.is_initialized());
2733*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(key_addr.is_separate_file());
2734*6777b538SAndroid Build Coastguard Worker 
2735*6777b538SAndroid Build Coastguard Worker   // Close the entry before messing up its files.
2736*6777b538SAndroid Build Coastguard Worker   entry->Close();
2737*6777b538SAndroid Build Coastguard Worker 
2738*6777b538SAndroid Build Coastguard Worker   // Mess up the terminating null in the external key file.
2739*6777b538SAndroid Build Coastguard Worker   auto key_file =
2740*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<disk_cache::File>(true /* want sync ops*/);
2741*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(key_file->Init(cache_impl_->GetFileName(key_addr)));
2742*6777b538SAndroid Build Coastguard Worker 
2743*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(key_file->Write("b", 1u, kVeryLong));
2744*6777b538SAndroid Build Coastguard Worker   key_file = nullptr;
2745*6777b538SAndroid Build Coastguard Worker 
2746*6777b538SAndroid Build Coastguard Worker   // This case gets graceful recovery.
2747*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
2748*6777b538SAndroid Build Coastguard Worker 
2749*6777b538SAndroid Build Coastguard Worker   // Make sure the key object isn't messed up.
2750*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kVeryLong, strlen(entry->GetKey().data()));
2751*6777b538SAndroid Build Coastguard Worker   entry->Close();
2752*6777b538SAndroid Build Coastguard Worker }
2753*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheInternalAsyncIO)2754*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheInternalAsyncIO) {
2755*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2756*6777b538SAndroid Build Coastguard Worker   InitCache();
2757*6777b538SAndroid Build Coastguard Worker   InternalAsyncIO();
2758*6777b538SAndroid Build Coastguard Worker }
2759*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheExternalAsyncIO)2760*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheExternalAsyncIO) {
2761*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2762*6777b538SAndroid Build Coastguard Worker   InitCache();
2763*6777b538SAndroid Build Coastguard Worker   ExternalAsyncIO();
2764*6777b538SAndroid Build Coastguard Worker }
2765*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheReleaseBuffer)2766*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheReleaseBuffer) {
2767*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2768*6777b538SAndroid Build Coastguard Worker   InitCache();
2769*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2770*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(DoomAllEntries(), IsOk());
2771*6777b538SAndroid Build Coastguard Worker     ReleaseBuffer(i);
2772*6777b538SAndroid Build Coastguard Worker   }
2773*6777b538SAndroid Build Coastguard Worker }
2774*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheStreamAccess)2775*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheStreamAccess) {
2776*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2777*6777b538SAndroid Build Coastguard Worker   InitCache();
2778*6777b538SAndroid Build Coastguard Worker   StreamAccess();
2779*6777b538SAndroid Build Coastguard Worker }
2780*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheGetKey)2781*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheGetKey) {
2782*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2783*6777b538SAndroid Build Coastguard Worker   InitCache();
2784*6777b538SAndroid Build Coastguard Worker   GetKey();
2785*6777b538SAndroid Build Coastguard Worker }
2786*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheGetTimes)2787*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheGetTimes) {
2788*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2789*6777b538SAndroid Build Coastguard Worker   InitCache();
2790*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2791*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(DoomAllEntries(), IsOk());
2792*6777b538SAndroid Build Coastguard Worker     GetTimes(i);
2793*6777b538SAndroid Build Coastguard Worker   }
2794*6777b538SAndroid Build Coastguard Worker }
2795*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheGrowData)2796*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheGrowData) {
2797*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2798*6777b538SAndroid Build Coastguard Worker   InitCache();
2799*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2800*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(DoomAllEntries(), IsOk());
2801*6777b538SAndroid Build Coastguard Worker     GrowData(i);
2802*6777b538SAndroid Build Coastguard Worker   }
2803*6777b538SAndroid Build Coastguard Worker }
2804*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheTruncateData)2805*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheTruncateData) {
2806*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2807*6777b538SAndroid Build Coastguard Worker   InitCache();
2808*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2809*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(DoomAllEntries(), IsOk());
2810*6777b538SAndroid Build Coastguard Worker     TruncateData(i);
2811*6777b538SAndroid Build Coastguard Worker   }
2812*6777b538SAndroid Build Coastguard Worker }
2813*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheZeroLengthIO)2814*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheZeroLengthIO) {
2815*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2816*6777b538SAndroid Build Coastguard Worker   InitCache();
2817*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2818*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(DoomAllEntries(), IsOk());
2819*6777b538SAndroid Build Coastguard Worker     ZeroLengthIO(i);
2820*6777b538SAndroid Build Coastguard Worker   }
2821*6777b538SAndroid Build Coastguard Worker }
2822*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheSizeAtCreate)2823*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheSizeAtCreate) {
2824*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2825*6777b538SAndroid Build Coastguard Worker   InitCache();
2826*6777b538SAndroid Build Coastguard Worker   SizeAtCreate();
2827*6777b538SAndroid Build Coastguard Worker }
2828*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheReuseExternalEntry)2829*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheReuseExternalEntry) {
2830*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2831*6777b538SAndroid Build Coastguard Worker   SetMaxSize(200 * 1024);
2832*6777b538SAndroid Build Coastguard Worker   InitCache();
2833*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2834*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(DoomAllEntries(), IsOk());
2835*6777b538SAndroid Build Coastguard Worker     ReuseEntry(20 * 1024, i);
2836*6777b538SAndroid Build Coastguard Worker   }
2837*6777b538SAndroid Build Coastguard Worker }
2838*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheReuseInternalEntry)2839*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheReuseInternalEntry) {
2840*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2841*6777b538SAndroid Build Coastguard Worker   SetMaxSize(100 * 1024);
2842*6777b538SAndroid Build Coastguard Worker   InitCache();
2843*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2844*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(DoomAllEntries(), IsOk());
2845*6777b538SAndroid Build Coastguard Worker     ReuseEntry(10 * 1024, i);
2846*6777b538SAndroid Build Coastguard Worker   }
2847*6777b538SAndroid Build Coastguard Worker }
2848*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheGiantEntry)2849*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheGiantEntry) {
2850*6777b538SAndroid Build Coastguard Worker   const int kBufSize = 32 * 1024;
2851*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kBufSize);
2852*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kBufSize, false);
2853*6777b538SAndroid Build Coastguard Worker 
2854*6777b538SAndroid Build Coastguard Worker   // Make sure SimpleCache can write up to 5MiB entry even with a 20MiB cache
2855*6777b538SAndroid Build Coastguard Worker   // size that Android WebView uses at the time of this test's writing.
2856*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2857*6777b538SAndroid Build Coastguard Worker   SetMaxSize(20 * 1024 * 1024);
2858*6777b538SAndroid Build Coastguard Worker   InitCache();
2859*6777b538SAndroid Build Coastguard Worker 
2860*6777b538SAndroid Build Coastguard Worker   {
2861*6777b538SAndroid Build Coastguard Worker     std::string key1("the first key");
2862*6777b538SAndroid Build Coastguard Worker     disk_cache::Entry* entry1 = nullptr;
2863*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(CreateEntry(key1, &entry1), IsOk());
2864*6777b538SAndroid Build Coastguard Worker 
2865*6777b538SAndroid Build Coastguard Worker     const int kSize1 = 5 * 1024 * 1024;
2866*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kBufSize, WriteData(entry1, 1 /* stream */, kSize1 - kBufSize,
2867*6777b538SAndroid Build Coastguard Worker                                   buffer.get(), kBufSize, true /* truncate */));
2868*6777b538SAndroid Build Coastguard Worker     entry1->Close();
2869*6777b538SAndroid Build Coastguard Worker   }
2870*6777b538SAndroid Build Coastguard Worker 
2871*6777b538SAndroid Build Coastguard Worker   // ... but not bigger than that.
2872*6777b538SAndroid Build Coastguard Worker   {
2873*6777b538SAndroid Build Coastguard Worker     std::string key2("the second key");
2874*6777b538SAndroid Build Coastguard Worker     disk_cache::Entry* entry2 = nullptr;
2875*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(CreateEntry(key2, &entry2), IsOk());
2876*6777b538SAndroid Build Coastguard Worker 
2877*6777b538SAndroid Build Coastguard Worker     const int kSize2 = 5 * 1024 * 1024 + 1;
2878*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(net::ERR_FAILED,
2879*6777b538SAndroid Build Coastguard Worker               WriteData(entry2, 1 /* stream */, kSize2 - kBufSize, buffer.get(),
2880*6777b538SAndroid Build Coastguard Worker                         kBufSize, true /* truncate */));
2881*6777b538SAndroid Build Coastguard Worker     entry2->Close();
2882*6777b538SAndroid Build Coastguard Worker   }
2883*6777b538SAndroid Build Coastguard Worker }
2884*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheSizeChanges)2885*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheSizeChanges) {
2886*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2887*6777b538SAndroid Build Coastguard Worker   InitCache();
2888*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2889*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(DoomAllEntries(), IsOk());
2890*6777b538SAndroid Build Coastguard Worker     SizeChanges(i);
2891*6777b538SAndroid Build Coastguard Worker   }
2892*6777b538SAndroid Build Coastguard Worker }
2893*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheInvalidData)2894*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheInvalidData) {
2895*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2896*6777b538SAndroid Build Coastguard Worker   InitCache();
2897*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2898*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(DoomAllEntries(), IsOk());
2899*6777b538SAndroid Build Coastguard Worker     InvalidData(i);
2900*6777b538SAndroid Build Coastguard Worker   }
2901*6777b538SAndroid Build Coastguard Worker }
2902*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheReadWriteDestroyBuffer)2903*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheReadWriteDestroyBuffer) {
2904*6777b538SAndroid Build Coastguard Worker   // Proving that the test works well with optimistic operations enabled is
2905*6777b538SAndroid Build Coastguard Worker   // subtle, instead run only in APP_CACHE mode to disable optimistic
2906*6777b538SAndroid Build Coastguard Worker   // operations. Stream 0 always uses optimistic operations, so the test is not
2907*6777b538SAndroid Build Coastguard Worker   // run on stream 0.
2908*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
2909*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2910*6777b538SAndroid Build Coastguard Worker   InitCache();
2911*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2912*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(DoomAllEntries(), IsOk());
2913*6777b538SAndroid Build Coastguard Worker     ReadWriteDestroyBuffer(i);
2914*6777b538SAndroid Build Coastguard Worker   }
2915*6777b538SAndroid Build Coastguard Worker }
2916*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomEntry)2917*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomEntry) {
2918*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2919*6777b538SAndroid Build Coastguard Worker   InitCache();
2920*6777b538SAndroid Build Coastguard Worker   DoomNormalEntry();
2921*6777b538SAndroid Build Coastguard Worker }
2922*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomEntryNextToOpenEntry)2923*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomEntryNextToOpenEntry) {
2924*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2925*6777b538SAndroid Build Coastguard Worker   InitCache();
2926*6777b538SAndroid Build Coastguard Worker   DoomEntryNextToOpenEntry();
2927*6777b538SAndroid Build Coastguard Worker }
2928*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomedEntry)2929*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomedEntry) {
2930*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2931*6777b538SAndroid Build Coastguard Worker   InitCache();
2932*6777b538SAndroid Build Coastguard Worker   // Stream 2 is excluded because the implementation does not support writing to
2933*6777b538SAndroid Build Coastguard Worker   // it on a doomed entry, if it was previously lazily omitted.
2934*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount - 1; ++i) {
2935*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(DoomAllEntries(), IsOk());
2936*6777b538SAndroid Build Coastguard Worker     DoomedEntry(i);
2937*6777b538SAndroid Build Coastguard Worker   }
2938*6777b538SAndroid Build Coastguard Worker }
2939*6777b538SAndroid Build Coastguard Worker 
2940*6777b538SAndroid Build Coastguard Worker // Creates an entry with corrupted last byte in stream 0.
2941*6777b538SAndroid Build Coastguard Worker // Requires SimpleCacheMode.
SimpleCacheMakeBadChecksumEntry(const std::string & key,int data_size)2942*6777b538SAndroid Build Coastguard Worker bool DiskCacheEntryTest::SimpleCacheMakeBadChecksumEntry(const std::string& key,
2943*6777b538SAndroid Build Coastguard Worker                                                          int data_size) {
2944*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
2945*6777b538SAndroid Build Coastguard Worker 
2946*6777b538SAndroid Build Coastguard Worker   if (CreateEntry(key, &entry) != net::OK || !entry) {
2947*6777b538SAndroid Build Coastguard Worker     LOG(ERROR) << "Could not create entry";
2948*6777b538SAndroid Build Coastguard Worker     return false;
2949*6777b538SAndroid Build Coastguard Worker   }
2950*6777b538SAndroid Build Coastguard Worker 
2951*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(data_size);
2952*6777b538SAndroid Build Coastguard Worker   memset(buffer->data(), 'A', data_size);
2953*6777b538SAndroid Build Coastguard Worker 
2954*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(data_size, WriteData(entry, 1, 0, buffer.get(), data_size, false));
2955*6777b538SAndroid Build Coastguard Worker   entry->Close();
2956*6777b538SAndroid Build Coastguard Worker   entry = nullptr;
2957*6777b538SAndroid Build Coastguard Worker 
2958*6777b538SAndroid Build Coastguard Worker   // Corrupt the last byte of the data.
2959*6777b538SAndroid Build Coastguard Worker   base::FilePath entry_file0_path = cache_path_.AppendASCII(
2960*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
2961*6777b538SAndroid Build Coastguard Worker   base::File entry_file0(entry_file0_path,
2962*6777b538SAndroid Build Coastguard Worker                          base::File::FLAG_WRITE | base::File::FLAG_OPEN);
2963*6777b538SAndroid Build Coastguard Worker   if (!entry_file0.IsValid())
2964*6777b538SAndroid Build Coastguard Worker     return false;
2965*6777b538SAndroid Build Coastguard Worker 
2966*6777b538SAndroid Build Coastguard Worker   int64_t file_offset =
2967*6777b538SAndroid Build Coastguard Worker       sizeof(disk_cache::SimpleFileHeader) + key.size() + data_size - 2;
2968*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, entry_file0.Write(file_offset, "X", 1));
2969*6777b538SAndroid Build Coastguard Worker   return true;
2970*6777b538SAndroid Build Coastguard Worker }
2971*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheBadChecksum)2972*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheBadChecksum) {
2973*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2974*6777b538SAndroid Build Coastguard Worker   InitCache();
2975*6777b538SAndroid Build Coastguard Worker 
2976*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
2977*6777b538SAndroid Build Coastguard Worker   const int kLargeSize = 50000;
2978*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, kLargeSize));
2979*6777b538SAndroid Build Coastguard Worker 
2980*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
2981*6777b538SAndroid Build Coastguard Worker 
2982*6777b538SAndroid Build Coastguard Worker   // Open the entry. Can't spot the checksum that quickly with it so
2983*6777b538SAndroid Build Coastguard Worker   // huge.
2984*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
2985*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
2986*6777b538SAndroid Build Coastguard Worker 
2987*6777b538SAndroid Build Coastguard Worker   EXPECT_GE(kLargeSize, entry->GetDataSize(1));
2988*6777b538SAndroid Build Coastguard Worker   auto read_buffer = base::MakeRefCounted<net::IOBufferWithSize>(kLargeSize);
2989*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_CACHE_CHECKSUM_MISMATCH,
2990*6777b538SAndroid Build Coastguard Worker             ReadData(entry, 1, 0, read_buffer.get(), kLargeSize));
2991*6777b538SAndroid Build Coastguard Worker }
2992*6777b538SAndroid Build Coastguard Worker 
2993*6777b538SAndroid Build Coastguard Worker // Tests that an entry that has had an IO error occur can still be Doomed().
TEST_F(DiskCacheEntryTest,SimpleCacheErrorThenDoom)2994*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheErrorThenDoom) {
2995*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
2996*6777b538SAndroid Build Coastguard Worker   InitCache();
2997*6777b538SAndroid Build Coastguard Worker 
2998*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
2999*6777b538SAndroid Build Coastguard Worker   const int kLargeSize = 50000;
3000*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, kLargeSize));
3001*6777b538SAndroid Build Coastguard Worker 
3002*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
3003*6777b538SAndroid Build Coastguard Worker 
3004*6777b538SAndroid Build Coastguard Worker   // Open the entry, forcing an IO error.
3005*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
3006*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
3007*6777b538SAndroid Build Coastguard Worker 
3008*6777b538SAndroid Build Coastguard Worker   EXPECT_GE(kLargeSize, entry->GetDataSize(1));
3009*6777b538SAndroid Build Coastguard Worker   auto read_buffer = base::MakeRefCounted<net::IOBufferWithSize>(kLargeSize);
3010*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_CACHE_CHECKSUM_MISMATCH,
3011*6777b538SAndroid Build Coastguard Worker             ReadData(entry, 1, 0, read_buffer.get(), kLargeSize));
3012*6777b538SAndroid Build Coastguard Worker   entry->Doom();  // Should not crash.
3013*6777b538SAndroid Build Coastguard Worker }
3014*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheCreateAfterDiskLayerDoom)3015*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheCreateAfterDiskLayerDoom) {
3016*6777b538SAndroid Build Coastguard Worker   // Code coverage for what happens when a queued create runs after failure
3017*6777b538SAndroid Build Coastguard Worker   // was noticed at SimpleSynchronousEntry layer.
3018*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3019*6777b538SAndroid Build Coastguard Worker   // Disable optimistic ops so we can block on CreateEntry and start
3020*6777b538SAndroid Build Coastguard Worker   // WriteData off with an empty op queue.
3021*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
3022*6777b538SAndroid Build Coastguard Worker   InitCache();
3023*6777b538SAndroid Build Coastguard Worker 
3024*6777b538SAndroid Build Coastguard Worker   const char key[] = "the key";
3025*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 10;
3026*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
3027*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
3028*6777b538SAndroid Build Coastguard Worker 
3029*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
3030*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3031*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry != nullptr);
3032*6777b538SAndroid Build Coastguard Worker 
3033*6777b538SAndroid Build Coastguard Worker   // Make an empty _1 file, to cause a stream 2 write to fail.
3034*6777b538SAndroid Build Coastguard Worker   base::FilePath entry_file1_path = cache_path_.AppendASCII(
3035*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 1));
3036*6777b538SAndroid Build Coastguard Worker   base::File entry_file1(entry_file1_path,
3037*6777b538SAndroid Build Coastguard Worker                          base::File::FLAG_WRITE | base::File::FLAG_CREATE);
3038*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry_file1.IsValid());
3039*6777b538SAndroid Build Coastguard Worker 
3040*6777b538SAndroid Build Coastguard Worker   entry->WriteData(2, 0, buffer1.get(), kSize1, net::CompletionOnceCallback(),
3041*6777b538SAndroid Build Coastguard Worker                    /* truncate= */ true);
3042*6777b538SAndroid Build Coastguard Worker   entry->Close();
3043*6777b538SAndroid Build Coastguard Worker 
3044*6777b538SAndroid Build Coastguard Worker   // At this point we have put WriteData & Close on the queue, and WriteData
3045*6777b538SAndroid Build Coastguard Worker   // started, but we haven't given the event loop control so the failure
3046*6777b538SAndroid Build Coastguard Worker   // hasn't been reported and handled here, so the entry is still active
3047*6777b538SAndroid Build Coastguard Worker   // for the key. Queue up another create for same key, and run through the
3048*6777b538SAndroid Build Coastguard Worker   // events.
3049*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = nullptr;
3050*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::ERR_FAILED, CreateEntry(key, &entry2));
3051*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry2 == nullptr);
3052*6777b538SAndroid Build Coastguard Worker 
3053*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache_->GetEntryCount());
3054*6777b538SAndroid Build Coastguard Worker 
3055*6777b538SAndroid Build Coastguard Worker   // Should be able to create properly next time, though.
3056*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry3 = nullptr;
3057*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, CreateEntry(key, &entry3));
3058*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry3 != nullptr);
3059*6777b538SAndroid Build Coastguard Worker   entry3->Close();
3060*6777b538SAndroid Build Coastguard Worker }
3061*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheQueuedOpenOnDoomedEntry)3062*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheQueuedOpenOnDoomedEntry) {
3063*6777b538SAndroid Build Coastguard Worker   // This tests the following sequence of ops:
3064*6777b538SAndroid Build Coastguard Worker   // A = Create(K);
3065*6777b538SAndroid Build Coastguard Worker   // Close(A);
3066*6777b538SAndroid Build Coastguard Worker   // B = Open(K);
3067*6777b538SAndroid Build Coastguard Worker   // Doom(K);
3068*6777b538SAndroid Build Coastguard Worker   // Close(B);
3069*6777b538SAndroid Build Coastguard Worker   //
3070*6777b538SAndroid Build Coastguard Worker   // ... where the execution of the Open sits on the queue all the way till
3071*6777b538SAndroid Build Coastguard Worker   // Doom. This now succeeds, as the doom is merely queued at time of Open,
3072*6777b538SAndroid Build Coastguard Worker   // rather than completed.
3073*6777b538SAndroid Build Coastguard Worker 
3074*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3075*6777b538SAndroid Build Coastguard Worker   // Disable optimistic ops so we can block on CreateEntry and start
3076*6777b538SAndroid Build Coastguard Worker   // WriteData off with an empty op queue.
3077*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
3078*6777b538SAndroid Build Coastguard Worker   InitCache();
3079*6777b538SAndroid Build Coastguard Worker 
3080*6777b538SAndroid Build Coastguard Worker   const char key[] = "the key";
3081*6777b538SAndroid Build Coastguard Worker 
3082*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
3083*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, CreateEntry(key, &entry));  // event loop!
3084*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry != nullptr);
3085*6777b538SAndroid Build Coastguard Worker 
3086*6777b538SAndroid Build Coastguard Worker   entry->Close();
3087*6777b538SAndroid Build Coastguard Worker 
3088*6777b538SAndroid Build Coastguard Worker   // Done via cache_ -> no event loop.
3089*6777b538SAndroid Build Coastguard Worker   TestEntryResultCompletionCallback cb;
3090*6777b538SAndroid Build Coastguard Worker   EntryResult result = cache_->OpenEntry(key, net::HIGHEST, cb.callback());
3091*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::ERR_IO_PENDING, result.net_error());
3092*6777b538SAndroid Build Coastguard Worker 
3093*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb2;
3094*6777b538SAndroid Build Coastguard Worker   cache_->DoomEntry(key, net::HIGHEST, cb2.callback());
3095*6777b538SAndroid Build Coastguard Worker   // Now event loop.
3096*6777b538SAndroid Build Coastguard Worker   result = cb.WaitForResult();
3097*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result.net_error());
3098*6777b538SAndroid Build Coastguard Worker   result.ReleaseEntry()->Close();
3099*6777b538SAndroid Build Coastguard Worker 
3100*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, cb2.WaitForResult());
3101*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cache_->GetEntryCount());
3102*6777b538SAndroid Build Coastguard Worker }
3103*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomErrorRace)3104*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomErrorRace) {
3105*6777b538SAndroid Build Coastguard Worker   // Code coverage for a doom racing with a doom induced by a failure.
3106*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3107*6777b538SAndroid Build Coastguard Worker   // Disable optimistic ops so we can block on CreateEntry and start
3108*6777b538SAndroid Build Coastguard Worker   // WriteData off with an empty op queue.
3109*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
3110*6777b538SAndroid Build Coastguard Worker   InitCache();
3111*6777b538SAndroid Build Coastguard Worker 
3112*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "the first key";
3113*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 10;
3114*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
3115*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
3116*6777b538SAndroid Build Coastguard Worker 
3117*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
3118*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, CreateEntry(kKey, &entry));
3119*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry != nullptr);
3120*6777b538SAndroid Build Coastguard Worker 
3121*6777b538SAndroid Build Coastguard Worker   // Now an empty _1 file, to cause a stream 2 write to fail.
3122*6777b538SAndroid Build Coastguard Worker   base::FilePath entry_file1_path = cache_path_.AppendASCII(
3123*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(kKey, 1));
3124*6777b538SAndroid Build Coastguard Worker   base::File entry_file1(entry_file1_path,
3125*6777b538SAndroid Build Coastguard Worker                          base::File::FLAG_WRITE | base::File::FLAG_CREATE);
3126*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry_file1.IsValid());
3127*6777b538SAndroid Build Coastguard Worker 
3128*6777b538SAndroid Build Coastguard Worker   entry->WriteData(2, 0, buffer1.get(), kSize1, net::CompletionOnceCallback(),
3129*6777b538SAndroid Build Coastguard Worker                    /* truncate= */ true);
3130*6777b538SAndroid Build Coastguard Worker 
3131*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
3132*6777b538SAndroid Build Coastguard Worker   cache_->DoomEntry(kKey, net::HIGHEST, cb.callback());
3133*6777b538SAndroid Build Coastguard Worker   entry->Close();
3134*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, cb.WaitForResult());
3135*6777b538SAndroid Build Coastguard Worker }
3136*6777b538SAndroid Build Coastguard Worker 
TruncatePath(const base::FilePath & file_path,int64_t length)3137*6777b538SAndroid Build Coastguard Worker bool TruncatePath(const base::FilePath& file_path, int64_t length) {
3138*6777b538SAndroid Build Coastguard Worker   base::File file(file_path, base::File::FLAG_WRITE | base::File::FLAG_OPEN);
3139*6777b538SAndroid Build Coastguard Worker   if (!file.IsValid())
3140*6777b538SAndroid Build Coastguard Worker     return false;
3141*6777b538SAndroid Build Coastguard Worker   return file.SetLength(length);
3142*6777b538SAndroid Build Coastguard Worker }
3143*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheNoEOF)3144*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheNoEOF) {
3145*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3146*6777b538SAndroid Build Coastguard Worker   InitCache();
3147*6777b538SAndroid Build Coastguard Worker 
3148*6777b538SAndroid Build Coastguard Worker   const std::string key("the first key");
3149*6777b538SAndroid Build Coastguard Worker 
3150*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
3151*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
3152*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* null = nullptr;
3153*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry);
3154*6777b538SAndroid Build Coastguard Worker   entry->Close();
3155*6777b538SAndroid Build Coastguard Worker   entry = nullptr;
3156*6777b538SAndroid Build Coastguard Worker 
3157*6777b538SAndroid Build Coastguard Worker   // Force the entry to flush to disk, so subsequent platform file operations
3158*6777b538SAndroid Build Coastguard Worker   // succed.
3159*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
3160*6777b538SAndroid Build Coastguard Worker   entry->Close();
3161*6777b538SAndroid Build Coastguard Worker   entry = nullptr;
3162*6777b538SAndroid Build Coastguard Worker 
3163*6777b538SAndroid Build Coastguard Worker   // Truncate the file such that the length isn't sufficient to have an EOF
3164*6777b538SAndroid Build Coastguard Worker   // record.
3165*6777b538SAndroid Build Coastguard Worker   int kTruncationBytes = -static_cast<int>(sizeof(disk_cache::SimpleFileEOF));
3166*6777b538SAndroid Build Coastguard Worker   const base::FilePath entry_path = cache_path_.AppendASCII(
3167*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
3168*6777b538SAndroid Build Coastguard Worker   const int64_t invalid_size = disk_cache::simple_util::GetFileSizeFromDataSize(
3169*6777b538SAndroid Build Coastguard Worker       key.size(), kTruncationBytes);
3170*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TruncatePath(entry_path, invalid_size));
3171*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(OpenEntry(key, &entry), IsError(net::ERR_FAILED));
3172*6777b538SAndroid Build Coastguard Worker   DisableIntegrityCheck();
3173*6777b538SAndroid Build Coastguard Worker }
3174*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheNonOptimisticOperationsBasic)3175*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheNonOptimisticOperationsBasic) {
3176*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3177*6777b538SAndroid Build Coastguard Worker   // Create, Write, Read, Close.
3178*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);  // APP_CACHE doesn't use optimistic operations.
3179*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3180*6777b538SAndroid Build Coastguard Worker   InitCache();
3181*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* const null_entry = nullptr;
3182*6777b538SAndroid Build Coastguard Worker 
3183*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
3184*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(CreateEntry("my key", &entry), IsOk());
3185*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(null_entry, entry);
3186*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
3187*6777b538SAndroid Build Coastguard Worker 
3188*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 10;
3189*6777b538SAndroid Build Coastguard Worker   scoped_refptr<net::IOBufferWithSize> write_buffer =
3190*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
3191*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false);
3192*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
3193*6777b538SAndroid Build Coastguard Worker       write_buffer->size(),
3194*6777b538SAndroid Build Coastguard Worker       WriteData(entry, 1, 0, write_buffer.get(), write_buffer->size(), false));
3195*6777b538SAndroid Build Coastguard Worker 
3196*6777b538SAndroid Build Coastguard Worker   scoped_refptr<net::IOBufferWithSize> read_buffer =
3197*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
3198*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(read_buffer->size(),
3199*6777b538SAndroid Build Coastguard Worker             ReadData(entry, 1, 0, read_buffer.get(), read_buffer->size()));
3200*6777b538SAndroid Build Coastguard Worker }
3201*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheNonOptimisticOperationsDontBlock)3202*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheNonOptimisticOperationsDontBlock) {
3203*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3204*6777b538SAndroid Build Coastguard Worker   // Create, Write, Close.
3205*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);  // APP_CACHE doesn't use optimistic operations.
3206*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3207*6777b538SAndroid Build Coastguard Worker   InitCache();
3208*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* const null_entry = nullptr;
3209*6777b538SAndroid Build Coastguard Worker 
3210*6777b538SAndroid Build Coastguard Worker   MessageLoopHelper helper;
3211*6777b538SAndroid Build Coastguard Worker   CallbackTest create_callback(&helper, false);
3212*6777b538SAndroid Build Coastguard Worker 
3213*6777b538SAndroid Build Coastguard Worker   int expected_callback_runs = 0;
3214*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 10;
3215*6777b538SAndroid Build Coastguard Worker   scoped_refptr<net::IOBufferWithSize> write_buffer =
3216*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
3217*6777b538SAndroid Build Coastguard Worker 
3218*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
3219*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(CreateEntry("my key", &entry), IsOk());
3220*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(null_entry, entry);
3221*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
3222*6777b538SAndroid Build Coastguard Worker 
3223*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false);
3224*6777b538SAndroid Build Coastguard Worker   CallbackTest write_callback(&helper, false);
3225*6777b538SAndroid Build Coastguard Worker   int ret = entry->WriteData(
3226*6777b538SAndroid Build Coastguard Worker       1, 0, write_buffer.get(), write_buffer->size(),
3227*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&write_callback)),
3228*6777b538SAndroid Build Coastguard Worker       false);
3229*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(ret, IsError(net::ERR_IO_PENDING));
3230*6777b538SAndroid Build Coastguard Worker   helper.WaitUntilCacheIoFinished(++expected_callback_runs);
3231*6777b538SAndroid Build Coastguard Worker }
3232*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheNonOptimisticOperationsBasicsWithoutWaiting)3233*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest,
3234*6777b538SAndroid Build Coastguard Worker        SimpleCacheNonOptimisticOperationsBasicsWithoutWaiting) {
3235*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3236*6777b538SAndroid Build Coastguard Worker   // Create, Write, Read, Close.
3237*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);  // APP_CACHE doesn't use optimistic operations.
3238*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3239*6777b538SAndroid Build Coastguard Worker   InitCache();
3240*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* const null_entry = nullptr;
3241*6777b538SAndroid Build Coastguard Worker   MessageLoopHelper helper;
3242*6777b538SAndroid Build Coastguard Worker 
3243*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
3244*6777b538SAndroid Build Coastguard Worker   // Note that |entry| is only set once CreateEntry() completed which is why we
3245*6777b538SAndroid Build Coastguard Worker   // have to wait (i.e. use the helper CreateEntry() function).
3246*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(CreateEntry("my key", &entry), IsOk());
3247*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(null_entry, entry);
3248*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
3249*6777b538SAndroid Build Coastguard Worker 
3250*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 10;
3251*6777b538SAndroid Build Coastguard Worker   scoped_refptr<net::IOBufferWithSize> write_buffer =
3252*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
3253*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false);
3254*6777b538SAndroid Build Coastguard Worker   CallbackTest write_callback(&helper, false);
3255*6777b538SAndroid Build Coastguard Worker   int ret = entry->WriteData(
3256*6777b538SAndroid Build Coastguard Worker       1, 0, write_buffer.get(), write_buffer->size(),
3257*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&write_callback)),
3258*6777b538SAndroid Build Coastguard Worker       false);
3259*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ret, IsError(net::ERR_IO_PENDING));
3260*6777b538SAndroid Build Coastguard Worker   int expected_callback_runs = 1;
3261*6777b538SAndroid Build Coastguard Worker 
3262*6777b538SAndroid Build Coastguard Worker   scoped_refptr<net::IOBufferWithSize> read_buffer =
3263*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
3264*6777b538SAndroid Build Coastguard Worker   CallbackTest read_callback(&helper, false);
3265*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadData(
3266*6777b538SAndroid Build Coastguard Worker       1, 0, read_buffer.get(), read_buffer->size(),
3267*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&read_callback)));
3268*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ret, IsError(net::ERR_IO_PENDING));
3269*6777b538SAndroid Build Coastguard Worker   ++expected_callback_runs;
3270*6777b538SAndroid Build Coastguard Worker 
3271*6777b538SAndroid Build Coastguard Worker   helper.WaitUntilCacheIoFinished(expected_callback_runs);
3272*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(read_buffer->size(), write_buffer->size());
3273*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
3274*6777b538SAndroid Build Coastguard Worker       0,
3275*6777b538SAndroid Build Coastguard Worker       memcmp(read_buffer->data(), write_buffer->data(), read_buffer->size()));
3276*6777b538SAndroid Build Coastguard Worker }
3277*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheOptimistic)3278*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic) {
3279*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3280*6777b538SAndroid Build Coastguard Worker   // Create, Write, Read, Write, Read, Close.
3281*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3282*6777b538SAndroid Build Coastguard Worker   InitCache();
3283*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* null = nullptr;
3284*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3285*6777b538SAndroid Build Coastguard Worker 
3286*6777b538SAndroid Build Coastguard Worker   MessageLoopHelper helper;
3287*6777b538SAndroid Build Coastguard Worker   CallbackTest callback1(&helper, false);
3288*6777b538SAndroid Build Coastguard Worker   CallbackTest callback2(&helper, false);
3289*6777b538SAndroid Build Coastguard Worker   CallbackTest callback3(&helper, false);
3290*6777b538SAndroid Build Coastguard Worker   CallbackTest callback4(&helper, false);
3291*6777b538SAndroid Build Coastguard Worker   CallbackTest callback5(&helper, false);
3292*6777b538SAndroid Build Coastguard Worker 
3293*6777b538SAndroid Build Coastguard Worker   int expected = 0;
3294*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 10;
3295*6777b538SAndroid Build Coastguard Worker   const int kSize2 = 20;
3296*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
3297*6777b538SAndroid Build Coastguard Worker   auto buffer1_read = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
3298*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize2);
3299*6777b538SAndroid Build Coastguard Worker   auto buffer2_read = base::MakeRefCounted<net::IOBufferWithSize>(kSize2);
3300*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
3301*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize2, false);
3302*6777b538SAndroid Build Coastguard Worker 
3303*6777b538SAndroid Build Coastguard Worker   // Create is optimistic, must return OK.
3304*6777b538SAndroid Build Coastguard Worker   EntryResult result =
3305*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST,
3306*6777b538SAndroid Build Coastguard Worker                           base::BindOnce(&CallbackTest::RunWithEntry,
3307*6777b538SAndroid Build Coastguard Worker                                          base::Unretained(&callback1)));
3308*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result.net_error());
3309*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = result.ReleaseEntry();
3310*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(null, entry);
3311*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
3312*6777b538SAndroid Build Coastguard Worker 
3313*6777b538SAndroid Build Coastguard Worker   // This write may or may not be optimistic (it depends if the previous
3314*6777b538SAndroid Build Coastguard Worker   // optimistic create already finished by the time we call the write here).
3315*6777b538SAndroid Build Coastguard Worker   int ret = entry->WriteData(
3316*6777b538SAndroid Build Coastguard Worker       1, 0, buffer1.get(), kSize1,
3317*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&CallbackTest::Run, base::Unretained(&callback2)), false);
3318*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(kSize1 == ret || net::ERR_IO_PENDING == ret);
3319*6777b538SAndroid Build Coastguard Worker   if (net::ERR_IO_PENDING == ret)
3320*6777b538SAndroid Build Coastguard Worker     expected++;
3321*6777b538SAndroid Build Coastguard Worker 
3322*6777b538SAndroid Build Coastguard Worker   // This Read must not be optimistic, since we don't support that yet.
3323*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING,
3324*6777b538SAndroid Build Coastguard Worker             entry->ReadData(1, 0, buffer1_read.get(), kSize1,
3325*6777b538SAndroid Build Coastguard Worker                             base::BindOnce(&CallbackTest::Run,
3326*6777b538SAndroid Build Coastguard Worker                                            base::Unretained(&callback3))));
3327*6777b538SAndroid Build Coastguard Worker   expected++;
3328*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
3329*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read->data(), kSize1));
3330*6777b538SAndroid Build Coastguard Worker 
3331*6777b538SAndroid Build Coastguard Worker   // At this point after waiting, the pending operations queue on the entry
3332*6777b538SAndroid Build Coastguard Worker   // should be empty, so the next Write operation must run as optimistic.
3333*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize2,
3334*6777b538SAndroid Build Coastguard Worker             entry->WriteData(1, 0, buffer2.get(), kSize2,
3335*6777b538SAndroid Build Coastguard Worker                              base::BindOnce(&CallbackTest::Run,
3336*6777b538SAndroid Build Coastguard Worker                                             base::Unretained(&callback4)),
3337*6777b538SAndroid Build Coastguard Worker                              false));
3338*6777b538SAndroid Build Coastguard Worker 
3339*6777b538SAndroid Build Coastguard Worker   // Lets do another read so we block until both the write and the read
3340*6777b538SAndroid Build Coastguard Worker   // operation finishes and we can then test for HasOneRef() below.
3341*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING,
3342*6777b538SAndroid Build Coastguard Worker             entry->ReadData(1, 0, buffer2_read.get(), kSize2,
3343*6777b538SAndroid Build Coastguard Worker                             base::BindOnce(&CallbackTest::Run,
3344*6777b538SAndroid Build Coastguard Worker                                            base::Unretained(&callback5))));
3345*6777b538SAndroid Build Coastguard Worker   expected++;
3346*6777b538SAndroid Build Coastguard Worker 
3347*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
3348*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer2->data(), buffer2_read->data(), kSize2));
3349*6777b538SAndroid Build Coastguard Worker 
3350*6777b538SAndroid Build Coastguard Worker   // Check that we are not leaking.
3351*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(entry, null);
3352*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
3353*6777b538SAndroid Build Coastguard Worker       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
3354*6777b538SAndroid Build Coastguard Worker }
3355*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheOptimistic2)3356*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic2) {
3357*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3358*6777b538SAndroid Build Coastguard Worker   // Create, Open, Close, Close.
3359*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3360*6777b538SAndroid Build Coastguard Worker   InitCache();
3361*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3362*6777b538SAndroid Build Coastguard Worker 
3363*6777b538SAndroid Build Coastguard Worker   MessageLoopHelper helper;
3364*6777b538SAndroid Build Coastguard Worker   CallbackTest callback1(&helper, false);
3365*6777b538SAndroid Build Coastguard Worker   CallbackTest callback2(&helper, false);
3366*6777b538SAndroid Build Coastguard Worker 
3367*6777b538SAndroid Build Coastguard Worker   EntryResult result =
3368*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST,
3369*6777b538SAndroid Build Coastguard Worker                           base::BindOnce(&CallbackTest::RunWithEntry,
3370*6777b538SAndroid Build Coastguard Worker                                          base::Unretained(&callback1)));
3371*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result.net_error());
3372*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = result.ReleaseEntry();
3373*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry);
3374*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
3375*6777b538SAndroid Build Coastguard Worker 
3376*6777b538SAndroid Build Coastguard Worker   EntryResult result2 =
3377*6777b538SAndroid Build Coastguard Worker       cache_->OpenEntry(key, net::HIGHEST,
3378*6777b538SAndroid Build Coastguard Worker                         base::BindOnce(&CallbackTest::RunWithEntry,
3379*6777b538SAndroid Build Coastguard Worker                                        base::Unretained(&callback2)));
3380*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::ERR_IO_PENDING, result2.net_error());
3381*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(helper.WaitUntilCacheIoFinished(1));
3382*6777b538SAndroid Build Coastguard Worker   result2 = callback2.ReleaseLastEntryResult();
3383*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK, result2.net_error());
3384*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = result2.ReleaseEntry();
3385*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(nullptr, entry2);
3386*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(entry, entry2);
3387*6777b538SAndroid Build Coastguard Worker 
3388*6777b538SAndroid Build Coastguard Worker   // We have to call close twice, since we called create and open above.
3389*6777b538SAndroid Build Coastguard Worker   // (the other closes is from |entry_closer|).
3390*6777b538SAndroid Build Coastguard Worker   entry->Close();
3391*6777b538SAndroid Build Coastguard Worker 
3392*6777b538SAndroid Build Coastguard Worker   // Check that we are not leaking.
3393*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
3394*6777b538SAndroid Build Coastguard Worker       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
3395*6777b538SAndroid Build Coastguard Worker }
3396*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheOptimistic3)3397*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic3) {
3398*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3399*6777b538SAndroid Build Coastguard Worker   // Create, Close, Open, Close.
3400*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3401*6777b538SAndroid Build Coastguard Worker   InitCache();
3402*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3403*6777b538SAndroid Build Coastguard Worker 
3404*6777b538SAndroid Build Coastguard Worker   EntryResult result =
3405*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback());
3406*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result.net_error());
3407*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = result.ReleaseEntry();
3408*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry);
3409*6777b538SAndroid Build Coastguard Worker   entry->Close();
3410*6777b538SAndroid Build Coastguard Worker 
3411*6777b538SAndroid Build Coastguard Worker   TestEntryResultCompletionCallback cb;
3412*6777b538SAndroid Build Coastguard Worker   EntryResult result2 = cache_->OpenEntry(key, net::HIGHEST, cb.callback());
3413*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::ERR_IO_PENDING, result2.net_error());
3414*6777b538SAndroid Build Coastguard Worker   result2 = cb.WaitForResult();
3415*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(result2.net_error(), IsOk());
3416*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = result2.ReleaseEntry();
3417*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry2);
3418*6777b538SAndroid Build Coastguard Worker 
3419*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(nullptr, entry2);
3420*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(entry, entry2);
3421*6777b538SAndroid Build Coastguard Worker 
3422*6777b538SAndroid Build Coastguard Worker   // Check that we are not leaking.
3423*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
3424*6777b538SAndroid Build Coastguard Worker       static_cast<disk_cache::SimpleEntryImpl*>(entry2)->HasOneRef());
3425*6777b538SAndroid Build Coastguard Worker }
3426*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheOptimistic4)3427*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic4) {
3428*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3429*6777b538SAndroid Build Coastguard Worker   // Create, Close, Write, Open, Open, Close, Write, Read, Close.
3430*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3431*6777b538SAndroid Build Coastguard Worker   InitCache();
3432*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3433*6777b538SAndroid Build Coastguard Worker 
3434*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
3435*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 10;
3436*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
3437*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
3438*6777b538SAndroid Build Coastguard Worker 
3439*6777b538SAndroid Build Coastguard Worker   EntryResult result =
3440*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback());
3441*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result.net_error());
3442*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = result.ReleaseEntry();
3443*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry);
3444*6777b538SAndroid Build Coastguard Worker   entry->Close();
3445*6777b538SAndroid Build Coastguard Worker 
3446*6777b538SAndroid Build Coastguard Worker   // Lets do a Write so we block until both the Close and the Write
3447*6777b538SAndroid Build Coastguard Worker   // operation finishes. Write must fail since we are writing in a closed entry.
3448*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
3449*6777b538SAndroid Build Coastguard Worker       net::ERR_IO_PENDING,
3450*6777b538SAndroid Build Coastguard Worker       entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false));
3451*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cb.GetResult(net::ERR_IO_PENDING), IsError(net::ERR_FAILED));
3452*6777b538SAndroid Build Coastguard Worker 
3453*6777b538SAndroid Build Coastguard Worker   // Finish running the pending tasks so that we fully complete the close
3454*6777b538SAndroid Build Coastguard Worker   // operation and destroy the entry object.
3455*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3456*6777b538SAndroid Build Coastguard Worker 
3457*6777b538SAndroid Build Coastguard Worker   // At this point the |entry| must have been destroyed, and called
3458*6777b538SAndroid Build Coastguard Worker   // RemoveSelfFromBackend().
3459*6777b538SAndroid Build Coastguard Worker   TestEntryResultCompletionCallback cb2;
3460*6777b538SAndroid Build Coastguard Worker   EntryResult result2 = cache_->OpenEntry(key, net::HIGHEST, cb2.callback());
3461*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::ERR_IO_PENDING, result2.net_error());
3462*6777b538SAndroid Build Coastguard Worker   result2 = cb2.WaitForResult();
3463*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(result2.net_error(), IsOk());
3464*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = result2.ReleaseEntry();
3465*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(nullptr, entry2);
3466*6777b538SAndroid Build Coastguard Worker 
3467*6777b538SAndroid Build Coastguard Worker   EntryResult result3 = cache_->OpenEntry(key, net::HIGHEST, cb2.callback());
3468*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::ERR_IO_PENDING, result3.net_error());
3469*6777b538SAndroid Build Coastguard Worker   result3 = cb2.WaitForResult();
3470*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(result3.net_error(), IsOk());
3471*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry3 = result3.ReleaseEntry();
3472*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(nullptr, entry3);
3473*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(entry2, entry3);
3474*6777b538SAndroid Build Coastguard Worker   entry3->Close();
3475*6777b538SAndroid Build Coastguard Worker 
3476*6777b538SAndroid Build Coastguard Worker   // The previous Close doesn't actually closes the entry since we opened it
3477*6777b538SAndroid Build Coastguard Worker   // twice, so the next Write operation must succeed and it must be able to
3478*6777b538SAndroid Build Coastguard Worker   // perform it optimistically, since there is no operation running on this
3479*6777b538SAndroid Build Coastguard Worker   // entry.
3480*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize1, entry2->WriteData(1, 0, buffer1.get(), kSize1,
3481*6777b538SAndroid Build Coastguard Worker                                       net::CompletionOnceCallback(), false));
3482*6777b538SAndroid Build Coastguard Worker 
3483*6777b538SAndroid Build Coastguard Worker   // Lets do another read so we block until both the write and the read
3484*6777b538SAndroid Build Coastguard Worker   // operation finishes and we can then test for HasOneRef() below.
3485*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING,
3486*6777b538SAndroid Build Coastguard Worker             entry2->ReadData(1, 0, buffer1.get(), kSize1, cb.callback()));
3487*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
3488*6777b538SAndroid Build Coastguard Worker 
3489*6777b538SAndroid Build Coastguard Worker   // Check that we are not leaking.
3490*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
3491*6777b538SAndroid Build Coastguard Worker       static_cast<disk_cache::SimpleEntryImpl*>(entry2)->HasOneRef());
3492*6777b538SAndroid Build Coastguard Worker   entry2->Close();
3493*6777b538SAndroid Build Coastguard Worker }
3494*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheOptimistic5)3495*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic5) {
3496*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3497*6777b538SAndroid Build Coastguard Worker   // Create, Doom, Write, Read, Close.
3498*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3499*6777b538SAndroid Build Coastguard Worker   InitCache();
3500*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3501*6777b538SAndroid Build Coastguard Worker 
3502*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
3503*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 10;
3504*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
3505*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
3506*6777b538SAndroid Build Coastguard Worker 
3507*6777b538SAndroid Build Coastguard Worker   EntryResult result =
3508*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback());
3509*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result.net_error());
3510*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = result.ReleaseEntry();
3511*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry);
3512*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
3513*6777b538SAndroid Build Coastguard Worker   entry->Doom();
3514*6777b538SAndroid Build Coastguard Worker 
3515*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
3516*6777b538SAndroid Build Coastguard Worker       net::ERR_IO_PENDING,
3517*6777b538SAndroid Build Coastguard Worker       entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false));
3518*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
3519*6777b538SAndroid Build Coastguard Worker 
3520*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING,
3521*6777b538SAndroid Build Coastguard Worker             entry->ReadData(1, 0, buffer1.get(), kSize1, cb.callback()));
3522*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
3523*6777b538SAndroid Build Coastguard Worker 
3524*6777b538SAndroid Build Coastguard Worker   // Check that we are not leaking.
3525*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
3526*6777b538SAndroid Build Coastguard Worker       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
3527*6777b538SAndroid Build Coastguard Worker }
3528*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheOptimistic6)3529*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic6) {
3530*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3531*6777b538SAndroid Build Coastguard Worker   // Create, Write, Doom, Doom, Read, Doom, Close.
3532*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3533*6777b538SAndroid Build Coastguard Worker   InitCache();
3534*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3535*6777b538SAndroid Build Coastguard Worker 
3536*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
3537*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 10;
3538*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
3539*6777b538SAndroid Build Coastguard Worker   auto buffer1_read = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
3540*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
3541*6777b538SAndroid Build Coastguard Worker 
3542*6777b538SAndroid Build Coastguard Worker   EntryResult result =
3543*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback());
3544*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result.net_error());
3545*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = result.ReleaseEntry();
3546*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(nullptr, entry);
3547*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
3548*6777b538SAndroid Build Coastguard Worker 
3549*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
3550*6777b538SAndroid Build Coastguard Worker       net::ERR_IO_PENDING,
3551*6777b538SAndroid Build Coastguard Worker       entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false));
3552*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
3553*6777b538SAndroid Build Coastguard Worker 
3554*6777b538SAndroid Build Coastguard Worker   entry->Doom();
3555*6777b538SAndroid Build Coastguard Worker   entry->Doom();
3556*6777b538SAndroid Build Coastguard Worker 
3557*6777b538SAndroid Build Coastguard Worker   // This Read must not be optimistic, since we don't support that yet.
3558*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING,
3559*6777b538SAndroid Build Coastguard Worker             entry->ReadData(1, 0, buffer1_read.get(), kSize1, cb.callback()));
3560*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
3561*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read->data(), kSize1));
3562*6777b538SAndroid Build Coastguard Worker 
3563*6777b538SAndroid Build Coastguard Worker   entry->Doom();
3564*6777b538SAndroid Build Coastguard Worker }
3565*6777b538SAndroid Build Coastguard Worker 
3566*6777b538SAndroid Build Coastguard Worker // Confirm that IO buffers are not referenced by the Simple Cache after a write
3567*6777b538SAndroid Build Coastguard Worker // completes.
TEST_F(DiskCacheEntryTest,SimpleCacheOptimisticWriteReleases)3568*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOptimisticWriteReleases) {
3569*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3570*6777b538SAndroid Build Coastguard Worker   InitCache();
3571*6777b538SAndroid Build Coastguard Worker 
3572*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3573*6777b538SAndroid Build Coastguard Worker 
3574*6777b538SAndroid Build Coastguard Worker   // First, an optimistic create.
3575*6777b538SAndroid Build Coastguard Worker   EntryResult result =
3576*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback());
3577*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result.net_error());
3578*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = result.ReleaseEntry();
3579*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry);
3580*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
3581*6777b538SAndroid Build Coastguard Worker 
3582*6777b538SAndroid Build Coastguard Worker   const int kWriteSize = 512;
3583*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kWriteSize);
3584*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(buffer1->HasOneRef());
3585*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kWriteSize, false);
3586*6777b538SAndroid Build Coastguard Worker 
3587*6777b538SAndroid Build Coastguard Worker   // An optimistic write happens only when there is an empty queue of pending
3588*6777b538SAndroid Build Coastguard Worker   // operations. To ensure the queue is empty, we issue a write and wait until
3589*6777b538SAndroid Build Coastguard Worker   // it completes.
3590*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kWriteSize,
3591*6777b538SAndroid Build Coastguard Worker             WriteData(entry, 1, 0, buffer1.get(), kWriteSize, false));
3592*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(buffer1->HasOneRef());
3593*6777b538SAndroid Build Coastguard Worker 
3594*6777b538SAndroid Build Coastguard Worker   // Finally, we should perform an optimistic write and confirm that all
3595*6777b538SAndroid Build Coastguard Worker   // references to the IO buffer have been released.
3596*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kWriteSize, entry->WriteData(1, 0, buffer1.get(), kWriteSize,
3597*6777b538SAndroid Build Coastguard Worker                                          net::CompletionOnceCallback(), false));
3598*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(buffer1->HasOneRef());
3599*6777b538SAndroid Build Coastguard Worker }
3600*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheCreateDoomRace)3601*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheCreateDoomRace) {
3602*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3603*6777b538SAndroid Build Coastguard Worker   // Create, Doom, Write, Close, Check files are not on disk anymore.
3604*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3605*6777b538SAndroid Build Coastguard Worker   InitCache();
3606*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3607*6777b538SAndroid Build Coastguard Worker 
3608*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
3609*6777b538SAndroid Build Coastguard Worker   const int kSize1 = 10;
3610*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize1);
3611*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize1, false);
3612*6777b538SAndroid Build Coastguard Worker 
3613*6777b538SAndroid Build Coastguard Worker   EntryResult result =
3614*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback());
3615*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result.net_error());
3616*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = result.ReleaseEntry();
3617*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(nullptr, entry);
3618*6777b538SAndroid Build Coastguard Worker 
3619*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cache_->DoomEntry(key, net::HIGHEST, cb.callback()),
3620*6777b538SAndroid Build Coastguard Worker               IsError(net::ERR_IO_PENDING));
3621*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cb.GetResult(net::ERR_IO_PENDING), IsOk());
3622*6777b538SAndroid Build Coastguard Worker 
3623*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
3624*6777b538SAndroid Build Coastguard Worker       kSize1,
3625*6777b538SAndroid Build Coastguard Worker       entry->WriteData(0, 0, buffer1.get(), kSize1, cb.callback(), false));
3626*6777b538SAndroid Build Coastguard Worker 
3627*6777b538SAndroid Build Coastguard Worker   entry->Close();
3628*6777b538SAndroid Build Coastguard Worker 
3629*6777b538SAndroid Build Coastguard Worker   // Finish running the pending tasks so that we fully complete the close
3630*6777b538SAndroid Build Coastguard Worker   // operation and destroy the entry object.
3631*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
3632*6777b538SAndroid Build Coastguard Worker 
3633*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryNormalFileCount; ++i) {
3634*6777b538SAndroid Build Coastguard Worker     base::FilePath entry_file_path = cache_path_.AppendASCII(
3635*6777b538SAndroid Build Coastguard Worker         disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, i));
3636*6777b538SAndroid Build Coastguard Worker     base::File::Info info;
3637*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(base::GetFileInfo(entry_file_path, &info));
3638*6777b538SAndroid Build Coastguard Worker   }
3639*6777b538SAndroid Build Coastguard Worker }
3640*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomCreateRace)3641*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateRace) {
3642*6777b538SAndroid Build Coastguard Worker   // This test runs as APP_CACHE to make operations more synchronous. Test
3643*6777b538SAndroid Build Coastguard Worker   // sequence:
3644*6777b538SAndroid Build Coastguard Worker   // Create, Doom, Create.
3645*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
3646*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3647*6777b538SAndroid Build Coastguard Worker   InitCache();
3648*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3649*6777b538SAndroid Build Coastguard Worker 
3650*6777b538SAndroid Build Coastguard Worker   TestEntryResultCompletionCallback create_callback;
3651*6777b538SAndroid Build Coastguard Worker 
3652*6777b538SAndroid Build Coastguard Worker   EntryResult result1 = create_callback.GetResult(
3653*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST, create_callback.callback()));
3654*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result1.net_error());
3655*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1 = result1.ReleaseEntry();
3656*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry1_closer(entry1);
3657*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(nullptr, entry1);
3658*6777b538SAndroid Build Coastguard Worker 
3659*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback doom_callback;
3660*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING,
3661*6777b538SAndroid Build Coastguard Worker             cache_->DoomEntry(key, net::HIGHEST, doom_callback.callback()));
3662*6777b538SAndroid Build Coastguard Worker 
3663*6777b538SAndroid Build Coastguard Worker   EntryResult result2 = create_callback.GetResult(
3664*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST, create_callback.callback()));
3665*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result2.net_error());
3666*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = result2.ReleaseEntry();
3667*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry2_closer(entry2);
3668*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(doom_callback.GetResult(net::ERR_IO_PENDING), IsOk());
3669*6777b538SAndroid Build Coastguard Worker }
3670*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomCreateOptimistic)3671*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateOptimistic) {
3672*6777b538SAndroid Build Coastguard Worker   // Test that we optimize the doom -> create sequence when optimistic ops
3673*6777b538SAndroid Build Coastguard Worker   // are on.
3674*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3675*6777b538SAndroid Build Coastguard Worker   InitCache();
3676*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "the key";
3677*6777b538SAndroid Build Coastguard Worker 
3678*6777b538SAndroid Build Coastguard Worker   // Create entry and initiate its Doom.
3679*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1 = nullptr;
3680*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kKey, &entry1), IsOk());
3681*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry1 != nullptr);
3682*6777b538SAndroid Build Coastguard Worker 
3683*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback doom_callback;
3684*6777b538SAndroid Build Coastguard Worker   cache_->DoomEntry(kKey, net::HIGHEST, doom_callback.callback());
3685*6777b538SAndroid Build Coastguard Worker 
3686*6777b538SAndroid Build Coastguard Worker   TestEntryResultCompletionCallback create_callback;
3687*6777b538SAndroid Build Coastguard Worker   // Open entry2, with same key. With optimistic ops, this should succeed
3688*6777b538SAndroid Build Coastguard Worker   // immediately, hence us using cache_->CreateEntry directly rather than using
3689*6777b538SAndroid Build Coastguard Worker   // the DiskCacheTestWithCache::CreateEntry wrapper which blocks when needed.
3690*6777b538SAndroid Build Coastguard Worker   EntryResult result2 =
3691*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(kKey, net::HIGHEST, create_callback.callback());
3692*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result2.net_error());
3693*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = result2.ReleaseEntry();
3694*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry2);
3695*6777b538SAndroid Build Coastguard Worker 
3696*6777b538SAndroid Build Coastguard Worker   // Do some I/O to make sure it's alive.
3697*6777b538SAndroid Build Coastguard Worker   const int kSize = 2048;
3698*6777b538SAndroid Build Coastguard Worker   auto buf_1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
3699*6777b538SAndroid Build Coastguard Worker   auto buf_2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
3700*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf_1->data(), kSize, false);
3701*6777b538SAndroid Build Coastguard Worker 
3702*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry2, /* index = */ 1, /* offset = */ 0,
3703*6777b538SAndroid Build Coastguard Worker                              buf_1.get(), kSize, /* truncate = */ false));
3704*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry2, /* index = */ 1, /* offset = */ 0,
3705*6777b538SAndroid Build Coastguard Worker                             buf_2.get(), kSize));
3706*6777b538SAndroid Build Coastguard Worker 
3707*6777b538SAndroid Build Coastguard Worker   doom_callback.WaitForResult();
3708*6777b538SAndroid Build Coastguard Worker 
3709*6777b538SAndroid Build Coastguard Worker   entry1->Close();
3710*6777b538SAndroid Build Coastguard Worker   entry2->Close();
3711*6777b538SAndroid Build Coastguard Worker }
3712*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomCreateOptimisticMassDoom)3713*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateOptimisticMassDoom) {
3714*6777b538SAndroid Build Coastguard Worker   // Test that shows that a certain DCHECK in mass doom code had to be removed
3715*6777b538SAndroid Build Coastguard Worker   // once optimistic doom -> create was added.
3716*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3717*6777b538SAndroid Build Coastguard Worker   InitCache();
3718*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "the key";
3719*6777b538SAndroid Build Coastguard Worker 
3720*6777b538SAndroid Build Coastguard Worker   // Create entry and initiate its Doom.
3721*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1 = nullptr;
3722*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kKey, &entry1), IsOk());
3723*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry1 != nullptr);
3724*6777b538SAndroid Build Coastguard Worker 
3725*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback doom_callback;
3726*6777b538SAndroid Build Coastguard Worker   cache_->DoomEntry(kKey, net::HIGHEST, doom_callback.callback());
3727*6777b538SAndroid Build Coastguard Worker 
3728*6777b538SAndroid Build Coastguard Worker   TestEntryResultCompletionCallback create_callback;
3729*6777b538SAndroid Build Coastguard Worker   // Open entry2, with same key. With optimistic ops, this should succeed
3730*6777b538SAndroid Build Coastguard Worker   // immediately, hence us using cache_->CreateEntry directly rather than using
3731*6777b538SAndroid Build Coastguard Worker   // the DiskCacheTestWithCache::CreateEntry wrapper which blocks when needed.
3732*6777b538SAndroid Build Coastguard Worker   EntryResult result =
3733*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(kKey, net::HIGHEST, create_callback.callback());
3734*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result.net_error());
3735*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = result.ReleaseEntry();
3736*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, entry2);
3737*6777b538SAndroid Build Coastguard Worker 
3738*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback doomall_callback;
3739*6777b538SAndroid Build Coastguard Worker 
3740*6777b538SAndroid Build Coastguard Worker   // This is what had code that had a no-longer valid DCHECK.
3741*6777b538SAndroid Build Coastguard Worker   cache_->DoomAllEntries(doomall_callback.callback());
3742*6777b538SAndroid Build Coastguard Worker 
3743*6777b538SAndroid Build Coastguard Worker   doom_callback.WaitForResult();
3744*6777b538SAndroid Build Coastguard Worker   doomall_callback.WaitForResult();
3745*6777b538SAndroid Build Coastguard Worker 
3746*6777b538SAndroid Build Coastguard Worker   entry1->Close();
3747*6777b538SAndroid Build Coastguard Worker   entry2->Close();
3748*6777b538SAndroid Build Coastguard Worker }
3749*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomOpenOptimistic)3750*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomOpenOptimistic) {
3751*6777b538SAndroid Build Coastguard Worker   // Test that we optimize the doom -> optimize sequence when optimistic ops
3752*6777b538SAndroid Build Coastguard Worker   // are on.
3753*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3754*6777b538SAndroid Build Coastguard Worker   InitCache();
3755*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "the key";
3756*6777b538SAndroid Build Coastguard Worker 
3757*6777b538SAndroid Build Coastguard Worker   // Create entry and initiate its Doom.
3758*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1 = nullptr;
3759*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kKey, &entry1), IsOk());
3760*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry1 != nullptr);
3761*6777b538SAndroid Build Coastguard Worker   entry1->Close();
3762*6777b538SAndroid Build Coastguard Worker 
3763*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback doom_callback;
3764*6777b538SAndroid Build Coastguard Worker   cache_->DoomEntry(kKey, net::HIGHEST, doom_callback.callback());
3765*6777b538SAndroid Build Coastguard Worker 
3766*6777b538SAndroid Build Coastguard Worker   // Try to open entry. This should detect a miss immediately, since it's
3767*6777b538SAndroid Build Coastguard Worker   // the only thing after a doom.
3768*6777b538SAndroid Build Coastguard Worker 
3769*6777b538SAndroid Build Coastguard Worker   EntryResult result2 =
3770*6777b538SAndroid Build Coastguard Worker       cache_->OpenEntry(kKey, net::HIGHEST, EntryResultCallback());
3771*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_FAILED, result2.net_error());
3772*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, result2.ReleaseEntry());
3773*6777b538SAndroid Build Coastguard Worker   doom_callback.WaitForResult();
3774*6777b538SAndroid Build Coastguard Worker }
3775*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomDoom)3776*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomDoom) {
3777*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3778*6777b538SAndroid Build Coastguard Worker   // Create, Doom, Create, Doom (1st entry), Open.
3779*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3780*6777b538SAndroid Build Coastguard Worker   InitCache();
3781*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* null = nullptr;
3782*6777b538SAndroid Build Coastguard Worker 
3783*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3784*6777b538SAndroid Build Coastguard Worker 
3785*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1 = nullptr;
3786*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry1), IsOk());
3787*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry1_closer(entry1);
3788*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry1);
3789*6777b538SAndroid Build Coastguard Worker 
3790*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(DoomEntry(key), IsOk());
3791*6777b538SAndroid Build Coastguard Worker 
3792*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = nullptr;
3793*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry2), IsOk());
3794*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry2_closer(entry2);
3795*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry2);
3796*6777b538SAndroid Build Coastguard Worker 
3797*6777b538SAndroid Build Coastguard Worker   // Redundantly dooming entry1 should not delete entry2.
3798*6777b538SAndroid Build Coastguard Worker   disk_cache::SimpleEntryImpl* simple_entry1 =
3799*6777b538SAndroid Build Coastguard Worker       static_cast<disk_cache::SimpleEntryImpl*>(entry1);
3800*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
3801*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::OK,
3802*6777b538SAndroid Build Coastguard Worker             cb.GetResult(simple_entry1->DoomEntry(cb.callback())));
3803*6777b538SAndroid Build Coastguard Worker 
3804*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry3 = nullptr;
3805*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry3), IsOk());
3806*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry3_closer(entry3);
3807*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry3);
3808*6777b538SAndroid Build Coastguard Worker }
3809*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomCreateDoom)3810*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateDoom) {
3811*6777b538SAndroid Build Coastguard Worker   // Test sequence:
3812*6777b538SAndroid Build Coastguard Worker   // Create, Doom, Create, Doom.
3813*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3814*6777b538SAndroid Build Coastguard Worker   InitCache();
3815*6777b538SAndroid Build Coastguard Worker 
3816*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* null = nullptr;
3817*6777b538SAndroid Build Coastguard Worker 
3818*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3819*6777b538SAndroid Build Coastguard Worker 
3820*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1 = nullptr;
3821*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry1), IsOk());
3822*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry1_closer(entry1);
3823*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry1);
3824*6777b538SAndroid Build Coastguard Worker 
3825*6777b538SAndroid Build Coastguard Worker   entry1->Doom();
3826*6777b538SAndroid Build Coastguard Worker 
3827*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = nullptr;
3828*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry2), IsOk());
3829*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry2_closer(entry2);
3830*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry2);
3831*6777b538SAndroid Build Coastguard Worker 
3832*6777b538SAndroid Build Coastguard Worker   entry2->Doom();
3833*6777b538SAndroid Build Coastguard Worker 
3834*6777b538SAndroid Build Coastguard Worker   // This test passes if it doesn't crash.
3835*6777b538SAndroid Build Coastguard Worker }
3836*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomCloseCreateCloseOpen)3837*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomCloseCreateCloseOpen) {
3838*6777b538SAndroid Build Coastguard Worker   // Test sequence: Create, Doom, Close, Create, Close, Open.
3839*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3840*6777b538SAndroid Build Coastguard Worker   InitCache();
3841*6777b538SAndroid Build Coastguard Worker 
3842*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* null = nullptr;
3843*6777b538SAndroid Build Coastguard Worker 
3844*6777b538SAndroid Build Coastguard Worker   const char key[] = "this is a key";
3845*6777b538SAndroid Build Coastguard Worker 
3846*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1 = nullptr;
3847*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry1), IsOk());
3848*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry1_closer(entry1);
3849*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry1);
3850*6777b538SAndroid Build Coastguard Worker 
3851*6777b538SAndroid Build Coastguard Worker   entry1->Doom();
3852*6777b538SAndroid Build Coastguard Worker   entry1_closer.reset();
3853*6777b538SAndroid Build Coastguard Worker   entry1 = nullptr;
3854*6777b538SAndroid Build Coastguard Worker 
3855*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = nullptr;
3856*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry2), IsOk());
3857*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry2_closer(entry2);
3858*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry2);
3859*6777b538SAndroid Build Coastguard Worker 
3860*6777b538SAndroid Build Coastguard Worker   entry2_closer.reset();
3861*6777b538SAndroid Build Coastguard Worker   entry2 = nullptr;
3862*6777b538SAndroid Build Coastguard Worker 
3863*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry3 = nullptr;
3864*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry3), IsOk());
3865*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry3_closer(entry3);
3866*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry3);
3867*6777b538SAndroid Build Coastguard Worker }
3868*6777b538SAndroid Build Coastguard Worker 
3869*6777b538SAndroid Build Coastguard Worker // Checks that an optimistic Create would fail later on a racing Open.
TEST_F(DiskCacheEntryTest,SimpleCacheOptimisticCreateFailsOnOpen)3870*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOptimisticCreateFailsOnOpen) {
3871*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3872*6777b538SAndroid Build Coastguard Worker   InitCache();
3873*6777b538SAndroid Build Coastguard Worker 
3874*6777b538SAndroid Build Coastguard Worker   // Create a corrupt file in place of a future entry. Optimistic create should
3875*6777b538SAndroid Build Coastguard Worker   // initially succeed, but realize later that creation failed.
3876*6777b538SAndroid Build Coastguard Worker   const std::string key = "the key";
3877*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
3878*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = nullptr;
3879*6777b538SAndroid Build Coastguard Worker 
3880*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(disk_cache::simple_util::CreateCorruptFileForTests(
3881*6777b538SAndroid Build Coastguard Worker       key, cache_path_));
3882*6777b538SAndroid Build Coastguard Worker   EntryResult result =
3883*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback());
3884*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.net_error(), IsOk());
3885*6777b538SAndroid Build Coastguard Worker   entry = result.ReleaseEntry();
3886*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry);
3887*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
3888*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(net::OK, OpenEntry(key, &entry2));
3889*6777b538SAndroid Build Coastguard Worker 
3890*6777b538SAndroid Build Coastguard Worker   // Check that we are not leaking.
3891*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
3892*6777b538SAndroid Build Coastguard Worker       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
3893*6777b538SAndroid Build Coastguard Worker 
3894*6777b538SAndroid Build Coastguard Worker   DisableIntegrityCheck();
3895*6777b538SAndroid Build Coastguard Worker }
3896*6777b538SAndroid Build Coastguard Worker 
3897*6777b538SAndroid Build Coastguard Worker // Tests that old entries are evicted while new entries remain in the index.
3898*6777b538SAndroid Build Coastguard Worker // This test relies on non-mandatory properties of the simple Cache Backend:
3899*6777b538SAndroid Build Coastguard Worker // LRU eviction, specific values of high-watermark and low-watermark etc.
3900*6777b538SAndroid Build Coastguard Worker // When changing the eviction algorithm, the test will have to be re-engineered.
TEST_F(DiskCacheEntryTest,SimpleCacheEvictOldEntries)3901*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheEvictOldEntries) {
3902*6777b538SAndroid Build Coastguard Worker   const int kMaxSize = 200 * 1024;
3903*6777b538SAndroid Build Coastguard Worker   const int kWriteSize = kMaxSize / 10;
3904*6777b538SAndroid Build Coastguard Worker   const int kNumExtraEntries = 12;
3905*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3906*6777b538SAndroid Build Coastguard Worker   SetMaxSize(kMaxSize);
3907*6777b538SAndroid Build Coastguard Worker   InitCache();
3908*6777b538SAndroid Build Coastguard Worker 
3909*6777b538SAndroid Build Coastguard Worker   std::string key1("the first key");
3910*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
3911*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key1, &entry), IsOk());
3912*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kWriteSize);
3913*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kWriteSize, false);
3914*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kWriteSize,
3915*6777b538SAndroid Build Coastguard Worker             WriteData(entry, 1, 0, buffer.get(), kWriteSize, false));
3916*6777b538SAndroid Build Coastguard Worker   entry->Close();
3917*6777b538SAndroid Build Coastguard Worker   AddDelay();
3918*6777b538SAndroid Build Coastguard Worker 
3919*6777b538SAndroid Build Coastguard Worker   std::string key2("the key prefix");
3920*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kNumExtraEntries; i++) {
3921*6777b538SAndroid Build Coastguard Worker     if (i == kNumExtraEntries - 2) {
3922*6777b538SAndroid Build Coastguard Worker       // Create a distinct timestamp for the last two entries. These entries
3923*6777b538SAndroid Build Coastguard Worker       // will be checked for outliving the eviction.
3924*6777b538SAndroid Build Coastguard Worker       AddDelay();
3925*6777b538SAndroid Build Coastguard Worker     }
3926*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(CreateEntry(key2 + base::NumberToString(i), &entry), IsOk());
3927*6777b538SAndroid Build Coastguard Worker     ScopedEntryPtr entry_closer(entry);
3928*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kWriteSize,
3929*6777b538SAndroid Build Coastguard Worker               WriteData(entry, 1, 0, buffer.get(), kWriteSize, false));
3930*6777b538SAndroid Build Coastguard Worker   }
3931*6777b538SAndroid Build Coastguard Worker 
3932*6777b538SAndroid Build Coastguard Worker   // TODO(pasko): Find a way to wait for the eviction task(s) to finish by using
3933*6777b538SAndroid Build Coastguard Worker   // the internal knowledge about |SimpleBackendImpl|.
3934*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(net::OK, OpenEntry(key1, &entry))
3935*6777b538SAndroid Build Coastguard Worker       << "Should have evicted the old entry";
3936*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 2; i++) {
3937*6777b538SAndroid Build Coastguard Worker     int entry_no = kNumExtraEntries - i - 1;
3938*6777b538SAndroid Build Coastguard Worker     // Generally there is no guarantee that at this point the backround eviction
3939*6777b538SAndroid Build Coastguard Worker     // is finished. We are testing the positive case, i.e. when the eviction
3940*6777b538SAndroid Build Coastguard Worker     // never reaches this entry, should be non-flaky.
3941*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(net::OK, OpenEntry(key2 + base::NumberToString(entry_no), &entry))
3942*6777b538SAndroid Build Coastguard Worker         << "Should not have evicted fresh entry " << entry_no;
3943*6777b538SAndroid Build Coastguard Worker     entry->Close();
3944*6777b538SAndroid Build Coastguard Worker   }
3945*6777b538SAndroid Build Coastguard Worker }
3946*6777b538SAndroid Build Coastguard Worker 
3947*6777b538SAndroid Build Coastguard Worker // Tests that if a read and a following in-flight truncate are both in progress
3948*6777b538SAndroid Build Coastguard Worker // simultaniously that they both can occur successfully. See
3949*6777b538SAndroid Build Coastguard Worker // http://crbug.com/239223
TEST_F(DiskCacheEntryTest,SimpleCacheInFlightTruncate)3950*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheInFlightTruncate)  {
3951*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
3952*6777b538SAndroid Build Coastguard Worker   InitCache();
3953*6777b538SAndroid Build Coastguard Worker 
3954*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
3955*6777b538SAndroid Build Coastguard Worker 
3956*6777b538SAndroid Build Coastguard Worker   // We use a very large entry size here to make sure this doesn't hit
3957*6777b538SAndroid Build Coastguard Worker   // the prefetch path for any concievable setting. Hitting prefetch would
3958*6777b538SAndroid Build Coastguard Worker   // make us serve the read below from memory entirely on I/O thread, missing
3959*6777b538SAndroid Build Coastguard Worker   // the point of the test which coverred two concurrent disk ops, with
3960*6777b538SAndroid Build Coastguard Worker   // portions of work happening on the workpool.
3961*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 50000;
3962*6777b538SAndroid Build Coastguard Worker   auto write_buffer = base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
3963*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(write_buffer->data(), kBufferSize, false);
3964*6777b538SAndroid Build Coastguard Worker 
3965*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
3966*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
3967*6777b538SAndroid Build Coastguard Worker 
3968*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kBufferSize,
3969*6777b538SAndroid Build Coastguard Worker             WriteData(entry, 1, 0, write_buffer.get(), kBufferSize, false));
3970*6777b538SAndroid Build Coastguard Worker   entry->Close();
3971*6777b538SAndroid Build Coastguard Worker   entry = nullptr;
3972*6777b538SAndroid Build Coastguard Worker 
3973*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
3974*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
3975*6777b538SAndroid Build Coastguard Worker 
3976*6777b538SAndroid Build Coastguard Worker   MessageLoopHelper helper;
3977*6777b538SAndroid Build Coastguard Worker   int expected = 0;
3978*6777b538SAndroid Build Coastguard Worker 
3979*6777b538SAndroid Build Coastguard Worker   // Make a short read.
3980*6777b538SAndroid Build Coastguard Worker   const int kReadBufferSize = 512;
3981*6777b538SAndroid Build Coastguard Worker   auto read_buffer =
3982*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<net::IOBufferWithSize>(kReadBufferSize);
3983*6777b538SAndroid Build Coastguard Worker   CallbackTest read_callback(&helper, false);
3984*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING,
3985*6777b538SAndroid Build Coastguard Worker             entry->ReadData(1, 0, read_buffer.get(), kReadBufferSize,
3986*6777b538SAndroid Build Coastguard Worker                             base::BindOnce(&CallbackTest::Run,
3987*6777b538SAndroid Build Coastguard Worker                                            base::Unretained(&read_callback))));
3988*6777b538SAndroid Build Coastguard Worker   ++expected;
3989*6777b538SAndroid Build Coastguard Worker 
3990*6777b538SAndroid Build Coastguard Worker   // Truncate the entry to the length of that read.
3991*6777b538SAndroid Build Coastguard Worker   auto truncate_buffer =
3992*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<net::IOBufferWithSize>(kReadBufferSize);
3993*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(truncate_buffer->data(), kReadBufferSize, false);
3994*6777b538SAndroid Build Coastguard Worker   CallbackTest truncate_callback(&helper, false);
3995*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
3996*6777b538SAndroid Build Coastguard Worker       net::ERR_IO_PENDING,
3997*6777b538SAndroid Build Coastguard Worker       entry->WriteData(1, 0, truncate_buffer.get(), kReadBufferSize,
3998*6777b538SAndroid Build Coastguard Worker                        base::BindOnce(&CallbackTest::Run,
3999*6777b538SAndroid Build Coastguard Worker                                       base::Unretained(&truncate_callback)),
4000*6777b538SAndroid Build Coastguard Worker                        true));
4001*6777b538SAndroid Build Coastguard Worker   ++expected;
4002*6777b538SAndroid Build Coastguard Worker 
4003*6777b538SAndroid Build Coastguard Worker   // Wait for both the read and truncation to finish, and confirm that both
4004*6777b538SAndroid Build Coastguard Worker   // succeeded.
4005*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
4006*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kReadBufferSize, read_callback.last_result());
4007*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kReadBufferSize, truncate_callback.last_result());
4008*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0,
4009*6777b538SAndroid Build Coastguard Worker             memcmp(write_buffer->data(), read_buffer->data(), kReadBufferSize));
4010*6777b538SAndroid Build Coastguard Worker }
4011*6777b538SAndroid Build Coastguard Worker 
4012*6777b538SAndroid Build Coastguard Worker // Tests that if a write and a read dependant on it are both in flight
4013*6777b538SAndroid Build Coastguard Worker // simultaneiously that they both can complete successfully without erroneous
4014*6777b538SAndroid Build Coastguard Worker // early returns. See http://crbug.com/239223
TEST_F(DiskCacheEntryTest,SimpleCacheInFlightRead)4015*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheInFlightRead) {
4016*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4017*6777b538SAndroid Build Coastguard Worker   InitCache();
4018*6777b538SAndroid Build Coastguard Worker 
4019*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
4020*6777b538SAndroid Build Coastguard Worker   EntryResult result =
4021*6777b538SAndroid Build Coastguard Worker       cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback());
4022*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result.net_error());
4023*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = result.ReleaseEntry();
4024*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
4025*6777b538SAndroid Build Coastguard Worker 
4026*6777b538SAndroid Build Coastguard Worker   const int kBufferSize = 1024;
4027*6777b538SAndroid Build Coastguard Worker   auto write_buffer = base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
4028*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(write_buffer->data(), kBufferSize, false);
4029*6777b538SAndroid Build Coastguard Worker 
4030*6777b538SAndroid Build Coastguard Worker   MessageLoopHelper helper;
4031*6777b538SAndroid Build Coastguard Worker   int expected = 0;
4032*6777b538SAndroid Build Coastguard Worker 
4033*6777b538SAndroid Build Coastguard Worker   CallbackTest write_callback(&helper, false);
4034*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING,
4035*6777b538SAndroid Build Coastguard Worker             entry->WriteData(1, 0, write_buffer.get(), kBufferSize,
4036*6777b538SAndroid Build Coastguard Worker                              base::BindOnce(&CallbackTest::Run,
4037*6777b538SAndroid Build Coastguard Worker                                             base::Unretained(&write_callback)),
4038*6777b538SAndroid Build Coastguard Worker                              true));
4039*6777b538SAndroid Build Coastguard Worker   ++expected;
4040*6777b538SAndroid Build Coastguard Worker 
4041*6777b538SAndroid Build Coastguard Worker   auto read_buffer = base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
4042*6777b538SAndroid Build Coastguard Worker   CallbackTest read_callback(&helper, false);
4043*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING,
4044*6777b538SAndroid Build Coastguard Worker             entry->ReadData(1, 0, read_buffer.get(), kBufferSize,
4045*6777b538SAndroid Build Coastguard Worker                             base::BindOnce(&CallbackTest::Run,
4046*6777b538SAndroid Build Coastguard Worker                                            base::Unretained(&read_callback))));
4047*6777b538SAndroid Build Coastguard Worker   ++expected;
4048*6777b538SAndroid Build Coastguard Worker 
4049*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
4050*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kBufferSize, write_callback.last_result());
4051*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kBufferSize, read_callback.last_result());
4052*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(write_buffer->data(), read_buffer->data(), kBufferSize));
4053*6777b538SAndroid Build Coastguard Worker }
4054*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheOpenCreateRaceWithNoIndex)4055*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOpenCreateRaceWithNoIndex) {
4056*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4057*6777b538SAndroid Build Coastguard Worker   DisableSimpleCacheWaitForIndex();
4058*6777b538SAndroid Build Coastguard Worker   DisableIntegrityCheck();
4059*6777b538SAndroid Build Coastguard Worker   InitCache();
4060*6777b538SAndroid Build Coastguard Worker 
4061*6777b538SAndroid Build Coastguard Worker   // Assume the index is not initialized, which is likely, since we are blocking
4062*6777b538SAndroid Build Coastguard Worker   // the IO thread from executing the index finalization step.
4063*6777b538SAndroid Build Coastguard Worker   TestEntryResultCompletionCallback cb1;
4064*6777b538SAndroid Build Coastguard Worker   TestEntryResultCompletionCallback cb2;
4065*6777b538SAndroid Build Coastguard Worker   EntryResult rv1 = cache_->OpenEntry("key", net::HIGHEST, cb1.callback());
4066*6777b538SAndroid Build Coastguard Worker   EntryResult rv2 = cache_->CreateEntry("key", net::HIGHEST, cb2.callback());
4067*6777b538SAndroid Build Coastguard Worker 
4068*6777b538SAndroid Build Coastguard Worker   rv1 = cb1.GetResult(std::move(rv1));
4069*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv1.net_error(), IsError(net::ERR_FAILED));
4070*6777b538SAndroid Build Coastguard Worker   rv2 = cb2.GetResult(std::move(rv2));
4071*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv2.net_error(), IsOk());
4072*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = rv2.ReleaseEntry();
4073*6777b538SAndroid Build Coastguard Worker 
4074*6777b538SAndroid Build Coastguard Worker   // Try to get an alias for entry2. Open should succeed, and return the same
4075*6777b538SAndroid Build Coastguard Worker   // pointer.
4076*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry3 = nullptr;
4077*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, OpenEntry("key", &entry3));
4078*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(entry3, entry2);
4079*6777b538SAndroid Build Coastguard Worker 
4080*6777b538SAndroid Build Coastguard Worker   entry2->Close();
4081*6777b538SAndroid Build Coastguard Worker   entry3->Close();
4082*6777b538SAndroid Build Coastguard Worker }
4083*6777b538SAndroid Build Coastguard Worker 
4084*6777b538SAndroid Build Coastguard Worker // Checking one more scenario of overlapped reading of a bad entry.
4085*6777b538SAndroid Build Coastguard Worker // Differs from the |SimpleCacheMultipleReadersCheckCRC| only by the order of
4086*6777b538SAndroid Build Coastguard Worker // last two reads.
TEST_F(DiskCacheEntryTest,SimpleCacheMultipleReadersCheckCRC2)4087*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheMultipleReadersCheckCRC2) {
4088*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4089*6777b538SAndroid Build Coastguard Worker   InitCache();
4090*6777b538SAndroid Build Coastguard Worker 
4091*6777b538SAndroid Build Coastguard Worker   const char key[] = "key";
4092*6777b538SAndroid Build Coastguard Worker   int size = 50000;
4093*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, size));
4094*6777b538SAndroid Build Coastguard Worker 
4095*6777b538SAndroid Build Coastguard Worker   auto read_buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(size);
4096*6777b538SAndroid Build Coastguard Worker   auto read_buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(size);
4097*6777b538SAndroid Build Coastguard Worker 
4098*6777b538SAndroid Build Coastguard Worker   // Advance the first reader a little.
4099*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
4100*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4101*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
4102*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, ReadData(entry, 1, 0, read_buffer1.get(), 1));
4103*6777b538SAndroid Build Coastguard Worker 
4104*6777b538SAndroid Build Coastguard Worker   // Advance the 2nd reader by the same amount.
4105*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = nullptr;
4106*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(OpenEntry(key, &entry2), IsOk());
4107*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry2_closer(entry2);
4108*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, ReadData(entry2, 1, 0, read_buffer2.get(), 1));
4109*6777b538SAndroid Build Coastguard Worker 
4110*6777b538SAndroid Build Coastguard Worker   // Continue reading 1st.
4111*6777b538SAndroid Build Coastguard Worker   EXPECT_GT(0, ReadData(entry, 1, 1, read_buffer1.get(), size));
4112*6777b538SAndroid Build Coastguard Worker 
4113*6777b538SAndroid Build Coastguard Worker   // This read should fail as well because we have previous read failures.
4114*6777b538SAndroid Build Coastguard Worker   EXPECT_GT(0, ReadData(entry2, 1, 1, read_buffer2.get(), 1));
4115*6777b538SAndroid Build Coastguard Worker   DisableIntegrityCheck();
4116*6777b538SAndroid Build Coastguard Worker }
4117*6777b538SAndroid Build Coastguard Worker 
4118*6777b538SAndroid Build Coastguard Worker // Test if we can sequentially read each subset of the data until all the data
4119*6777b538SAndroid Build Coastguard Worker // is read, then the CRC is calculated correctly and the reads are successful.
TEST_F(DiskCacheEntryTest,SimpleCacheReadCombineCRC)4120*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheReadCombineCRC) {
4121*6777b538SAndroid Build Coastguard Worker   // Test sequence:
4122*6777b538SAndroid Build Coastguard Worker   // Create, Write, Read (first half of data), Read (second half of data),
4123*6777b538SAndroid Build Coastguard Worker   // Close.
4124*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4125*6777b538SAndroid Build Coastguard Worker   InitCache();
4126*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* null = nullptr;
4127*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
4128*6777b538SAndroid Build Coastguard Worker 
4129*6777b538SAndroid Build Coastguard Worker   const int kHalfSize = 200;
4130*6777b538SAndroid Build Coastguard Worker   const int kSize = 2 * kHalfSize;
4131*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4132*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize, false);
4133*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
4134*6777b538SAndroid Build Coastguard Worker 
4135*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4136*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry);
4137*6777b538SAndroid Build Coastguard Worker 
4138*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer1.get(), kSize, false));
4139*6777b538SAndroid Build Coastguard Worker   entry->Close();
4140*6777b538SAndroid Build Coastguard Worker 
4141*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = nullptr;
4142*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry2), IsOk());
4143*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(entry, entry2);
4144*6777b538SAndroid Build Coastguard Worker 
4145*6777b538SAndroid Build Coastguard Worker   // Read the first half of the data.
4146*6777b538SAndroid Build Coastguard Worker   int offset = 0;
4147*6777b538SAndroid Build Coastguard Worker   int buf_len = kHalfSize;
4148*6777b538SAndroid Build Coastguard Worker   auto buffer1_read1 = base::MakeRefCounted<net::IOBufferWithSize>(buf_len);
4149*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(buf_len, ReadData(entry2, 1, offset, buffer1_read1.get(), buf_len));
4150*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), buf_len));
4151*6777b538SAndroid Build Coastguard Worker 
4152*6777b538SAndroid Build Coastguard Worker   // Read the second half of the data.
4153*6777b538SAndroid Build Coastguard Worker   offset = buf_len;
4154*6777b538SAndroid Build Coastguard Worker   buf_len = kHalfSize;
4155*6777b538SAndroid Build Coastguard Worker   auto buffer1_read2 = base::MakeRefCounted<net::IOBufferWithSize>(buf_len);
4156*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(buf_len, ReadData(entry2, 1, offset, buffer1_read2.get(), buf_len));
4157*6777b538SAndroid Build Coastguard Worker   char* buffer1_data = buffer1->data() + offset;
4158*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer1_data, buffer1_read2->data(), buf_len));
4159*6777b538SAndroid Build Coastguard Worker 
4160*6777b538SAndroid Build Coastguard Worker   // Check that we are not leaking.
4161*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(entry, null);
4162*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4163*6777b538SAndroid Build Coastguard Worker       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
4164*6777b538SAndroid Build Coastguard Worker   entry->Close();
4165*6777b538SAndroid Build Coastguard Worker   entry = nullptr;
4166*6777b538SAndroid Build Coastguard Worker }
4167*6777b538SAndroid Build Coastguard Worker 
4168*6777b538SAndroid Build Coastguard Worker // Test if we can write the data not in sequence and read correctly. In
4169*6777b538SAndroid Build Coastguard Worker // this case the CRC will not be present.
TEST_F(DiskCacheEntryTest,SimpleCacheNonSequentialWrite)4170*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheNonSequentialWrite) {
4171*6777b538SAndroid Build Coastguard Worker   // Test sequence:
4172*6777b538SAndroid Build Coastguard Worker   // Create, Write (second half of data), Write (first half of data), Read,
4173*6777b538SAndroid Build Coastguard Worker   // Close.
4174*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4175*6777b538SAndroid Build Coastguard Worker   InitCache();
4176*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* null = nullptr;
4177*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
4178*6777b538SAndroid Build Coastguard Worker 
4179*6777b538SAndroid Build Coastguard Worker   const int kHalfSize = 200;
4180*6777b538SAndroid Build Coastguard Worker   const int kSize = 2 * kHalfSize;
4181*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4182*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4183*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize, false);
4184*6777b538SAndroid Build Coastguard Worker   char* buffer1_data = buffer1->data() + kHalfSize;
4185*6777b538SAndroid Build Coastguard Worker   memcpy(buffer2->data(), buffer1_data, kHalfSize);
4186*6777b538SAndroid Build Coastguard Worker 
4187*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
4188*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4189*6777b538SAndroid Build Coastguard Worker   entry->Close();
4190*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
4191*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4192*6777b538SAndroid Build Coastguard Worker     EXPECT_NE(null, entry);
4193*6777b538SAndroid Build Coastguard Worker 
4194*6777b538SAndroid Build Coastguard Worker     int offset = kHalfSize;
4195*6777b538SAndroid Build Coastguard Worker     int buf_len = kHalfSize;
4196*6777b538SAndroid Build Coastguard Worker 
4197*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(buf_len,
4198*6777b538SAndroid Build Coastguard Worker               WriteData(entry, i, offset, buffer2.get(), buf_len, false));
4199*6777b538SAndroid Build Coastguard Worker     offset = 0;
4200*6777b538SAndroid Build Coastguard Worker     buf_len = kHalfSize;
4201*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(buf_len,
4202*6777b538SAndroid Build Coastguard Worker               WriteData(entry, i, offset, buffer1.get(), buf_len, false));
4203*6777b538SAndroid Build Coastguard Worker     entry->Close();
4204*6777b538SAndroid Build Coastguard Worker 
4205*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4206*6777b538SAndroid Build Coastguard Worker 
4207*6777b538SAndroid Build Coastguard Worker     auto buffer1_read1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4208*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kSize, ReadData(entry, i, 0, buffer1_read1.get(), kSize));
4209*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), kSize));
4210*6777b538SAndroid Build Coastguard Worker     // Check that we are not leaking.
4211*6777b538SAndroid Build Coastguard Worker     ASSERT_NE(entry, null);
4212*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
4213*6777b538SAndroid Build Coastguard Worker     entry->Close();
4214*6777b538SAndroid Build Coastguard Worker   }
4215*6777b538SAndroid Build Coastguard Worker }
4216*6777b538SAndroid Build Coastguard Worker 
4217*6777b538SAndroid Build Coastguard Worker // Test that changing stream1 size does not affect stream0 (stream0 and stream1
4218*6777b538SAndroid Build Coastguard Worker // are stored in the same file in Simple Cache).
TEST_F(DiskCacheEntryTest,SimpleCacheStream1SizeChanges)4219*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheStream1SizeChanges) {
4220*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4221*6777b538SAndroid Build Coastguard Worker   InitCache();
4222*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
4223*6777b538SAndroid Build Coastguard Worker   const std::string key("the key");
4224*6777b538SAndroid Build Coastguard Worker   const int kSize = 100;
4225*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4226*6777b538SAndroid Build Coastguard Worker   auto buffer_read = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4227*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
4228*6777b538SAndroid Build Coastguard Worker 
4229*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4230*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(entry);
4231*6777b538SAndroid Build Coastguard Worker 
4232*6777b538SAndroid Build Coastguard Worker   // Write something into stream0.
4233*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
4234*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize));
4235*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize));
4236*6777b538SAndroid Build Coastguard Worker   entry->Close();
4237*6777b538SAndroid Build Coastguard Worker 
4238*6777b538SAndroid Build Coastguard Worker   // Extend stream1.
4239*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4240*6777b538SAndroid Build Coastguard Worker   int stream1_size = 100;
4241*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, 1, stream1_size, buffer.get(), 0, false));
4242*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(stream1_size, entry->GetDataSize(1));
4243*6777b538SAndroid Build Coastguard Worker   entry->Close();
4244*6777b538SAndroid Build Coastguard Worker 
4245*6777b538SAndroid Build Coastguard Worker   // Check that stream0 data has not been modified and that the EOF record for
4246*6777b538SAndroid Build Coastguard Worker   // stream 0 contains a crc.
4247*6777b538SAndroid Build Coastguard Worker   // The entry needs to be reopened before checking the crc: Open will perform
4248*6777b538SAndroid Build Coastguard Worker   // the synchronization with the previous Close. This ensures the EOF records
4249*6777b538SAndroid Build Coastguard Worker   // have been written to disk before we attempt to read them independently.
4250*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4251*6777b538SAndroid Build Coastguard Worker   base::FilePath entry_file0_path = cache_path_.AppendASCII(
4252*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
4253*6777b538SAndroid Build Coastguard Worker   base::File entry_file0(entry_file0_path,
4254*6777b538SAndroid Build Coastguard Worker                          base::File::FLAG_READ | base::File::FLAG_OPEN);
4255*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry_file0.IsValid());
4256*6777b538SAndroid Build Coastguard Worker 
4257*6777b538SAndroid Build Coastguard Worker   int data_size[disk_cache::kSimpleEntryStreamCount] = {kSize, stream1_size, 0};
4258*6777b538SAndroid Build Coastguard Worker   int sparse_data_size = 0;
4259*6777b538SAndroid Build Coastguard Worker   disk_cache::SimpleEntryStat entry_stat(
4260*6777b538SAndroid Build Coastguard Worker       base::Time::Now(), base::Time::Now(), data_size, sparse_data_size);
4261*6777b538SAndroid Build Coastguard Worker   int eof_offset = entry_stat.GetEOFOffsetInFile(key.size(), 0);
4262*6777b538SAndroid Build Coastguard Worker   disk_cache::SimpleFileEOF eof_record;
4263*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(static_cast<int>(sizeof(eof_record)),
4264*6777b538SAndroid Build Coastguard Worker             entry_file0.Read(eof_offset, reinterpret_cast<char*>(&eof_record),
4265*6777b538SAndroid Build Coastguard Worker                              sizeof(eof_record)));
4266*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(disk_cache::kSimpleFinalMagicNumber, eof_record.final_magic_number);
4267*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE((eof_record.flags & disk_cache::SimpleFileEOF::FLAG_HAS_CRC32) ==
4268*6777b538SAndroid Build Coastguard Worker               disk_cache::SimpleFileEOF::FLAG_HAS_CRC32);
4269*6777b538SAndroid Build Coastguard Worker 
4270*6777b538SAndroid Build Coastguard Worker   buffer_read = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4271*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize));
4272*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize));
4273*6777b538SAndroid Build Coastguard Worker 
4274*6777b538SAndroid Build Coastguard Worker   // Shrink stream1.
4275*6777b538SAndroid Build Coastguard Worker   stream1_size = 50;
4276*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, 1, stream1_size, buffer.get(), 0, true));
4277*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(stream1_size, entry->GetDataSize(1));
4278*6777b538SAndroid Build Coastguard Worker   entry->Close();
4279*6777b538SAndroid Build Coastguard Worker 
4280*6777b538SAndroid Build Coastguard Worker   // Check that stream0 data has not been modified.
4281*6777b538SAndroid Build Coastguard Worker   buffer_read = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4282*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4283*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize));
4284*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize));
4285*6777b538SAndroid Build Coastguard Worker   entry->Close();
4286*6777b538SAndroid Build Coastguard Worker   entry = nullptr;
4287*6777b538SAndroid Build Coastguard Worker }
4288*6777b538SAndroid Build Coastguard Worker 
4289*6777b538SAndroid Build Coastguard Worker // Test that writing within the range for which the crc has already been
4290*6777b538SAndroid Build Coastguard Worker // computed will properly invalidate the computed crc.
TEST_F(DiskCacheEntryTest,SimpleCacheCRCRewrite)4291*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheCRCRewrite) {
4292*6777b538SAndroid Build Coastguard Worker   // Test sequence:
4293*6777b538SAndroid Build Coastguard Worker   // Create, Write (big data), Write (small data in the middle), Close.
4294*6777b538SAndroid Build Coastguard Worker   // Open, Read (all), Close.
4295*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4296*6777b538SAndroid Build Coastguard Worker   InitCache();
4297*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* null = nullptr;
4298*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
4299*6777b538SAndroid Build Coastguard Worker 
4300*6777b538SAndroid Build Coastguard Worker   const int kHalfSize = 200;
4301*6777b538SAndroid Build Coastguard Worker   const int kSize = 2 * kHalfSize;
4302*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4303*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kHalfSize);
4304*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize, false);
4305*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kHalfSize, false);
4306*6777b538SAndroid Build Coastguard Worker 
4307*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
4308*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4309*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry);
4310*6777b538SAndroid Build Coastguard Worker   entry->Close();
4311*6777b538SAndroid Build Coastguard Worker 
4312*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
4313*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4314*6777b538SAndroid Build Coastguard Worker     int offset = 0;
4315*6777b538SAndroid Build Coastguard Worker     int buf_len = kSize;
4316*6777b538SAndroid Build Coastguard Worker 
4317*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(buf_len,
4318*6777b538SAndroid Build Coastguard Worker               WriteData(entry, i, offset, buffer1.get(), buf_len, false));
4319*6777b538SAndroid Build Coastguard Worker     offset = kHalfSize;
4320*6777b538SAndroid Build Coastguard Worker     buf_len = kHalfSize;
4321*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(buf_len,
4322*6777b538SAndroid Build Coastguard Worker               WriteData(entry, i, offset, buffer2.get(), buf_len, false));
4323*6777b538SAndroid Build Coastguard Worker     entry->Close();
4324*6777b538SAndroid Build Coastguard Worker 
4325*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4326*6777b538SAndroid Build Coastguard Worker 
4327*6777b538SAndroid Build Coastguard Worker     auto buffer1_read1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4328*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kSize, ReadData(entry, i, 0, buffer1_read1.get(), kSize));
4329*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), kHalfSize));
4330*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(
4331*6777b538SAndroid Build Coastguard Worker         0,
4332*6777b538SAndroid Build Coastguard Worker         memcmp(buffer2->data(), buffer1_read1->data() + kHalfSize, kHalfSize));
4333*6777b538SAndroid Build Coastguard Worker 
4334*6777b538SAndroid Build Coastguard Worker     entry->Close();
4335*6777b538SAndroid Build Coastguard Worker   }
4336*6777b538SAndroid Build Coastguard Worker }
4337*6777b538SAndroid Build Coastguard Worker 
SimpleCacheThirdStreamFileExists(const char * key)4338*6777b538SAndroid Build Coastguard Worker bool DiskCacheEntryTest::SimpleCacheThirdStreamFileExists(const char* key) {
4339*6777b538SAndroid Build Coastguard Worker   int third_stream_file_index =
4340*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFileIndexFromStreamIndex(2);
4341*6777b538SAndroid Build Coastguard Worker   base::FilePath third_stream_file_path = cache_path_.AppendASCII(
4342*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(
4343*6777b538SAndroid Build Coastguard Worker           key, third_stream_file_index));
4344*6777b538SAndroid Build Coastguard Worker   return PathExists(third_stream_file_path);
4345*6777b538SAndroid Build Coastguard Worker }
4346*6777b538SAndroid Build Coastguard Worker 
SyncDoomEntry(const char * key)4347*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::SyncDoomEntry(const char* key) {
4348*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback callback;
4349*6777b538SAndroid Build Coastguard Worker   cache_->DoomEntry(key, net::HIGHEST, callback.callback());
4350*6777b538SAndroid Build Coastguard Worker   callback.WaitForResult();
4351*6777b538SAndroid Build Coastguard Worker }
4352*6777b538SAndroid Build Coastguard Worker 
CreateEntryWithHeaderBodyAndSideData(const std::string & key,int data_size)4353*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::CreateEntryWithHeaderBodyAndSideData(
4354*6777b538SAndroid Build Coastguard Worker     const std::string& key,
4355*6777b538SAndroid Build Coastguard Worker     int data_size) {
4356*6777b538SAndroid Build Coastguard Worker   // Use one buffer for simplicity.
4357*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(data_size);
4358*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), data_size, false);
4359*6777b538SAndroid Build Coastguard Worker 
4360*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
4361*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4362*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
4363*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(data_size, WriteData(entry, i, /* offset */ 0, buffer.get(),
4364*6777b538SAndroid Build Coastguard Worker                                    data_size, false));
4365*6777b538SAndroid Build Coastguard Worker   }
4366*6777b538SAndroid Build Coastguard Worker   entry->Close();
4367*6777b538SAndroid Build Coastguard Worker }
4368*6777b538SAndroid Build Coastguard Worker 
TruncateFileFromEnd(int file_index,const std::string & key,int data_size,int truncate_size)4369*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::TruncateFileFromEnd(int file_index,
4370*6777b538SAndroid Build Coastguard Worker                                              const std::string& key,
4371*6777b538SAndroid Build Coastguard Worker                                              int data_size,
4372*6777b538SAndroid Build Coastguard Worker                                              int truncate_size) {
4373*6777b538SAndroid Build Coastguard Worker   // Remove last eof bytes from cache file.
4374*6777b538SAndroid Build Coastguard Worker   ASSERT_GT(data_size, truncate_size);
4375*6777b538SAndroid Build Coastguard Worker   const int64_t new_size =
4376*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFileSizeFromDataSize(key.size(), data_size) -
4377*6777b538SAndroid Build Coastguard Worker       truncate_size;
4378*6777b538SAndroid Build Coastguard Worker   const base::FilePath entry_path = cache_path_.AppendASCII(
4379*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, file_index));
4380*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(TruncatePath(entry_path, new_size));
4381*6777b538SAndroid Build Coastguard Worker }
4382*6777b538SAndroid Build Coastguard Worker 
UseAfterBackendDestruction()4383*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::UseAfterBackendDestruction() {
4384*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
4385*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("the first key", &entry), IsOk());
4386*6777b538SAndroid Build Coastguard Worker   ResetCaches();
4387*6777b538SAndroid Build Coastguard Worker 
4388*6777b538SAndroid Build Coastguard Worker   const int kSize = 100;
4389*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4390*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
4391*6777b538SAndroid Build Coastguard Worker 
4392*6777b538SAndroid Build Coastguard Worker   // Do some writes and reads, but don't change the result. We're OK
4393*6777b538SAndroid Build Coastguard Worker   // with them failing, just not them crashing.
4394*6777b538SAndroid Build Coastguard Worker   WriteData(entry, 1, 0, buffer.get(), kSize, false);
4395*6777b538SAndroid Build Coastguard Worker   ReadData(entry, 1, 0, buffer.get(), kSize);
4396*6777b538SAndroid Build Coastguard Worker   WriteSparseData(entry, 20000, buffer.get(), kSize);
4397*6777b538SAndroid Build Coastguard Worker 
4398*6777b538SAndroid Build Coastguard Worker   entry->Close();
4399*6777b538SAndroid Build Coastguard Worker }
4400*6777b538SAndroid Build Coastguard Worker 
CloseSparseAfterBackendDestruction()4401*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::CloseSparseAfterBackendDestruction() {
4402*6777b538SAndroid Build Coastguard Worker   const int kSize = 100;
4403*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4404*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
4405*6777b538SAndroid Build Coastguard Worker 
4406*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
4407*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("the first key", &entry), IsOk());
4408*6777b538SAndroid Build Coastguard Worker   WriteSparseData(entry, 20000, buffer.get(), kSize);
4409*6777b538SAndroid Build Coastguard Worker 
4410*6777b538SAndroid Build Coastguard Worker   ResetCaches();
4411*6777b538SAndroid Build Coastguard Worker 
4412*6777b538SAndroid Build Coastguard Worker   // This call shouldn't DCHECK or crash.
4413*6777b538SAndroid Build Coastguard Worker   entry->Close();
4414*6777b538SAndroid Build Coastguard Worker }
4415*6777b538SAndroid Build Coastguard Worker 
4416*6777b538SAndroid Build Coastguard Worker // Check that a newly-created entry with no third-stream writes omits the
4417*6777b538SAndroid Build Coastguard Worker // third stream file.
TEST_F(DiskCacheEntryTest,SimpleCacheOmittedThirdStream1)4418*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream1) {
4419*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4420*6777b538SAndroid Build Coastguard Worker   InitCache();
4421*6777b538SAndroid Build Coastguard Worker 
4422*6777b538SAndroid Build Coastguard Worker   const char key[] = "key";
4423*6777b538SAndroid Build Coastguard Worker 
4424*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
4425*6777b538SAndroid Build Coastguard Worker 
4426*6777b538SAndroid Build Coastguard Worker   // Create entry and close without writing: third stream file should be
4427*6777b538SAndroid Build Coastguard Worker   // omitted, since the stream is empty.
4428*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4429*6777b538SAndroid Build Coastguard Worker   entry->Close();
4430*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
4431*6777b538SAndroid Build Coastguard Worker 
4432*6777b538SAndroid Build Coastguard Worker   SyncDoomEntry(key);
4433*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
4434*6777b538SAndroid Build Coastguard Worker }
4435*6777b538SAndroid Build Coastguard Worker 
4436*6777b538SAndroid Build Coastguard Worker // Check that a newly-created entry with only a single zero-offset, zero-length
4437*6777b538SAndroid Build Coastguard Worker // write omits the third stream file.
TEST_F(DiskCacheEntryTest,SimpleCacheOmittedThirdStream2)4438*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream2) {
4439*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4440*6777b538SAndroid Build Coastguard Worker   InitCache();
4441*6777b538SAndroid Build Coastguard Worker 
4442*6777b538SAndroid Build Coastguard Worker   const int kHalfSize = 8;
4443*6777b538SAndroid Build Coastguard Worker   const int kSize = kHalfSize * 2;
4444*6777b538SAndroid Build Coastguard Worker   const char key[] = "key";
4445*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4446*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kHalfSize, false);
4447*6777b538SAndroid Build Coastguard Worker 
4448*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
4449*6777b538SAndroid Build Coastguard Worker 
4450*6777b538SAndroid Build Coastguard Worker   // Create entry, write empty buffer to third stream, and close: third stream
4451*6777b538SAndroid Build Coastguard Worker   // should still be omitted, since the entry ignores writes that don't modify
4452*6777b538SAndroid Build Coastguard Worker   // data or change the length.
4453*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4454*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, 2, 0, buffer.get(), 0, true));
4455*6777b538SAndroid Build Coastguard Worker   entry->Close();
4456*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
4457*6777b538SAndroid Build Coastguard Worker 
4458*6777b538SAndroid Build Coastguard Worker   SyncDoomEntry(key);
4459*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
4460*6777b538SAndroid Build Coastguard Worker }
4461*6777b538SAndroid Build Coastguard Worker 
4462*6777b538SAndroid Build Coastguard Worker // Check that we can read back data written to the third stream.
TEST_F(DiskCacheEntryTest,SimpleCacheOmittedThirdStream3)4463*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream3) {
4464*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4465*6777b538SAndroid Build Coastguard Worker   InitCache();
4466*6777b538SAndroid Build Coastguard Worker 
4467*6777b538SAndroid Build Coastguard Worker   const int kHalfSize = 8;
4468*6777b538SAndroid Build Coastguard Worker   const int kSize = kHalfSize * 2;
4469*6777b538SAndroid Build Coastguard Worker   const char key[] = "key";
4470*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4471*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4472*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kHalfSize, false);
4473*6777b538SAndroid Build Coastguard Worker 
4474*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
4475*6777b538SAndroid Build Coastguard Worker 
4476*6777b538SAndroid Build Coastguard Worker   // Create entry, write data to third stream, and close: third stream should
4477*6777b538SAndroid Build Coastguard Worker   // not be omitted, since it contains data.  Re-open entry and ensure there
4478*6777b538SAndroid Build Coastguard Worker   // are that many bytes in the third stream.
4479*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4480*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1.get(), kHalfSize, true));
4481*6777b538SAndroid Build Coastguard Worker   entry->Close();
4482*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
4483*6777b538SAndroid Build Coastguard Worker 
4484*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4485*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kHalfSize, ReadData(entry, 2, 0, buffer2.get(), kSize));
4486*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kHalfSize));
4487*6777b538SAndroid Build Coastguard Worker   entry->Close();
4488*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
4489*6777b538SAndroid Build Coastguard Worker 
4490*6777b538SAndroid Build Coastguard Worker   SyncDoomEntry(key);
4491*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
4492*6777b538SAndroid Build Coastguard Worker }
4493*6777b538SAndroid Build Coastguard Worker 
4494*6777b538SAndroid Build Coastguard Worker // Check that we remove the third stream file upon opening an entry and finding
4495*6777b538SAndroid Build Coastguard Worker // the third stream empty.  (This is the upgrade path for entries written
4496*6777b538SAndroid Build Coastguard Worker // before the third stream was optional.)
TEST_F(DiskCacheEntryTest,SimpleCacheOmittedThirdStream4)4497*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream4) {
4498*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4499*6777b538SAndroid Build Coastguard Worker   InitCache();
4500*6777b538SAndroid Build Coastguard Worker 
4501*6777b538SAndroid Build Coastguard Worker   const int kHalfSize = 8;
4502*6777b538SAndroid Build Coastguard Worker   const int kSize = kHalfSize * 2;
4503*6777b538SAndroid Build Coastguard Worker   const char key[] = "key";
4504*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4505*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4506*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kHalfSize, false);
4507*6777b538SAndroid Build Coastguard Worker 
4508*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
4509*6777b538SAndroid Build Coastguard Worker 
4510*6777b538SAndroid Build Coastguard Worker   // Create entry, write data to third stream, truncate third stream back to
4511*6777b538SAndroid Build Coastguard Worker   // empty, and close: third stream will not initially be omitted, since entry
4512*6777b538SAndroid Build Coastguard Worker   // creates the file when the first significant write comes in, and only
4513*6777b538SAndroid Build Coastguard Worker   // removes it on open if it is empty.  Reopen, ensure that the file is
4514*6777b538SAndroid Build Coastguard Worker   // deleted, and that there's no data in the third stream.
4515*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4516*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1.get(), kHalfSize, true));
4517*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, 2, 0, buffer1.get(), 0, true));
4518*6777b538SAndroid Build Coastguard Worker   entry->Close();
4519*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
4520*6777b538SAndroid Build Coastguard Worker 
4521*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4522*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
4523*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, ReadData(entry, 2, 0, buffer2.get(), kSize));
4524*6777b538SAndroid Build Coastguard Worker   entry->Close();
4525*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
4526*6777b538SAndroid Build Coastguard Worker 
4527*6777b538SAndroid Build Coastguard Worker   SyncDoomEntry(key);
4528*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
4529*6777b538SAndroid Build Coastguard Worker }
4530*6777b538SAndroid Build Coastguard Worker 
4531*6777b538SAndroid Build Coastguard Worker // Check that we don't accidentally create the third stream file once the entry
4532*6777b538SAndroid Build Coastguard Worker // has been doomed.
TEST_F(DiskCacheEntryTest,SimpleCacheOmittedThirdStream5)4533*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream5) {
4534*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4535*6777b538SAndroid Build Coastguard Worker   InitCache();
4536*6777b538SAndroid Build Coastguard Worker 
4537*6777b538SAndroid Build Coastguard Worker   const int kHalfSize = 8;
4538*6777b538SAndroid Build Coastguard Worker   const int kSize = kHalfSize * 2;
4539*6777b538SAndroid Build Coastguard Worker   const char key[] = "key";
4540*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4541*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kHalfSize, false);
4542*6777b538SAndroid Build Coastguard Worker 
4543*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
4544*6777b538SAndroid Build Coastguard Worker 
4545*6777b538SAndroid Build Coastguard Worker   // Create entry, doom entry, write data to third stream, and close: third
4546*6777b538SAndroid Build Coastguard Worker   // stream should not exist.  (Note: We don't care if the write fails, just
4547*6777b538SAndroid Build Coastguard Worker   // that it doesn't cause the file to be created on disk.)
4548*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4549*6777b538SAndroid Build Coastguard Worker   entry->Doom();
4550*6777b538SAndroid Build Coastguard Worker   WriteData(entry, 2, 0, buffer.get(), kHalfSize, true);
4551*6777b538SAndroid Build Coastguard Worker   entry->Close();
4552*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
4553*6777b538SAndroid Build Coastguard Worker }
4554*6777b538SAndroid Build Coastguard Worker 
4555*6777b538SAndroid Build Coastguard Worker // There could be a race between Doom and an optimistic write.
TEST_F(DiskCacheEntryTest,SimpleCacheDoomOptimisticWritesRace)4556*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomOptimisticWritesRace) {
4557*6777b538SAndroid Build Coastguard Worker   // Test sequence:
4558*6777b538SAndroid Build Coastguard Worker   // Create, first Write, second Write, Close.
4559*6777b538SAndroid Build Coastguard Worker   // Open, Close.
4560*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4561*6777b538SAndroid Build Coastguard Worker   InitCache();
4562*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* null = nullptr;
4563*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
4564*6777b538SAndroid Build Coastguard Worker 
4565*6777b538SAndroid Build Coastguard Worker   const int kSize = 200;
4566*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4567*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4568*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize, false);
4569*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, false);
4570*6777b538SAndroid Build Coastguard Worker 
4571*6777b538SAndroid Build Coastguard Worker   // The race only happens on stream 1 and stream 2.
4572*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
4573*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(DoomAllEntries(), IsOk());
4574*6777b538SAndroid Build Coastguard Worker     disk_cache::Entry* entry = nullptr;
4575*6777b538SAndroid Build Coastguard Worker 
4576*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4577*6777b538SAndroid Build Coastguard Worker     EXPECT_NE(null, entry);
4578*6777b538SAndroid Build Coastguard Worker     entry->Close();
4579*6777b538SAndroid Build Coastguard Worker     entry = nullptr;
4580*6777b538SAndroid Build Coastguard Worker 
4581*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(DoomAllEntries(), IsOk());
4582*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4583*6777b538SAndroid Build Coastguard Worker     EXPECT_NE(null, entry);
4584*6777b538SAndroid Build Coastguard Worker 
4585*6777b538SAndroid Build Coastguard Worker     int offset = 0;
4586*6777b538SAndroid Build Coastguard Worker     int buf_len = kSize;
4587*6777b538SAndroid Build Coastguard Worker     // This write should not be optimistic (since create is).
4588*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(buf_len,
4589*6777b538SAndroid Build Coastguard Worker               WriteData(entry, i, offset, buffer1.get(), buf_len, false));
4590*6777b538SAndroid Build Coastguard Worker 
4591*6777b538SAndroid Build Coastguard Worker     offset = kSize;
4592*6777b538SAndroid Build Coastguard Worker     // This write should be optimistic.
4593*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(buf_len,
4594*6777b538SAndroid Build Coastguard Worker               WriteData(entry, i, offset, buffer2.get(), buf_len, false));
4595*6777b538SAndroid Build Coastguard Worker     entry->Close();
4596*6777b538SAndroid Build Coastguard Worker 
4597*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4598*6777b538SAndroid Build Coastguard Worker     EXPECT_NE(null, entry);
4599*6777b538SAndroid Build Coastguard Worker 
4600*6777b538SAndroid Build Coastguard Worker     entry->Close();
4601*6777b538SAndroid Build Coastguard Worker     entry = nullptr;
4602*6777b538SAndroid Build Coastguard Worker   }
4603*6777b538SAndroid Build Coastguard Worker }
4604*6777b538SAndroid Build Coastguard Worker 
4605*6777b538SAndroid Build Coastguard Worker // Tests for a regression in crbug.com/317138 , in which deleting an already
4606*6777b538SAndroid Build Coastguard Worker // doomed entry was removing the active entry from the index.
TEST_F(DiskCacheEntryTest,SimpleCachePreserveActiveEntries)4607*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCachePreserveActiveEntries) {
4608*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4609*6777b538SAndroid Build Coastguard Worker   InitCache();
4610*6777b538SAndroid Build Coastguard Worker 
4611*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* null = nullptr;
4612*6777b538SAndroid Build Coastguard Worker 
4613*6777b538SAndroid Build Coastguard Worker   const char key[] = "this is a key";
4614*6777b538SAndroid Build Coastguard Worker 
4615*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1 = nullptr;
4616*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry1), IsOk());
4617*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry1_closer(entry1);
4618*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry1);
4619*6777b538SAndroid Build Coastguard Worker   entry1->Doom();
4620*6777b538SAndroid Build Coastguard Worker 
4621*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = nullptr;
4622*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry2), IsOk());
4623*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry2_closer(entry2);
4624*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry2);
4625*6777b538SAndroid Build Coastguard Worker   entry2_closer.reset();
4626*6777b538SAndroid Build Coastguard Worker 
4627*6777b538SAndroid Build Coastguard Worker   // Closing then reopening entry2 insures that entry2 is serialized, and so
4628*6777b538SAndroid Build Coastguard Worker   // it can be opened from files without error.
4629*6777b538SAndroid Build Coastguard Worker   entry2 = nullptr;
4630*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry2), IsOk());
4631*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry2);
4632*6777b538SAndroid Build Coastguard Worker   entry2_closer.reset(entry2);
4633*6777b538SAndroid Build Coastguard Worker 
4634*6777b538SAndroid Build Coastguard Worker   scoped_refptr<disk_cache::SimpleEntryImpl>
4635*6777b538SAndroid Build Coastguard Worker       entry1_refptr = static_cast<disk_cache::SimpleEntryImpl*>(entry1);
4636*6777b538SAndroid Build Coastguard Worker 
4637*6777b538SAndroid Build Coastguard Worker   // If crbug.com/317138 has regressed, this will remove |entry2| from
4638*6777b538SAndroid Build Coastguard Worker   // the backend's |active_entries_| while |entry2| is still alive and its
4639*6777b538SAndroid Build Coastguard Worker   // files are still on disk.
4640*6777b538SAndroid Build Coastguard Worker   entry1_closer.reset();
4641*6777b538SAndroid Build Coastguard Worker   entry1 = nullptr;
4642*6777b538SAndroid Build Coastguard Worker 
4643*6777b538SAndroid Build Coastguard Worker   // Close does not have a callback. However, we need to be sure the close is
4644*6777b538SAndroid Build Coastguard Worker   // finished before we continue the test. We can take advantage of how the ref
4645*6777b538SAndroid Build Coastguard Worker   // counting of a SimpleEntryImpl works to fake out a callback: When the
4646*6777b538SAndroid Build Coastguard Worker   // last Close() call is made to an entry, an IO operation is sent to the
4647*6777b538SAndroid Build Coastguard Worker   // synchronous entry to close the platform files. This IO operation holds a
4648*6777b538SAndroid Build Coastguard Worker   // ref pointer to the entry, which expires when the operation is done. So,
4649*6777b538SAndroid Build Coastguard Worker   // we take a refpointer, and watch the SimpleEntry object until it has only
4650*6777b538SAndroid Build Coastguard Worker   // one ref; this indicates the IO operation is complete.
4651*6777b538SAndroid Build Coastguard Worker   while (!entry1_refptr->HasOneRef()) {
4652*6777b538SAndroid Build Coastguard Worker     base::PlatformThread::YieldCurrentThread();
4653*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
4654*6777b538SAndroid Build Coastguard Worker   }
4655*6777b538SAndroid Build Coastguard Worker   entry1_refptr = nullptr;
4656*6777b538SAndroid Build Coastguard Worker 
4657*6777b538SAndroid Build Coastguard Worker   // In the bug case, this new entry ends up being a duplicate object pointing
4658*6777b538SAndroid Build Coastguard Worker   // at the same underlying files.
4659*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry3 = nullptr;
4660*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(OpenEntry(key, &entry3), IsOk());
4661*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry3_closer(entry3);
4662*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry3);
4663*6777b538SAndroid Build Coastguard Worker 
4664*6777b538SAndroid Build Coastguard Worker   // The test passes if these two dooms do not crash.
4665*6777b538SAndroid Build Coastguard Worker   entry2->Doom();
4666*6777b538SAndroid Build Coastguard Worker   entry3->Doom();
4667*6777b538SAndroid Build Coastguard Worker }
4668*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheBasicSparseIO)4669*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheBasicSparseIO) {
4670*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4671*6777b538SAndroid Build Coastguard Worker   InitCache();
4672*6777b538SAndroid Build Coastguard Worker   BasicSparseIO();
4673*6777b538SAndroid Build Coastguard Worker }
4674*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheHugeSparseIO)4675*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheHugeSparseIO) {
4676*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4677*6777b538SAndroid Build Coastguard Worker   InitCache();
4678*6777b538SAndroid Build Coastguard Worker   HugeSparseIO();
4679*6777b538SAndroid Build Coastguard Worker }
4680*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheGetAvailableRange)4681*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheGetAvailableRange) {
4682*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4683*6777b538SAndroid Build Coastguard Worker   InitCache();
4684*6777b538SAndroid Build Coastguard Worker   GetAvailableRangeTest();
4685*6777b538SAndroid Build Coastguard Worker }
4686*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheUpdateSparseEntry)4687*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheUpdateSparseEntry) {
4688*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4689*6777b538SAndroid Build Coastguard Worker   InitCache();
4690*6777b538SAndroid Build Coastguard Worker   UpdateSparseEntry();
4691*6777b538SAndroid Build Coastguard Worker }
4692*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoomSparseEntry)4693*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoomSparseEntry) {
4694*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4695*6777b538SAndroid Build Coastguard Worker   InitCache();
4696*6777b538SAndroid Build Coastguard Worker   DoomSparseEntry();
4697*6777b538SAndroid Build Coastguard Worker }
4698*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCachePartialSparseEntry)4699*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCachePartialSparseEntry) {
4700*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4701*6777b538SAndroid Build Coastguard Worker   InitCache();
4702*6777b538SAndroid Build Coastguard Worker   PartialSparseEntry();
4703*6777b538SAndroid Build Coastguard Worker }
4704*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheTruncateLargeSparseFile)4705*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheTruncateLargeSparseFile) {
4706*6777b538SAndroid Build Coastguard Worker   const int kSize = 1024;
4707*6777b538SAndroid Build Coastguard Worker 
4708*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4709*6777b538SAndroid Build Coastguard Worker   // An entry is allowed sparse data 1/10 the size of the cache, so this size
4710*6777b538SAndroid Build Coastguard Worker   // allows for one |kSize|-sized range plus overhead, but not two ranges.
4711*6777b538SAndroid Build Coastguard Worker   SetMaxSize(kSize * 15);
4712*6777b538SAndroid Build Coastguard Worker   InitCache();
4713*6777b538SAndroid Build Coastguard Worker 
4714*6777b538SAndroid Build Coastguard Worker   const char key[] = "key";
4715*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* null = nullptr;
4716*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
4717*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4718*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(null, entry);
4719*6777b538SAndroid Build Coastguard Worker 
4720*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4721*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
4722*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback callback;
4723*6777b538SAndroid Build Coastguard Worker   int ret;
4724*6777b538SAndroid Build Coastguard Worker 
4725*6777b538SAndroid Build Coastguard Worker   // Verify initial conditions.
4726*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
4727*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, callback.GetResult(ret));
4728*6777b538SAndroid Build Coastguard Worker 
4729*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadSparseData(kSize, buffer.get(), kSize, callback.callback());
4730*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, callback.GetResult(ret));
4731*6777b538SAndroid Build Coastguard Worker 
4732*6777b538SAndroid Build Coastguard Worker   // Write a range and make sure it reads back.
4733*6777b538SAndroid Build Coastguard Worker   ret = entry->WriteSparseData(0, buffer.get(), kSize, callback.callback());
4734*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, callback.GetResult(ret));
4735*6777b538SAndroid Build Coastguard Worker 
4736*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
4737*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, callback.GetResult(ret));
4738*6777b538SAndroid Build Coastguard Worker 
4739*6777b538SAndroid Build Coastguard Worker   // Write another range and make sure it reads back.
4740*6777b538SAndroid Build Coastguard Worker   ret = entry->WriteSparseData(kSize, buffer.get(), kSize, callback.callback());
4741*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, callback.GetResult(ret));
4742*6777b538SAndroid Build Coastguard Worker 
4743*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadSparseData(kSize, buffer.get(), kSize, callback.callback());
4744*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, callback.GetResult(ret));
4745*6777b538SAndroid Build Coastguard Worker 
4746*6777b538SAndroid Build Coastguard Worker   // Make sure the first range was removed when the second was written.
4747*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
4748*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, callback.GetResult(ret));
4749*6777b538SAndroid Build Coastguard Worker 
4750*6777b538SAndroid Build Coastguard Worker   // Close and reopen the entry and make sure the first entry is still absent
4751*6777b538SAndroid Build Coastguard Worker   // and the second entry is still present.
4752*6777b538SAndroid Build Coastguard Worker   entry->Close();
4753*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4754*6777b538SAndroid Build Coastguard Worker 
4755*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
4756*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, callback.GetResult(ret));
4757*6777b538SAndroid Build Coastguard Worker 
4758*6777b538SAndroid Build Coastguard Worker   ret = entry->ReadSparseData(kSize, buffer.get(), kSize, callback.callback());
4759*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, callback.GetResult(ret));
4760*6777b538SAndroid Build Coastguard Worker 
4761*6777b538SAndroid Build Coastguard Worker   entry->Close();
4762*6777b538SAndroid Build Coastguard Worker }
4763*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheNoBodyEOF)4764*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheNoBodyEOF) {
4765*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4766*6777b538SAndroid Build Coastguard Worker   InitCache();
4767*6777b538SAndroid Build Coastguard Worker 
4768*6777b538SAndroid Build Coastguard Worker   const std::string key("the first key");
4769*6777b538SAndroid Build Coastguard Worker   const int kSize = 1024;
4770*6777b538SAndroid Build Coastguard Worker   CreateEntryWithHeaderBodyAndSideData(key, kSize);
4771*6777b538SAndroid Build Coastguard Worker 
4772*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
4773*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4774*6777b538SAndroid Build Coastguard Worker   entry->Close();
4775*6777b538SAndroid Build Coastguard Worker 
4776*6777b538SAndroid Build Coastguard Worker   TruncateFileFromEnd(0 /*header and body file index*/, key, kSize,
4777*6777b538SAndroid Build Coastguard Worker                       static_cast<int>(sizeof(disk_cache::SimpleFileEOF)));
4778*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(OpenEntry(key, &entry), IsError(net::ERR_FAILED));
4779*6777b538SAndroid Build Coastguard Worker }
4780*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheNoSideDataEOF)4781*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheNoSideDataEOF) {
4782*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4783*6777b538SAndroid Build Coastguard Worker   InitCache();
4784*6777b538SAndroid Build Coastguard Worker 
4785*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
4786*6777b538SAndroid Build Coastguard Worker   const int kSize = 1024;
4787*6777b538SAndroid Build Coastguard Worker   CreateEntryWithHeaderBodyAndSideData(key, kSize);
4788*6777b538SAndroid Build Coastguard Worker 
4789*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
4790*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4791*6777b538SAndroid Build Coastguard Worker   entry->Close();
4792*6777b538SAndroid Build Coastguard Worker 
4793*6777b538SAndroid Build Coastguard Worker   TruncateFileFromEnd(1 /*side data file_index*/, key, kSize,
4794*6777b538SAndroid Build Coastguard Worker                       static_cast<int>(sizeof(disk_cache::SimpleFileEOF)));
4795*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(OpenEntry(key, &entry), IsOk());
4796*6777b538SAndroid Build Coastguard Worker   // The corrupted stream should have been deleted.
4797*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
4798*6777b538SAndroid Build Coastguard Worker   // _0 should still exist.
4799*6777b538SAndroid Build Coastguard Worker   base::FilePath path_0 = cache_path_.AppendASCII(
4800*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
4801*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::PathExists(path_0));
4802*6777b538SAndroid Build Coastguard Worker 
4803*6777b538SAndroid Build Coastguard Worker   auto check_stream_data = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4804*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 0, 0, check_stream_data.get(), kSize));
4805*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 1, 0, check_stream_data.get(), kSize));
4806*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, entry->GetDataSize(2));
4807*6777b538SAndroid Build Coastguard Worker   entry->Close();
4808*6777b538SAndroid Build Coastguard Worker }
4809*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheReadWithoutKeySHA256)4810*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheReadWithoutKeySHA256) {
4811*6777b538SAndroid Build Coastguard Worker   // This test runs as APP_CACHE to make operations more synchronous.
4812*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
4813*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4814*6777b538SAndroid Build Coastguard Worker   InitCache();
4815*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
4816*6777b538SAndroid Build Coastguard Worker   std::string key("a key");
4817*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4818*6777b538SAndroid Build Coastguard Worker 
4819*6777b538SAndroid Build Coastguard Worker   const std::string stream_0_data = "data for stream zero";
4820*6777b538SAndroid Build Coastguard Worker   auto stream_0_iobuffer =
4821*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<net::StringIOBuffer>(stream_0_data);
4822*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(stream_0_data.size()),
4823*6777b538SAndroid Build Coastguard Worker             WriteData(entry, 0, 0, stream_0_iobuffer.get(),
4824*6777b538SAndroid Build Coastguard Worker                       stream_0_data.size(), false));
4825*6777b538SAndroid Build Coastguard Worker   const std::string stream_1_data = "FOR STREAM ONE, QUITE DIFFERENT THINGS";
4826*6777b538SAndroid Build Coastguard Worker   auto stream_1_iobuffer =
4827*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<net::StringIOBuffer>(stream_1_data);
4828*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(stream_1_data.size()),
4829*6777b538SAndroid Build Coastguard Worker             WriteData(entry, 1, 0, stream_1_iobuffer.get(),
4830*6777b538SAndroid Build Coastguard Worker                       stream_1_data.size(), false));
4831*6777b538SAndroid Build Coastguard Worker   entry->Close();
4832*6777b538SAndroid Build Coastguard Worker 
4833*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4834*6777b538SAndroid Build Coastguard Worker   disk_cache::FlushCacheThreadForTesting();
4835*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4836*6777b538SAndroid Build Coastguard Worker 
4837*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4838*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::RemoveKeySHA256FromEntry(key, cache_path_));
4839*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4840*6777b538SAndroid Build Coastguard Worker   ScopedEntryPtr entry_closer(entry);
4841*6777b538SAndroid Build Coastguard Worker 
4842*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(stream_0_data.size()), entry->GetDataSize(0));
4843*6777b538SAndroid Build Coastguard Worker   auto check_stream_0_data =
4844*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<net::IOBufferWithSize>(stream_0_data.size());
4845*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
4846*6777b538SAndroid Build Coastguard Worker       static_cast<int>(stream_0_data.size()),
4847*6777b538SAndroid Build Coastguard Worker       ReadData(entry, 0, 0, check_stream_0_data.get(), stream_0_data.size()));
4848*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, stream_0_data.compare(0, std::string::npos,
4849*6777b538SAndroid Build Coastguard Worker                                      check_stream_0_data->data(),
4850*6777b538SAndroid Build Coastguard Worker                                      stream_0_data.size()));
4851*6777b538SAndroid Build Coastguard Worker 
4852*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(stream_1_data.size()), entry->GetDataSize(1));
4853*6777b538SAndroid Build Coastguard Worker   auto check_stream_1_data =
4854*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<net::IOBufferWithSize>(stream_1_data.size());
4855*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
4856*6777b538SAndroid Build Coastguard Worker       static_cast<int>(stream_1_data.size()),
4857*6777b538SAndroid Build Coastguard Worker       ReadData(entry, 1, 0, check_stream_1_data.get(), stream_1_data.size()));
4858*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, stream_1_data.compare(0, std::string::npos,
4859*6777b538SAndroid Build Coastguard Worker                                      check_stream_1_data->data(),
4860*6777b538SAndroid Build Coastguard Worker                                      stream_1_data.size()));
4861*6777b538SAndroid Build Coastguard Worker }
4862*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheDoubleOpenWithoutKeySHA256)4863*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheDoubleOpenWithoutKeySHA256) {
4864*6777b538SAndroid Build Coastguard Worker   // This test runs as APP_CACHE to make operations more synchronous.
4865*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
4866*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4867*6777b538SAndroid Build Coastguard Worker   InitCache();
4868*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
4869*6777b538SAndroid Build Coastguard Worker   std::string key("a key");
4870*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4871*6777b538SAndroid Build Coastguard Worker   entry->Close();
4872*6777b538SAndroid Build Coastguard Worker 
4873*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4874*6777b538SAndroid Build Coastguard Worker   disk_cache::FlushCacheThreadForTesting();
4875*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4876*6777b538SAndroid Build Coastguard Worker 
4877*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4878*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::RemoveKeySHA256FromEntry(key, cache_path_));
4879*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4880*6777b538SAndroid Build Coastguard Worker   entry->Close();
4881*6777b538SAndroid Build Coastguard Worker 
4882*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4883*6777b538SAndroid Build Coastguard Worker   disk_cache::FlushCacheThreadForTesting();
4884*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4885*6777b538SAndroid Build Coastguard Worker 
4886*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4887*6777b538SAndroid Build Coastguard Worker   entry->Close();
4888*6777b538SAndroid Build Coastguard Worker }
4889*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheReadCorruptKeySHA256)4890*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheReadCorruptKeySHA256) {
4891*6777b538SAndroid Build Coastguard Worker   // This test runs as APP_CACHE to make operations more synchronous.
4892*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
4893*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4894*6777b538SAndroid Build Coastguard Worker   InitCache();
4895*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
4896*6777b538SAndroid Build Coastguard Worker   std::string key("a key");
4897*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4898*6777b538SAndroid Build Coastguard Worker   entry->Close();
4899*6777b538SAndroid Build Coastguard Worker 
4900*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4901*6777b538SAndroid Build Coastguard Worker   disk_cache::FlushCacheThreadForTesting();
4902*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4903*6777b538SAndroid Build Coastguard Worker 
4904*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4905*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::CorruptKeySHA256FromEntry(key, cache_path_));
4906*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(net::OK, OpenEntry(key, &entry));
4907*6777b538SAndroid Build Coastguard Worker }
4908*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheReadCorruptLength)4909*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheReadCorruptLength) {
4910*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
4911*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4912*6777b538SAndroid Build Coastguard Worker   InitCache();
4913*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
4914*6777b538SAndroid Build Coastguard Worker   std::string key("a key");
4915*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
4916*6777b538SAndroid Build Coastguard Worker   entry->Close();
4917*6777b538SAndroid Build Coastguard Worker 
4918*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4919*6777b538SAndroid Build Coastguard Worker   disk_cache::FlushCacheThreadForTesting();
4920*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
4921*6777b538SAndroid Build Coastguard Worker 
4922*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
4923*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::CorruptStream0LengthFromEntry(key, cache_path_));
4924*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(net::OK, OpenEntry(key, &entry));
4925*6777b538SAndroid Build Coastguard Worker }
4926*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheCreateRecoverFromRmdir)4927*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheCreateRecoverFromRmdir) {
4928*6777b538SAndroid Build Coastguard Worker   // This test runs as APP_CACHE to make operations more synchronous.
4929*6777b538SAndroid Build Coastguard Worker   // (in particular we want to see if create succeeded or not, so we don't
4930*6777b538SAndroid Build Coastguard Worker   //  want an optimistic one).
4931*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
4932*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4933*6777b538SAndroid Build Coastguard Worker   InitCache();
4934*6777b538SAndroid Build Coastguard Worker 
4935*6777b538SAndroid Build Coastguard Worker   // Pretend someone deleted the cache dir. This shouldn't be too scary in
4936*6777b538SAndroid Build Coastguard Worker   // the test since cache_path_ is set as:
4937*6777b538SAndroid Build Coastguard Worker   //   CHECK(temp_dir_.CreateUniqueTempDir());
4938*6777b538SAndroid Build Coastguard Worker   //   cache_path_ = temp_dir_.GetPath().AppendASCII("cache");
4939*6777b538SAndroid Build Coastguard Worker   disk_cache::DeleteCache(cache_path_,
4940*6777b538SAndroid Build Coastguard Worker                           true /* delete the dir, what we really want*/);
4941*6777b538SAndroid Build Coastguard Worker 
4942*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
4943*6777b538SAndroid Build Coastguard Worker   std::string key("a key");
4944*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4945*6777b538SAndroid Build Coastguard Worker   entry->Close();
4946*6777b538SAndroid Build Coastguard Worker }
4947*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheSparseErrorHandling)4948*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheSparseErrorHandling) {
4949*6777b538SAndroid Build Coastguard Worker   // If there is corruption in sparse file, we should delete all the files
4950*6777b538SAndroid Build Coastguard Worker   // before returning the failure. Further additional sparse operations in
4951*6777b538SAndroid Build Coastguard Worker   // failure state should fail gracefully.
4952*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
4953*6777b538SAndroid Build Coastguard Worker   InitCache();
4954*6777b538SAndroid Build Coastguard Worker 
4955*6777b538SAndroid Build Coastguard Worker   std::string key("a key");
4956*6777b538SAndroid Build Coastguard Worker 
4957*6777b538SAndroid Build Coastguard Worker   disk_cache::SimpleFileTracker::EntryFileKey num_key(
4958*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetEntryHashKey(key));
4959*6777b538SAndroid Build Coastguard Worker   base::FilePath path_0 = cache_path_.AppendASCII(
4960*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFilenameFromEntryFileKeyAndFileIndex(num_key,
4961*6777b538SAndroid Build Coastguard Worker                                                                        0));
4962*6777b538SAndroid Build Coastguard Worker   base::FilePath path_s = cache_path_.AppendASCII(
4963*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetSparseFilenameFromEntryFileKey(num_key));
4964*6777b538SAndroid Build Coastguard Worker 
4965*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
4966*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
4967*6777b538SAndroid Build Coastguard Worker 
4968*6777b538SAndroid Build Coastguard Worker   const int kSize = 1024;
4969*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
4970*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
4971*6777b538SAndroid Build Coastguard Worker 
4972*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, 0, buffer.get(), kSize));
4973*6777b538SAndroid Build Coastguard Worker   entry->Close();
4974*6777b538SAndroid Build Coastguard Worker 
4975*6777b538SAndroid Build Coastguard Worker   disk_cache::FlushCacheThreadForTesting();
4976*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::PathExists(path_0));
4977*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::PathExists(path_s));
4978*6777b538SAndroid Build Coastguard Worker 
4979*6777b538SAndroid Build Coastguard Worker   // Now corrupt the _s file in a way that makes it look OK on open, but not on
4980*6777b538SAndroid Build Coastguard Worker   // read.
4981*6777b538SAndroid Build Coastguard Worker   base::File file_s(path_s, base::File::FLAG_OPEN | base::File::FLAG_READ |
4982*6777b538SAndroid Build Coastguard Worker                                 base::File::FLAG_WRITE);
4983*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(file_s.IsValid());
4984*6777b538SAndroid Build Coastguard Worker   file_s.SetLength(sizeof(disk_cache::SimpleFileHeader) +
4985*6777b538SAndroid Build Coastguard Worker                    sizeof(disk_cache::SimpleFileSparseRangeHeader) +
4986*6777b538SAndroid Build Coastguard Worker                    key.size());
4987*6777b538SAndroid Build Coastguard Worker   file_s.Close();
4988*6777b538SAndroid Build Coastguard Worker 
4989*6777b538SAndroid Build Coastguard Worker   // Re-open, it should still be fine.
4990*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
4991*6777b538SAndroid Build Coastguard Worker 
4992*6777b538SAndroid Build Coastguard Worker   // Read should fail though.
4993*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_CACHE_READ_FAILURE,
4994*6777b538SAndroid Build Coastguard Worker             ReadSparseData(entry, 0, buffer.get(), kSize));
4995*6777b538SAndroid Build Coastguard Worker 
4996*6777b538SAndroid Build Coastguard Worker   // At the point read returns to us, the files should already been gone.
4997*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(base::PathExists(path_0));
4998*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(base::PathExists(path_s));
4999*6777b538SAndroid Build Coastguard Worker 
5000*6777b538SAndroid Build Coastguard Worker   // Re-trying should still fail. Not DCHECK-fail.
5001*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_FAILED, ReadSparseData(entry, 0, buffer.get(), kSize));
5002*6777b538SAndroid Build Coastguard Worker 
5003*6777b538SAndroid Build Coastguard Worker   // Similarly for other ops.
5004*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_FAILED, WriteSparseData(entry, 0, buffer.get(), kSize));
5005*6777b538SAndroid Build Coastguard Worker   net::TestCompletionCallback cb;
5006*6777b538SAndroid Build Coastguard Worker 
5007*6777b538SAndroid Build Coastguard Worker   TestRangeResultCompletionCallback range_cb;
5008*6777b538SAndroid Build Coastguard Worker   RangeResult result = range_cb.GetResult(
5009*6777b538SAndroid Build Coastguard Worker       entry->GetAvailableRange(0, 1024, range_cb.callback()));
5010*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_FAILED, result.net_error);
5011*6777b538SAndroid Build Coastguard Worker 
5012*6777b538SAndroid Build Coastguard Worker   entry->Close();
5013*6777b538SAndroid Build Coastguard Worker   disk_cache::FlushCacheThreadForTesting();
5014*6777b538SAndroid Build Coastguard Worker 
5015*6777b538SAndroid Build Coastguard Worker   // Closing shouldn't resurrect files, either.
5016*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(base::PathExists(path_0));
5017*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(base::PathExists(path_s));
5018*6777b538SAndroid Build Coastguard Worker }
5019*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheCreateCollision)5020*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheCreateCollision) {
5021*6777b538SAndroid Build Coastguard Worker   // These two keys collide; this test is that we properly handled creation
5022*6777b538SAndroid Build Coastguard Worker   // of both.
5023*6777b538SAndroid Build Coastguard Worker   const char kCollKey1[] =
5024*6777b538SAndroid Build Coastguard Worker       "\xfb\x4e\x9c\x1d\x66\x71\xf7\x54\xa3\x11\xa0\x7e\x16\xa5\x68\xf6";
5025*6777b538SAndroid Build Coastguard Worker   const char kCollKey2[] =
5026*6777b538SAndroid Build Coastguard Worker       "\xbc\x60\x64\x92\xbc\xa0\x5c\x15\x17\x93\x29\x2d\xe4\x21\xbd\x03";
5027*6777b538SAndroid Build Coastguard Worker 
5028*6777b538SAndroid Build Coastguard Worker   const int kSize = 256;
5029*6777b538SAndroid Build Coastguard Worker   auto buffer1 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5030*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5031*6777b538SAndroid Build Coastguard Worker   auto read_buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5032*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer1->data(), kSize, false);
5033*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer2->data(), kSize, false);
5034*6777b538SAndroid Build Coastguard Worker 
5035*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5036*6777b538SAndroid Build Coastguard Worker   InitCache();
5037*6777b538SAndroid Build Coastguard Worker 
5038*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1;
5039*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kCollKey1, &entry1), IsOk());
5040*6777b538SAndroid Build Coastguard Worker 
5041*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2;
5042*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kCollKey2, &entry2), IsOk());
5043*6777b538SAndroid Build Coastguard Worker 
5044*6777b538SAndroid Build Coastguard Worker   // Make sure that entry was actually created and we didn't just succeed
5045*6777b538SAndroid Build Coastguard Worker   // optimistically. (Oddly I can't seem to hit the sequence of events required
5046*6777b538SAndroid Build Coastguard Worker   // for the bug that used to be here if I just set this to APP_CACHE).
5047*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry2, 0, 0, buffer2.get(), kSize, false));
5048*6777b538SAndroid Build Coastguard Worker 
5049*6777b538SAndroid Build Coastguard Worker   // entry1 is still usable, though, and distinct (we just won't be able to
5050*6777b538SAndroid Build Coastguard Worker   // re-open it).
5051*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry1, 0, 0, buffer1.get(), kSize, false));
5052*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry1, 0, 0, read_buffer.get(), kSize));
5053*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer1->data(), read_buffer->data(), kSize));
5054*6777b538SAndroid Build Coastguard Worker 
5055*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry2, 0, 0, read_buffer.get(), kSize));
5056*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer2->data(), read_buffer->data(), kSize));
5057*6777b538SAndroid Build Coastguard Worker 
5058*6777b538SAndroid Build Coastguard Worker   entry1->Close();
5059*6777b538SAndroid Build Coastguard Worker   entry2->Close();
5060*6777b538SAndroid Build Coastguard Worker }
5061*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheConvertToSparseStream2LeftOver)5062*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheConvertToSparseStream2LeftOver) {
5063*6777b538SAndroid Build Coastguard Worker   // Testcase for what happens when we have a sparse stream and a left over
5064*6777b538SAndroid Build Coastguard Worker   // empty stream 2 file.
5065*6777b538SAndroid Build Coastguard Worker   const int kSize = 10;
5066*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5067*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
5068*6777b538SAndroid Build Coastguard Worker 
5069*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5070*6777b538SAndroid Build Coastguard Worker   InitCache();
5071*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry;
5072*6777b538SAndroid Build Coastguard Worker   std::string key("a key");
5073*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(key, &entry), IsOk());
5074*6777b538SAndroid Build Coastguard Worker   // Create an empty stream 2. To do that, we first make a non-empty one, then
5075*6777b538SAndroid Build Coastguard Worker   // truncate it (since otherwise the write would just get ignored).
5076*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteData(entry, /* stream = */ 2, /* offset = */ 0,
5077*6777b538SAndroid Build Coastguard Worker                              buffer.get(), kSize, false));
5078*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, /* stream = */ 2, /* offset = */ 0,
5079*6777b538SAndroid Build Coastguard Worker                          buffer.get(), 0, true));
5080*6777b538SAndroid Build Coastguard Worker 
5081*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, WriteSparseData(entry, 5, buffer.get(), kSize));
5082*6777b538SAndroid Build Coastguard Worker   entry->Close();
5083*6777b538SAndroid Build Coastguard Worker 
5084*6777b538SAndroid Build Coastguard Worker   // Reopen, and try to get the sparse data back.
5085*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(key, &entry), IsOk());
5086*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5087*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadSparseData(entry, 5, buffer2.get(), kSize));
5088*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer->data(), buffer2->data(), kSize));
5089*6777b538SAndroid Build Coastguard Worker   entry->Close();
5090*6777b538SAndroid Build Coastguard Worker }
5091*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheLazyStream2CreateFailure)5092*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheLazyStream2CreateFailure) {
5093*6777b538SAndroid Build Coastguard Worker   // Testcase for what happens when lazy-creation of stream 2 fails.
5094*6777b538SAndroid Build Coastguard Worker   const int kSize = 10;
5095*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5096*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
5097*6777b538SAndroid Build Coastguard Worker 
5098*6777b538SAndroid Build Coastguard Worker   // Synchronous ops, for ease of disk state;
5099*6777b538SAndroid Build Coastguard Worker   SetCacheType(net::APP_CACHE);
5100*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5101*6777b538SAndroid Build Coastguard Worker   InitCache();
5102*6777b538SAndroid Build Coastguard Worker 
5103*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5104*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
5105*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kKey, &entry), IsOk());
5106*6777b538SAndroid Build Coastguard Worker 
5107*6777b538SAndroid Build Coastguard Worker   // Create _1 file for stream 2; this should inject a failure when the cache
5108*6777b538SAndroid Build Coastguard Worker   // tries to create it itself.
5109*6777b538SAndroid Build Coastguard Worker   base::FilePath entry_file1_path = cache_path_.AppendASCII(
5110*6777b538SAndroid Build Coastguard Worker       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(kKey, 1));
5111*6777b538SAndroid Build Coastguard Worker   base::File entry_file1(entry_file1_path,
5112*6777b538SAndroid Build Coastguard Worker                          base::File::FLAG_WRITE | base::File::FLAG_CREATE);
5113*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry_file1.IsValid());
5114*6777b538SAndroid Build Coastguard Worker   entry_file1.Close();
5115*6777b538SAndroid Build Coastguard Worker 
5116*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_CACHE_WRITE_FAILURE,
5117*6777b538SAndroid Build Coastguard Worker             WriteData(entry, /* index = */ 2, /* offset = */ 0, buffer.get(),
5118*6777b538SAndroid Build Coastguard Worker                       kSize, /* truncate = */ false));
5119*6777b538SAndroid Build Coastguard Worker   entry->Close();
5120*6777b538SAndroid Build Coastguard Worker }
5121*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheChecksumpScrewUp)5122*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheChecksumpScrewUp) {
5123*6777b538SAndroid Build Coastguard Worker   // Test for a bug that occurred during development of  movement of CRC
5124*6777b538SAndroid Build Coastguard Worker   // computation off I/O thread.
5125*6777b538SAndroid Build Coastguard Worker   const int kSize = 10;
5126*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5127*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
5128*6777b538SAndroid Build Coastguard Worker 
5129*6777b538SAndroid Build Coastguard Worker   const int kDoubleSize = kSize * 2;
5130*6777b538SAndroid Build Coastguard Worker   auto big_buffer = base::MakeRefCounted<net::IOBufferWithSize>(kDoubleSize);
5131*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(big_buffer->data(), kDoubleSize, false);
5132*6777b538SAndroid Build Coastguard Worker 
5133*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5134*6777b538SAndroid Build Coastguard Worker   InitCache();
5135*6777b538SAndroid Build Coastguard Worker 
5136*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5137*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
5138*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kKey, &entry), IsOk());
5139*6777b538SAndroid Build Coastguard Worker 
5140*6777b538SAndroid Build Coastguard Worker   // Write out big_buffer for the double range. Checksum will be set to this.
5141*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kDoubleSize,
5142*6777b538SAndroid Build Coastguard Worker             WriteData(entry, 1, 0, big_buffer.get(), kDoubleSize, false));
5143*6777b538SAndroid Build Coastguard Worker 
5144*6777b538SAndroid Build Coastguard Worker   // Reset remembered position to 0 by writing at an earlier non-zero offset.
5145*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1, WriteData(entry, /* stream = */ 1, /* offset = */ 1,
5146*6777b538SAndroid Build Coastguard Worker                          big_buffer.get(), /* len = */ 1, false));
5147*6777b538SAndroid Build Coastguard Worker 
5148*6777b538SAndroid Build Coastguard Worker   // Now write out the half-range twice. An intermediate revision would
5149*6777b538SAndroid Build Coastguard Worker   // incorrectly compute checksum as if payload was buffer followed by buffer
5150*6777b538SAndroid Build Coastguard Worker   // rather than buffer followed by end of big_buffer.
5151*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kSize, WriteData(entry, 1, 0, buffer.get(), kSize, false));
5152*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kSize, WriteData(entry, 1, 0, buffer.get(), kSize, false));
5153*6777b538SAndroid Build Coastguard Worker   entry->Close();
5154*6777b538SAndroid Build Coastguard Worker 
5155*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(kKey, &entry), IsOk());
5156*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5157*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 1, 0, buffer2.get(), kSize));
5158*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer->data(), buffer2->data(), kSize));
5159*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, 1, kSize, buffer2.get(), kSize));
5160*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(big_buffer->data() + kSize, buffer2->data(), kSize));
5161*6777b538SAndroid Build Coastguard Worker   entry->Close();
5162*6777b538SAndroid Build Coastguard Worker }
5163*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleUseAfterBackendDestruction)5164*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleUseAfterBackendDestruction) {
5165*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5166*6777b538SAndroid Build Coastguard Worker   InitCache();
5167*6777b538SAndroid Build Coastguard Worker   UseAfterBackendDestruction();
5168*6777b538SAndroid Build Coastguard Worker }
5169*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyUseAfterBackendDestruction)5170*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyUseAfterBackendDestruction) {
5171*6777b538SAndroid Build Coastguard Worker   // https://crbug.com/741620
5172*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
5173*6777b538SAndroid Build Coastguard Worker   InitCache();
5174*6777b538SAndroid Build Coastguard Worker   UseAfterBackendDestruction();
5175*6777b538SAndroid Build Coastguard Worker }
5176*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCloseSparseAfterBackendDestruction)5177*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCloseSparseAfterBackendDestruction) {
5178*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5179*6777b538SAndroid Build Coastguard Worker   InitCache();
5180*6777b538SAndroid Build Coastguard Worker   CloseSparseAfterBackendDestruction();
5181*6777b538SAndroid Build Coastguard Worker }
5182*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyCloseSparseAfterBackendDestruction)5183*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyCloseSparseAfterBackendDestruction) {
5184*6777b538SAndroid Build Coastguard Worker   // https://crbug.com/946434
5185*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
5186*6777b538SAndroid Build Coastguard Worker   InitCache();
5187*6777b538SAndroid Build Coastguard Worker   CloseSparseAfterBackendDestruction();
5188*6777b538SAndroid Build Coastguard Worker }
5189*6777b538SAndroid Build Coastguard Worker 
LastUsedTimePersists()5190*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::LastUsedTimePersists() {
5191*6777b538SAndroid Build Coastguard Worker   // Make sure that SetLastUsedTimeForTest persists. When used with SimpleCache,
5192*6777b538SAndroid Build Coastguard Worker   // this also checks that Entry::GetLastUsed is based on information in index,
5193*6777b538SAndroid Build Coastguard Worker   // when available, not atime on disk, which can be inaccurate.
5194*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5195*6777b538SAndroid Build Coastguard Worker   InitCache();
5196*6777b538SAndroid Build Coastguard Worker 
5197*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry1 = nullptr;
5198*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kKey, &entry1), IsOk());
5199*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(nullptr != entry1);
5200*6777b538SAndroid Build Coastguard Worker   base::Time modified_last_used = entry1->GetLastUsed() - base::Minutes(5);
5201*6777b538SAndroid Build Coastguard Worker   entry1->SetLastUsedTimeForTest(modified_last_used);
5202*6777b538SAndroid Build Coastguard Worker   entry1->Close();
5203*6777b538SAndroid Build Coastguard Worker 
5204*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = nullptr;
5205*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(kKey, &entry2), IsOk());
5206*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(nullptr != entry2);
5207*6777b538SAndroid Build Coastguard Worker 
5208*6777b538SAndroid Build Coastguard Worker   base::TimeDelta diff = modified_last_used - entry2->GetLastUsed();
5209*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(diff, base::Seconds(2));
5210*6777b538SAndroid Build Coastguard Worker   EXPECT_GT(diff, -base::Seconds(2));
5211*6777b538SAndroid Build Coastguard Worker   entry2->Close();
5212*6777b538SAndroid Build Coastguard Worker }
5213*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,LastUsedTimePersists)5214*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, LastUsedTimePersists) {
5215*6777b538SAndroid Build Coastguard Worker   LastUsedTimePersists();
5216*6777b538SAndroid Build Coastguard Worker }
5217*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleLastUsedTimePersists)5218*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleLastUsedTimePersists) {
5219*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5220*6777b538SAndroid Build Coastguard Worker   LastUsedTimePersists();
5221*6777b538SAndroid Build Coastguard Worker }
5222*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyLastUsedTimePersists)5223*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyLastUsedTimePersists) {
5224*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
5225*6777b538SAndroid Build Coastguard Worker   LastUsedTimePersists();
5226*6777b538SAndroid Build Coastguard Worker }
5227*6777b538SAndroid Build Coastguard Worker 
TruncateBackwards()5228*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::TruncateBackwards() {
5229*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5230*6777b538SAndroid Build Coastguard Worker 
5231*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
5232*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kKey, &entry), IsOk());
5233*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry != nullptr);
5234*6777b538SAndroid Build Coastguard Worker 
5235*6777b538SAndroid Build Coastguard Worker   const int kBigSize = 40 * 1024;
5236*6777b538SAndroid Build Coastguard Worker   const int kSmallSize = 9727;
5237*6777b538SAndroid Build Coastguard Worker 
5238*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kBigSize);
5239*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kBigSize, false);
5240*6777b538SAndroid Build Coastguard Worker   auto read_buf = base::MakeRefCounted<net::IOBufferWithSize>(kBigSize);
5241*6777b538SAndroid Build Coastguard Worker 
5242*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kSmallSize, WriteData(entry, /* index = */ 0,
5243*6777b538SAndroid Build Coastguard Worker                                   /* offset = */ kBigSize, buffer.get(),
5244*6777b538SAndroid Build Coastguard Worker                                   /* size = */ kSmallSize,
5245*6777b538SAndroid Build Coastguard Worker                                   /* truncate = */ false));
5246*6777b538SAndroid Build Coastguard Worker   memset(read_buf->data(), 0, kBigSize);
5247*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kSmallSize, ReadData(entry, /* index = */ 0,
5248*6777b538SAndroid Build Coastguard Worker                                  /* offset = */ kBigSize, read_buf.get(),
5249*6777b538SAndroid Build Coastguard Worker                                  /* size = */ kSmallSize));
5250*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(read_buf->data(), buffer->data(), kSmallSize));
5251*6777b538SAndroid Build Coastguard Worker 
5252*6777b538SAndroid Build Coastguard Worker   // A partly overlapping truncate before the previous write.
5253*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kBigSize,
5254*6777b538SAndroid Build Coastguard Worker             WriteData(entry, /* index = */ 0,
5255*6777b538SAndroid Build Coastguard Worker                       /* offset = */ 3, buffer.get(), /* size = */ kBigSize,
5256*6777b538SAndroid Build Coastguard Worker                       /* truncate = */ true));
5257*6777b538SAndroid Build Coastguard Worker   memset(read_buf->data(), 0, kBigSize);
5258*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kBigSize,
5259*6777b538SAndroid Build Coastguard Worker             ReadData(entry, /* index = */ 0,
5260*6777b538SAndroid Build Coastguard Worker                      /* offset = */ 3, read_buf.get(), /* size = */ kBigSize));
5261*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(read_buf->data(), buffer->data(), kBigSize));
5262*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kBigSize + 3, entry->GetDataSize(0));
5263*6777b538SAndroid Build Coastguard Worker   entry->Close();
5264*6777b538SAndroid Build Coastguard Worker }
5265*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,TruncateBackwards)5266*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, TruncateBackwards) {
5267*6777b538SAndroid Build Coastguard Worker   // https://crbug.com/946539/
5268*6777b538SAndroid Build Coastguard Worker   InitCache();
5269*6777b538SAndroid Build Coastguard Worker   TruncateBackwards();
5270*6777b538SAndroid Build Coastguard Worker }
5271*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleTruncateBackwards)5272*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleTruncateBackwards) {
5273*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5274*6777b538SAndroid Build Coastguard Worker   InitCache();
5275*6777b538SAndroid Build Coastguard Worker   TruncateBackwards();
5276*6777b538SAndroid Build Coastguard Worker }
5277*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyTruncateBackwards)5278*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyTruncateBackwards) {
5279*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
5280*6777b538SAndroid Build Coastguard Worker   InitCache();
5281*6777b538SAndroid Build Coastguard Worker   TruncateBackwards();
5282*6777b538SAndroid Build Coastguard Worker }
5283*6777b538SAndroid Build Coastguard Worker 
ZeroWriteBackwards()5284*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::ZeroWriteBackwards() {
5285*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5286*6777b538SAndroid Build Coastguard Worker 
5287*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
5288*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kKey, &entry), IsOk());
5289*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry != nullptr);
5290*6777b538SAndroid Build Coastguard Worker 
5291*6777b538SAndroid Build Coastguard Worker   const int kSize = 1024;
5292*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5293*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
5294*6777b538SAndroid Build Coastguard Worker 
5295*6777b538SAndroid Build Coastguard Worker   // Offset here needs to be > blockfile's kMaxBlockSize to hit
5296*6777b538SAndroid Build Coastguard Worker   // https://crbug.com/946538, as writes close to beginning are handled
5297*6777b538SAndroid Build Coastguard Worker   // specially.
5298*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, /* index = */ 0,
5299*6777b538SAndroid Build Coastguard Worker                          /* offset = */ 17000, buffer.get(),
5300*6777b538SAndroid Build Coastguard Worker                          /* size = */ 0, /* truncate = */ true));
5301*6777b538SAndroid Build Coastguard Worker 
5302*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, WriteData(entry, /* index = */ 0,
5303*6777b538SAndroid Build Coastguard Worker                          /* offset = */ 0, buffer.get(),
5304*6777b538SAndroid Build Coastguard Worker                          /* size = */ 0, /* truncate = */ false));
5305*6777b538SAndroid Build Coastguard Worker 
5306*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry, /* index = */ 0,
5307*6777b538SAndroid Build Coastguard Worker                             /* offset = */ 0, buffer.get(),
5308*6777b538SAndroid Build Coastguard Worker                             /* size = */ kSize));
5309*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < kSize; ++i) {
5310*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, buffer->data()[i]) << i;
5311*6777b538SAndroid Build Coastguard Worker   }
5312*6777b538SAndroid Build Coastguard Worker   entry->Close();
5313*6777b538SAndroid Build Coastguard Worker }
5314*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,ZeroWriteBackwards)5315*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, ZeroWriteBackwards) {
5316*6777b538SAndroid Build Coastguard Worker   // https://crbug.com/946538/
5317*6777b538SAndroid Build Coastguard Worker   InitCache();
5318*6777b538SAndroid Build Coastguard Worker   ZeroWriteBackwards();
5319*6777b538SAndroid Build Coastguard Worker }
5320*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleZeroWriteBackwards)5321*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleZeroWriteBackwards) {
5322*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5323*6777b538SAndroid Build Coastguard Worker   InitCache();
5324*6777b538SAndroid Build Coastguard Worker   ZeroWriteBackwards();
5325*6777b538SAndroid Build Coastguard Worker }
5326*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlyZeroWriteBackwards)5327*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlyZeroWriteBackwards) {
5328*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
5329*6777b538SAndroid Build Coastguard Worker   InitCache();
5330*6777b538SAndroid Build Coastguard Worker   ZeroWriteBackwards();
5331*6777b538SAndroid Build Coastguard Worker }
5332*6777b538SAndroid Build Coastguard Worker 
SparseOffset64Bit()5333*6777b538SAndroid Build Coastguard Worker void DiskCacheEntryTest::SparseOffset64Bit() {
5334*6777b538SAndroid Build Coastguard Worker   // Offsets to sparse ops are 64-bit, make sure we keep track of all of them.
5335*6777b538SAndroid Build Coastguard Worker   // (Or, as at least in case of blockfile, fail things cleanly, as it has a
5336*6777b538SAndroid Build Coastguard Worker   //  cap on max offset that's much lower).
5337*6777b538SAndroid Build Coastguard Worker   bool blockfile = !memory_only_ && !simple_cache_mode_;
5338*6777b538SAndroid Build Coastguard Worker   InitCache();
5339*6777b538SAndroid Build Coastguard Worker 
5340*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5341*6777b538SAndroid Build Coastguard Worker 
5342*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
5343*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kKey, &entry), IsOk());
5344*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry != nullptr);
5345*6777b538SAndroid Build Coastguard Worker 
5346*6777b538SAndroid Build Coastguard Worker   const int kSize = 1024;
5347*6777b538SAndroid Build Coastguard Worker   // One bit set very high, so intermediate truncations to 32-bit would drop it
5348*6777b538SAndroid Build Coastguard Worker   // even if they happen after a bunch of shifting right.
5349*6777b538SAndroid Build Coastguard Worker   const int64_t kOffset = (1ll << 61);
5350*6777b538SAndroid Build Coastguard Worker 
5351*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5352*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
5353*6777b538SAndroid Build Coastguard Worker 
5354*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(blockfile ? net::ERR_CACHE_OPERATION_NOT_SUPPORTED : kSize,
5355*6777b538SAndroid Build Coastguard Worker             WriteSparseData(entry, kOffset, buffer.get(), kSize));
5356*6777b538SAndroid Build Coastguard Worker 
5357*6777b538SAndroid Build Coastguard Worker   int64_t start_out = -1;
5358*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, GetAvailableRange(entry, /* offset = */ 0, kSize, &start_out));
5359*6777b538SAndroid Build Coastguard Worker 
5360*6777b538SAndroid Build Coastguard Worker   start_out = -1;
5361*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(blockfile ? 0 : kSize,
5362*6777b538SAndroid Build Coastguard Worker             GetAvailableRange(entry, kOffset, kSize, &start_out));
5363*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kOffset, start_out);
5364*6777b538SAndroid Build Coastguard Worker 
5365*6777b538SAndroid Build Coastguard Worker   entry->Close();
5366*6777b538SAndroid Build Coastguard Worker }
5367*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SparseOffset64Bit)5368*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SparseOffset64Bit) {
5369*6777b538SAndroid Build Coastguard Worker   InitCache();
5370*6777b538SAndroid Build Coastguard Worker   SparseOffset64Bit();
5371*6777b538SAndroid Build Coastguard Worker }
5372*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleSparseOffset64Bit)5373*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleSparseOffset64Bit) {
5374*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5375*6777b538SAndroid Build Coastguard Worker   InitCache();
5376*6777b538SAndroid Build Coastguard Worker   SparseOffset64Bit();
5377*6777b538SAndroid Build Coastguard Worker }
5378*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,MemoryOnlySparseOffset64Bit)5379*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, MemoryOnlySparseOffset64Bit) {
5380*6777b538SAndroid Build Coastguard Worker   // https://crbug.com/946436
5381*6777b538SAndroid Build Coastguard Worker   SetMemoryOnlyMode();
5382*6777b538SAndroid Build Coastguard Worker   InitCache();
5383*6777b538SAndroid Build Coastguard Worker   SparseOffset64Bit();
5384*6777b538SAndroid Build Coastguard Worker }
5385*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,SimpleCacheCloseResurrection)5386*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, SimpleCacheCloseResurrection) {
5387*6777b538SAndroid Build Coastguard Worker   const int kSize = 10;
5388*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5389*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buffer->data(), kSize, false);
5390*6777b538SAndroid Build Coastguard Worker 
5391*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "key";
5392*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5393*6777b538SAndroid Build Coastguard Worker   InitCache();
5394*6777b538SAndroid Build Coastguard Worker 
5395*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
5396*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry(kKey, &entry), IsOk());
5397*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry != nullptr);
5398*6777b538SAndroid Build Coastguard Worker 
5399*6777b538SAndroid Build Coastguard Worker   // Let optimistic create finish.
5400*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5401*6777b538SAndroid Build Coastguard Worker   disk_cache::FlushCacheThreadForTesting();
5402*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5403*6777b538SAndroid Build Coastguard Worker 
5404*6777b538SAndroid Build Coastguard Worker   int rv = entry->WriteData(1, 0, buffer.get(), kSize,
5405*6777b538SAndroid Build Coastguard Worker                             net::CompletionOnceCallback(), false);
5406*6777b538SAndroid Build Coastguard Worker 
5407*6777b538SAndroid Build Coastguard Worker   // Write should be optimistic.
5408*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kSize, rv);
5409*6777b538SAndroid Build Coastguard Worker 
5410*6777b538SAndroid Build Coastguard Worker   // Since the write is still pending, the open will get queued...
5411*6777b538SAndroid Build Coastguard Worker   TestEntryResultCompletionCallback cb_open;
5412*6777b538SAndroid Build Coastguard Worker   EntryResult result2 =
5413*6777b538SAndroid Build Coastguard Worker       cache_->OpenEntry(kKey, net::HIGHEST, cb_open.callback());
5414*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING, result2.net_error());
5415*6777b538SAndroid Build Coastguard Worker 
5416*6777b538SAndroid Build Coastguard Worker   // ... as the open is queued, this Close will temporarily reduce the number
5417*6777b538SAndroid Build Coastguard Worker   // of external references to 0.  This should not break things.
5418*6777b538SAndroid Build Coastguard Worker   entry->Close();
5419*6777b538SAndroid Build Coastguard Worker 
5420*6777b538SAndroid Build Coastguard Worker   // Wait till open finishes.
5421*6777b538SAndroid Build Coastguard Worker   result2 = cb_open.GetResult(std::move(result2));
5422*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(net::OK, result2.net_error());
5423*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry2 = result2.ReleaseEntry();
5424*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry2 != nullptr);
5425*6777b538SAndroid Build Coastguard Worker 
5426*6777b538SAndroid Build Coastguard Worker   // Get first close a chance to finish.
5427*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5428*6777b538SAndroid Build Coastguard Worker   disk_cache::FlushCacheThreadForTesting();
5429*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
5430*6777b538SAndroid Build Coastguard Worker 
5431*6777b538SAndroid Build Coastguard Worker   // Make sure |entry2| is still usable.
5432*6777b538SAndroid Build Coastguard Worker   auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5433*6777b538SAndroid Build Coastguard Worker   memset(buffer2->data(), 0, kSize);
5434*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kSize, ReadData(entry2, 1, 0, buffer2.get(), kSize));
5435*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(buffer->data(), buffer2->data(), kSize));
5436*6777b538SAndroid Build Coastguard Worker   entry2->Close();
5437*6777b538SAndroid Build Coastguard Worker }
5438*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheEntryTest,BlockFileSparsePendingAfterDtor)5439*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheEntryTest, BlockFileSparsePendingAfterDtor) {
5440*6777b538SAndroid Build Coastguard Worker   // Test of behavior of ~EntryImpl for sparse entry that runs after backend
5441*6777b538SAndroid Build Coastguard Worker   // destruction.
5442*6777b538SAndroid Build Coastguard Worker   //
5443*6777b538SAndroid Build Coastguard Worker   // Hand-creating the backend for realistic shutdown behavior.
5444*6777b538SAndroid Build Coastguard Worker   CleanupCacheDir();
5445*6777b538SAndroid Build Coastguard Worker   CreateBackend(disk_cache::kNone);
5446*6777b538SAndroid Build Coastguard Worker 
5447*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
5448*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(CreateEntry("key", &entry), IsOk());
5449*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(entry != nullptr);
5450*6777b538SAndroid Build Coastguard Worker 
5451*6777b538SAndroid Build Coastguard Worker   const int kSize = 61184;
5452*6777b538SAndroid Build Coastguard Worker 
5453*6777b538SAndroid Build Coastguard Worker   auto buf = base::MakeRefCounted<net::IOBufferWithSize>(kSize);
5454*6777b538SAndroid Build Coastguard Worker   CacheTestFillBuffer(buf->data(), kSize, false);
5455*6777b538SAndroid Build Coastguard Worker 
5456*6777b538SAndroid Build Coastguard Worker   // The write pattern here avoids the second write being handled by the
5457*6777b538SAndroid Build Coastguard Worker   // buffering layer, making SparseControl have to deal with its asynchrony.
5458*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, WriteSparseData(entry, 65535, buf.get(), 1));
5459*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(net::ERR_IO_PENDING,
5460*6777b538SAndroid Build Coastguard Worker             entry->WriteSparseData(2560, buf.get(), kSize, base::DoNothing()));
5461*6777b538SAndroid Build Coastguard Worker   entry->Close();
5462*6777b538SAndroid Build Coastguard Worker   ResetCaches();
5463*6777b538SAndroid Build Coastguard Worker 
5464*6777b538SAndroid Build Coastguard Worker   // Create a new instance as a way of flushing the thread.
5465*6777b538SAndroid Build Coastguard Worker   InitCache();
5466*6777b538SAndroid Build Coastguard Worker   FlushQueueForTest();
5467*6777b538SAndroid Build Coastguard Worker }
5468*6777b538SAndroid Build Coastguard Worker 
5469*6777b538SAndroid Build Coastguard Worker class DiskCacheSimplePrefetchTest : public DiskCacheEntryTest {
5470*6777b538SAndroid Build Coastguard Worker  public:
5471*6777b538SAndroid Build Coastguard Worker   DiskCacheSimplePrefetchTest() = default;
5472*6777b538SAndroid Build Coastguard Worker 
5473*6777b538SAndroid Build Coastguard Worker   enum { kEntrySize = 1024 };
5474*6777b538SAndroid Build Coastguard Worker 
SetUp()5475*6777b538SAndroid Build Coastguard Worker   void SetUp() override {
5476*6777b538SAndroid Build Coastguard Worker     payload_ = base::MakeRefCounted<net::IOBufferWithSize>(kEntrySize);
5477*6777b538SAndroid Build Coastguard Worker     CacheTestFillBuffer(payload_->data(), kEntrySize, false);
5478*6777b538SAndroid Build Coastguard Worker     DiskCacheEntryTest::SetUp();
5479*6777b538SAndroid Build Coastguard Worker   }
5480*6777b538SAndroid Build Coastguard Worker 
SetupFullAndTrailerPrefetch(int full_size,int trailer_speculative_size)5481*6777b538SAndroid Build Coastguard Worker   void SetupFullAndTrailerPrefetch(int full_size,
5482*6777b538SAndroid Build Coastguard Worker                                    int trailer_speculative_size) {
5483*6777b538SAndroid Build Coastguard Worker     std::map<std::string, std::string> params;
5484*6777b538SAndroid Build Coastguard Worker     params[disk_cache::kSimpleCacheFullPrefetchBytesParam] =
5485*6777b538SAndroid Build Coastguard Worker         base::NumberToString(full_size);
5486*6777b538SAndroid Build Coastguard Worker     params[disk_cache::kSimpleCacheTrailerPrefetchSpeculativeBytesParam] =
5487*6777b538SAndroid Build Coastguard Worker         base::NumberToString(trailer_speculative_size);
5488*6777b538SAndroid Build Coastguard Worker     scoped_feature_list_.InitAndEnableFeatureWithParameters(
5489*6777b538SAndroid Build Coastguard Worker         disk_cache::kSimpleCachePrefetchExperiment, params);
5490*6777b538SAndroid Build Coastguard Worker   }
5491*6777b538SAndroid Build Coastguard Worker 
SetupFullPrefetch(int size)5492*6777b538SAndroid Build Coastguard Worker   void SetupFullPrefetch(int size) { SetupFullAndTrailerPrefetch(size, 0); }
5493*6777b538SAndroid Build Coastguard Worker 
InitCacheAndCreateEntry(const std::string & key)5494*6777b538SAndroid Build Coastguard Worker   void InitCacheAndCreateEntry(const std::string& key) {
5495*6777b538SAndroid Build Coastguard Worker     SetSimpleCacheMode();
5496*6777b538SAndroid Build Coastguard Worker     SetCacheType(SimpleCacheType());
5497*6777b538SAndroid Build Coastguard Worker     InitCache();
5498*6777b538SAndroid Build Coastguard Worker 
5499*6777b538SAndroid Build Coastguard Worker     disk_cache::Entry* entry;
5500*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
5501*6777b538SAndroid Build Coastguard Worker     // Use stream 1 since that's what new prefetch stuff is about.
5502*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(kEntrySize,
5503*6777b538SAndroid Build Coastguard Worker               WriteData(entry, 1, 0, payload_.get(), kEntrySize, false));
5504*6777b538SAndroid Build Coastguard Worker     entry->Close();
5505*6777b538SAndroid Build Coastguard Worker   }
5506*6777b538SAndroid Build Coastguard Worker 
SimpleCacheType() const5507*6777b538SAndroid Build Coastguard Worker   virtual net::CacheType SimpleCacheType() const { return net::DISK_CACHE; }
5508*6777b538SAndroid Build Coastguard Worker 
InitCacheAndCreateEntryWithNoCrc(const std::string & key)5509*6777b538SAndroid Build Coastguard Worker   void InitCacheAndCreateEntryWithNoCrc(const std::string& key) {
5510*6777b538SAndroid Build Coastguard Worker     const int kHalfSize = kEntrySize / 2;
5511*6777b538SAndroid Build Coastguard Worker     const int kRemSize = kEntrySize - kHalfSize;
5512*6777b538SAndroid Build Coastguard Worker 
5513*6777b538SAndroid Build Coastguard Worker     SetSimpleCacheMode();
5514*6777b538SAndroid Build Coastguard Worker     InitCache();
5515*6777b538SAndroid Build Coastguard Worker 
5516*6777b538SAndroid Build Coastguard Worker     disk_cache::Entry* entry;
5517*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
5518*6777b538SAndroid Build Coastguard Worker     // Use stream 1 since that's what new prefetch stuff is about.
5519*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(kEntrySize,
5520*6777b538SAndroid Build Coastguard Worker               WriteData(entry, 1, 0, payload_.get(), kEntrySize, false));
5521*6777b538SAndroid Build Coastguard Worker 
5522*6777b538SAndroid Build Coastguard Worker     // Overwrite later part of the buffer, since we can't keep track of
5523*6777b538SAndroid Build Coastguard Worker     // the checksum in that case.  Do it with identical contents, though,
5524*6777b538SAndroid Build Coastguard Worker     // so that the only difference between here and InitCacheAndCreateEntry()
5525*6777b538SAndroid Build Coastguard Worker     // would be whether the result has a checkum or not.
5526*6777b538SAndroid Build Coastguard Worker     auto second_half = base::MakeRefCounted<net::IOBufferWithSize>(kRemSize);
5527*6777b538SAndroid Build Coastguard Worker     memcpy(second_half->data(), payload_->data() + kHalfSize, kRemSize);
5528*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(kRemSize, WriteData(entry, 1, kHalfSize, second_half.get(),
5529*6777b538SAndroid Build Coastguard Worker                                   kRemSize, false));
5530*6777b538SAndroid Build Coastguard Worker     entry->Close();
5531*6777b538SAndroid Build Coastguard Worker   }
5532*6777b538SAndroid Build Coastguard Worker 
TryRead(const std::string & key,bool expect_preread_stream1)5533*6777b538SAndroid Build Coastguard Worker   void TryRead(const std::string& key, bool expect_preread_stream1) {
5534*6777b538SAndroid Build Coastguard Worker     disk_cache::Entry* entry = nullptr;
5535*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(OpenEntry(key, &entry), IsOk());
5536*6777b538SAndroid Build Coastguard Worker     auto read_buf = base::MakeRefCounted<net::IOBufferWithSize>(kEntrySize);
5537*6777b538SAndroid Build Coastguard Worker     net::TestCompletionCallback cb;
5538*6777b538SAndroid Build Coastguard Worker     int rv = entry->ReadData(1, 0, read_buf.get(), kEntrySize, cb.callback());
5539*6777b538SAndroid Build Coastguard Worker 
5540*6777b538SAndroid Build Coastguard Worker     // if preload happened, sync reply is expected.
5541*6777b538SAndroid Build Coastguard Worker     if (expect_preread_stream1)
5542*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(kEntrySize, rv);
5543*6777b538SAndroid Build Coastguard Worker     else
5544*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(net::ERR_IO_PENDING, rv);
5545*6777b538SAndroid Build Coastguard Worker     rv = cb.GetResult(rv);
5546*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kEntrySize, rv);
5547*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(read_buf->data(), payload_->data(), kEntrySize));
5548*6777b538SAndroid Build Coastguard Worker     entry->Close();
5549*6777b538SAndroid Build Coastguard Worker   }
5550*6777b538SAndroid Build Coastguard Worker 
5551*6777b538SAndroid Build Coastguard Worker  protected:
5552*6777b538SAndroid Build Coastguard Worker   scoped_refptr<net::IOBuffer> payload_;
5553*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList scoped_feature_list_;
5554*6777b538SAndroid Build Coastguard Worker };
5555*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,NoPrefetch)5556*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, NoPrefetch) {
5557*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5558*6777b538SAndroid Build Coastguard Worker   SetupFullPrefetch(0);
5559*6777b538SAndroid Build Coastguard Worker 
5560*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5561*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5562*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5563*6777b538SAndroid Build Coastguard Worker 
5564*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
5565*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_NONE, 1);
5566*6777b538SAndroid Build Coastguard Worker }
5567*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,YesPrefetch)5568*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, YesPrefetch) {
5569*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5570*6777b538SAndroid Build Coastguard Worker   SetupFullPrefetch(2 * kEntrySize);
5571*6777b538SAndroid Build Coastguard Worker 
5572*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5573*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5574*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ true);
5575*6777b538SAndroid Build Coastguard Worker 
5576*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
5577*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_FULL, 1);
5578*6777b538SAndroid Build Coastguard Worker }
5579*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,YesPrefetchNoRead)5580*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, YesPrefetchNoRead) {
5581*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5582*6777b538SAndroid Build Coastguard Worker   SetupFullPrefetch(2 * kEntrySize);
5583*6777b538SAndroid Build Coastguard Worker 
5584*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5585*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5586*6777b538SAndroid Build Coastguard Worker 
5587*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
5588*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(kKey, &entry), IsOk());
5589*6777b538SAndroid Build Coastguard Worker   entry->Close();
5590*6777b538SAndroid Build Coastguard Worker 
5591*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
5592*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_FULL, 1);
5593*6777b538SAndroid Build Coastguard Worker }
5594*6777b538SAndroid Build Coastguard Worker 
5595*6777b538SAndroid Build Coastguard Worker // This makes sure we detect checksum error on entry that's small enough to be
5596*6777b538SAndroid Build Coastguard Worker // prefetched. This is like DiskCacheEntryTest.BadChecksum, but we make sure
5597*6777b538SAndroid Build Coastguard Worker // to configure prefetch explicitly.
TEST_F(DiskCacheSimplePrefetchTest,BadChecksumSmall)5598*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, BadChecksumSmall) {
5599*6777b538SAndroid Build Coastguard Worker   SetupFullPrefetch(1024);  // bigger than stuff below.
5600*6777b538SAndroid Build Coastguard Worker   SetSimpleCacheMode();
5601*6777b538SAndroid Build Coastguard Worker   InitCache();
5602*6777b538SAndroid Build Coastguard Worker 
5603*6777b538SAndroid Build Coastguard Worker   const char key[] = "the first key";
5604*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, 10));
5605*6777b538SAndroid Build Coastguard Worker 
5606*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
5607*6777b538SAndroid Build Coastguard Worker 
5608*6777b538SAndroid Build Coastguard Worker   // Open the entry. Since we made a small entry, we will detect the CRC
5609*6777b538SAndroid Build Coastguard Worker   // problem at open.
5610*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(OpenEntry(key, &entry), IsError(net::ERR_FAILED));
5611*6777b538SAndroid Build Coastguard Worker }
5612*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,ChecksumNoPrefetch)5613*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, ChecksumNoPrefetch) {
5614*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5615*6777b538SAndroid Build Coastguard Worker 
5616*6777b538SAndroid Build Coastguard Worker   SetupFullPrefetch(0);
5617*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5618*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5619*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5620*6777b538SAndroid Build Coastguard Worker 
5621*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncCheckEOFResult",
5622*6777b538SAndroid Build Coastguard Worker                                       disk_cache::CHECK_EOF_RESULT_SUCCESS, 2);
5623*6777b538SAndroid Build Coastguard Worker }
5624*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,NoChecksumNoPrefetch)5625*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, NoChecksumNoPrefetch) {
5626*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5627*6777b538SAndroid Build Coastguard Worker 
5628*6777b538SAndroid Build Coastguard Worker   SetupFullPrefetch(0);
5629*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5630*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntryWithNoCrc(kKey);
5631*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5632*6777b538SAndroid Build Coastguard Worker 
5633*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncCheckEOFResult",
5634*6777b538SAndroid Build Coastguard Worker                                       disk_cache::CHECK_EOF_RESULT_SUCCESS, 2);
5635*6777b538SAndroid Build Coastguard Worker }
5636*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,ChecksumPrefetch)5637*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, ChecksumPrefetch) {
5638*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5639*6777b538SAndroid Build Coastguard Worker 
5640*6777b538SAndroid Build Coastguard Worker   SetupFullPrefetch(2 * kEntrySize);
5641*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5642*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5643*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ true);
5644*6777b538SAndroid Build Coastguard Worker 
5645*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncCheckEOFResult",
5646*6777b538SAndroid Build Coastguard Worker                                       disk_cache::CHECK_EOF_RESULT_SUCCESS, 2);
5647*6777b538SAndroid Build Coastguard Worker }
5648*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,NoChecksumPrefetch)5649*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, NoChecksumPrefetch) {
5650*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5651*6777b538SAndroid Build Coastguard Worker 
5652*6777b538SAndroid Build Coastguard Worker   SetupFullPrefetch(2 * kEntrySize);
5653*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5654*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntryWithNoCrc(kKey);
5655*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ true);
5656*6777b538SAndroid Build Coastguard Worker 
5657*6777b538SAndroid Build Coastguard Worker   // EOF check is recorded even if there is no CRC there.
5658*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncCheckEOFResult",
5659*6777b538SAndroid Build Coastguard Worker                                       disk_cache::CHECK_EOF_RESULT_SUCCESS, 2);
5660*6777b538SAndroid Build Coastguard Worker }
5661*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,PrefetchReadsSync)5662*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, PrefetchReadsSync) {
5663*6777b538SAndroid Build Coastguard Worker   // Make sure we can read things synchronously after prefetch.
5664*6777b538SAndroid Build Coastguard Worker   SetupFullPrefetch(32768);  // way bigger than kEntrySize
5665*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5666*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5667*6777b538SAndroid Build Coastguard Worker 
5668*6777b538SAndroid Build Coastguard Worker   disk_cache::Entry* entry = nullptr;
5669*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(OpenEntry(kKey, &entry), IsOk());
5670*6777b538SAndroid Build Coastguard Worker   auto read_buf = base::MakeRefCounted<net::IOBufferWithSize>(kEntrySize);
5671*6777b538SAndroid Build Coastguard Worker 
5672*6777b538SAndroid Build Coastguard Worker   // That this is entry->ReadData(...) rather than ReadData(entry, ...) is
5673*6777b538SAndroid Build Coastguard Worker   // meaningful here, as the latter is a helper in the test fixture that blocks
5674*6777b538SAndroid Build Coastguard Worker   // if needed.
5675*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kEntrySize, entry->ReadData(1, 0, read_buf.get(), kEntrySize,
5676*6777b538SAndroid Build Coastguard Worker                                         net::CompletionOnceCallback()));
5677*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(read_buf->data(), payload_->data(), kEntrySize));
5678*6777b538SAndroid Build Coastguard Worker   entry->Close();
5679*6777b538SAndroid Build Coastguard Worker }
5680*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,NoFullNoSpeculative)5681*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, NoFullNoSpeculative) {
5682*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5683*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(0, 0);
5684*6777b538SAndroid Build Coastguard Worker 
5685*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5686*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5687*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5688*6777b538SAndroid Build Coastguard Worker 
5689*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
5690*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_NONE, 1);
5691*6777b538SAndroid Build Coastguard Worker }
5692*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,NoFullSmallSpeculative)5693*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, NoFullSmallSpeculative) {
5694*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5695*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(0, kEntrySize / 2);
5696*6777b538SAndroid Build Coastguard Worker 
5697*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5698*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5699*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5700*6777b538SAndroid Build Coastguard Worker 
5701*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
5702*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_TRAILER, 1);
5703*6777b538SAndroid Build Coastguard Worker }
5704*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,NoFullLargeSpeculative)5705*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, NoFullLargeSpeculative) {
5706*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5707*6777b538SAndroid Build Coastguard Worker   // A large speculative trailer prefetch that exceeds the entry file
5708*6777b538SAndroid Build Coastguard Worker   // size should effectively trigger full prefetch behavior.
5709*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(0, kEntrySize * 2);
5710*6777b538SAndroid Build Coastguard Worker 
5711*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5712*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5713*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ true);
5714*6777b538SAndroid Build Coastguard Worker 
5715*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
5716*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_FULL, 1);
5717*6777b538SAndroid Build Coastguard Worker }
5718*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,SmallFullNoSpeculative)5719*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, SmallFullNoSpeculative) {
5720*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5721*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(kEntrySize / 2, 0);
5722*6777b538SAndroid Build Coastguard Worker 
5723*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5724*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5725*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5726*6777b538SAndroid Build Coastguard Worker 
5727*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
5728*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_NONE, 1);
5729*6777b538SAndroid Build Coastguard Worker }
5730*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,LargeFullNoSpeculative)5731*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, LargeFullNoSpeculative) {
5732*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5733*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(kEntrySize * 2, 0);
5734*6777b538SAndroid Build Coastguard Worker 
5735*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5736*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5737*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ true);
5738*6777b538SAndroid Build Coastguard Worker 
5739*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
5740*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_FULL, 1);
5741*6777b538SAndroid Build Coastguard Worker }
5742*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,SmallFullSmallSpeculative)5743*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, SmallFullSmallSpeculative) {
5744*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5745*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(kEntrySize / 2, kEntrySize / 2);
5746*6777b538SAndroid Build Coastguard Worker 
5747*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5748*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5749*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5750*6777b538SAndroid Build Coastguard Worker 
5751*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
5752*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_TRAILER, 1);
5753*6777b538SAndroid Build Coastguard Worker }
5754*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimplePrefetchTest,LargeFullSmallSpeculative)5755*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimplePrefetchTest, LargeFullSmallSpeculative) {
5756*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5757*6777b538SAndroid Build Coastguard Worker   // Full prefetch takes precedence over a trailer speculative prefetch.
5758*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(kEntrySize * 2, kEntrySize / 2);
5759*6777b538SAndroid Build Coastguard Worker 
5760*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5761*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5762*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ true);
5763*6777b538SAndroid Build Coastguard Worker 
5764*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
5765*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_FULL, 1);
5766*6777b538SAndroid Build Coastguard Worker }
5767*6777b538SAndroid Build Coastguard Worker 
5768*6777b538SAndroid Build Coastguard Worker class DiskCacheSimpleAppCachePrefetchTest : public DiskCacheSimplePrefetchTest {
5769*6777b538SAndroid Build Coastguard Worker  public:
5770*6777b538SAndroid Build Coastguard Worker   // APP_CACHE mode will enable trailer prefetch hint support.
SimpleCacheType() const5771*6777b538SAndroid Build Coastguard Worker   net::CacheType SimpleCacheType() const override { return net::APP_CACHE; }
5772*6777b538SAndroid Build Coastguard Worker };
5773*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimpleAppCachePrefetchTest,NoFullNoSpeculative)5774*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullNoSpeculative) {
5775*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5776*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(0, 0);
5777*6777b538SAndroid Build Coastguard Worker 
5778*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5779*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5780*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5781*6777b538SAndroid Build Coastguard Worker 
5782*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
5783*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_TRAILER, 1);
5784*6777b538SAndroid Build Coastguard Worker }
5785*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimpleAppCachePrefetchTest,NoFullSmallSpeculative)5786*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullSmallSpeculative) {
5787*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5788*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(0, kEntrySize / 2);
5789*6777b538SAndroid Build Coastguard Worker 
5790*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5791*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5792*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5793*6777b538SAndroid Build Coastguard Worker 
5794*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
5795*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_TRAILER, 1);
5796*6777b538SAndroid Build Coastguard Worker }
5797*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimpleAppCachePrefetchTest,NoFullLargeSpeculative)5798*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullLargeSpeculative) {
5799*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5800*6777b538SAndroid Build Coastguard Worker   // Even though the speculative trailer prefetch size is larger than the
5801*6777b538SAndroid Build Coastguard Worker   // file size, the hint should take precedence and still perform a limited
5802*6777b538SAndroid Build Coastguard Worker   // trailer prefetch.
5803*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(0, kEntrySize * 2);
5804*6777b538SAndroid Build Coastguard Worker 
5805*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5806*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5807*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5808*6777b538SAndroid Build Coastguard Worker 
5809*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
5810*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_TRAILER, 1);
5811*6777b538SAndroid Build Coastguard Worker }
5812*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimpleAppCachePrefetchTest,SmallFullNoSpeculative)5813*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimpleAppCachePrefetchTest, SmallFullNoSpeculative) {
5814*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5815*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(kEntrySize / 2, 0);
5816*6777b538SAndroid Build Coastguard Worker 
5817*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5818*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5819*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5820*6777b538SAndroid Build Coastguard Worker 
5821*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
5822*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_TRAILER, 1);
5823*6777b538SAndroid Build Coastguard Worker }
5824*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimpleAppCachePrefetchTest,LargeFullNoSpeculative)5825*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimpleAppCachePrefetchTest, LargeFullNoSpeculative) {
5826*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5827*6777b538SAndroid Build Coastguard Worker   // Full prefetch takes precedence over a trailer hint prefetch.
5828*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(kEntrySize * 2, 0);
5829*6777b538SAndroid Build Coastguard Worker 
5830*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5831*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5832*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ true);
5833*6777b538SAndroid Build Coastguard Worker 
5834*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
5835*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_FULL, 1);
5836*6777b538SAndroid Build Coastguard Worker }
5837*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimpleAppCachePrefetchTest,SmallFullSmallSpeculative)5838*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimpleAppCachePrefetchTest, SmallFullSmallSpeculative) {
5839*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5840*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(kEntrySize / 2, kEntrySize / 2);
5841*6777b538SAndroid Build Coastguard Worker 
5842*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5843*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5844*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ false);
5845*6777b538SAndroid Build Coastguard Worker 
5846*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
5847*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_TRAILER, 1);
5848*6777b538SAndroid Build Coastguard Worker }
5849*6777b538SAndroid Build Coastguard Worker 
TEST_F(DiskCacheSimpleAppCachePrefetchTest,LargeFullSmallSpeculative)5850*6777b538SAndroid Build Coastguard Worker TEST_F(DiskCacheSimpleAppCachePrefetchTest, LargeFullSmallSpeculative) {
5851*6777b538SAndroid Build Coastguard Worker   base::HistogramTester histogram_tester;
5852*6777b538SAndroid Build Coastguard Worker   // Full prefetch takes precedence over a trailer speculative prefetch.
5853*6777b538SAndroid Build Coastguard Worker   SetupFullAndTrailerPrefetch(kEntrySize * 2, kEntrySize / 2);
5854*6777b538SAndroid Build Coastguard Worker 
5855*6777b538SAndroid Build Coastguard Worker   const char kKey[] = "a key";
5856*6777b538SAndroid Build Coastguard Worker   InitCacheAndCreateEntry(kKey);
5857*6777b538SAndroid Build Coastguard Worker   TryRead(kKey, /* expect_preread_stream1 */ true);
5858*6777b538SAndroid Build Coastguard Worker 
5859*6777b538SAndroid Build Coastguard Worker   histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
5860*6777b538SAndroid Build Coastguard Worker                                       disk_cache::OPEN_PREFETCH_FULL, 1);
5861*6777b538SAndroid Build Coastguard Worker }
5862