Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / net / disk_cache / entry_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/bind_helpers.h"
8 #include "base/files/file.h"
9 #include "base/files/file_util.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/threading/platform_thread.h"
13 #include "base/timer/timer.h"
14 #include "net/base/completion_callback.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/disk_cache/blockfile/backend_impl.h"
19 #include "net/disk_cache/blockfile/entry_impl.h"
20 #include "net/disk_cache/disk_cache_test_base.h"
21 #include "net/disk_cache/disk_cache_test_util.h"
22 #include "net/disk_cache/memory/mem_entry_impl.h"
23 #include "net/disk_cache/simple/simple_entry_format.h"
24 #include "net/disk_cache/simple/simple_entry_impl.h"
25 #include "net/disk_cache/simple/simple_synchronous_entry.h"
26 #include "net/disk_cache/simple/simple_test_util.h"
27 #include "net/disk_cache/simple/simple_util.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29
30 using base::Time;
31 using disk_cache::ScopedEntryPtr;
32
33 // Tests that can run with different types of caches.
34 class DiskCacheEntryTest : public DiskCacheTestWithCache {
35  public:
36   void InternalSyncIOBackground(disk_cache::Entry* entry);
37   void ExternalSyncIOBackground(disk_cache::Entry* entry);
38
39  protected:
40   void InternalSyncIO();
41   void InternalAsyncIO();
42   void ExternalSyncIO();
43   void ExternalAsyncIO();
44   void ReleaseBuffer(int stream_index);
45   void StreamAccess();
46   void GetKey();
47   void GetTimes(int stream_index);
48   void GrowData(int stream_index);
49   void TruncateData(int stream_index);
50   void ZeroLengthIO(int stream_index);
51   void Buffering();
52   void SizeAtCreate();
53   void SizeChanges(int stream_index);
54   void ReuseEntry(int size, int stream_index);
55   void InvalidData(int stream_index);
56   void ReadWriteDestroyBuffer(int stream_index);
57   void DoomNormalEntry();
58   void DoomEntryNextToOpenEntry();
59   void DoomedEntry(int stream_index);
60   void BasicSparseIO();
61   void HugeSparseIO();
62   void GetAvailableRange();
63   void CouldBeSparse();
64   void UpdateSparseEntry();
65   void DoomSparseEntry();
66   void PartialSparseEntry();
67   bool SimpleCacheMakeBadChecksumEntry(const std::string& key, int* data_size);
68   bool SimpleCacheThirdStreamFileExists(const char* key);
69   void SyncDoomEntry(const char* key);
70 };
71
72 // This part of the test runs on the background thread.
73 void DiskCacheEntryTest::InternalSyncIOBackground(disk_cache::Entry* entry) {
74   const int kSize1 = 10;
75   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
76   CacheTestFillBuffer(buffer1->data(), kSize1, false);
77   EXPECT_EQ(
78       0,
79       entry->ReadData(0, 0, buffer1.get(), kSize1, net::CompletionCallback()));
80   base::strlcpy(buffer1->data(), "the data", kSize1);
81   EXPECT_EQ(10,
82             entry->WriteData(
83                 0, 0, buffer1.get(), kSize1, net::CompletionCallback(), false));
84   memset(buffer1->data(), 0, kSize1);
85   EXPECT_EQ(
86       10,
87       entry->ReadData(0, 0, buffer1.get(), kSize1, net::CompletionCallback()));
88   EXPECT_STREQ("the data", buffer1->data());
89
90   const int kSize2 = 5000;
91   const int kSize3 = 10000;
92   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
93   scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3));
94   memset(buffer3->data(), 0, kSize3);
95   CacheTestFillBuffer(buffer2->data(), kSize2, false);
96   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
97   EXPECT_EQ(
98       5000,
99       entry->WriteData(
100           1, 1500, buffer2.get(), kSize2, net::CompletionCallback(), false));
101   memset(buffer2->data(), 0, kSize2);
102   EXPECT_EQ(4989,
103             entry->ReadData(
104                 1, 1511, buffer2.get(), kSize2, net::CompletionCallback()));
105   EXPECT_STREQ("big data goes here", buffer2->data());
106   EXPECT_EQ(
107       5000,
108       entry->ReadData(1, 0, buffer2.get(), kSize2, net::CompletionCallback()));
109   EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 1500));
110   EXPECT_EQ(1500,
111             entry->ReadData(
112                 1, 5000, buffer2.get(), kSize2, net::CompletionCallback()));
113
114   EXPECT_EQ(0,
115             entry->ReadData(
116                 1, 6500, buffer2.get(), kSize2, net::CompletionCallback()));
117   EXPECT_EQ(
118       6500,
119       entry->ReadData(1, 0, buffer3.get(), kSize3, net::CompletionCallback()));
120   EXPECT_EQ(8192,
121             entry->WriteData(
122                 1, 0, buffer3.get(), 8192, net::CompletionCallback(), false));
123   EXPECT_EQ(
124       8192,
125       entry->ReadData(1, 0, buffer3.get(), kSize3, net::CompletionCallback()));
126   EXPECT_EQ(8192, entry->GetDataSize(1));
127
128   // We need to delete the memory buffer on this thread.
129   EXPECT_EQ(0, entry->WriteData(
130       0, 0, NULL, 0, net::CompletionCallback(), true));
131   EXPECT_EQ(0, entry->WriteData(
132       1, 0, NULL, 0, net::CompletionCallback(), true));
133 }
134
135 // We need to support synchronous IO even though it is not a supported operation
136 // from the point of view of the disk cache's public interface, because we use
137 // it internally, not just by a few tests, but as part of the implementation
138 // (see sparse_control.cc, for example).
139 void DiskCacheEntryTest::InternalSyncIO() {
140   disk_cache::Entry* entry = NULL;
141   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
142   ASSERT_TRUE(NULL != entry);
143
144   // The bulk of the test runs from within the callback, on the cache thread.
145   RunTaskForTest(base::Bind(&DiskCacheEntryTest::InternalSyncIOBackground,
146                             base::Unretained(this),
147                             entry));
148
149
150   entry->Doom();
151   entry->Close();
152   FlushQueueForTest();
153   EXPECT_EQ(0, cache_->GetEntryCount());
154 }
155
156 TEST_F(DiskCacheEntryTest, InternalSyncIO) {
157   InitCache();
158   InternalSyncIO();
159 }
160
161 TEST_F(DiskCacheEntryTest, MemoryOnlyInternalSyncIO) {
162   SetMemoryOnlyMode();
163   InitCache();
164   InternalSyncIO();
165 }
166
167 void DiskCacheEntryTest::InternalAsyncIO() {
168   disk_cache::Entry* entry = NULL;
169   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
170   ASSERT_TRUE(NULL != entry);
171
172   // Avoid using internal buffers for the test. We have to write something to
173   // the entry and close it so that we flush the internal buffer to disk. After
174   // that, IO operations will be really hitting the disk. We don't care about
175   // the content, so just extending the entry is enough (all extensions zero-
176   // fill any holes).
177   EXPECT_EQ(0, WriteData(entry, 0, 15 * 1024, NULL, 0, false));
178   EXPECT_EQ(0, WriteData(entry, 1, 15 * 1024, NULL, 0, false));
179   entry->Close();
180   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry));
181
182   MessageLoopHelper helper;
183   // Let's verify that each IO goes to the right callback object.
184   CallbackTest callback1(&helper, false);
185   CallbackTest callback2(&helper, false);
186   CallbackTest callback3(&helper, false);
187   CallbackTest callback4(&helper, false);
188   CallbackTest callback5(&helper, false);
189   CallbackTest callback6(&helper, false);
190   CallbackTest callback7(&helper, false);
191   CallbackTest callback8(&helper, false);
192   CallbackTest callback9(&helper, false);
193   CallbackTest callback10(&helper, false);
194   CallbackTest callback11(&helper, false);
195   CallbackTest callback12(&helper, false);
196   CallbackTest callback13(&helper, false);
197
198   const int kSize1 = 10;
199   const int kSize2 = 5000;
200   const int kSize3 = 10000;
201   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
202   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
203   scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3));
204   CacheTestFillBuffer(buffer1->data(), kSize1, false);
205   CacheTestFillBuffer(buffer2->data(), kSize2, false);
206   CacheTestFillBuffer(buffer3->data(), kSize3, false);
207
208   EXPECT_EQ(0,
209             entry->ReadData(
210                 0,
211                 15 * 1024,
212                 buffer1.get(),
213                 kSize1,
214                 base::Bind(&CallbackTest::Run, base::Unretained(&callback1))));
215   base::strlcpy(buffer1->data(), "the data", kSize1);
216   int expected = 0;
217   int ret = entry->WriteData(
218       0,
219       0,
220       buffer1.get(),
221       kSize1,
222       base::Bind(&CallbackTest::Run, base::Unretained(&callback2)),
223       false);
224   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
225   if (net::ERR_IO_PENDING == ret)
226     expected++;
227
228   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
229   memset(buffer2->data(), 0, kSize2);
230   ret = entry->ReadData(
231       0,
232       0,
233       buffer2.get(),
234       kSize1,
235       base::Bind(&CallbackTest::Run, base::Unretained(&callback3)));
236   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
237   if (net::ERR_IO_PENDING == ret)
238     expected++;
239
240   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
241   EXPECT_STREQ("the data", buffer2->data());
242
243   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
244   ret = entry->WriteData(
245       1,
246       1500,
247       buffer2.get(),
248       kSize2,
249       base::Bind(&CallbackTest::Run, base::Unretained(&callback4)),
250       true);
251   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
252   if (net::ERR_IO_PENDING == ret)
253     expected++;
254
255   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
256   memset(buffer3->data(), 0, kSize3);
257   ret = entry->ReadData(
258       1,
259       1511,
260       buffer3.get(),
261       kSize2,
262       base::Bind(&CallbackTest::Run, base::Unretained(&callback5)));
263   EXPECT_TRUE(4989 == ret || net::ERR_IO_PENDING == ret);
264   if (net::ERR_IO_PENDING == ret)
265     expected++;
266
267   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
268   EXPECT_STREQ("big data goes here", buffer3->data());
269   ret = entry->ReadData(
270       1,
271       0,
272       buffer2.get(),
273       kSize2,
274       base::Bind(&CallbackTest::Run, base::Unretained(&callback6)));
275   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
276   if (net::ERR_IO_PENDING == ret)
277     expected++;
278
279   memset(buffer3->data(), 0, kSize3);
280
281   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
282   EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 1500));
283   ret = entry->ReadData(
284       1,
285       5000,
286       buffer2.get(),
287       kSize2,
288       base::Bind(&CallbackTest::Run, base::Unretained(&callback7)));
289   EXPECT_TRUE(1500 == ret || net::ERR_IO_PENDING == ret);
290   if (net::ERR_IO_PENDING == ret)
291     expected++;
292
293   ret = entry->ReadData(
294       1,
295       0,
296       buffer3.get(),
297       kSize3,
298       base::Bind(&CallbackTest::Run, base::Unretained(&callback9)));
299   EXPECT_TRUE(6500 == ret || net::ERR_IO_PENDING == ret);
300   if (net::ERR_IO_PENDING == ret)
301     expected++;
302
303   ret = entry->WriteData(
304       1,
305       0,
306       buffer3.get(),
307       8192,
308       base::Bind(&CallbackTest::Run, base::Unretained(&callback10)),
309       true);
310   EXPECT_TRUE(8192 == ret || net::ERR_IO_PENDING == ret);
311   if (net::ERR_IO_PENDING == ret)
312     expected++;
313
314   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
315   ret = entry->ReadData(
316       1,
317       0,
318       buffer3.get(),
319       kSize3,
320       base::Bind(&CallbackTest::Run, base::Unretained(&callback11)));
321   EXPECT_TRUE(8192 == ret || net::ERR_IO_PENDING == ret);
322   if (net::ERR_IO_PENDING == ret)
323     expected++;
324
325   EXPECT_EQ(8192, entry->GetDataSize(1));
326
327   ret = entry->ReadData(
328       0,
329       0,
330       buffer1.get(),
331       kSize1,
332       base::Bind(&CallbackTest::Run, base::Unretained(&callback12)));
333   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
334   if (net::ERR_IO_PENDING == ret)
335     expected++;
336
337   ret = entry->ReadData(
338       1,
339       0,
340       buffer2.get(),
341       kSize2,
342       base::Bind(&CallbackTest::Run, base::Unretained(&callback13)));
343   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
344   if (net::ERR_IO_PENDING == ret)
345     expected++;
346
347   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
348
349   EXPECT_FALSE(helper.callback_reused_error());
350
351   entry->Doom();
352   entry->Close();
353   FlushQueueForTest();
354   EXPECT_EQ(0, cache_->GetEntryCount());
355 }
356
357 TEST_F(DiskCacheEntryTest, InternalAsyncIO) {
358   InitCache();
359   InternalAsyncIO();
360 }
361
362 TEST_F(DiskCacheEntryTest, MemoryOnlyInternalAsyncIO) {
363   SetMemoryOnlyMode();
364   InitCache();
365   InternalAsyncIO();
366 }
367
368 // This part of the test runs on the background thread.
369 void DiskCacheEntryTest::ExternalSyncIOBackground(disk_cache::Entry* entry) {
370   const int kSize1 = 17000;
371   const int kSize2 = 25000;
372   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
373   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
374   CacheTestFillBuffer(buffer1->data(), kSize1, false);
375   CacheTestFillBuffer(buffer2->data(), kSize2, false);
376   base::strlcpy(buffer1->data(), "the data", kSize1);
377   EXPECT_EQ(17000,
378             entry->WriteData(
379                 0, 0, buffer1.get(), kSize1, net::CompletionCallback(), false));
380   memset(buffer1->data(), 0, kSize1);
381   EXPECT_EQ(
382       17000,
383       entry->ReadData(0, 0, buffer1.get(), kSize1, net::CompletionCallback()));
384   EXPECT_STREQ("the data", buffer1->data());
385
386   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
387   EXPECT_EQ(
388       25000,
389       entry->WriteData(
390           1, 10000, buffer2.get(), kSize2, net::CompletionCallback(), false));
391   memset(buffer2->data(), 0, kSize2);
392   EXPECT_EQ(24989,
393             entry->ReadData(
394                 1, 10011, buffer2.get(), kSize2, net::CompletionCallback()));
395   EXPECT_STREQ("big data goes here", buffer2->data());
396   EXPECT_EQ(
397       25000,
398       entry->ReadData(1, 0, buffer2.get(), kSize2, net::CompletionCallback()));
399   EXPECT_EQ(5000,
400             entry->ReadData(
401                 1, 30000, buffer2.get(), kSize2, net::CompletionCallback()));
402
403   EXPECT_EQ(0,
404             entry->ReadData(
405                 1, 35000, buffer2.get(), kSize2, net::CompletionCallback()));
406   EXPECT_EQ(
407       17000,
408       entry->ReadData(1, 0, buffer1.get(), kSize1, net::CompletionCallback()));
409   EXPECT_EQ(
410       17000,
411       entry->WriteData(
412           1, 20000, buffer1.get(), kSize1, net::CompletionCallback(), false));
413   EXPECT_EQ(37000, entry->GetDataSize(1));
414
415   // We need to delete the memory buffer on this thread.
416   EXPECT_EQ(0, entry->WriteData(
417       0, 0, NULL, 0, net::CompletionCallback(), true));
418   EXPECT_EQ(0, entry->WriteData(
419       1, 0, NULL, 0, net::CompletionCallback(), true));
420 }
421
422 void DiskCacheEntryTest::ExternalSyncIO() {
423   disk_cache::Entry* entry;
424   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
425
426   // The bulk of the test runs from within the callback, on the cache thread.
427   RunTaskForTest(base::Bind(&DiskCacheEntryTest::ExternalSyncIOBackground,
428                             base::Unretained(this),
429                             entry));
430
431   entry->Doom();
432   entry->Close();
433   FlushQueueForTest();
434   EXPECT_EQ(0, cache_->GetEntryCount());
435 }
436
437 TEST_F(DiskCacheEntryTest, ExternalSyncIO) {
438   InitCache();
439   ExternalSyncIO();
440 }
441
442 TEST_F(DiskCacheEntryTest, ExternalSyncIONoBuffer) {
443   InitCache();
444   cache_impl_->SetFlags(disk_cache::kNoBuffering);
445   ExternalSyncIO();
446 }
447
448 TEST_F(DiskCacheEntryTest, MemoryOnlyExternalSyncIO) {
449   SetMemoryOnlyMode();
450   InitCache();
451   ExternalSyncIO();
452 }
453
454 void DiskCacheEntryTest::ExternalAsyncIO() {
455   disk_cache::Entry* entry;
456   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
457
458   int expected = 0;
459
460   MessageLoopHelper helper;
461   // Let's verify that each IO goes to the right callback object.
462   CallbackTest callback1(&helper, false);
463   CallbackTest callback2(&helper, false);
464   CallbackTest callback3(&helper, false);
465   CallbackTest callback4(&helper, false);
466   CallbackTest callback5(&helper, false);
467   CallbackTest callback6(&helper, false);
468   CallbackTest callback7(&helper, false);
469   CallbackTest callback8(&helper, false);
470   CallbackTest callback9(&helper, false);
471
472   const int kSize1 = 17000;
473   const int kSize2 = 25000;
474   const int kSize3 = 25000;
475   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
476   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
477   scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3));
478   CacheTestFillBuffer(buffer1->data(), kSize1, false);
479   CacheTestFillBuffer(buffer2->data(), kSize2, false);
480   CacheTestFillBuffer(buffer3->data(), kSize3, false);
481   base::strlcpy(buffer1->data(), "the data", kSize1);
482   int ret = entry->WriteData(
483       0,
484       0,
485       buffer1.get(),
486       kSize1,
487       base::Bind(&CallbackTest::Run, base::Unretained(&callback1)),
488       false);
489   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
490   if (net::ERR_IO_PENDING == ret)
491     expected++;
492
493   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
494
495   memset(buffer2->data(), 0, kSize1);
496   ret = entry->ReadData(
497       0,
498       0,
499       buffer2.get(),
500       kSize1,
501       base::Bind(&CallbackTest::Run, base::Unretained(&callback2)));
502   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
503   if (net::ERR_IO_PENDING == ret)
504     expected++;
505
506   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
507   EXPECT_STREQ("the data", buffer2->data());
508
509   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
510   ret = entry->WriteData(
511       1,
512       10000,
513       buffer2.get(),
514       kSize2,
515       base::Bind(&CallbackTest::Run, base::Unretained(&callback3)),
516       false);
517   EXPECT_TRUE(25000 == ret || net::ERR_IO_PENDING == ret);
518   if (net::ERR_IO_PENDING == ret)
519     expected++;
520
521   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
522
523   memset(buffer3->data(), 0, kSize3);
524   ret = entry->ReadData(
525       1,
526       10011,
527       buffer3.get(),
528       kSize3,
529       base::Bind(&CallbackTest::Run, base::Unretained(&callback4)));
530   EXPECT_TRUE(24989 == ret || net::ERR_IO_PENDING == ret);
531   if (net::ERR_IO_PENDING == ret)
532     expected++;
533
534   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
535   EXPECT_STREQ("big data goes here", buffer3->data());
536   ret = entry->ReadData(
537       1,
538       0,
539       buffer2.get(),
540       kSize2,
541       base::Bind(&CallbackTest::Run, base::Unretained(&callback5)));
542   EXPECT_TRUE(25000 == ret || net::ERR_IO_PENDING == ret);
543   if (net::ERR_IO_PENDING == ret)
544     expected++;
545
546   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
547   memset(buffer3->data(), 0, kSize3);
548   EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 10000));
549   ret = entry->ReadData(
550       1,
551       30000,
552       buffer2.get(),
553       kSize2,
554       base::Bind(&CallbackTest::Run, base::Unretained(&callback6)));
555   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
556   if (net::ERR_IO_PENDING == ret)
557     expected++;
558
559   EXPECT_EQ(0,
560             entry->ReadData(
561                 1,
562                 35000,
563                 buffer2.get(),
564                 kSize2,
565                 base::Bind(&CallbackTest::Run, base::Unretained(&callback7))));
566   ret = entry->ReadData(
567       1,
568       0,
569       buffer1.get(),
570       kSize1,
571       base::Bind(&CallbackTest::Run, base::Unretained(&callback8)));
572   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
573   if (net::ERR_IO_PENDING == ret)
574     expected++;
575   ret = entry->WriteData(
576       1,
577       20000,
578       buffer3.get(),
579       kSize1,
580       base::Bind(&CallbackTest::Run, base::Unretained(&callback9)),
581       false);
582   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
583   if (net::ERR_IO_PENDING == ret)
584     expected++;
585
586   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
587   EXPECT_EQ(37000, entry->GetDataSize(1));
588
589   EXPECT_FALSE(helper.callback_reused_error());
590
591   entry->Doom();
592   entry->Close();
593   FlushQueueForTest();
594   EXPECT_EQ(0, cache_->GetEntryCount());
595 }
596
597 TEST_F(DiskCacheEntryTest, ExternalAsyncIO) {
598   InitCache();
599   ExternalAsyncIO();
600 }
601
602 TEST_F(DiskCacheEntryTest, ExternalAsyncIONoBuffer) {
603   InitCache();
604   cache_impl_->SetFlags(disk_cache::kNoBuffering);
605   ExternalAsyncIO();
606 }
607
608 TEST_F(DiskCacheEntryTest, MemoryOnlyExternalAsyncIO) {
609   SetMemoryOnlyMode();
610   InitCache();
611   ExternalAsyncIO();
612 }
613
614 // Tests that IOBuffers are not referenced after IO completes.
615 void DiskCacheEntryTest::ReleaseBuffer(int stream_index) {
616   disk_cache::Entry* entry = NULL;
617   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
618   ASSERT_TRUE(NULL != entry);
619
620   const int kBufferSize = 1024;
621   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
622   CacheTestFillBuffer(buffer->data(), kBufferSize, false);
623
624   net::ReleaseBufferCompletionCallback cb(buffer.get());
625   int rv = entry->WriteData(
626       stream_index, 0, buffer.get(), kBufferSize, cb.callback(), false);
627   EXPECT_EQ(kBufferSize, cb.GetResult(rv));
628   entry->Close();
629 }
630
631 TEST_F(DiskCacheEntryTest, ReleaseBuffer) {
632   InitCache();
633   cache_impl_->SetFlags(disk_cache::kNoBuffering);
634   ReleaseBuffer(0);
635 }
636
637 TEST_F(DiskCacheEntryTest, MemoryOnlyReleaseBuffer) {
638   SetMemoryOnlyMode();
639   InitCache();
640   ReleaseBuffer(0);
641 }
642
643 void DiskCacheEntryTest::StreamAccess() {
644   disk_cache::Entry* entry = NULL;
645   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
646   ASSERT_TRUE(NULL != entry);
647
648   const int kBufferSize = 1024;
649   const int kNumStreams = 3;
650   scoped_refptr<net::IOBuffer> reference_buffers[kNumStreams];
651   for (int i = 0; i < kNumStreams; i++) {
652     reference_buffers[i] = new net::IOBuffer(kBufferSize);
653     CacheTestFillBuffer(reference_buffers[i]->data(), kBufferSize, false);
654   }
655   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kBufferSize));
656   for (int i = 0; i < kNumStreams; i++) {
657     EXPECT_EQ(
658         kBufferSize,
659         WriteData(entry, i, 0, reference_buffers[i].get(), kBufferSize, false));
660     memset(buffer1->data(), 0, kBufferSize);
661     EXPECT_EQ(kBufferSize, ReadData(entry, i, 0, buffer1.get(), kBufferSize));
662     EXPECT_EQ(
663         0, memcmp(reference_buffers[i]->data(), buffer1->data(), kBufferSize));
664   }
665   EXPECT_EQ(net::ERR_INVALID_ARGUMENT,
666             ReadData(entry, kNumStreams, 0, buffer1.get(), kBufferSize));
667   entry->Close();
668
669   // Open the entry and read it in chunks, including a read past the end.
670   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry));
671   ASSERT_TRUE(NULL != entry);
672   const int kReadBufferSize = 600;
673   const int kFinalReadSize = kBufferSize - kReadBufferSize;
674   COMPILE_ASSERT(kFinalReadSize < kReadBufferSize, should_be_exactly_two_reads);
675   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kReadBufferSize));
676   for (int i = 0; i < kNumStreams; i++) {
677     memset(buffer2->data(), 0, kReadBufferSize);
678     EXPECT_EQ(kReadBufferSize,
679               ReadData(entry, i, 0, buffer2.get(), kReadBufferSize));
680     EXPECT_EQ(
681         0,
682         memcmp(reference_buffers[i]->data(), buffer2->data(), kReadBufferSize));
683
684     memset(buffer2->data(), 0, kReadBufferSize);
685     EXPECT_EQ(
686         kFinalReadSize,
687         ReadData(entry, i, kReadBufferSize, buffer2.get(), kReadBufferSize));
688     EXPECT_EQ(0,
689               memcmp(reference_buffers[i]->data() + kReadBufferSize,
690                      buffer2->data(),
691                      kFinalReadSize));
692   }
693
694   entry->Close();
695 }
696
697 TEST_F(DiskCacheEntryTest, StreamAccess) {
698   InitCache();
699   StreamAccess();
700 }
701
702 TEST_F(DiskCacheEntryTest, MemoryOnlyStreamAccess) {
703   SetMemoryOnlyMode();
704   InitCache();
705   StreamAccess();
706 }
707
708 void DiskCacheEntryTest::GetKey() {
709   std::string key("the first key");
710   disk_cache::Entry* entry;
711   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
712   EXPECT_EQ(key, entry->GetKey()) << "short key";
713   entry->Close();
714
715   int seed = static_cast<int>(Time::Now().ToInternalValue());
716   srand(seed);
717   char key_buffer[20000];
718
719   CacheTestFillBuffer(key_buffer, 3000, true);
720   key_buffer[1000] = '\0';
721
722   key = key_buffer;
723   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
724   EXPECT_TRUE(key == entry->GetKey()) << "1000 bytes key";
725   entry->Close();
726
727   key_buffer[1000] = 'p';
728   key_buffer[3000] = '\0';
729   key = key_buffer;
730   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
731   EXPECT_TRUE(key == entry->GetKey()) << "medium size key";
732   entry->Close();
733
734   CacheTestFillBuffer(key_buffer, sizeof(key_buffer), true);
735   key_buffer[19999] = '\0';
736
737   key = key_buffer;
738   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
739   EXPECT_TRUE(key == entry->GetKey()) << "long key";
740   entry->Close();
741
742   CacheTestFillBuffer(key_buffer, 0x4000, true);
743   key_buffer[0x4000] = '\0';
744
745   key = key_buffer;
746   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
747   EXPECT_TRUE(key == entry->GetKey()) << "16KB key";
748   entry->Close();
749 }
750
751 TEST_F(DiskCacheEntryTest, GetKey) {
752   InitCache();
753   GetKey();
754 }
755
756 TEST_F(DiskCacheEntryTest, MemoryOnlyGetKey) {
757   SetMemoryOnlyMode();
758   InitCache();
759   GetKey();
760 }
761
762 void DiskCacheEntryTest::GetTimes(int stream_index) {
763   std::string key("the first key");
764   disk_cache::Entry* entry;
765
766   Time t1 = Time::Now();
767   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
768   EXPECT_TRUE(entry->GetLastModified() >= t1);
769   EXPECT_TRUE(entry->GetLastModified() == entry->GetLastUsed());
770
771   AddDelay();
772   Time t2 = Time::Now();
773   EXPECT_TRUE(t2 > t1);
774   EXPECT_EQ(0, WriteData(entry, stream_index, 200, NULL, 0, false));
775   if (type_ == net::APP_CACHE) {
776     EXPECT_TRUE(entry->GetLastModified() < t2);
777   } else {
778     EXPECT_TRUE(entry->GetLastModified() >= t2);
779   }
780   EXPECT_TRUE(entry->GetLastModified() == entry->GetLastUsed());
781
782   AddDelay();
783   Time t3 = Time::Now();
784   EXPECT_TRUE(t3 > t2);
785   const int kSize = 200;
786   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
787   EXPECT_EQ(kSize, ReadData(entry, stream_index, 0, buffer.get(), kSize));
788   if (type_ == net::APP_CACHE) {
789     EXPECT_TRUE(entry->GetLastUsed() < t2);
790     EXPECT_TRUE(entry->GetLastModified() < t2);
791   } else if (type_ == net::SHADER_CACHE) {
792     EXPECT_TRUE(entry->GetLastUsed() < t3);
793     EXPECT_TRUE(entry->GetLastModified() < t3);
794   } else {
795     EXPECT_TRUE(entry->GetLastUsed() >= t3);
796     EXPECT_TRUE(entry->GetLastModified() < t3);
797   }
798   entry->Close();
799 }
800
801 TEST_F(DiskCacheEntryTest, GetTimes) {
802   InitCache();
803   GetTimes(0);
804 }
805
806 TEST_F(DiskCacheEntryTest, MemoryOnlyGetTimes) {
807   SetMemoryOnlyMode();
808   InitCache();
809   GetTimes(0);
810 }
811
812 TEST_F(DiskCacheEntryTest, AppCacheGetTimes) {
813   SetCacheType(net::APP_CACHE);
814   InitCache();
815   GetTimes(0);
816 }
817
818 TEST_F(DiskCacheEntryTest, ShaderCacheGetTimes) {
819   SetCacheType(net::SHADER_CACHE);
820   InitCache();
821   GetTimes(0);
822 }
823
824 void DiskCacheEntryTest::GrowData(int stream_index) {
825   std::string key1("the first key");
826   disk_cache::Entry* entry;
827   ASSERT_EQ(net::OK, CreateEntry(key1, &entry));
828
829   const int kSize = 20000;
830   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
831   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
832   CacheTestFillBuffer(buffer1->data(), kSize, false);
833   memset(buffer2->data(), 0, kSize);
834
835   base::strlcpy(buffer1->data(), "the data", kSize);
836   EXPECT_EQ(10, WriteData(entry, stream_index, 0, buffer1.get(), 10, false));
837   EXPECT_EQ(10, ReadData(entry, stream_index, 0, buffer2.get(), 10));
838   EXPECT_STREQ("the data", buffer2->data());
839   EXPECT_EQ(10, entry->GetDataSize(stream_index));
840
841   EXPECT_EQ(2000,
842             WriteData(entry, stream_index, 0, buffer1.get(), 2000, false));
843   EXPECT_EQ(2000, entry->GetDataSize(stream_index));
844   EXPECT_EQ(2000, ReadData(entry, stream_index, 0, buffer2.get(), 2000));
845   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 2000));
846
847   EXPECT_EQ(20000,
848             WriteData(entry, stream_index, 0, buffer1.get(), kSize, false));
849   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
850   EXPECT_EQ(20000, ReadData(entry, stream_index, 0, buffer2.get(), kSize));
851   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), kSize));
852   entry->Close();
853
854   memset(buffer2->data(), 0, kSize);
855   std::string key2("Second key");
856   ASSERT_EQ(net::OK, CreateEntry(key2, &entry));
857   EXPECT_EQ(10, WriteData(entry, stream_index, 0, buffer1.get(), 10, false));
858   EXPECT_EQ(10, entry->GetDataSize(stream_index));
859   entry->Close();
860
861   // Go from an internal address to a bigger block size.
862   ASSERT_EQ(net::OK, OpenEntry(key2, &entry));
863   EXPECT_EQ(2000,
864             WriteData(entry, stream_index, 0, buffer1.get(), 2000, false));
865   EXPECT_EQ(2000, entry->GetDataSize(stream_index));
866   EXPECT_EQ(2000, ReadData(entry, stream_index, 0, buffer2.get(), 2000));
867   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 2000));
868   entry->Close();
869   memset(buffer2->data(), 0, kSize);
870
871   // Go from an internal address to an external one.
872   ASSERT_EQ(net::OK, OpenEntry(key2, &entry));
873   EXPECT_EQ(20000,
874             WriteData(entry, stream_index, 0, buffer1.get(), kSize, false));
875   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
876   EXPECT_EQ(20000, ReadData(entry, stream_index, 0, buffer2.get(), kSize));
877   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), kSize));
878   entry->Close();
879
880   // Double check the size from disk.
881   ASSERT_EQ(net::OK, OpenEntry(key2, &entry));
882   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
883
884   // Now extend the entry without actual data.
885   EXPECT_EQ(0, WriteData(entry, stream_index, 45500, buffer1.get(), 0, false));
886   entry->Close();
887
888   // And check again from disk.
889   ASSERT_EQ(net::OK, OpenEntry(key2, &entry));
890   EXPECT_EQ(45500, entry->GetDataSize(stream_index));
891   entry->Close();
892 }
893
894 TEST_F(DiskCacheEntryTest, GrowData) {
895   InitCache();
896   GrowData(0);
897 }
898
899 TEST_F(DiskCacheEntryTest, GrowDataNoBuffer) {
900   InitCache();
901   cache_impl_->SetFlags(disk_cache::kNoBuffering);
902   GrowData(0);
903 }
904
905 TEST_F(DiskCacheEntryTest, MemoryOnlyGrowData) {
906   SetMemoryOnlyMode();
907   InitCache();
908   GrowData(0);
909 }
910
911 void DiskCacheEntryTest::TruncateData(int stream_index) {
912   std::string key("the first key");
913   disk_cache::Entry* entry;
914   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
915
916   const int kSize1 = 20000;
917   const int kSize2 = 20000;
918   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
919   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
920
921   CacheTestFillBuffer(buffer1->data(), kSize1, false);
922   memset(buffer2->data(), 0, kSize2);
923
924   // Simple truncation:
925   EXPECT_EQ(200, WriteData(entry, stream_index, 0, buffer1.get(), 200, false));
926   EXPECT_EQ(200, entry->GetDataSize(stream_index));
927   EXPECT_EQ(100, WriteData(entry, stream_index, 0, buffer1.get(), 100, false));
928   EXPECT_EQ(200, entry->GetDataSize(stream_index));
929   EXPECT_EQ(100, WriteData(entry, stream_index, 0, buffer1.get(), 100, true));
930   EXPECT_EQ(100, entry->GetDataSize(stream_index));
931   EXPECT_EQ(0, WriteData(entry, stream_index, 50, buffer1.get(), 0, true));
932   EXPECT_EQ(50, entry->GetDataSize(stream_index));
933   EXPECT_EQ(0, WriteData(entry, stream_index, 0, buffer1.get(), 0, true));
934   EXPECT_EQ(0, entry->GetDataSize(stream_index));
935   entry->Close();
936   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
937
938   // Go to an external file.
939   EXPECT_EQ(20000,
940             WriteData(entry, stream_index, 0, buffer1.get(), 20000, true));
941   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
942   EXPECT_EQ(20000, ReadData(entry, stream_index, 0, buffer2.get(), 20000));
943   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 20000));
944   memset(buffer2->data(), 0, kSize2);
945
946   // External file truncation
947   EXPECT_EQ(18000,
948             WriteData(entry, stream_index, 0, buffer1.get(), 18000, false));
949   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
950   EXPECT_EQ(18000,
951             WriteData(entry, stream_index, 0, buffer1.get(), 18000, true));
952   EXPECT_EQ(18000, entry->GetDataSize(stream_index));
953   EXPECT_EQ(0, WriteData(entry, stream_index, 17500, buffer1.get(), 0, true));
954   EXPECT_EQ(17500, entry->GetDataSize(stream_index));
955
956   // And back to an internal block.
957   EXPECT_EQ(600,
958             WriteData(entry, stream_index, 1000, buffer1.get(), 600, true));
959   EXPECT_EQ(1600, entry->GetDataSize(stream_index));
960   EXPECT_EQ(600, ReadData(entry, stream_index, 1000, buffer2.get(), 600));
961   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 600));
962   EXPECT_EQ(1000, ReadData(entry, stream_index, 0, buffer2.get(), 1000));
963   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 1000))
964       << "Preserves previous data";
965
966   // Go from external file to zero length.
967   EXPECT_EQ(20000,
968             WriteData(entry, stream_index, 0, buffer1.get(), 20000, true));
969   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
970   EXPECT_EQ(0, WriteData(entry, stream_index, 0, buffer1.get(), 0, true));
971   EXPECT_EQ(0, entry->GetDataSize(stream_index));
972
973   entry->Close();
974 }
975
976 TEST_F(DiskCacheEntryTest, TruncateData) {
977   InitCache();
978   TruncateData(0);
979 }
980
981 TEST_F(DiskCacheEntryTest, TruncateDataNoBuffer) {
982   InitCache();
983   cache_impl_->SetFlags(disk_cache::kNoBuffering);
984   TruncateData(0);
985 }
986
987 TEST_F(DiskCacheEntryTest, MemoryOnlyTruncateData) {
988   SetMemoryOnlyMode();
989   InitCache();
990   TruncateData(0);
991 }
992
993 void DiskCacheEntryTest::ZeroLengthIO(int stream_index) {
994   std::string key("the first key");
995   disk_cache::Entry* entry;
996   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
997
998   EXPECT_EQ(0, ReadData(entry, stream_index, 0, NULL, 0));
999   EXPECT_EQ(0, WriteData(entry, stream_index, 0, NULL, 0, false));
1000
1001   // This write should extend the entry.
1002   EXPECT_EQ(0, WriteData(entry, stream_index, 1000, NULL, 0, false));
1003   EXPECT_EQ(0, ReadData(entry, stream_index, 500, NULL, 0));
1004   EXPECT_EQ(0, ReadData(entry, stream_index, 2000, NULL, 0));
1005   EXPECT_EQ(1000, entry->GetDataSize(stream_index));
1006
1007   EXPECT_EQ(0, WriteData(entry, stream_index, 100000, NULL, 0, true));
1008   EXPECT_EQ(0, ReadData(entry, stream_index, 50000, NULL, 0));
1009   EXPECT_EQ(100000, entry->GetDataSize(stream_index));
1010
1011   // Let's verify the actual content.
1012   const int kSize = 20;
1013   const char zeros[kSize] = {};
1014   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
1015
1016   CacheTestFillBuffer(buffer->data(), kSize, false);
1017   EXPECT_EQ(kSize, ReadData(entry, stream_index, 500, buffer.get(), kSize));
1018   EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize));
1019
1020   CacheTestFillBuffer(buffer->data(), kSize, false);
1021   EXPECT_EQ(kSize, ReadData(entry, stream_index, 5000, buffer.get(), kSize));
1022   EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize));
1023
1024   CacheTestFillBuffer(buffer->data(), kSize, false);
1025   EXPECT_EQ(kSize, ReadData(entry, stream_index, 50000, buffer.get(), kSize));
1026   EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize));
1027
1028   entry->Close();
1029 }
1030
1031 TEST_F(DiskCacheEntryTest, ZeroLengthIO) {
1032   InitCache();
1033   ZeroLengthIO(0);
1034 }
1035
1036 TEST_F(DiskCacheEntryTest, ZeroLengthIONoBuffer) {
1037   InitCache();
1038   cache_impl_->SetFlags(disk_cache::kNoBuffering);
1039   ZeroLengthIO(0);
1040 }
1041
1042 TEST_F(DiskCacheEntryTest, MemoryOnlyZeroLengthIO) {
1043   SetMemoryOnlyMode();
1044   InitCache();
1045   ZeroLengthIO(0);
1046 }
1047
1048 // Tests that we handle the content correctly when buffering, a feature of the
1049 // standard cache that permits fast responses to certain reads.
1050 void DiskCacheEntryTest::Buffering() {
1051   std::string key("the first key");
1052   disk_cache::Entry* entry;
1053   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1054
1055   const int kSize = 200;
1056   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
1057   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
1058   CacheTestFillBuffer(buffer1->data(), kSize, true);
1059   CacheTestFillBuffer(buffer2->data(), kSize, true);
1060
1061   EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer1.get(), kSize, false));
1062   entry->Close();
1063
1064   // Write a little more and read what we wrote before.
1065   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1066   EXPECT_EQ(kSize, WriteData(entry, 1, 5000, buffer1.get(), kSize, false));
1067   EXPECT_EQ(kSize, ReadData(entry, 1, 0, buffer2.get(), kSize));
1068   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1069
1070   // Now go to an external file.
1071   EXPECT_EQ(kSize, WriteData(entry, 1, 18000, buffer1.get(), kSize, false));
1072   entry->Close();
1073
1074   // Write something else and verify old data.
1075   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1076   EXPECT_EQ(kSize, WriteData(entry, 1, 10000, buffer1.get(), kSize, false));
1077   CacheTestFillBuffer(buffer2->data(), kSize, true);
1078   EXPECT_EQ(kSize, ReadData(entry, 1, 5000, buffer2.get(), kSize));
1079   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1080   CacheTestFillBuffer(buffer2->data(), kSize, true);
1081   EXPECT_EQ(kSize, ReadData(entry, 1, 0, buffer2.get(), kSize));
1082   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1083   CacheTestFillBuffer(buffer2->data(), kSize, true);
1084   EXPECT_EQ(kSize, ReadData(entry, 1, 18000, buffer2.get(), kSize));
1085   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1086
1087   // Extend the file some more.
1088   EXPECT_EQ(kSize, WriteData(entry, 1, 23000, buffer1.get(), kSize, false));
1089   entry->Close();
1090
1091   // And now make sure that we can deal with data in both places (ram/disk).
1092   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1093   EXPECT_EQ(kSize, WriteData(entry, 1, 17000, buffer1.get(), kSize, false));
1094
1095   // We should not overwrite the data at 18000 with this.
1096   EXPECT_EQ(kSize, WriteData(entry, 1, 19000, buffer1.get(), kSize, false));
1097   CacheTestFillBuffer(buffer2->data(), kSize, true);
1098   EXPECT_EQ(kSize, ReadData(entry, 1, 18000, buffer2.get(), kSize));
1099   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1100   CacheTestFillBuffer(buffer2->data(), kSize, true);
1101   EXPECT_EQ(kSize, ReadData(entry, 1, 17000, buffer2.get(), kSize));
1102   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1103
1104   EXPECT_EQ(kSize, WriteData(entry, 1, 22900, buffer1.get(), kSize, false));
1105   CacheTestFillBuffer(buffer2->data(), kSize, true);
1106   EXPECT_EQ(100, ReadData(entry, 1, 23000, buffer2.get(), kSize));
1107   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + 100, 100));
1108
1109   CacheTestFillBuffer(buffer2->data(), kSize, true);
1110   EXPECT_EQ(100, ReadData(entry, 1, 23100, buffer2.get(), kSize));
1111   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + 100, 100));
1112
1113   // Extend the file again and read before without closing the entry.
1114   EXPECT_EQ(kSize, WriteData(entry, 1, 25000, buffer1.get(), kSize, false));
1115   EXPECT_EQ(kSize, WriteData(entry, 1, 45000, buffer1.get(), kSize, false));
1116   CacheTestFillBuffer(buffer2->data(), kSize, true);
1117   EXPECT_EQ(kSize, ReadData(entry, 1, 25000, buffer2.get(), kSize));
1118   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1119   CacheTestFillBuffer(buffer2->data(), kSize, true);
1120   EXPECT_EQ(kSize, ReadData(entry, 1, 45000, buffer2.get(), kSize));
1121   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
1122
1123   entry->Close();
1124 }
1125
1126 TEST_F(DiskCacheEntryTest, Buffering) {
1127   InitCache();
1128   Buffering();
1129 }
1130
1131 TEST_F(DiskCacheEntryTest, BufferingNoBuffer) {
1132   InitCache();
1133   cache_impl_->SetFlags(disk_cache::kNoBuffering);
1134   Buffering();
1135 }
1136
1137 // Checks that entries are zero length when created.
1138 void DiskCacheEntryTest::SizeAtCreate() {
1139   const char key[]  = "the first key";
1140   disk_cache::Entry* entry;
1141   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1142
1143   const int kNumStreams = 3;
1144   for (int i = 0; i < kNumStreams; ++i)
1145     EXPECT_EQ(0, entry->GetDataSize(i));
1146   entry->Close();
1147 }
1148
1149 TEST_F(DiskCacheEntryTest, SizeAtCreate) {
1150   InitCache();
1151   SizeAtCreate();
1152 }
1153
1154 TEST_F(DiskCacheEntryTest, MemoryOnlySizeAtCreate) {
1155   SetMemoryOnlyMode();
1156   InitCache();
1157   SizeAtCreate();
1158 }
1159
1160 // Some extra tests to make sure that buffering works properly when changing
1161 // the entry size.
1162 void DiskCacheEntryTest::SizeChanges(int stream_index) {
1163   std::string key("the first key");
1164   disk_cache::Entry* entry;
1165   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1166
1167   const int kSize = 200;
1168   const char zeros[kSize] = {};
1169   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
1170   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
1171   CacheTestFillBuffer(buffer1->data(), kSize, true);
1172   CacheTestFillBuffer(buffer2->data(), kSize, true);
1173
1174   EXPECT_EQ(kSize,
1175             WriteData(entry, stream_index, 0, buffer1.get(), kSize, true));
1176   EXPECT_EQ(kSize,
1177             WriteData(entry, stream_index, 17000, buffer1.get(), kSize, true));
1178   EXPECT_EQ(kSize,
1179             WriteData(entry, stream_index, 23000, buffer1.get(), kSize, true));
1180   entry->Close();
1181
1182   // Extend the file and read between the old size and the new write.
1183   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1184   EXPECT_EQ(23000 + kSize, entry->GetDataSize(stream_index));
1185   EXPECT_EQ(kSize,
1186             WriteData(entry, stream_index, 25000, buffer1.get(), kSize, true));
1187   EXPECT_EQ(25000 + kSize, entry->GetDataSize(stream_index));
1188   EXPECT_EQ(kSize, ReadData(entry, stream_index, 24000, buffer2.get(), kSize));
1189   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, kSize));
1190
1191   // Read at the end of the old file size.
1192   EXPECT_EQ(
1193       kSize,
1194       ReadData(entry, stream_index, 23000 + kSize - 35, buffer2.get(), kSize));
1195   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + kSize - 35, 35));
1196
1197   // Read slightly before the last write.
1198   CacheTestFillBuffer(buffer2->data(), kSize, true);
1199   EXPECT_EQ(kSize, ReadData(entry, stream_index, 24900, buffer2.get(), kSize));
1200   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
1201   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
1202
1203   // Extend the entry a little more.
1204   EXPECT_EQ(kSize,
1205             WriteData(entry, stream_index, 26000, buffer1.get(), kSize, true));
1206   EXPECT_EQ(26000 + kSize, entry->GetDataSize(stream_index));
1207   CacheTestFillBuffer(buffer2->data(), kSize, true);
1208   EXPECT_EQ(kSize, ReadData(entry, stream_index, 25900, buffer2.get(), kSize));
1209   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
1210   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
1211
1212   // And now reduce the size.
1213   EXPECT_EQ(kSize,
1214             WriteData(entry, stream_index, 25000, buffer1.get(), kSize, true));
1215   EXPECT_EQ(25000 + kSize, entry->GetDataSize(stream_index));
1216   EXPECT_EQ(
1217       28,
1218       ReadData(entry, stream_index, 25000 + kSize - 28, buffer2.get(), kSize));
1219   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + kSize - 28, 28));
1220
1221   // Reduce the size with a buffer that is not extending the size.
1222   EXPECT_EQ(kSize,
1223             WriteData(entry, stream_index, 24000, buffer1.get(), kSize, false));
1224   EXPECT_EQ(25000 + kSize, entry->GetDataSize(stream_index));
1225   EXPECT_EQ(kSize,
1226             WriteData(entry, stream_index, 24500, buffer1.get(), kSize, true));
1227   EXPECT_EQ(24500 + kSize, entry->GetDataSize(stream_index));
1228   EXPECT_EQ(kSize, ReadData(entry, stream_index, 23900, buffer2.get(), kSize));
1229   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
1230   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
1231
1232   // And now reduce the size below the old size.
1233   EXPECT_EQ(kSize,
1234             WriteData(entry, stream_index, 19000, buffer1.get(), kSize, true));
1235   EXPECT_EQ(19000 + kSize, entry->GetDataSize(stream_index));
1236   EXPECT_EQ(kSize, ReadData(entry, stream_index, 18900, buffer2.get(), kSize));
1237   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
1238   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
1239
1240   // Verify that the actual file is truncated.
1241   entry->Close();
1242   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1243   EXPECT_EQ(19000 + kSize, entry->GetDataSize(stream_index));
1244
1245   // Extend the newly opened file with a zero length write, expect zero fill.
1246   EXPECT_EQ(
1247       0,
1248       WriteData(entry, stream_index, 20000 + kSize, buffer1.get(), 0, false));
1249   EXPECT_EQ(kSize,
1250             ReadData(entry, stream_index, 19000 + kSize, buffer1.get(), kSize));
1251   EXPECT_EQ(0, memcmp(buffer1->data(), zeros, kSize));
1252
1253   entry->Close();
1254 }
1255
1256 TEST_F(DiskCacheEntryTest, SizeChanges) {
1257   InitCache();
1258   SizeChanges(1);
1259 }
1260
1261 TEST_F(DiskCacheEntryTest, SizeChangesNoBuffer) {
1262   InitCache();
1263   cache_impl_->SetFlags(disk_cache::kNoBuffering);
1264   SizeChanges(1);
1265 }
1266
1267 // Write more than the total cache capacity but to a single entry. |size| is the
1268 // amount of bytes to write each time.
1269 void DiskCacheEntryTest::ReuseEntry(int size, int stream_index) {
1270   std::string key1("the first key");
1271   disk_cache::Entry* entry;
1272   ASSERT_EQ(net::OK, CreateEntry(key1, &entry));
1273
1274   entry->Close();
1275   std::string key2("the second key");
1276   ASSERT_EQ(net::OK, CreateEntry(key2, &entry));
1277
1278   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(size));
1279   CacheTestFillBuffer(buffer->data(), size, false);
1280
1281   for (int i = 0; i < 15; i++) {
1282     EXPECT_EQ(0, WriteData(entry, stream_index, 0, buffer.get(), 0, true));
1283     EXPECT_EQ(size,
1284               WriteData(entry, stream_index, 0, buffer.get(), size, false));
1285     entry->Close();
1286     ASSERT_EQ(net::OK, OpenEntry(key2, &entry));
1287   }
1288
1289   entry->Close();
1290   ASSERT_EQ(net::OK, OpenEntry(key1, &entry)) << "have not evicted this entry";
1291   entry->Close();
1292 }
1293
1294 TEST_F(DiskCacheEntryTest, ReuseExternalEntry) {
1295   SetMaxSize(200 * 1024);
1296   InitCache();
1297   ReuseEntry(20 * 1024, 0);
1298 }
1299
1300 TEST_F(DiskCacheEntryTest, MemoryOnlyReuseExternalEntry) {
1301   SetMemoryOnlyMode();
1302   SetMaxSize(200 * 1024);
1303   InitCache();
1304   ReuseEntry(20 * 1024, 0);
1305 }
1306
1307 TEST_F(DiskCacheEntryTest, ReuseInternalEntry) {
1308   SetMaxSize(100 * 1024);
1309   InitCache();
1310   ReuseEntry(10 * 1024, 0);
1311 }
1312
1313 TEST_F(DiskCacheEntryTest, MemoryOnlyReuseInternalEntry) {
1314   SetMemoryOnlyMode();
1315   SetMaxSize(100 * 1024);
1316   InitCache();
1317   ReuseEntry(10 * 1024, 0);
1318 }
1319
1320 // Reading somewhere that was not written should return zeros.
1321 void DiskCacheEntryTest::InvalidData(int stream_index) {
1322   std::string key("the first key");
1323   disk_cache::Entry* entry;
1324   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1325
1326   const int kSize1 = 20000;
1327   const int kSize2 = 20000;
1328   const int kSize3 = 20000;
1329   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
1330   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
1331   scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3));
1332
1333   CacheTestFillBuffer(buffer1->data(), kSize1, false);
1334   memset(buffer2->data(), 0, kSize2);
1335
1336   // Simple data grow:
1337   EXPECT_EQ(200,
1338             WriteData(entry, stream_index, 400, buffer1.get(), 200, false));
1339   EXPECT_EQ(600, entry->GetDataSize(stream_index));
1340   EXPECT_EQ(100, ReadData(entry, stream_index, 300, buffer3.get(), 100));
1341   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
1342   entry->Close();
1343   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1344
1345   // The entry is now on disk. Load it and extend it.
1346   EXPECT_EQ(200,
1347             WriteData(entry, stream_index, 800, buffer1.get(), 200, false));
1348   EXPECT_EQ(1000, entry->GetDataSize(stream_index));
1349   EXPECT_EQ(100, ReadData(entry, stream_index, 700, buffer3.get(), 100));
1350   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
1351   entry->Close();
1352   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1353
1354   // This time using truncate.
1355   EXPECT_EQ(200,
1356             WriteData(entry, stream_index, 1800, buffer1.get(), 200, true));
1357   EXPECT_EQ(2000, entry->GetDataSize(stream_index));
1358   EXPECT_EQ(100, ReadData(entry, stream_index, 1500, buffer3.get(), 100));
1359   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
1360
1361   // Go to an external file.
1362   EXPECT_EQ(200,
1363             WriteData(entry, stream_index, 19800, buffer1.get(), 200, false));
1364   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
1365   EXPECT_EQ(4000, ReadData(entry, stream_index, 14000, buffer3.get(), 4000));
1366   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 4000));
1367
1368   // And back to an internal block.
1369   EXPECT_EQ(600,
1370             WriteData(entry, stream_index, 1000, buffer1.get(), 600, true));
1371   EXPECT_EQ(1600, entry->GetDataSize(stream_index));
1372   EXPECT_EQ(600, ReadData(entry, stream_index, 1000, buffer3.get(), 600));
1373   EXPECT_TRUE(!memcmp(buffer3->data(), buffer1->data(), 600));
1374
1375   // Extend it again.
1376   EXPECT_EQ(600,
1377             WriteData(entry, stream_index, 2000, buffer1.get(), 600, false));
1378   EXPECT_EQ(2600, entry->GetDataSize(stream_index));
1379   EXPECT_EQ(200, ReadData(entry, stream_index, 1800, buffer3.get(), 200));
1380   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 200));
1381
1382   // And again (with truncation flag).
1383   EXPECT_EQ(600,
1384             WriteData(entry, stream_index, 3000, buffer1.get(), 600, true));
1385   EXPECT_EQ(3600, entry->GetDataSize(stream_index));
1386   EXPECT_EQ(200, ReadData(entry, stream_index, 2800, buffer3.get(), 200));
1387   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 200));
1388
1389   entry->Close();
1390 }
1391
1392 TEST_F(DiskCacheEntryTest, InvalidData) {
1393   InitCache();
1394   InvalidData(0);
1395 }
1396
1397 TEST_F(DiskCacheEntryTest, InvalidDataNoBuffer) {
1398   InitCache();
1399   cache_impl_->SetFlags(disk_cache::kNoBuffering);
1400   InvalidData(0);
1401 }
1402
1403 TEST_F(DiskCacheEntryTest, MemoryOnlyInvalidData) {
1404   SetMemoryOnlyMode();
1405   InitCache();
1406   InvalidData(0);
1407 }
1408
1409 // Tests that the cache preserves the buffer of an IO operation.
1410 void DiskCacheEntryTest::ReadWriteDestroyBuffer(int stream_index) {
1411   std::string key("the first key");
1412   disk_cache::Entry* entry;
1413   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1414
1415   const int kSize = 200;
1416   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
1417   CacheTestFillBuffer(buffer->data(), kSize, false);
1418
1419   net::TestCompletionCallback cb;
1420   EXPECT_EQ(net::ERR_IO_PENDING,
1421             entry->WriteData(
1422                 stream_index, 0, buffer.get(), kSize, cb.callback(), false));
1423
1424   // Release our reference to the buffer.
1425   buffer = NULL;
1426   EXPECT_EQ(kSize, cb.WaitForResult());
1427
1428   // And now test with a Read().
1429   buffer = new net::IOBuffer(kSize);
1430   CacheTestFillBuffer(buffer->data(), kSize, false);
1431
1432   EXPECT_EQ(
1433       net::ERR_IO_PENDING,
1434       entry->ReadData(stream_index, 0, buffer.get(), kSize, cb.callback()));
1435   buffer = NULL;
1436   EXPECT_EQ(kSize, cb.WaitForResult());
1437
1438   entry->Close();
1439 }
1440
1441 TEST_F(DiskCacheEntryTest, ReadWriteDestroyBuffer) {
1442   InitCache();
1443   ReadWriteDestroyBuffer(0);
1444 }
1445
1446 void DiskCacheEntryTest::DoomNormalEntry() {
1447   std::string key("the first key");
1448   disk_cache::Entry* entry;
1449   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1450   entry->Doom();
1451   entry->Close();
1452
1453   const int kSize = 20000;
1454   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
1455   CacheTestFillBuffer(buffer->data(), kSize, true);
1456   buffer->data()[19999] = '\0';
1457
1458   key = buffer->data();
1459   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1460   EXPECT_EQ(20000, WriteData(entry, 0, 0, buffer.get(), kSize, false));
1461   EXPECT_EQ(20000, WriteData(entry, 1, 0, buffer.get(), kSize, false));
1462   entry->Doom();
1463   entry->Close();
1464
1465   FlushQueueForTest();
1466   EXPECT_EQ(0, cache_->GetEntryCount());
1467 }
1468
1469 TEST_F(DiskCacheEntryTest, DoomEntry) {
1470   InitCache();
1471   DoomNormalEntry();
1472 }
1473
1474 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomEntry) {
1475   SetMemoryOnlyMode();
1476   InitCache();
1477   DoomNormalEntry();
1478 }
1479
1480 // Tests dooming an entry that's linked to an open entry.
1481 void DiskCacheEntryTest::DoomEntryNextToOpenEntry() {
1482   disk_cache::Entry* entry1;
1483   disk_cache::Entry* entry2;
1484   ASSERT_EQ(net::OK, CreateEntry("fixed", &entry1));
1485   entry1->Close();
1486   ASSERT_EQ(net::OK, CreateEntry("foo", &entry1));
1487   entry1->Close();
1488   ASSERT_EQ(net::OK, CreateEntry("bar", &entry1));
1489   entry1->Close();
1490
1491   ASSERT_EQ(net::OK, OpenEntry("foo", &entry1));
1492   ASSERT_EQ(net::OK, OpenEntry("bar", &entry2));
1493   entry2->Doom();
1494   entry2->Close();
1495
1496   ASSERT_EQ(net::OK, OpenEntry("foo", &entry2));
1497   entry2->Doom();
1498   entry2->Close();
1499   entry1->Close();
1500
1501   ASSERT_EQ(net::OK, OpenEntry("fixed", &entry1));
1502   entry1->Close();
1503 }
1504
1505 TEST_F(DiskCacheEntryTest, DoomEntryNextToOpenEntry) {
1506   InitCache();
1507   DoomEntryNextToOpenEntry();
1508 }
1509
1510 TEST_F(DiskCacheEntryTest, NewEvictionDoomEntryNextToOpenEntry) {
1511   SetNewEviction();
1512   InitCache();
1513   DoomEntryNextToOpenEntry();
1514 }
1515
1516 TEST_F(DiskCacheEntryTest, AppCacheDoomEntryNextToOpenEntry) {
1517   SetCacheType(net::APP_CACHE);
1518   InitCache();
1519   DoomEntryNextToOpenEntry();
1520 }
1521
1522 // Verify that basic operations work as expected with doomed entries.
1523 void DiskCacheEntryTest::DoomedEntry(int stream_index) {
1524   std::string key("the first key");
1525   disk_cache::Entry* entry;
1526   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1527   entry->Doom();
1528
1529   FlushQueueForTest();
1530   EXPECT_EQ(0, cache_->GetEntryCount());
1531   Time initial = Time::Now();
1532   AddDelay();
1533
1534   const int kSize1 = 2000;
1535   const int kSize2 = 2000;
1536   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
1537   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
1538   CacheTestFillBuffer(buffer1->data(), kSize1, false);
1539   memset(buffer2->data(), 0, kSize2);
1540
1541   EXPECT_EQ(2000,
1542             WriteData(entry, stream_index, 0, buffer1.get(), 2000, false));
1543   EXPECT_EQ(2000, ReadData(entry, stream_index, 0, buffer2.get(), 2000));
1544   EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize1));
1545   EXPECT_EQ(key, entry->GetKey());
1546   EXPECT_TRUE(initial < entry->GetLastModified());
1547   EXPECT_TRUE(initial < entry->GetLastUsed());
1548
1549   entry->Close();
1550 }
1551
1552 TEST_F(DiskCacheEntryTest, DoomedEntry) {
1553   InitCache();
1554   DoomedEntry(0);
1555 }
1556
1557 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomedEntry) {
1558   SetMemoryOnlyMode();
1559   InitCache();
1560   DoomedEntry(0);
1561 }
1562
1563 // Tests that we discard entries if the data is missing.
1564 TEST_F(DiskCacheEntryTest, MissingData) {
1565   InitCache();
1566
1567   std::string key("the first key");
1568   disk_cache::Entry* entry;
1569   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1570
1571   // Write to an external file.
1572   const int kSize = 20000;
1573   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
1574   CacheTestFillBuffer(buffer->data(), kSize, false);
1575   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
1576   entry->Close();
1577   FlushQueueForTest();
1578
1579   disk_cache::Addr address(0x80000001);
1580   base::FilePath name = cache_impl_->GetFileName(address);
1581   EXPECT_TRUE(base::DeleteFile(name, false));
1582
1583   // Attempt to read the data.
1584   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1585   EXPECT_EQ(net::ERR_FILE_NOT_FOUND,
1586             ReadData(entry, 0, 0, buffer.get(), kSize));
1587   entry->Close();
1588
1589   // The entry should be gone.
1590   ASSERT_NE(net::OK, OpenEntry(key, &entry));
1591 }
1592
1593 // Test that child entries in a memory cache backend are not visible from
1594 // enumerations.
1595 TEST_F(DiskCacheEntryTest, MemoryOnlyEnumerationWithSparseEntries) {
1596   SetMemoryOnlyMode();
1597   InitCache();
1598
1599   const int kSize = 4096;
1600   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
1601   CacheTestFillBuffer(buf->data(), kSize, false);
1602
1603   std::string key("the first key");
1604   disk_cache::Entry* parent_entry;
1605   ASSERT_EQ(net::OK, CreateEntry(key, &parent_entry));
1606
1607   // Writes to the parent entry.
1608   EXPECT_EQ(kSize,
1609             parent_entry->WriteSparseData(
1610                 0, buf.get(), kSize, net::CompletionCallback()));
1611
1612   // This write creates a child entry and writes to it.
1613   EXPECT_EQ(kSize,
1614             parent_entry->WriteSparseData(
1615                 8192, buf.get(), kSize, net::CompletionCallback()));
1616
1617   parent_entry->Close();
1618
1619   // Perform the enumerations.
1620   scoped_ptr<TestIterator> iter = CreateIterator();
1621   disk_cache::Entry* entry = NULL;
1622   int count = 0;
1623   while (iter->OpenNextEntry(&entry) == net::OK) {
1624     ASSERT_TRUE(entry != NULL);
1625     ++count;
1626     disk_cache::MemEntryImpl* mem_entry =
1627         reinterpret_cast<disk_cache::MemEntryImpl*>(entry);
1628     EXPECT_EQ(disk_cache::MemEntryImpl::kParentEntry, mem_entry->type());
1629     mem_entry->Close();
1630   }
1631   EXPECT_EQ(1, count);
1632 }
1633
1634 // Writes |buf_1| to offset and reads it back as |buf_2|.
1635 void VerifySparseIO(disk_cache::Entry* entry, int64 offset,
1636                     net::IOBuffer* buf_1, int size, net::IOBuffer* buf_2) {
1637   net::TestCompletionCallback cb;
1638
1639   memset(buf_2->data(), 0, size);
1640   int ret = entry->ReadSparseData(offset, buf_2, size, cb.callback());
1641   EXPECT_EQ(0, cb.GetResult(ret));
1642
1643   ret = entry->WriteSparseData(offset, buf_1, size, cb.callback());
1644   EXPECT_EQ(size, cb.GetResult(ret));
1645
1646   ret = entry->ReadSparseData(offset, buf_2, size, cb.callback());
1647   EXPECT_EQ(size, cb.GetResult(ret));
1648
1649   EXPECT_EQ(0, memcmp(buf_1->data(), buf_2->data(), size));
1650 }
1651
1652 // Reads |size| bytes from |entry| at |offset| and verifies that they are the
1653 // same as the content of the provided |buffer|.
1654 void VerifyContentSparseIO(disk_cache::Entry* entry, int64 offset, char* buffer,
1655                            int size) {
1656   net::TestCompletionCallback cb;
1657
1658   scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(size));
1659   memset(buf_1->data(), 0, size);
1660   int ret = entry->ReadSparseData(offset, buf_1.get(), size, cb.callback());
1661   EXPECT_EQ(size, cb.GetResult(ret));
1662   EXPECT_EQ(0, memcmp(buf_1->data(), buffer, size));
1663 }
1664
1665 void DiskCacheEntryTest::BasicSparseIO() {
1666   std::string key("the first key");
1667   disk_cache::Entry* entry;
1668   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1669
1670   const int kSize = 2048;
1671   scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize));
1672   scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize));
1673   CacheTestFillBuffer(buf_1->data(), kSize, false);
1674
1675   // Write at offset 0.
1676   VerifySparseIO(entry, 0, buf_1.get(), kSize, buf_2.get());
1677
1678   // Write at offset 0x400000 (4 MB).
1679   VerifySparseIO(entry, 0x400000, buf_1.get(), kSize, buf_2.get());
1680
1681   // Write at offset 0x800000000 (32 GB).
1682   VerifySparseIO(entry, 0x800000000LL, buf_1.get(), kSize, buf_2.get());
1683
1684   entry->Close();
1685
1686   // Check everything again.
1687   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1688   VerifyContentSparseIO(entry, 0, buf_1->data(), kSize);
1689   VerifyContentSparseIO(entry, 0x400000, buf_1->data(), kSize);
1690   VerifyContentSparseIO(entry, 0x800000000LL, buf_1->data(), kSize);
1691   entry->Close();
1692 }
1693
1694 TEST_F(DiskCacheEntryTest, BasicSparseIO) {
1695   InitCache();
1696   BasicSparseIO();
1697 }
1698
1699 TEST_F(DiskCacheEntryTest, MemoryOnlyBasicSparseIO) {
1700   SetMemoryOnlyMode();
1701   InitCache();
1702   BasicSparseIO();
1703 }
1704
1705 void DiskCacheEntryTest::HugeSparseIO() {
1706   std::string key("the first key");
1707   disk_cache::Entry* entry;
1708   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1709
1710   // Write 1.2 MB so that we cover multiple entries.
1711   const int kSize = 1200 * 1024;
1712   scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize));
1713   scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize));
1714   CacheTestFillBuffer(buf_1->data(), kSize, false);
1715
1716   // Write at offset 0x20F0000 (33 MB - 64 KB).
1717   VerifySparseIO(entry, 0x20F0000, buf_1.get(), kSize, buf_2.get());
1718   entry->Close();
1719
1720   // Check it again.
1721   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1722   VerifyContentSparseIO(entry, 0x20F0000, buf_1->data(), kSize);
1723   entry->Close();
1724 }
1725
1726 TEST_F(DiskCacheEntryTest, HugeSparseIO) {
1727   InitCache();
1728   HugeSparseIO();
1729 }
1730
1731 TEST_F(DiskCacheEntryTest, MemoryOnlyHugeSparseIO) {
1732   SetMemoryOnlyMode();
1733   InitCache();
1734   HugeSparseIO();
1735 }
1736
1737 void DiskCacheEntryTest::GetAvailableRange() {
1738   std::string key("the first key");
1739   disk_cache::Entry* entry;
1740   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1741
1742   const int kSize = 16 * 1024;
1743   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
1744   CacheTestFillBuffer(buf->data(), kSize, false);
1745
1746   // Write at offset 0x20F0000 (33 MB - 64 KB), and 0x20F4400 (33 MB - 47 KB).
1747   EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F0000, buf.get(), kSize));
1748   EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F4400, buf.get(), kSize));
1749
1750   // We stop at the first empty block.
1751   int64 start;
1752   net::TestCompletionCallback cb;
1753   int rv = entry->GetAvailableRange(
1754       0x20F0000, kSize * 2, &start, cb.callback());
1755   EXPECT_EQ(kSize, cb.GetResult(rv));
1756   EXPECT_EQ(0x20F0000, start);
1757
1758   start = 0;
1759   rv = entry->GetAvailableRange(0, kSize, &start, cb.callback());
1760   EXPECT_EQ(0, cb.GetResult(rv));
1761   rv = entry->GetAvailableRange(
1762       0x20F0000 - kSize, kSize, &start, cb.callback());
1763   EXPECT_EQ(0, cb.GetResult(rv));
1764   rv = entry->GetAvailableRange(0, 0x2100000, &start, cb.callback());
1765   EXPECT_EQ(kSize, cb.GetResult(rv));
1766   EXPECT_EQ(0x20F0000, start);
1767
1768   // We should be able to Read based on the results of GetAvailableRange.
1769   start = -1;
1770   rv = entry->GetAvailableRange(0x2100000, kSize, &start, cb.callback());
1771   EXPECT_EQ(0, cb.GetResult(rv));
1772   rv = entry->ReadSparseData(start, buf.get(), kSize, cb.callback());
1773   EXPECT_EQ(0, cb.GetResult(rv));
1774
1775   start = 0;
1776   rv = entry->GetAvailableRange(0x20F2000, kSize, &start, cb.callback());
1777   EXPECT_EQ(0x2000, cb.GetResult(rv));
1778   EXPECT_EQ(0x20F2000, start);
1779   EXPECT_EQ(0x2000, ReadSparseData(entry, start, buf.get(), kSize));
1780
1781   // Make sure that we respect the |len| argument.
1782   start = 0;
1783   rv = entry->GetAvailableRange(
1784       0x20F0001 - kSize, kSize, &start, cb.callback());
1785   EXPECT_EQ(1, cb.GetResult(rv));
1786   EXPECT_EQ(0x20F0000, start);
1787
1788   entry->Close();
1789 }
1790
1791 TEST_F(DiskCacheEntryTest, GetAvailableRange) {
1792   InitCache();
1793   GetAvailableRange();
1794 }
1795
1796 TEST_F(DiskCacheEntryTest, MemoryOnlyGetAvailableRange) {
1797   SetMemoryOnlyMode();
1798   InitCache();
1799   GetAvailableRange();
1800 }
1801
1802 void DiskCacheEntryTest::CouldBeSparse() {
1803   std::string key("the first key");
1804   disk_cache::Entry* entry;
1805   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1806
1807   const int kSize = 16 * 1024;
1808   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
1809   CacheTestFillBuffer(buf->data(), kSize, false);
1810
1811   // Write at offset 0x20F0000 (33 MB - 64 KB).
1812   EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F0000, buf.get(), kSize));
1813
1814   EXPECT_TRUE(entry->CouldBeSparse());
1815   entry->Close();
1816
1817   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1818   EXPECT_TRUE(entry->CouldBeSparse());
1819   entry->Close();
1820
1821   // Now verify a regular entry.
1822   key.assign("another key");
1823   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1824   EXPECT_FALSE(entry->CouldBeSparse());
1825
1826   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buf.get(), kSize, false));
1827   EXPECT_EQ(kSize, WriteData(entry, 1, 0, buf.get(), kSize, false));
1828   EXPECT_EQ(kSize, WriteData(entry, 2, 0, buf.get(), kSize, false));
1829
1830   EXPECT_FALSE(entry->CouldBeSparse());
1831   entry->Close();
1832
1833   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1834   EXPECT_FALSE(entry->CouldBeSparse());
1835   entry->Close();
1836 }
1837
1838 TEST_F(DiskCacheEntryTest, CouldBeSparse) {
1839   InitCache();
1840   CouldBeSparse();
1841 }
1842
1843 TEST_F(DiskCacheEntryTest, MemoryCouldBeSparse) {
1844   SetMemoryOnlyMode();
1845   InitCache();
1846   CouldBeSparse();
1847 }
1848
1849 TEST_F(DiskCacheEntryTest, MemoryOnlyMisalignedSparseIO) {
1850   SetMemoryOnlyMode();
1851   InitCache();
1852
1853   const int kSize = 8192;
1854   scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize));
1855   scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize));
1856   CacheTestFillBuffer(buf_1->data(), kSize, false);
1857
1858   std::string key("the first key");
1859   disk_cache::Entry* entry;
1860   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1861
1862   // This loop writes back to back starting from offset 0 and 9000.
1863   for (int i = 0; i < kSize; i += 1024) {
1864     scoped_refptr<net::WrappedIOBuffer> buf_3(
1865       new net::WrappedIOBuffer(buf_1->data() + i));
1866     VerifySparseIO(entry, i, buf_3.get(), 1024, buf_2.get());
1867     VerifySparseIO(entry, 9000 + i, buf_3.get(), 1024, buf_2.get());
1868   }
1869
1870   // Make sure we have data written.
1871   VerifyContentSparseIO(entry, 0, buf_1->data(), kSize);
1872   VerifyContentSparseIO(entry, 9000, buf_1->data(), kSize);
1873
1874   // This tests a large write that spans 3 entries from a misaligned offset.
1875   VerifySparseIO(entry, 20481, buf_1.get(), 8192, buf_2.get());
1876
1877   entry->Close();
1878 }
1879
1880 TEST_F(DiskCacheEntryTest, MemoryOnlyMisalignedGetAvailableRange) {
1881   SetMemoryOnlyMode();
1882   InitCache();
1883
1884   const int kSize = 8192;
1885   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
1886   CacheTestFillBuffer(buf->data(), kSize, false);
1887
1888   disk_cache::Entry* entry;
1889   std::string key("the first key");
1890   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1891
1892   // Writes in the middle of an entry.
1893   EXPECT_EQ(
1894       1024,
1895       entry->WriteSparseData(0, buf.get(), 1024, net::CompletionCallback()));
1896   EXPECT_EQ(
1897       1024,
1898       entry->WriteSparseData(5120, buf.get(), 1024, net::CompletionCallback()));
1899   EXPECT_EQ(1024,
1900             entry->WriteSparseData(
1901                 10000, buf.get(), 1024, net::CompletionCallback()));
1902
1903   // Writes in the middle of an entry and spans 2 child entries.
1904   EXPECT_EQ(8192,
1905             entry->WriteSparseData(
1906                 50000, buf.get(), 8192, net::CompletionCallback()));
1907
1908   int64 start;
1909   net::TestCompletionCallback cb;
1910   // Test that we stop at a discontinuous child at the second block.
1911   int rv = entry->GetAvailableRange(0, 10000, &start, cb.callback());
1912   EXPECT_EQ(1024, cb.GetResult(rv));
1913   EXPECT_EQ(0, start);
1914
1915   // Test that number of bytes is reported correctly when we start from the
1916   // middle of a filled region.
1917   rv = entry->GetAvailableRange(512, 10000, &start, cb.callback());
1918   EXPECT_EQ(512, cb.GetResult(rv));
1919   EXPECT_EQ(512, start);
1920
1921   // Test that we found bytes in the child of next block.
1922   rv = entry->GetAvailableRange(1024, 10000, &start, cb.callback());
1923   EXPECT_EQ(1024, cb.GetResult(rv));
1924   EXPECT_EQ(5120, start);
1925
1926   // Test that the desired length is respected. It starts within a filled
1927   // region.
1928   rv = entry->GetAvailableRange(5500, 512, &start, cb.callback());
1929   EXPECT_EQ(512, cb.GetResult(rv));
1930   EXPECT_EQ(5500, start);
1931
1932   // Test that the desired length is respected. It starts before a filled
1933   // region.
1934   rv = entry->GetAvailableRange(5000, 620, &start, cb.callback());
1935   EXPECT_EQ(500, cb.GetResult(rv));
1936   EXPECT_EQ(5120, start);
1937
1938   // Test that multiple blocks are scanned.
1939   rv = entry->GetAvailableRange(40000, 20000, &start, cb.callback());
1940   EXPECT_EQ(8192, cb.GetResult(rv));
1941   EXPECT_EQ(50000, start);
1942
1943   entry->Close();
1944 }
1945
1946 void DiskCacheEntryTest::UpdateSparseEntry() {
1947   std::string key("the first key");
1948   disk_cache::Entry* entry1;
1949   ASSERT_EQ(net::OK, CreateEntry(key, &entry1));
1950
1951   const int kSize = 2048;
1952   scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize));
1953   scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize));
1954   CacheTestFillBuffer(buf_1->data(), kSize, false);
1955
1956   // Write at offset 0.
1957   VerifySparseIO(entry1, 0, buf_1.get(), kSize, buf_2.get());
1958   entry1->Close();
1959
1960   // Write at offset 2048.
1961   ASSERT_EQ(net::OK, OpenEntry(key, &entry1));
1962   VerifySparseIO(entry1, 2048, buf_1.get(), kSize, buf_2.get());
1963
1964   disk_cache::Entry* entry2;
1965   ASSERT_EQ(net::OK, CreateEntry("the second key", &entry2));
1966
1967   entry1->Close();
1968   entry2->Close();
1969   FlushQueueForTest();
1970   if (memory_only_ || simple_cache_mode_)
1971     EXPECT_EQ(2, cache_->GetEntryCount());
1972   else
1973     EXPECT_EQ(3, cache_->GetEntryCount());
1974 }
1975
1976 TEST_F(DiskCacheEntryTest, UpdateSparseEntry) {
1977   SetCacheType(net::MEDIA_CACHE);
1978   InitCache();
1979   UpdateSparseEntry();
1980 }
1981
1982 TEST_F(DiskCacheEntryTest, MemoryOnlyUpdateSparseEntry) {
1983   SetMemoryOnlyMode();
1984   SetCacheType(net::MEDIA_CACHE);
1985   InitCache();
1986   UpdateSparseEntry();
1987 }
1988
1989 void DiskCacheEntryTest::DoomSparseEntry() {
1990   std::string key1("the first key");
1991   std::string key2("the second key");
1992   disk_cache::Entry *entry1, *entry2;
1993   ASSERT_EQ(net::OK, CreateEntry(key1, &entry1));
1994   ASSERT_EQ(net::OK, CreateEntry(key2, &entry2));
1995
1996   const int kSize = 4 * 1024;
1997   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
1998   CacheTestFillBuffer(buf->data(), kSize, false);
1999
2000   int64 offset = 1024;
2001   // Write to a bunch of ranges.
2002   for (int i = 0; i < 12; i++) {
2003     EXPECT_EQ(kSize, WriteSparseData(entry1, offset, buf.get(), kSize));
2004     // Keep the second map under the default size.
2005     if (i < 9)
2006       EXPECT_EQ(kSize, WriteSparseData(entry2, offset, buf.get(), kSize));
2007
2008     offset *= 4;
2009   }
2010
2011   if (memory_only_ || simple_cache_mode_)
2012     EXPECT_EQ(2, cache_->GetEntryCount());
2013   else
2014     EXPECT_EQ(15, cache_->GetEntryCount());
2015
2016   // Doom the first entry while it's still open.
2017   entry1->Doom();
2018   entry1->Close();
2019   entry2->Close();
2020
2021   // Doom the second entry after it's fully saved.
2022   EXPECT_EQ(net::OK, DoomEntry(key2));
2023
2024   // Make sure we do all needed work. This may fail for entry2 if between Close
2025   // and DoomEntry the system decides to remove all traces of the file from the
2026   // system cache so we don't see that there is pending IO.
2027   base::MessageLoop::current()->RunUntilIdle();
2028
2029   if (memory_only_) {
2030     EXPECT_EQ(0, cache_->GetEntryCount());
2031   } else {
2032     if (5 == cache_->GetEntryCount()) {
2033       // Most likely we are waiting for the result of reading the sparse info
2034       // (it's always async on Posix so it is easy to miss). Unfortunately we
2035       // don't have any signal to watch for so we can only wait.
2036       base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(500));
2037       base::MessageLoop::current()->RunUntilIdle();
2038     }
2039     EXPECT_EQ(0, cache_->GetEntryCount());
2040   }
2041 }
2042
2043 TEST_F(DiskCacheEntryTest, DoomSparseEntry) {
2044   UseCurrentThread();
2045   InitCache();
2046   DoomSparseEntry();
2047 }
2048
2049 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomSparseEntry) {
2050   SetMemoryOnlyMode();
2051   InitCache();
2052   DoomSparseEntry();
2053 }
2054
2055 // A CompletionCallback wrapper that deletes the cache from within the callback.
2056 // The way a CompletionCallback works means that all tasks (even new ones)
2057 // are executed by the message loop before returning to the caller so the only
2058 // way to simulate a race is to execute what we want on the callback.
2059 class SparseTestCompletionCallback: public net::TestCompletionCallback {
2060  public:
2061   explicit SparseTestCompletionCallback(scoped_ptr<disk_cache::Backend> cache)
2062       : cache_(cache.Pass()) {
2063   }
2064
2065  private:
2066   virtual void SetResult(int result) OVERRIDE {
2067     cache_.reset();
2068     TestCompletionCallback::SetResult(result);
2069   }
2070
2071   scoped_ptr<disk_cache::Backend> cache_;
2072   DISALLOW_COPY_AND_ASSIGN(SparseTestCompletionCallback);
2073 };
2074
2075 // Tests that we don't crash when the backend is deleted while we are working
2076 // deleting the sub-entries of a sparse entry.
2077 TEST_F(DiskCacheEntryTest, DoomSparseEntry2) {
2078   UseCurrentThread();
2079   InitCache();
2080   std::string key("the key");
2081   disk_cache::Entry* entry;
2082   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
2083
2084   const int kSize = 4 * 1024;
2085   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
2086   CacheTestFillBuffer(buf->data(), kSize, false);
2087
2088   int64 offset = 1024;
2089   // Write to a bunch of ranges.
2090   for (int i = 0; i < 12; i++) {
2091     EXPECT_EQ(kSize,
2092               entry->WriteSparseData(
2093                   offset, buf.get(), kSize, net::CompletionCallback()));
2094     offset *= 4;
2095   }
2096   EXPECT_EQ(9, cache_->GetEntryCount());
2097
2098   entry->Close();
2099   disk_cache::Backend* cache = cache_.get();
2100   SparseTestCompletionCallback cb(cache_.Pass());
2101   int rv = cache->DoomEntry(key, cb.callback());
2102   EXPECT_EQ(net::ERR_IO_PENDING, rv);
2103   EXPECT_EQ(net::OK, cb.WaitForResult());
2104 }
2105
2106 void DiskCacheEntryTest::PartialSparseEntry() {
2107   std::string key("the first key");
2108   disk_cache::Entry* entry;
2109   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
2110
2111   // We should be able to deal with IO that is not aligned to the block size
2112   // of a sparse entry, at least to write a big range without leaving holes.
2113   const int kSize = 4 * 1024;
2114   const int kSmallSize = 128;
2115   scoped_refptr<net::IOBuffer> buf1(new net::IOBuffer(kSize));
2116   CacheTestFillBuffer(buf1->data(), kSize, false);
2117
2118   // The first write is just to extend the entry. The third write occupies
2119   // a 1KB block partially, it may not be written internally depending on the
2120   // implementation.
2121   EXPECT_EQ(kSize, WriteSparseData(entry, 20000, buf1.get(), kSize));
2122   EXPECT_EQ(kSize, WriteSparseData(entry, 500, buf1.get(), kSize));
2123   EXPECT_EQ(kSmallSize,
2124             WriteSparseData(entry, 1080321, buf1.get(), kSmallSize));
2125   entry->Close();
2126   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
2127
2128   scoped_refptr<net::IOBuffer> buf2(new net::IOBuffer(kSize));
2129   memset(buf2->data(), 0, kSize);
2130   EXPECT_EQ(0, ReadSparseData(entry, 8000, buf2.get(), kSize));
2131
2132   EXPECT_EQ(500, ReadSparseData(entry, kSize, buf2.get(), kSize));
2133   EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500));
2134   EXPECT_EQ(0, ReadSparseData(entry, 0, buf2.get(), kSize));
2135
2136   // This read should not change anything.
2137   EXPECT_EQ(96, ReadSparseData(entry, 24000, buf2.get(), kSize));
2138   EXPECT_EQ(500, ReadSparseData(entry, kSize, buf2.get(), kSize));
2139   EXPECT_EQ(0, ReadSparseData(entry, 99, buf2.get(), kSize));
2140
2141   int rv;
2142   int64 start;
2143   net::TestCompletionCallback cb;
2144   if (memory_only_ || simple_cache_mode_) {
2145     rv = entry->GetAvailableRange(0, 600, &start, cb.callback());
2146     EXPECT_EQ(100, cb.GetResult(rv));
2147     EXPECT_EQ(500, start);
2148   } else {
2149     rv = entry->GetAvailableRange(0, 2048, &start, cb.callback());
2150     EXPECT_EQ(1024, cb.GetResult(rv));
2151     EXPECT_EQ(1024, start);
2152   }
2153   rv = entry->GetAvailableRange(kSize, kSize, &start, cb.callback());
2154   EXPECT_EQ(500, cb.GetResult(rv));
2155   EXPECT_EQ(kSize, start);
2156   rv = entry->GetAvailableRange(20 * 1024, 10000, &start, cb.callback());
2157   EXPECT_EQ(3616, cb.GetResult(rv));
2158   EXPECT_EQ(20 * 1024, start);
2159
2160   // 1. Query before a filled 1KB block.
2161   // 2. Query within a filled 1KB block.
2162   // 3. Query beyond a filled 1KB block.
2163   if (memory_only_ || simple_cache_mode_) {
2164     rv = entry->GetAvailableRange(19400, kSize, &start, cb.callback());
2165     EXPECT_EQ(3496, cb.GetResult(rv));
2166     EXPECT_EQ(20000, start);
2167   } else {
2168     rv = entry->GetAvailableRange(19400, kSize, &start, cb.callback());
2169     EXPECT_EQ(3016, cb.GetResult(rv));
2170     EXPECT_EQ(20480, start);
2171   }
2172   rv = entry->GetAvailableRange(3073, kSize, &start, cb.callback());
2173   EXPECT_EQ(1523, cb.GetResult(rv));
2174   EXPECT_EQ(3073, start);
2175   rv = entry->GetAvailableRange(4600, kSize, &start, cb.callback());
2176   EXPECT_EQ(0, cb.GetResult(rv));
2177   EXPECT_EQ(4600, start);
2178
2179   // Now make another write and verify that there is no hole in between.
2180   EXPECT_EQ(kSize, WriteSparseData(entry, 500 + kSize, buf1.get(), kSize));
2181   rv = entry->GetAvailableRange(1024, 10000, &start, cb.callback());
2182   EXPECT_EQ(7 * 1024 + 500, cb.GetResult(rv));
2183   EXPECT_EQ(1024, start);
2184   EXPECT_EQ(kSize, ReadSparseData(entry, kSize, buf2.get(), kSize));
2185   EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500));
2186   EXPECT_EQ(0, memcmp(buf2->data() + 500, buf1->data(), kSize - 500));
2187
2188   entry->Close();
2189 }
2190
2191 TEST_F(DiskCacheEntryTest, PartialSparseEntry) {
2192   InitCache();
2193   PartialSparseEntry();
2194 }
2195
2196 TEST_F(DiskCacheEntryTest, MemoryPartialSparseEntry) {
2197   SetMemoryOnlyMode();
2198   InitCache();
2199   PartialSparseEntry();
2200 }
2201
2202 // Tests that corrupt sparse children are removed automatically.
2203 TEST_F(DiskCacheEntryTest, CleanupSparseEntry) {
2204   InitCache();
2205   std::string key("the first key");
2206   disk_cache::Entry* entry;
2207   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
2208
2209   const int kSize = 4 * 1024;
2210   scoped_refptr<net::IOBuffer> buf1(new net::IOBuffer(kSize));
2211   CacheTestFillBuffer(buf1->data(), kSize, false);
2212
2213   const int k1Meg = 1024 * 1024;
2214   EXPECT_EQ(kSize, WriteSparseData(entry, 8192, buf1.get(), kSize));
2215   EXPECT_EQ(kSize, WriteSparseData(entry, k1Meg + 8192, buf1.get(), kSize));
2216   EXPECT_EQ(kSize, WriteSparseData(entry, 2 * k1Meg + 8192, buf1.get(), kSize));
2217   entry->Close();
2218   EXPECT_EQ(4, cache_->GetEntryCount());
2219
2220   scoped_ptr<TestIterator> iter = CreateIterator();
2221   int count = 0;
2222   std::string child_key[2];
2223   while (iter->OpenNextEntry(&entry) == net::OK) {
2224     ASSERT_TRUE(entry != NULL);
2225     // Writing to an entry will alter the LRU list and invalidate the iterator.
2226     if (entry->GetKey() != key && count < 2)
2227       child_key[count++] = entry->GetKey();
2228     entry->Close();
2229   }
2230   for (int i = 0; i < 2; i++) {
2231     ASSERT_EQ(net::OK, OpenEntry(child_key[i], &entry));
2232     // Overwrite the header's magic and signature.
2233     EXPECT_EQ(12, WriteData(entry, 2, 0, buf1.get(), 12, false));
2234     entry->Close();
2235   }
2236
2237   EXPECT_EQ(4, cache_->GetEntryCount());
2238   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
2239
2240   // Two children should be gone. One while reading and one while writing.
2241   EXPECT_EQ(0, ReadSparseData(entry, 2 * k1Meg + 8192, buf1.get(), kSize));
2242   EXPECT_EQ(kSize, WriteSparseData(entry, k1Meg + 16384, buf1.get(), kSize));
2243   EXPECT_EQ(0, ReadSparseData(entry, k1Meg + 8192, buf1.get(), kSize));
2244
2245   // We never touched this one.
2246   EXPECT_EQ(kSize, ReadSparseData(entry, 8192, buf1.get(), kSize));
2247   entry->Close();
2248
2249   // We re-created one of the corrupt children.
2250   EXPECT_EQ(3, cache_->GetEntryCount());
2251 }
2252
2253 TEST_F(DiskCacheEntryTest, CancelSparseIO) {
2254   UseCurrentThread();
2255   InitCache();
2256   std::string key("the first key");
2257   disk_cache::Entry* entry;
2258   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
2259
2260   const int kSize = 40 * 1024;
2261   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
2262   CacheTestFillBuffer(buf->data(), kSize, false);
2263
2264   // This will open and write two "real" entries.
2265   net::TestCompletionCallback cb1, cb2, cb3, cb4, cb5;
2266   int rv = entry->WriteSparseData(
2267       1024 * 1024 - 4096, buf.get(), kSize, cb1.callback());
2268   EXPECT_EQ(net::ERR_IO_PENDING, rv);
2269
2270   int64 offset = 0;
2271   rv = entry->GetAvailableRange(offset, kSize, &offset, cb5.callback());
2272   rv = cb5.GetResult(rv);
2273   if (!cb1.have_result()) {
2274     // We may or may not have finished writing to the entry. If we have not,
2275     // we cannot start another operation at this time.
2276     EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, rv);
2277   }
2278
2279   // We cancel the pending operation, and register multiple notifications.
2280   entry->CancelSparseIO();
2281   EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(cb2.callback()));
2282   EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(cb3.callback()));
2283   entry->CancelSparseIO();  // Should be a no op at this point.
2284   EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(cb4.callback()));
2285
2286   if (!cb1.have_result()) {
2287     EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED,
2288               entry->ReadSparseData(
2289                   offset, buf.get(), kSize, net::CompletionCallback()));
2290     EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED,
2291               entry->WriteSparseData(
2292                   offset, buf.get(), kSize, net::CompletionCallback()));
2293   }
2294
2295   // Now see if we receive all notifications. Note that we should not be able
2296   // to write everything (unless the timing of the system is really weird).
2297   rv = cb1.WaitForResult();
2298   EXPECT_TRUE(rv == 4096 || rv == kSize);
2299   EXPECT_EQ(net::OK, cb2.WaitForResult());
2300   EXPECT_EQ(net::OK, cb3.WaitForResult());
2301   EXPECT_EQ(net::OK, cb4.WaitForResult());
2302
2303   rv = entry->GetAvailableRange(offset, kSize, &offset, cb5.callback());
2304   EXPECT_EQ(0, cb5.GetResult(rv));
2305   entry->Close();
2306 }
2307
2308 // Tests that we perform sanity checks on an entry's key. Note that there are
2309 // other tests that exercise sanity checks by using saved corrupt files.
2310 TEST_F(DiskCacheEntryTest, KeySanityCheck) {
2311   UseCurrentThread();
2312   InitCache();
2313   std::string key("the first key");
2314   disk_cache::Entry* entry;
2315   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
2316
2317   disk_cache::EntryImpl* entry_impl =
2318       static_cast<disk_cache::EntryImpl*>(entry);
2319   disk_cache::EntryStore* store = entry_impl->entry()->Data();
2320
2321   // We have reserved space for a short key (one block), let's say that the key
2322   // takes more than one block, and remove the NULLs after the actual key.
2323   store->key_len = 800;
2324   memset(store->key + key.size(), 'k', sizeof(store->key) - key.size());
2325   entry_impl->entry()->set_modified();
2326   entry->Close();
2327
2328   // We have a corrupt entry. Now reload it. We should NOT read beyond the
2329   // allocated buffer here.
2330   ASSERT_NE(net::OK, OpenEntry(key, &entry));
2331   DisableIntegrityCheck();
2332 }
2333
2334 // The Simple Cache backend requires a few guarantees from the filesystem like
2335 // atomic renaming of recently open files. Those guarantees are not provided in
2336 // general on Windows.
2337 #if defined(OS_POSIX)
2338
2339 TEST_F(DiskCacheEntryTest, SimpleCacheInternalAsyncIO) {
2340   SetSimpleCacheMode();
2341   InitCache();
2342   InternalAsyncIO();
2343 }
2344
2345 TEST_F(DiskCacheEntryTest, SimpleCacheExternalAsyncIO) {
2346   SetSimpleCacheMode();
2347   InitCache();
2348   ExternalAsyncIO();
2349 }
2350
2351 TEST_F(DiskCacheEntryTest, SimpleCacheReleaseBuffer) {
2352   SetSimpleCacheMode();
2353   InitCache();
2354   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2355     EXPECT_EQ(net::OK, DoomAllEntries());
2356     ReleaseBuffer(i);
2357   }
2358 }
2359
2360 TEST_F(DiskCacheEntryTest, SimpleCacheStreamAccess) {
2361   SetSimpleCacheMode();
2362   InitCache();
2363   StreamAccess();
2364 }
2365
2366 TEST_F(DiskCacheEntryTest, SimpleCacheGetKey) {
2367   SetSimpleCacheMode();
2368   InitCache();
2369   GetKey();
2370 }
2371
2372 TEST_F(DiskCacheEntryTest, SimpleCacheGetTimes) {
2373   SetSimpleCacheMode();
2374   InitCache();
2375   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2376     EXPECT_EQ(net::OK, DoomAllEntries());
2377     GetTimes(i);
2378   }
2379 }
2380
2381 TEST_F(DiskCacheEntryTest, SimpleCacheGrowData) {
2382   SetSimpleCacheMode();
2383   InitCache();
2384   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2385     EXPECT_EQ(net::OK, DoomAllEntries());
2386     GrowData(i);
2387   }
2388 }
2389
2390 TEST_F(DiskCacheEntryTest, SimpleCacheTruncateData) {
2391   SetSimpleCacheMode();
2392   InitCache();
2393   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2394     EXPECT_EQ(net::OK, DoomAllEntries());
2395     TruncateData(i);
2396   }
2397 }
2398
2399 TEST_F(DiskCacheEntryTest, SimpleCacheZeroLengthIO) {
2400   SetSimpleCacheMode();
2401   InitCache();
2402   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2403     EXPECT_EQ(net::OK, DoomAllEntries());
2404     ZeroLengthIO(i);
2405   }
2406 }
2407
2408 TEST_F(DiskCacheEntryTest, SimpleCacheSizeAtCreate) {
2409   SetSimpleCacheMode();
2410   InitCache();
2411   SizeAtCreate();
2412 }
2413
2414 TEST_F(DiskCacheEntryTest, SimpleCacheReuseExternalEntry) {
2415   SetSimpleCacheMode();
2416   SetMaxSize(200 * 1024);
2417   InitCache();
2418   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2419     EXPECT_EQ(net::OK, DoomAllEntries());
2420     ReuseEntry(20 * 1024, i);
2421   }
2422 }
2423
2424 TEST_F(DiskCacheEntryTest, SimpleCacheReuseInternalEntry) {
2425   SetSimpleCacheMode();
2426   SetMaxSize(100 * 1024);
2427   InitCache();
2428   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2429     EXPECT_EQ(net::OK, DoomAllEntries());
2430     ReuseEntry(10 * 1024, i);
2431   }
2432 }
2433
2434 TEST_F(DiskCacheEntryTest, SimpleCacheSizeChanges) {
2435   SetSimpleCacheMode();
2436   InitCache();
2437   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2438     EXPECT_EQ(net::OK, DoomAllEntries());
2439     SizeChanges(i);
2440   }
2441 }
2442
2443 TEST_F(DiskCacheEntryTest, SimpleCacheInvalidData) {
2444   SetSimpleCacheMode();
2445   InitCache();
2446   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2447     EXPECT_EQ(net::OK, DoomAllEntries());
2448     InvalidData(i);
2449   }
2450 }
2451
2452 TEST_F(DiskCacheEntryTest, SimpleCacheReadWriteDestroyBuffer) {
2453   // Proving that the test works well with optimistic operations enabled is
2454   // subtle, instead run only in APP_CACHE mode to disable optimistic
2455   // operations. Stream 0 always uses optimistic operations, so the test is not
2456   // run on stream 0.
2457   SetCacheType(net::APP_CACHE);
2458   SetSimpleCacheMode();
2459   InitCache();
2460   for (int i = 1; i < disk_cache::kSimpleEntryStreamCount; ++i) {
2461     EXPECT_EQ(net::OK, DoomAllEntries());
2462     ReadWriteDestroyBuffer(i);
2463   }
2464 }
2465
2466 TEST_F(DiskCacheEntryTest, SimpleCacheDoomEntry) {
2467   SetSimpleCacheMode();
2468   InitCache();
2469   DoomNormalEntry();
2470 }
2471
2472 TEST_F(DiskCacheEntryTest, SimpleCacheDoomEntryNextToOpenEntry) {
2473   SetSimpleCacheMode();
2474   InitCache();
2475   DoomEntryNextToOpenEntry();
2476 }
2477
2478 TEST_F(DiskCacheEntryTest, SimpleCacheDoomedEntry) {
2479   SetSimpleCacheMode();
2480   InitCache();
2481   // Stream 2 is excluded because the implementation does not support writing to
2482   // it on a doomed entry, if it was previously lazily omitted.
2483   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount - 1; ++i) {
2484     EXPECT_EQ(net::OK, DoomAllEntries());
2485     DoomedEntry(i);
2486   }
2487 }
2488
2489 // Creates an entry with corrupted last byte in stream 0.
2490 // Requires SimpleCacheMode.
2491 bool DiskCacheEntryTest::SimpleCacheMakeBadChecksumEntry(const std::string& key,
2492                                                          int* data_size) {
2493   disk_cache::Entry* entry = NULL;
2494
2495   if (CreateEntry(key, &entry) != net::OK || !entry) {
2496     LOG(ERROR) << "Could not create entry";
2497     return false;
2498   }
2499
2500   const char data[] = "this is very good data";
2501   const int kDataSize = arraysize(data);
2502   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kDataSize));
2503   base::strlcpy(buffer->data(), data, kDataSize);
2504
2505   EXPECT_EQ(kDataSize, WriteData(entry, 1, 0, buffer.get(), kDataSize, false));
2506   entry->Close();
2507   entry = NULL;
2508
2509   // Corrupt the last byte of the data.
2510   base::FilePath entry_file0_path = cache_path_.AppendASCII(
2511       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
2512   base::File entry_file0(entry_file0_path,
2513                          base::File::FLAG_WRITE | base::File::FLAG_OPEN);
2514   if (!entry_file0.IsValid())
2515     return false;
2516
2517   int64 file_offset =
2518       sizeof(disk_cache::SimpleFileHeader) + key.size() + kDataSize - 2;
2519   EXPECT_EQ(1, entry_file0.Write(file_offset, "X", 1));
2520   *data_size = kDataSize;
2521   return true;
2522 }
2523
2524 // Tests that the simple cache can detect entries that have bad data.
2525 TEST_F(DiskCacheEntryTest, SimpleCacheBadChecksum) {
2526   SetSimpleCacheMode();
2527   InitCache();
2528
2529   const char key[] = "the first key";
2530   int size_unused;
2531   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size_unused));
2532
2533   disk_cache::Entry* entry = NULL;
2534
2535   // Open the entry.
2536   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
2537   ScopedEntryPtr entry_closer(entry);
2538
2539   const int kReadBufferSize = 200;
2540   EXPECT_GE(kReadBufferSize, entry->GetDataSize(1));
2541   scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kReadBufferSize));
2542   EXPECT_EQ(net::ERR_CACHE_CHECKSUM_MISMATCH,
2543             ReadData(entry, 1, 0, read_buffer.get(), kReadBufferSize));
2544 }
2545
2546 // Tests that an entry that has had an IO error occur can still be Doomed().
2547 TEST_F(DiskCacheEntryTest, SimpleCacheErrorThenDoom) {
2548   SetSimpleCacheMode();
2549   InitCache();
2550
2551   const char key[] = "the first key";
2552   int size_unused;
2553   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size_unused));
2554
2555   disk_cache::Entry* entry = NULL;
2556
2557   // Open the entry, forcing an IO error.
2558   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
2559   ScopedEntryPtr entry_closer(entry);
2560
2561   const int kReadBufferSize = 200;
2562   EXPECT_GE(kReadBufferSize, entry->GetDataSize(1));
2563   scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kReadBufferSize));
2564   EXPECT_EQ(net::ERR_CACHE_CHECKSUM_MISMATCH,
2565             ReadData(entry, 1, 0, read_buffer.get(), kReadBufferSize));
2566
2567   entry->Doom();  // Should not crash.
2568 }
2569
2570 bool TruncatePath(const base::FilePath& file_path, int64 length)  {
2571   base::File file(file_path, base::File::FLAG_WRITE | base::File::FLAG_OPEN);
2572   if (!file.IsValid())
2573     return false;
2574   return file.SetLength(length);
2575 }
2576
2577 TEST_F(DiskCacheEntryTest, SimpleCacheNoEOF) {
2578   SetSimpleCacheMode();
2579   InitCache();
2580
2581   const char key[] = "the first key";
2582
2583   disk_cache::Entry* entry = NULL;
2584   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
2585   disk_cache::Entry* null = NULL;
2586   EXPECT_NE(null, entry);
2587   entry->Close();
2588   entry = NULL;
2589
2590   // Force the entry to flush to disk, so subsequent platform file operations
2591   // succed.
2592   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
2593   entry->Close();
2594   entry = NULL;
2595
2596   // Truncate the file such that the length isn't sufficient to have an EOF
2597   // record.
2598   int kTruncationBytes = -implicit_cast<int>(sizeof(disk_cache::SimpleFileEOF));
2599   const base::FilePath entry_path = cache_path_.AppendASCII(
2600       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
2601   const int64 invalid_size =
2602       disk_cache::simple_util::GetFileSizeFromKeyAndDataSize(key,
2603                                                              kTruncationBytes);
2604   EXPECT_TRUE(TruncatePath(entry_path, invalid_size));
2605   EXPECT_EQ(net::ERR_FAILED, OpenEntry(key, &entry));
2606   DisableIntegrityCheck();
2607 }
2608
2609 TEST_F(DiskCacheEntryTest, SimpleCacheNonOptimisticOperationsBasic) {
2610   // Test sequence:
2611   // Create, Write, Read, Close.
2612   SetCacheType(net::APP_CACHE);  // APP_CACHE doesn't use optimistic operations.
2613   SetSimpleCacheMode();
2614   InitCache();
2615   disk_cache::Entry* const null_entry = NULL;
2616
2617   disk_cache::Entry* entry = NULL;
2618   EXPECT_EQ(net::OK, CreateEntry("my key", &entry));
2619   ASSERT_NE(null_entry, entry);
2620   ScopedEntryPtr entry_closer(entry);
2621
2622   const int kBufferSize = 10;
2623   scoped_refptr<net::IOBufferWithSize> write_buffer(
2624       new net::IOBufferWithSize(kBufferSize));
2625   CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false);
2626   EXPECT_EQ(
2627       write_buffer->size(),
2628       WriteData(entry, 1, 0, write_buffer.get(), write_buffer->size(), false));
2629
2630   scoped_refptr<net::IOBufferWithSize> read_buffer(
2631       new net::IOBufferWithSize(kBufferSize));
2632   EXPECT_EQ(read_buffer->size(),
2633             ReadData(entry, 1, 0, read_buffer.get(), read_buffer->size()));
2634 }
2635
2636 TEST_F(DiskCacheEntryTest, SimpleCacheNonOptimisticOperationsDontBlock) {
2637   // Test sequence:
2638   // Create, Write, Close.
2639   SetCacheType(net::APP_CACHE);  // APP_CACHE doesn't use optimistic operations.
2640   SetSimpleCacheMode();
2641   InitCache();
2642   disk_cache::Entry* const null_entry = NULL;
2643
2644   MessageLoopHelper helper;
2645   CallbackTest create_callback(&helper, false);
2646
2647   int expected_callback_runs = 0;
2648   const int kBufferSize = 10;
2649   scoped_refptr<net::IOBufferWithSize> write_buffer(
2650       new net::IOBufferWithSize(kBufferSize));
2651
2652   disk_cache::Entry* entry = NULL;
2653   EXPECT_EQ(net::OK, CreateEntry("my key", &entry));
2654   ASSERT_NE(null_entry, entry);
2655   ScopedEntryPtr entry_closer(entry);
2656
2657   CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false);
2658   CallbackTest write_callback(&helper, false);
2659   int ret = entry->WriteData(
2660       1,
2661       0,
2662       write_buffer.get(),
2663       write_buffer->size(),
2664       base::Bind(&CallbackTest::Run, base::Unretained(&write_callback)),
2665       false);
2666   ASSERT_EQ(net::ERR_IO_PENDING, ret);
2667   helper.WaitUntilCacheIoFinished(++expected_callback_runs);
2668 }
2669
2670 TEST_F(DiskCacheEntryTest,
2671        SimpleCacheNonOptimisticOperationsBasicsWithoutWaiting) {
2672   // Test sequence:
2673   // Create, Write, Read, Close.
2674   SetCacheType(net::APP_CACHE);  // APP_CACHE doesn't use optimistic operations.
2675   SetSimpleCacheMode();
2676   InitCache();
2677   disk_cache::Entry* const null_entry = NULL;
2678   MessageLoopHelper helper;
2679
2680   disk_cache::Entry* entry = NULL;
2681   // Note that |entry| is only set once CreateEntry() completed which is why we
2682   // have to wait (i.e. use the helper CreateEntry() function).
2683   EXPECT_EQ(net::OK, CreateEntry("my key", &entry));
2684   ASSERT_NE(null_entry, entry);
2685   ScopedEntryPtr entry_closer(entry);
2686
2687   const int kBufferSize = 10;
2688   scoped_refptr<net::IOBufferWithSize> write_buffer(
2689       new net::IOBufferWithSize(kBufferSize));
2690   CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false);
2691   CallbackTest write_callback(&helper, false);
2692   int ret = entry->WriteData(
2693       1,
2694       0,
2695       write_buffer.get(),
2696       write_buffer->size(),
2697       base::Bind(&CallbackTest::Run, base::Unretained(&write_callback)),
2698       false);
2699   EXPECT_EQ(net::ERR_IO_PENDING, ret);
2700   int expected_callback_runs = 1;
2701
2702   scoped_refptr<net::IOBufferWithSize> read_buffer(
2703       new net::IOBufferWithSize(kBufferSize));
2704   CallbackTest read_callback(&helper, false);
2705   ret = entry->ReadData(
2706       1,
2707       0,
2708       read_buffer.get(),
2709       read_buffer->size(),
2710       base::Bind(&CallbackTest::Run, base::Unretained(&read_callback)));
2711   EXPECT_EQ(net::ERR_IO_PENDING, ret);
2712   ++expected_callback_runs;
2713
2714   helper.WaitUntilCacheIoFinished(expected_callback_runs);
2715   ASSERT_EQ(read_buffer->size(), write_buffer->size());
2716   EXPECT_EQ(
2717       0,
2718       memcmp(read_buffer->data(), write_buffer->data(), read_buffer->size()));
2719 }
2720
2721 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic) {
2722   // Test sequence:
2723   // Create, Write, Read, Write, Read, Close.
2724   SetSimpleCacheMode();
2725   InitCache();
2726   disk_cache::Entry* null = NULL;
2727   const char key[] = "the first key";
2728
2729   MessageLoopHelper helper;
2730   CallbackTest callback1(&helper, false);
2731   CallbackTest callback2(&helper, false);
2732   CallbackTest callback3(&helper, false);
2733   CallbackTest callback4(&helper, false);
2734   CallbackTest callback5(&helper, false);
2735
2736   int expected = 0;
2737   const int kSize1 = 10;
2738   const int kSize2 = 20;
2739   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
2740   scoped_refptr<net::IOBuffer> buffer1_read(new net::IOBuffer(kSize1));
2741   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
2742   scoped_refptr<net::IOBuffer> buffer2_read(new net::IOBuffer(kSize2));
2743   CacheTestFillBuffer(buffer1->data(), kSize1, false);
2744   CacheTestFillBuffer(buffer2->data(), kSize2, false);
2745
2746   disk_cache::Entry* entry = NULL;
2747   // Create is optimistic, must return OK.
2748   ASSERT_EQ(net::OK,
2749             cache_->CreateEntry(key, &entry,
2750                                 base::Bind(&CallbackTest::Run,
2751                                            base::Unretained(&callback1))));
2752   EXPECT_NE(null, entry);
2753   ScopedEntryPtr entry_closer(entry);
2754
2755   // This write may or may not be optimistic (it depends if the previous
2756   // optimistic create already finished by the time we call the write here).
2757   int ret = entry->WriteData(
2758       1,
2759       0,
2760       buffer1.get(),
2761       kSize1,
2762       base::Bind(&CallbackTest::Run, base::Unretained(&callback2)),
2763       false);
2764   EXPECT_TRUE(kSize1 == ret || net::ERR_IO_PENDING == ret);
2765   if (net::ERR_IO_PENDING == ret)
2766     expected++;
2767
2768   // This Read must not be optimistic, since we don't support that yet.
2769   EXPECT_EQ(net::ERR_IO_PENDING,
2770             entry->ReadData(
2771                 1,
2772                 0,
2773                 buffer1_read.get(),
2774                 kSize1,
2775                 base::Bind(&CallbackTest::Run, base::Unretained(&callback3))));
2776   expected++;
2777   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
2778   EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read->data(), kSize1));
2779
2780   // At this point after waiting, the pending operations queue on the entry
2781   // should be empty, so the next Write operation must run as optimistic.
2782   EXPECT_EQ(kSize2,
2783             entry->WriteData(
2784                 1,
2785                 0,
2786                 buffer2.get(),
2787                 kSize2,
2788                 base::Bind(&CallbackTest::Run, base::Unretained(&callback4)),
2789                 false));
2790
2791   // Lets do another read so we block until both the write and the read
2792   // operation finishes and we can then test for HasOneRef() below.
2793   EXPECT_EQ(net::ERR_IO_PENDING,
2794             entry->ReadData(
2795                 1,
2796                 0,
2797                 buffer2_read.get(),
2798                 kSize2,
2799                 base::Bind(&CallbackTest::Run, base::Unretained(&callback5))));
2800   expected++;
2801
2802   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
2803   EXPECT_EQ(0, memcmp(buffer2->data(), buffer2_read->data(), kSize2));
2804
2805   // Check that we are not leaking.
2806   EXPECT_NE(entry, null);
2807   EXPECT_TRUE(
2808       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
2809 }
2810
2811 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic2) {
2812   // Test sequence:
2813   // Create, Open, Close, Close.
2814   SetSimpleCacheMode();
2815   InitCache();
2816   disk_cache::Entry* null = NULL;
2817   const char key[] = "the first key";
2818
2819   MessageLoopHelper helper;
2820   CallbackTest callback1(&helper, false);
2821   CallbackTest callback2(&helper, false);
2822
2823   disk_cache::Entry* entry = NULL;
2824   ASSERT_EQ(net::OK,
2825             cache_->CreateEntry(key, &entry,
2826                                 base::Bind(&CallbackTest::Run,
2827                                            base::Unretained(&callback1))));
2828   EXPECT_NE(null, entry);
2829   ScopedEntryPtr entry_closer(entry);
2830
2831   disk_cache::Entry* entry2 = NULL;
2832   ASSERT_EQ(net::ERR_IO_PENDING,
2833             cache_->OpenEntry(key, &entry2,
2834                               base::Bind(&CallbackTest::Run,
2835                                          base::Unretained(&callback2))));
2836   ASSERT_TRUE(helper.WaitUntilCacheIoFinished(1));
2837
2838   EXPECT_NE(null, entry2);
2839   EXPECT_EQ(entry, entry2);
2840
2841   // We have to call close twice, since we called create and open above.
2842   entry->Close();
2843
2844   // Check that we are not leaking.
2845   EXPECT_TRUE(
2846       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
2847 }
2848
2849 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic3) {
2850   // Test sequence:
2851   // Create, Close, Open, Close.
2852   SetSimpleCacheMode();
2853   InitCache();
2854   disk_cache::Entry* null = NULL;
2855   const char key[] = "the first key";
2856
2857   disk_cache::Entry* entry = NULL;
2858   ASSERT_EQ(net::OK,
2859             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
2860   EXPECT_NE(null, entry);
2861   entry->Close();
2862
2863   net::TestCompletionCallback cb;
2864   disk_cache::Entry* entry2 = NULL;
2865   ASSERT_EQ(net::ERR_IO_PENDING,
2866             cache_->OpenEntry(key, &entry2, cb.callback()));
2867   ASSERT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
2868   ScopedEntryPtr entry_closer(entry2);
2869
2870   EXPECT_NE(null, entry2);
2871   EXPECT_EQ(entry, entry2);
2872
2873   // Check that we are not leaking.
2874   EXPECT_TRUE(
2875       static_cast<disk_cache::SimpleEntryImpl*>(entry2)->HasOneRef());
2876 }
2877
2878 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic4) {
2879   // Test sequence:
2880   // Create, Close, Write, Open, Open, Close, Write, Read, Close.
2881   SetSimpleCacheMode();
2882   InitCache();
2883   disk_cache::Entry* null = NULL;
2884   const char key[] = "the first key";
2885
2886   net::TestCompletionCallback cb;
2887   const int kSize1 = 10;
2888   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
2889   CacheTestFillBuffer(buffer1->data(), kSize1, false);
2890   disk_cache::Entry* entry = NULL;
2891
2892   ASSERT_EQ(net::OK,
2893             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
2894   EXPECT_NE(null, entry);
2895   entry->Close();
2896
2897   // Lets do a Write so we block until both the Close and the Write
2898   // operation finishes. Write must fail since we are writing in a closed entry.
2899   EXPECT_EQ(
2900       net::ERR_IO_PENDING,
2901       entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false));
2902   EXPECT_EQ(net::ERR_FAILED, cb.GetResult(net::ERR_IO_PENDING));
2903
2904   // Finish running the pending tasks so that we fully complete the close
2905   // operation and destroy the entry object.
2906   base::MessageLoop::current()->RunUntilIdle();
2907
2908   // At this point the |entry| must have been destroyed, and called
2909   // RemoveSelfFromBackend().
2910   disk_cache::Entry* entry2 = NULL;
2911   ASSERT_EQ(net::ERR_IO_PENDING,
2912             cache_->OpenEntry(key, &entry2, cb.callback()));
2913   ASSERT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
2914   EXPECT_NE(null, entry2);
2915
2916   disk_cache::Entry* entry3 = NULL;
2917   ASSERT_EQ(net::ERR_IO_PENDING,
2918             cache_->OpenEntry(key, &entry3, cb.callback()));
2919   ASSERT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
2920   EXPECT_NE(null, entry3);
2921   EXPECT_EQ(entry2, entry3);
2922   entry3->Close();
2923
2924   // The previous Close doesn't actually closes the entry since we opened it
2925   // twice, so the next Write operation must succeed and it must be able to
2926   // perform it optimistically, since there is no operation running on this
2927   // entry.
2928   EXPECT_EQ(kSize1,
2929             entry2->WriteData(
2930                 1, 0, buffer1.get(), kSize1, net::CompletionCallback(), false));
2931
2932   // Lets do another read so we block until both the write and the read
2933   // operation finishes and we can then test for HasOneRef() below.
2934   EXPECT_EQ(net::ERR_IO_PENDING,
2935             entry2->ReadData(1, 0, buffer1.get(), kSize1, cb.callback()));
2936   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
2937
2938   // Check that we are not leaking.
2939   EXPECT_TRUE(
2940       static_cast<disk_cache::SimpleEntryImpl*>(entry2)->HasOneRef());
2941   entry2->Close();
2942 }
2943
2944 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic5) {
2945   // Test sequence:
2946   // Create, Doom, Write, Read, Close.
2947   SetSimpleCacheMode();
2948   InitCache();
2949   disk_cache::Entry* null = NULL;
2950   const char key[] = "the first key";
2951
2952   net::TestCompletionCallback cb;
2953   const int kSize1 = 10;
2954   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
2955   CacheTestFillBuffer(buffer1->data(), kSize1, false);
2956   disk_cache::Entry* entry = NULL;
2957
2958   ASSERT_EQ(net::OK,
2959             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
2960   EXPECT_NE(null, entry);
2961   ScopedEntryPtr entry_closer(entry);
2962   entry->Doom();
2963
2964   EXPECT_EQ(
2965       net::ERR_IO_PENDING,
2966       entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false));
2967   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
2968
2969   EXPECT_EQ(net::ERR_IO_PENDING,
2970             entry->ReadData(1, 0, buffer1.get(), kSize1, cb.callback()));
2971   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
2972
2973   // Check that we are not leaking.
2974   EXPECT_TRUE(
2975       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
2976 }
2977
2978 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic6) {
2979   // Test sequence:
2980   // Create, Write, Doom, Doom, Read, Doom, Close.
2981   SetSimpleCacheMode();
2982   InitCache();
2983   disk_cache::Entry* null = NULL;
2984   const char key[] = "the first key";
2985
2986   net::TestCompletionCallback cb;
2987   const int kSize1 = 10;
2988   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
2989   scoped_refptr<net::IOBuffer> buffer1_read(new net::IOBuffer(kSize1));
2990   CacheTestFillBuffer(buffer1->data(), kSize1, false);
2991   disk_cache::Entry* entry = NULL;
2992
2993   ASSERT_EQ(net::OK,
2994             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
2995   EXPECT_NE(null, entry);
2996   ScopedEntryPtr entry_closer(entry);
2997
2998   EXPECT_EQ(
2999       net::ERR_IO_PENDING,
3000       entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false));
3001   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
3002
3003   entry->Doom();
3004   entry->Doom();
3005
3006   // This Read must not be optimistic, since we don't support that yet.
3007   EXPECT_EQ(net::ERR_IO_PENDING,
3008             entry->ReadData(1, 0, buffer1_read.get(), kSize1, cb.callback()));
3009   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
3010   EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read->data(), kSize1));
3011
3012   entry->Doom();
3013 }
3014
3015 // Confirm that IO buffers are not referenced by the Simple Cache after a write
3016 // completes.
3017 TEST_F(DiskCacheEntryTest, SimpleCacheOptimisticWriteReleases) {
3018   SetSimpleCacheMode();
3019   InitCache();
3020
3021   const char key[] = "the first key";
3022   disk_cache::Entry* entry = NULL;
3023
3024   // First, an optimistic create.
3025   ASSERT_EQ(net::OK,
3026             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
3027   ASSERT_TRUE(entry);
3028   ScopedEntryPtr entry_closer(entry);
3029
3030   const int kWriteSize = 512;
3031   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kWriteSize));
3032   EXPECT_TRUE(buffer1->HasOneRef());
3033   CacheTestFillBuffer(buffer1->data(), kWriteSize, false);
3034
3035   // An optimistic write happens only when there is an empty queue of pending
3036   // operations. To ensure the queue is empty, we issue a write and wait until
3037   // it completes.
3038   EXPECT_EQ(kWriteSize,
3039             WriteData(entry, 1, 0, buffer1.get(), kWriteSize, false));
3040   EXPECT_TRUE(buffer1->HasOneRef());
3041
3042   // Finally, we should perform an optimistic write and confirm that all
3043   // references to the IO buffer have been released.
3044   EXPECT_EQ(
3045       kWriteSize,
3046       entry->WriteData(
3047           1, 0, buffer1.get(), kWriteSize, net::CompletionCallback(), false));
3048   EXPECT_TRUE(buffer1->HasOneRef());
3049 }
3050
3051 TEST_F(DiskCacheEntryTest, SimpleCacheCreateDoomRace) {
3052   // Test sequence:
3053   // Create, Doom, Write, Close, Check files are not on disk anymore.
3054   SetSimpleCacheMode();
3055   InitCache();
3056   disk_cache::Entry* null = NULL;
3057   const char key[] = "the first key";
3058
3059   net::TestCompletionCallback cb;
3060   const int kSize1 = 10;
3061   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
3062   CacheTestFillBuffer(buffer1->data(), kSize1, false);
3063   disk_cache::Entry* entry = NULL;
3064
3065   ASSERT_EQ(net::OK,
3066             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
3067   EXPECT_NE(null, entry);
3068
3069   EXPECT_EQ(net::ERR_IO_PENDING, cache_->DoomEntry(key, cb.callback()));
3070   EXPECT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
3071
3072   EXPECT_EQ(
3073       kSize1,
3074       entry->WriteData(0, 0, buffer1.get(), kSize1, cb.callback(), false));
3075
3076   entry->Close();
3077
3078   // Finish running the pending tasks so that we fully complete the close
3079   // operation and destroy the entry object.
3080   base::MessageLoop::current()->RunUntilIdle();
3081
3082   for (int i = 0; i < disk_cache::kSimpleEntryFileCount; ++i) {
3083     base::FilePath entry_file_path = cache_path_.AppendASCII(
3084         disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, i));
3085     base::File::Info info;
3086     EXPECT_FALSE(base::GetFileInfo(entry_file_path, &info));
3087   }
3088 }
3089
3090 TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateRace) {
3091   // This test runs as APP_CACHE to make operations more synchronous. Test
3092   // sequence:
3093   // Create, Doom, Create.
3094   SetCacheType(net::APP_CACHE);
3095   SetSimpleCacheMode();
3096   InitCache();
3097   disk_cache::Entry* null = NULL;
3098   const char key[] = "the first key";
3099
3100   net::TestCompletionCallback create_callback;
3101
3102   disk_cache::Entry* entry1 = NULL;
3103   ASSERT_EQ(net::OK,
3104             create_callback.GetResult(
3105                 cache_->CreateEntry(key, &entry1, create_callback.callback())));
3106   ScopedEntryPtr entry1_closer(entry1);
3107   EXPECT_NE(null, entry1);
3108
3109   net::TestCompletionCallback doom_callback;
3110   EXPECT_EQ(net::ERR_IO_PENDING,
3111             cache_->DoomEntry(key, doom_callback.callback()));
3112
3113   disk_cache::Entry* entry2 = NULL;
3114   ASSERT_EQ(net::OK,
3115             create_callback.GetResult(
3116                 cache_->CreateEntry(key, &entry2, create_callback.callback())));
3117   ScopedEntryPtr entry2_closer(entry2);
3118   EXPECT_EQ(net::OK, doom_callback.GetResult(net::ERR_IO_PENDING));
3119 }
3120
3121 TEST_F(DiskCacheEntryTest, SimpleCacheDoomDoom) {
3122   // Test sequence:
3123   // Create, Doom, Create, Doom (1st entry), Open.
3124   SetSimpleCacheMode();
3125   InitCache();
3126   disk_cache::Entry* null = NULL;
3127
3128   const char key[] = "the first key";
3129
3130   disk_cache::Entry* entry1 = NULL;
3131   ASSERT_EQ(net::OK, CreateEntry(key, &entry1));
3132   ScopedEntryPtr entry1_closer(entry1);
3133   EXPECT_NE(null, entry1);
3134
3135   EXPECT_EQ(net::OK, DoomEntry(key));
3136
3137   disk_cache::Entry* entry2 = NULL;
3138   ASSERT_EQ(net::OK, CreateEntry(key, &entry2));
3139   ScopedEntryPtr entry2_closer(entry2);
3140   EXPECT_NE(null, entry2);
3141
3142   // Redundantly dooming entry1 should not delete entry2.
3143   disk_cache::SimpleEntryImpl* simple_entry1 =
3144       static_cast<disk_cache::SimpleEntryImpl*>(entry1);
3145   net::TestCompletionCallback cb;
3146   EXPECT_EQ(net::OK,
3147             cb.GetResult(simple_entry1->DoomEntry(cb.callback())));
3148
3149   disk_cache::Entry* entry3 = NULL;
3150   ASSERT_EQ(net::OK, OpenEntry(key, &entry3));
3151   ScopedEntryPtr entry3_closer(entry3);
3152   EXPECT_NE(null, entry3);
3153 }
3154
3155 TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateDoom) {
3156   // Test sequence:
3157   // Create, Doom, Create, Doom.
3158   SetSimpleCacheMode();
3159   InitCache();
3160
3161   disk_cache::Entry* null = NULL;
3162
3163   const char key[] = "the first key";
3164
3165   disk_cache::Entry* entry1 = NULL;
3166   ASSERT_EQ(net::OK, CreateEntry(key, &entry1));
3167   ScopedEntryPtr entry1_closer(entry1);
3168   EXPECT_NE(null, entry1);
3169
3170   entry1->Doom();
3171
3172   disk_cache::Entry* entry2 = NULL;
3173   ASSERT_EQ(net::OK, CreateEntry(key, &entry2));
3174   ScopedEntryPtr entry2_closer(entry2);
3175   EXPECT_NE(null, entry2);
3176
3177   entry2->Doom();
3178
3179   // This test passes if it doesn't crash.
3180 }
3181
3182 TEST_F(DiskCacheEntryTest, SimpleCacheDoomCloseCreateCloseOpen) {
3183   // Test sequence: Create, Doom, Close, Create, Close, Open.
3184   SetSimpleCacheMode();
3185   InitCache();
3186
3187   disk_cache::Entry* null = NULL;
3188
3189   const char key[] = "this is a key";
3190
3191   disk_cache::Entry* entry1 = NULL;
3192   ASSERT_EQ(net::OK, CreateEntry(key, &entry1));
3193   ScopedEntryPtr entry1_closer(entry1);
3194   EXPECT_NE(null, entry1);
3195
3196   entry1->Doom();
3197   entry1_closer.reset();
3198   entry1 = NULL;
3199
3200   disk_cache::Entry* entry2 = NULL;
3201   ASSERT_EQ(net::OK, CreateEntry(key, &entry2));
3202   ScopedEntryPtr entry2_closer(entry2);
3203   EXPECT_NE(null, entry2);
3204
3205   entry2_closer.reset();
3206   entry2 = NULL;
3207
3208   disk_cache::Entry* entry3 = NULL;
3209   ASSERT_EQ(net::OK, OpenEntry(key, &entry3));
3210   ScopedEntryPtr entry3_closer(entry3);
3211   EXPECT_NE(null, entry3);
3212 }
3213
3214 // Checks that an optimistic Create would fail later on a racing Open.
3215 TEST_F(DiskCacheEntryTest, SimpleCacheOptimisticCreateFailsOnOpen) {
3216   SetSimpleCacheMode();
3217   InitCache();
3218
3219   // Create a corrupt file in place of a future entry. Optimistic create should
3220   // initially succeed, but realize later that creation failed.
3221   const std::string key = "the key";
3222   net::TestCompletionCallback cb;
3223   disk_cache::Entry* entry = NULL;
3224   disk_cache::Entry* entry2 = NULL;
3225
3226   EXPECT_TRUE(disk_cache::simple_util::CreateCorruptFileForTests(
3227       key, cache_path_));
3228   EXPECT_EQ(net::OK, cache_->CreateEntry(key, &entry, cb.callback()));
3229   ASSERT_TRUE(entry);
3230   ScopedEntryPtr entry_closer(entry);
3231   ASSERT_NE(net::OK, OpenEntry(key, &entry2));
3232
3233   // Check that we are not leaking.
3234   EXPECT_TRUE(
3235       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
3236
3237   DisableIntegrityCheck();
3238 }
3239
3240 // Tests that old entries are evicted while new entries remain in the index.
3241 // This test relies on non-mandatory properties of the simple Cache Backend:
3242 // LRU eviction, specific values of high-watermark and low-watermark etc.
3243 // When changing the eviction algorithm, the test will have to be re-engineered.
3244 TEST_F(DiskCacheEntryTest, SimpleCacheEvictOldEntries) {
3245   const int kMaxSize = 200 * 1024;
3246   const int kWriteSize = kMaxSize / 10;
3247   const int kNumExtraEntries = 12;
3248   SetSimpleCacheMode();
3249   SetMaxSize(kMaxSize);
3250   InitCache();
3251
3252   std::string key1("the first key");
3253   disk_cache::Entry* entry;
3254   ASSERT_EQ(net::OK, CreateEntry(key1, &entry));
3255   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kWriteSize));
3256   CacheTestFillBuffer(buffer->data(), kWriteSize, false);
3257   EXPECT_EQ(kWriteSize,
3258             WriteData(entry, 1, 0, buffer.get(), kWriteSize, false));
3259   entry->Close();
3260   AddDelay();
3261
3262   std::string key2("the key prefix");
3263   for (int i = 0; i < kNumExtraEntries; i++) {
3264     if (i == kNumExtraEntries - 2) {
3265       // Create a distinct timestamp for the last two entries. These entries
3266       // will be checked for outliving the eviction.
3267       AddDelay();
3268     }
3269     ASSERT_EQ(net::OK, CreateEntry(key2 + base::StringPrintf("%d", i), &entry));
3270     ScopedEntryPtr entry_closer(entry);
3271     EXPECT_EQ(kWriteSize,
3272               WriteData(entry, 1, 0, buffer.get(), kWriteSize, false));
3273   }
3274
3275   // TODO(pasko): Find a way to wait for the eviction task(s) to finish by using
3276   // the internal knowledge about |SimpleBackendImpl|.
3277   ASSERT_NE(net::OK, OpenEntry(key1, &entry))
3278       << "Should have evicted the old entry";
3279   for (int i = 0; i < 2; i++) {
3280     int entry_no = kNumExtraEntries - i - 1;
3281     // Generally there is no guarantee that at this point the backround eviction
3282     // is finished. We are testing the positive case, i.e. when the eviction
3283     // never reaches this entry, should be non-flaky.
3284     ASSERT_EQ(net::OK, OpenEntry(key2 + base::StringPrintf("%d", entry_no),
3285                                  &entry))
3286         << "Should not have evicted fresh entry " << entry_no;
3287     entry->Close();
3288   }
3289 }
3290
3291 // Tests that if a read and a following in-flight truncate are both in progress
3292 // simultaniously that they both can occur successfully. See
3293 // http://crbug.com/239223
3294 TEST_F(DiskCacheEntryTest, SimpleCacheInFlightTruncate)  {
3295   SetSimpleCacheMode();
3296   InitCache();
3297
3298   const char key[] = "the first key";
3299
3300   const int kBufferSize = 1024;
3301   scoped_refptr<net::IOBuffer> write_buffer(new net::IOBuffer(kBufferSize));
3302   CacheTestFillBuffer(write_buffer->data(), kBufferSize, false);
3303
3304   disk_cache::Entry* entry = NULL;
3305   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3306
3307   EXPECT_EQ(kBufferSize,
3308             WriteData(entry, 1, 0, write_buffer.get(), kBufferSize, false));
3309   entry->Close();
3310   entry = NULL;
3311
3312   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3313   ScopedEntryPtr entry_closer(entry);
3314
3315   MessageLoopHelper helper;
3316   int expected = 0;
3317
3318   // Make a short read.
3319   const int kReadBufferSize = 512;
3320   scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kReadBufferSize));
3321   CallbackTest read_callback(&helper, false);
3322   EXPECT_EQ(net::ERR_IO_PENDING,
3323             entry->ReadData(1,
3324                             0,
3325                             read_buffer.get(),
3326                             kReadBufferSize,
3327                             base::Bind(&CallbackTest::Run,
3328                                        base::Unretained(&read_callback))));
3329   ++expected;
3330
3331   // Truncate the entry to the length of that read.
3332   scoped_refptr<net::IOBuffer>
3333       truncate_buffer(new net::IOBuffer(kReadBufferSize));
3334   CacheTestFillBuffer(truncate_buffer->data(), kReadBufferSize, false);
3335   CallbackTest truncate_callback(&helper, false);
3336   EXPECT_EQ(net::ERR_IO_PENDING,
3337             entry->WriteData(1,
3338                              0,
3339                              truncate_buffer.get(),
3340                              kReadBufferSize,
3341                              base::Bind(&CallbackTest::Run,
3342                                         base::Unretained(&truncate_callback)),
3343                              true));
3344   ++expected;
3345
3346   // Wait for both the read and truncation to finish, and confirm that both
3347   // succeeded.
3348   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
3349   EXPECT_EQ(kReadBufferSize, read_callback.last_result());
3350   EXPECT_EQ(kReadBufferSize, truncate_callback.last_result());
3351   EXPECT_EQ(0,
3352             memcmp(write_buffer->data(), read_buffer->data(), kReadBufferSize));
3353 }
3354
3355 // Tests that if a write and a read dependant on it are both in flight
3356 // simultaneiously that they both can complete successfully without erroneous
3357 // early returns. See http://crbug.com/239223
3358 TEST_F(DiskCacheEntryTest, SimpleCacheInFlightRead) {
3359   SetSimpleCacheMode();
3360   InitCache();
3361
3362   const char key[] = "the first key";
3363   disk_cache::Entry* entry = NULL;
3364   ASSERT_EQ(net::OK,
3365             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
3366   ScopedEntryPtr entry_closer(entry);
3367
3368   const int kBufferSize = 1024;
3369   scoped_refptr<net::IOBuffer> write_buffer(new net::IOBuffer(kBufferSize));
3370   CacheTestFillBuffer(write_buffer->data(), kBufferSize, false);
3371
3372   MessageLoopHelper helper;
3373   int expected = 0;
3374
3375   CallbackTest write_callback(&helper, false);
3376   EXPECT_EQ(net::ERR_IO_PENDING,
3377             entry->WriteData(1,
3378                              0,
3379                              write_buffer.get(),
3380                              kBufferSize,
3381                              base::Bind(&CallbackTest::Run,
3382                                         base::Unretained(&write_callback)),
3383                              true));
3384   ++expected;
3385
3386   scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kBufferSize));
3387   CallbackTest read_callback(&helper, false);
3388   EXPECT_EQ(net::ERR_IO_PENDING,
3389             entry->ReadData(1,
3390                             0,
3391                             read_buffer.get(),
3392                             kBufferSize,
3393                             base::Bind(&CallbackTest::Run,
3394                                        base::Unretained(&read_callback))));
3395   ++expected;
3396
3397   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
3398   EXPECT_EQ(kBufferSize, write_callback.last_result());
3399   EXPECT_EQ(kBufferSize, read_callback.last_result());
3400   EXPECT_EQ(0, memcmp(write_buffer->data(), read_buffer->data(), kBufferSize));
3401 }
3402
3403 TEST_F(DiskCacheEntryTest, SimpleCacheOpenCreateRaceWithNoIndex) {
3404   SetSimpleCacheMode();
3405   DisableSimpleCacheWaitForIndex();
3406   DisableIntegrityCheck();
3407   InitCache();
3408
3409   // Assume the index is not initialized, which is likely, since we are blocking
3410   // the IO thread from executing the index finalization step.
3411   disk_cache::Entry* entry1;
3412   net::TestCompletionCallback cb1;
3413   disk_cache::Entry* entry2;
3414   net::TestCompletionCallback cb2;
3415   int rv1 = cache_->OpenEntry("key", &entry1, cb1.callback());
3416   int rv2 = cache_->CreateEntry("key", &entry2, cb2.callback());
3417
3418   EXPECT_EQ(net::ERR_FAILED, cb1.GetResult(rv1));
3419   ASSERT_EQ(net::OK, cb2.GetResult(rv2));
3420   entry2->Close();
3421 }
3422
3423 // Checks that reading two entries simultaneously does not discard a CRC check.
3424 // TODO(pasko): make it work with Simple Cache.
3425 TEST_F(DiskCacheEntryTest, DISABLED_SimpleCacheMultipleReadersCheckCRC) {
3426   SetSimpleCacheMode();
3427   InitCache();
3428
3429   const char key[] = "key";
3430
3431   int size;
3432   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size));
3433
3434   scoped_refptr<net::IOBuffer> read_buffer1(new net::IOBuffer(size));
3435   scoped_refptr<net::IOBuffer> read_buffer2(new net::IOBuffer(size));
3436
3437   // Advance the first reader a little.
3438   disk_cache::Entry* entry = NULL;
3439   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3440   EXPECT_EQ(1, ReadData(entry, 0, 0, read_buffer1.get(), 1));
3441
3442   // Make the second reader pass the point where the first one is, and close.
3443   disk_cache::Entry* entry2 = NULL;
3444   EXPECT_EQ(net::OK, OpenEntry(key, &entry2));
3445   EXPECT_EQ(1, ReadData(entry2, 0, 0, read_buffer2.get(), 1));
3446   EXPECT_EQ(1, ReadData(entry2, 0, 1, read_buffer2.get(), 1));
3447   entry2->Close();
3448
3449   // Read the data till the end should produce an error.
3450   EXPECT_GT(0, ReadData(entry, 0, 1, read_buffer1.get(), size));
3451   entry->Close();
3452   DisableIntegrityCheck();
3453 }
3454
3455 // Checking one more scenario of overlapped reading of a bad entry.
3456 // Differs from the |SimpleCacheMultipleReadersCheckCRC| only by the order of
3457 // last two reads.
3458 TEST_F(DiskCacheEntryTest, SimpleCacheMultipleReadersCheckCRC2) {
3459   SetSimpleCacheMode();
3460   InitCache();
3461
3462   const char key[] = "key";
3463   int size;
3464   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size));
3465
3466   scoped_refptr<net::IOBuffer> read_buffer1(new net::IOBuffer(size));
3467   scoped_refptr<net::IOBuffer> read_buffer2(new net::IOBuffer(size));
3468
3469   // Advance the first reader a little.
3470   disk_cache::Entry* entry = NULL;
3471   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3472   ScopedEntryPtr entry_closer(entry);
3473   EXPECT_EQ(1, ReadData(entry, 1, 0, read_buffer1.get(), 1));
3474
3475   // Advance the 2nd reader by the same amount.
3476   disk_cache::Entry* entry2 = NULL;
3477   EXPECT_EQ(net::OK, OpenEntry(key, &entry2));
3478   ScopedEntryPtr entry2_closer(entry2);
3479   EXPECT_EQ(1, ReadData(entry2, 1, 0, read_buffer2.get(), 1));
3480
3481   // Continue reading 1st.
3482   EXPECT_GT(0, ReadData(entry, 1, 1, read_buffer1.get(), size));
3483
3484   // This read should fail as well because we have previous read failures.
3485   EXPECT_GT(0, ReadData(entry2, 1, 1, read_buffer2.get(), 1));
3486   DisableIntegrityCheck();
3487 }
3488
3489 // Test if we can sequentially read each subset of the data until all the data
3490 // is read, then the CRC is calculated correctly and the reads are successful.
3491 TEST_F(DiskCacheEntryTest, SimpleCacheReadCombineCRC) {
3492   // Test sequence:
3493   // Create, Write, Read (first half of data), Read (second half of data),
3494   // Close.
3495   SetSimpleCacheMode();
3496   InitCache();
3497   disk_cache::Entry* null = NULL;
3498   const char key[] = "the first key";
3499
3500   const int kHalfSize = 200;
3501   const int kSize = 2 * kHalfSize;
3502   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
3503   CacheTestFillBuffer(buffer1->data(), kSize, false);
3504   disk_cache::Entry* entry = NULL;
3505
3506   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3507   EXPECT_NE(null, entry);
3508
3509   EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer1.get(), kSize, false));
3510   entry->Close();
3511
3512   disk_cache::Entry* entry2 = NULL;
3513   ASSERT_EQ(net::OK, OpenEntry(key, &entry2));
3514   EXPECT_EQ(entry, entry2);
3515
3516   // Read the first half of the data.
3517   int offset = 0;
3518   int buf_len = kHalfSize;
3519   scoped_refptr<net::IOBuffer> buffer1_read1(new net::IOBuffer(buf_len));
3520   EXPECT_EQ(buf_len, ReadData(entry2, 1, offset, buffer1_read1.get(), buf_len));
3521   EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), buf_len));
3522
3523   // Read the second half of the data.
3524   offset = buf_len;
3525   buf_len = kHalfSize;
3526   scoped_refptr<net::IOBuffer> buffer1_read2(new net::IOBuffer(buf_len));
3527   EXPECT_EQ(buf_len, ReadData(entry2, 1, offset, buffer1_read2.get(), buf_len));
3528   char* buffer1_data = buffer1->data() + offset;
3529   EXPECT_EQ(0, memcmp(buffer1_data, buffer1_read2->data(), buf_len));
3530
3531   // Check that we are not leaking.
3532   EXPECT_NE(entry, null);
3533   EXPECT_TRUE(
3534       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
3535   entry->Close();
3536   entry = NULL;
3537 }
3538
3539 // Test if we can write the data not in sequence and read correctly. In
3540 // this case the CRC will not be present.
3541 TEST_F(DiskCacheEntryTest, SimpleCacheNonSequentialWrite) {
3542   // Test sequence:
3543   // Create, Write (second half of data), Write (first half of data), Read,
3544   // Close.
3545   SetSimpleCacheMode();
3546   InitCache();
3547   disk_cache::Entry* null = NULL;
3548   const char key[] = "the first key";
3549
3550   const int kHalfSize = 200;
3551   const int kSize = 2 * kHalfSize;
3552   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
3553   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
3554   CacheTestFillBuffer(buffer1->data(), kSize, false);
3555   char* buffer1_data = buffer1->data() + kHalfSize;
3556   memcpy(buffer2->data(), buffer1_data, kHalfSize);
3557
3558   disk_cache::Entry* entry = NULL;
3559   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3560   entry->Close();
3561   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
3562     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3563     EXPECT_NE(null, entry);
3564
3565     int offset = kHalfSize;
3566     int buf_len = kHalfSize;
3567
3568     EXPECT_EQ(buf_len,
3569               WriteData(entry, i, offset, buffer2.get(), buf_len, false));
3570     offset = 0;
3571     buf_len = kHalfSize;
3572     EXPECT_EQ(buf_len,
3573               WriteData(entry, i, offset, buffer1.get(), buf_len, false));
3574     entry->Close();
3575
3576     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3577
3578     scoped_refptr<net::IOBuffer> buffer1_read1(new net::IOBuffer(kSize));
3579     EXPECT_EQ(kSize, ReadData(entry, i, 0, buffer1_read1.get(), kSize));
3580     EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), kSize));
3581     // Check that we are not leaking.
3582     ASSERT_NE(entry, null);
3583     EXPECT_TRUE(static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
3584     entry->Close();
3585   }
3586 }
3587
3588 // Test that changing stream1 size does not affect stream0 (stream0 and stream1
3589 // are stored in the same file in Simple Cache).
3590 TEST_F(DiskCacheEntryTest, SimpleCacheStream1SizeChanges) {
3591   SetSimpleCacheMode();
3592   InitCache();
3593   disk_cache::Entry* entry = NULL;
3594   const char key[] = "the key";
3595   const int kSize = 100;
3596   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
3597   scoped_refptr<net::IOBuffer> buffer_read(new net::IOBuffer(kSize));
3598   CacheTestFillBuffer(buffer->data(), kSize, false);
3599
3600   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3601   EXPECT_TRUE(entry);
3602
3603   // Write something into stream0.
3604   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
3605   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize));
3606   EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize));
3607   entry->Close();
3608
3609   // Extend stream1.
3610   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3611   int stream1_size = 100;
3612   EXPECT_EQ(0, WriteData(entry, 1, stream1_size, buffer.get(), 0, false));
3613   EXPECT_EQ(stream1_size, entry->GetDataSize(1));
3614   entry->Close();
3615
3616   // Check that stream0 data has not been modified and that the EOF record for
3617   // stream 0 contains a crc.
3618   // The entry needs to be reopened before checking the crc: Open will perform
3619   // the synchronization with the previous Close. This ensures the EOF records
3620   // have been written to disk before we attempt to read them independently.
3621   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3622   base::FilePath entry_file0_path = cache_path_.AppendASCII(
3623       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
3624   base::File entry_file0(entry_file0_path,
3625                          base::File::FLAG_READ | base::File::FLAG_OPEN);
3626   ASSERT_TRUE(entry_file0.IsValid());
3627
3628   int data_size[disk_cache::kSimpleEntryStreamCount] = {kSize, stream1_size, 0};
3629   int sparse_data_size = 0;
3630   disk_cache::SimpleEntryStat entry_stat(
3631       base::Time::Now(), base::Time::Now(), data_size, sparse_data_size);
3632   int eof_offset = entry_stat.GetEOFOffsetInFile(key, 0);
3633   disk_cache::SimpleFileEOF eof_record;
3634   ASSERT_EQ(static_cast<int>(sizeof(eof_record)),
3635             entry_file0.Read(eof_offset, reinterpret_cast<char*>(&eof_record),
3636                              sizeof(eof_record)));
3637   EXPECT_EQ(disk_cache::kSimpleFinalMagicNumber, eof_record.final_magic_number);
3638   EXPECT_TRUE((eof_record.flags & disk_cache::SimpleFileEOF::FLAG_HAS_CRC32) ==
3639               disk_cache::SimpleFileEOF::FLAG_HAS_CRC32);
3640
3641   buffer_read = new net::IOBuffer(kSize);
3642   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize));
3643   EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize));
3644
3645   // Shrink stream1.
3646   stream1_size = 50;
3647   EXPECT_EQ(0, WriteData(entry, 1, stream1_size, buffer.get(), 0, true));
3648   EXPECT_EQ(stream1_size, entry->GetDataSize(1));
3649   entry->Close();
3650
3651   // Check that stream0 data has not been modified.
3652   buffer_read = new net::IOBuffer(kSize);
3653   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3654   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize));
3655   EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize));
3656   entry->Close();
3657   entry = NULL;
3658 }
3659
3660 // Test that writing within the range for which the crc has already been
3661 // computed will properly invalidate the computed crc.
3662 TEST_F(DiskCacheEntryTest, SimpleCacheCRCRewrite) {
3663   // Test sequence:
3664   // Create, Write (big data), Write (small data in the middle), Close.
3665   // Open, Read (all), Close.
3666   SetSimpleCacheMode();
3667   InitCache();
3668   disk_cache::Entry* null = NULL;
3669   const char key[] = "the first key";
3670
3671   const int kHalfSize = 200;
3672   const int kSize = 2 * kHalfSize;
3673   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
3674   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kHalfSize));
3675   CacheTestFillBuffer(buffer1->data(), kSize, false);
3676   CacheTestFillBuffer(buffer2->data(), kHalfSize, false);
3677
3678   disk_cache::Entry* entry = NULL;
3679   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3680   EXPECT_NE(null, entry);
3681   entry->Close();
3682
3683   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
3684     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3685     int offset = 0;
3686     int buf_len = kSize;
3687
3688     EXPECT_EQ(buf_len,
3689               WriteData(entry, i, offset, buffer1.get(), buf_len, false));
3690     offset = kHalfSize;
3691     buf_len = kHalfSize;
3692     EXPECT_EQ(buf_len,
3693               WriteData(entry, i, offset, buffer2.get(), buf_len, false));
3694     entry->Close();
3695
3696     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3697
3698     scoped_refptr<net::IOBuffer> buffer1_read1(new net::IOBuffer(kSize));
3699     EXPECT_EQ(kSize, ReadData(entry, i, 0, buffer1_read1.get(), kSize));
3700     EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), kHalfSize));
3701     EXPECT_EQ(
3702         0,
3703         memcmp(buffer2->data(), buffer1_read1->data() + kHalfSize, kHalfSize));
3704
3705     entry->Close();
3706   }
3707 }
3708
3709 bool DiskCacheEntryTest::SimpleCacheThirdStreamFileExists(const char* key) {
3710   int third_stream_file_index =
3711       disk_cache::simple_util::GetFileIndexFromStreamIndex(2);
3712   base::FilePath third_stream_file_path = cache_path_.AppendASCII(
3713       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(
3714           key, third_stream_file_index));
3715   return PathExists(third_stream_file_path);
3716 }
3717
3718 void DiskCacheEntryTest::SyncDoomEntry(const char* key) {
3719   net::TestCompletionCallback callback;
3720   cache_->DoomEntry(key, callback.callback());
3721   callback.WaitForResult();
3722 }
3723
3724 // Check that a newly-created entry with no third-stream writes omits the
3725 // third stream file.
3726 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream1) {
3727   SetSimpleCacheMode();
3728   InitCache();
3729
3730   const char key[] = "key";
3731
3732   disk_cache::Entry* entry;
3733
3734   // Create entry and close without writing: third stream file should be
3735   // omitted, since the stream is empty.
3736   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3737   entry->Close();
3738   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
3739
3740   SyncDoomEntry(key);
3741   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
3742 }
3743
3744 // Check that a newly-created entry with only a single zero-offset, zero-length
3745 // write omits the third stream file.
3746 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream2) {
3747   SetSimpleCacheMode();
3748   InitCache();
3749
3750   const int kHalfSize = 8;
3751   const int kSize = kHalfSize * 2;
3752   const char key[] = "key";
3753   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
3754   CacheTestFillBuffer(buffer->data(), kHalfSize, false);
3755
3756   disk_cache::Entry* entry;
3757
3758   // Create entry, write empty buffer to third stream, and close: third stream
3759   // should still be omitted, since the entry ignores writes that don't modify
3760   // data or change the length.
3761   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3762   EXPECT_EQ(0, WriteData(entry, 2, 0, buffer.get(), 0, true));
3763   entry->Close();
3764   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
3765
3766   SyncDoomEntry(key);
3767   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
3768 }
3769
3770 // Check that we can read back data written to the third stream.
3771 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream3) {
3772   SetSimpleCacheMode();
3773   InitCache();
3774
3775   const int kHalfSize = 8;
3776   const int kSize = kHalfSize * 2;
3777   const char key[] = "key";
3778   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
3779   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
3780   CacheTestFillBuffer(buffer1->data(), kHalfSize, false);
3781
3782   disk_cache::Entry* entry;
3783
3784   // Create entry, write data to third stream, and close: third stream should
3785   // not be omitted, since it contains data.  Re-open entry and ensure there
3786   // are that many bytes in the third stream.
3787   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3788   EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1.get(), kHalfSize, true));
3789   entry->Close();
3790   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
3791
3792   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3793   EXPECT_EQ(kHalfSize, ReadData(entry, 2, 0, buffer2.get(), kSize));
3794   EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kHalfSize));
3795   entry->Close();
3796   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
3797
3798   SyncDoomEntry(key);
3799   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
3800 }
3801
3802 // Check that we remove the third stream file upon opening an entry and finding
3803 // the third stream empty.  (This is the upgrade path for entries written
3804 // before the third stream was optional.)
3805 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream4) {
3806   SetSimpleCacheMode();
3807   InitCache();
3808
3809   const int kHalfSize = 8;
3810   const int kSize = kHalfSize * 2;
3811   const char key[] = "key";
3812   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
3813   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
3814   CacheTestFillBuffer(buffer1->data(), kHalfSize, false);
3815
3816   disk_cache::Entry* entry;
3817
3818   // Create entry, write data to third stream, truncate third stream back to
3819   // empty, and close: third stream will not initially be omitted, since entry
3820   // creates the file when the first significant write comes in, and only
3821   // removes it on open if it is empty.  Reopen, ensure that the file is
3822   // deleted, and that there's no data in the third stream.
3823   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3824   EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1.get(), kHalfSize, true));
3825   EXPECT_EQ(0, WriteData(entry, 2, 0, buffer1.get(), 0, true));
3826   entry->Close();
3827   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
3828
3829   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3830   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
3831   EXPECT_EQ(0, ReadData(entry, 2, 0, buffer2.get(), kSize));
3832   entry->Close();
3833   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
3834
3835   SyncDoomEntry(key);
3836   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
3837 }
3838
3839 // Check that we don't accidentally create the third stream file once the entry
3840 // has been doomed.
3841 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream5) {
3842   SetSimpleCacheMode();
3843   InitCache();
3844
3845   const int kHalfSize = 8;
3846   const int kSize = kHalfSize * 2;
3847   const char key[] = "key";
3848   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
3849   CacheTestFillBuffer(buffer->data(), kHalfSize, false);
3850
3851   disk_cache::Entry* entry;
3852
3853   // Create entry, doom entry, write data to third stream, and close: third
3854   // stream should not exist.  (Note: We don't care if the write fails, just
3855   // that it doesn't cause the file to be created on disk.)
3856   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3857   entry->Doom();
3858   WriteData(entry, 2, 0, buffer.get(), kHalfSize, true);
3859   entry->Close();
3860   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
3861 }
3862
3863 // There could be a race between Doom and an optimistic write.
3864 TEST_F(DiskCacheEntryTest, SimpleCacheDoomOptimisticWritesRace) {
3865   // Test sequence:
3866   // Create, first Write, second Write, Close.
3867   // Open, Close.
3868   SetSimpleCacheMode();
3869   InitCache();
3870   disk_cache::Entry* null = NULL;
3871   const char key[] = "the first key";
3872
3873   const int kSize = 200;
3874   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
3875   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
3876   CacheTestFillBuffer(buffer1->data(), kSize, false);
3877   CacheTestFillBuffer(buffer2->data(), kSize, false);
3878
3879   // The race only happens on stream 1 and stream 2.
3880   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
3881     ASSERT_EQ(net::OK, DoomAllEntries());
3882     disk_cache::Entry* entry = NULL;
3883
3884     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3885     EXPECT_NE(null, entry);
3886     entry->Close();
3887     entry = NULL;
3888
3889     ASSERT_EQ(net::OK, DoomAllEntries());
3890     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3891     EXPECT_NE(null, entry);
3892
3893     int offset = 0;
3894     int buf_len = kSize;
3895     // This write should not be optimistic (since create is).
3896     EXPECT_EQ(buf_len,
3897               WriteData(entry, i, offset, buffer1.get(), buf_len, false));
3898
3899     offset = kSize;
3900     // This write should be optimistic.
3901     EXPECT_EQ(buf_len,
3902               WriteData(entry, i, offset, buffer2.get(), buf_len, false));
3903     entry->Close();
3904
3905     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3906     EXPECT_NE(null, entry);
3907
3908     entry->Close();
3909     entry = NULL;
3910   }
3911 }
3912
3913 // Tests for a regression in crbug.com/317138 , in which deleting an already
3914 // doomed entry was removing the active entry from the index.
3915 TEST_F(DiskCacheEntryTest, SimpleCachePreserveActiveEntries) {
3916   SetSimpleCacheMode();
3917   InitCache();
3918
3919   disk_cache::Entry* null = NULL;
3920
3921   const char key[] = "this is a key";
3922
3923   disk_cache::Entry* entry1 = NULL;
3924   ASSERT_EQ(net::OK, CreateEntry(key, &entry1));
3925   ScopedEntryPtr entry1_closer(entry1);
3926   EXPECT_NE(null, entry1);
3927   entry1->Doom();
3928
3929   disk_cache::Entry* entry2 = NULL;
3930   ASSERT_EQ(net::OK, CreateEntry(key, &entry2));
3931   ScopedEntryPtr entry2_closer(entry2);
3932   EXPECT_NE(null, entry2);
3933   entry2_closer.reset();
3934
3935   // Closing then reopening entry2 insures that entry2 is serialized, and so
3936   // it can be opened from files without error.
3937   entry2 = NULL;
3938   ASSERT_EQ(net::OK, OpenEntry(key, &entry2));
3939   EXPECT_NE(null, entry2);
3940   entry2_closer.reset(entry2);
3941
3942   scoped_refptr<disk_cache::SimpleEntryImpl>
3943       entry1_refptr = static_cast<disk_cache::SimpleEntryImpl*>(entry1);
3944
3945   // If crbug.com/317138 has regressed, this will remove |entry2| from
3946   // the backend's |active_entries_| while |entry2| is still alive and its
3947   // files are still on disk.
3948   entry1_closer.reset();
3949   entry1 = NULL;
3950
3951   // Close does not have a callback. However, we need to be sure the close is
3952   // finished before we continue the test. We can take advantage of how the ref
3953   // counting of a SimpleEntryImpl works to fake out a callback: When the
3954   // last Close() call is made to an entry, an IO operation is sent to the
3955   // synchronous entry to close the platform files. This IO operation holds a
3956   // ref pointer to the entry, which expires when the operation is done. So,
3957   // we take a refpointer, and watch the SimpleEntry object until it has only
3958   // one ref; this indicates the IO operation is complete.
3959   while (!entry1_refptr->HasOneRef()) {
3960     base::PlatformThread::YieldCurrentThread();
3961     base::MessageLoop::current()->RunUntilIdle();
3962   }
3963   entry1_refptr = NULL;
3964
3965   // In the bug case, this new entry ends up being a duplicate object pointing
3966   // at the same underlying files.
3967   disk_cache::Entry* entry3 = NULL;
3968   EXPECT_EQ(net::OK, OpenEntry(key, &entry3));
3969   ScopedEntryPtr entry3_closer(entry3);
3970   EXPECT_NE(null, entry3);
3971
3972   // The test passes if these two dooms do not crash.
3973   entry2->Doom();
3974   entry3->Doom();
3975 }
3976
3977 TEST_F(DiskCacheEntryTest, SimpleCacheBasicSparseIO) {
3978   SetSimpleCacheMode();
3979   InitCache();
3980   BasicSparseIO();
3981 }
3982
3983 TEST_F(DiskCacheEntryTest, SimpleCacheHugeSparseIO) {
3984   SetSimpleCacheMode();
3985   InitCache();
3986   HugeSparseIO();
3987 }
3988
3989 TEST_F(DiskCacheEntryTest, SimpleCacheGetAvailableRange) {
3990   SetSimpleCacheMode();
3991   InitCache();
3992   GetAvailableRange();
3993 }
3994
3995 TEST_F(DiskCacheEntryTest, DISABLED_SimpleCacheCouldBeSparse) {
3996   SetSimpleCacheMode();
3997   InitCache();
3998   CouldBeSparse();
3999 }
4000
4001 TEST_F(DiskCacheEntryTest, SimpleCacheUpdateSparseEntry) {
4002   SetSimpleCacheMode();
4003   InitCache();
4004   UpdateSparseEntry();
4005 }
4006
4007 TEST_F(DiskCacheEntryTest, SimpleCacheDoomSparseEntry) {
4008   SetSimpleCacheMode();
4009   InitCache();
4010   DoomSparseEntry();
4011 }
4012
4013 TEST_F(DiskCacheEntryTest, SimpleCachePartialSparseEntry) {
4014   SetSimpleCacheMode();
4015   InitCache();
4016   PartialSparseEntry();
4017 }
4018
4019 TEST_F(DiskCacheEntryTest, SimpleCacheTruncateLargeSparseFile) {
4020   const int kSize = 1024;
4021
4022   SetSimpleCacheMode();
4023   // An entry is allowed sparse data 1/10 the size of the cache, so this size
4024   // allows for one |kSize|-sized range plus overhead, but not two ranges.
4025   SetMaxSize(kSize * 15);
4026   InitCache();
4027
4028   const char key[] = "key";
4029   disk_cache::Entry* null = NULL;
4030   disk_cache::Entry* entry;
4031   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
4032   EXPECT_NE(null, entry);
4033
4034   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
4035   CacheTestFillBuffer(buffer->data(), kSize, false);
4036   net::TestCompletionCallback callback;
4037   int ret;
4038
4039   // Verify initial conditions.
4040   ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
4041   EXPECT_EQ(0, callback.GetResult(ret));
4042
4043   ret = entry->ReadSparseData(kSize, buffer.get(), kSize, callback.callback());
4044   EXPECT_EQ(0, callback.GetResult(ret));
4045
4046   // Write a range and make sure it reads back.
4047   ret = entry->WriteSparseData(0, buffer.get(), kSize, callback.callback());
4048   EXPECT_EQ(kSize, callback.GetResult(ret));
4049
4050   ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
4051   EXPECT_EQ(kSize, callback.GetResult(ret));
4052
4053   // Write another range and make sure it reads back.
4054   ret = entry->WriteSparseData(kSize, buffer.get(), kSize, callback.callback());
4055   EXPECT_EQ(kSize, callback.GetResult(ret));
4056
4057   ret = entry->ReadSparseData(kSize, buffer.get(), kSize, callback.callback());
4058   EXPECT_EQ(kSize, callback.GetResult(ret));
4059
4060   // Make sure the first range was removed when the second was written.
4061   ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
4062   EXPECT_EQ(0, callback.GetResult(ret));
4063
4064   entry->Close();
4065 }
4066
4067 #endif  // defined(OS_POSIX)