Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / net / disk_cache / entry_unittest.cc
index a94f6fb..afe93ac 100644 (file)
@@ -5,8 +5,8 @@
 #include "base/basictypes.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
-#include "base/file_util.h"
 #include "base/files/file.h"
+#include "base/files/file_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/platform_thread.h"
@@ -1617,10 +1617,10 @@ TEST_F(DiskCacheEntryTest, MemoryOnlyEnumerationWithSparseEntries) {
   parent_entry->Close();
 
   // Perform the enumerations.
-  void* iter = NULL;
+  scoped_ptr<TestIterator> iter = CreateIterator();
   disk_cache::Entry* entry = NULL;
   int count = 0;
-  while (OpenNextEntry(&iter, &entry) == net::OK) {
+  while (iter->OpenNextEntry(&entry) == net::OK) {
     ASSERT_TRUE(entry != NULL);
     ++count;
     disk_cache::MemEntryImpl* mem_entry =
@@ -2217,10 +2217,10 @@ TEST_F(DiskCacheEntryTest, CleanupSparseEntry) {
   entry->Close();
   EXPECT_EQ(4, cache_->GetEntryCount());
 
-  void* iter = NULL;
+  scoped_ptr<TestIterator> iter = CreateIterator();
   int count = 0;
   std::string child_key[2];
-  while (OpenNextEntry(&iter, &entry) == net::OK) {
+  while (iter->OpenNextEntry(&entry) == net::OK) {
     ASSERT_TRUE(entry != NULL);
     // Writing to an entry will alter the LRU list and invalidate the iterator.
     if (entry->GetKey() != key && count < 2)
@@ -3759,7 +3759,7 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream2) {
   // should still be omitted, since the entry ignores writes that don't modify
   // data or change the length.
   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
-  EXPECT_EQ(0, WriteData(entry, 2, 0, buffer, 0, true));
+  EXPECT_EQ(0, WriteData(entry, 2, 0, buffer.get(), 0, true));
   entry->Close();
   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
 
@@ -3785,12 +3785,12 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream3) {
   // not be omitted, since it contains data.  Re-open entry and ensure there
   // are that many bytes in the third stream.
   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
-  EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1, kHalfSize, true));
+  EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1.get(), kHalfSize, true));
   entry->Close();
   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
 
   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
-  EXPECT_EQ(kHalfSize, ReadData(entry, 2, 0, buffer2, kSize));
+  EXPECT_EQ(kHalfSize, ReadData(entry, 2, 0, buffer2.get(), kSize));
   EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kHalfSize));
   entry->Close();
   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
@@ -3821,14 +3821,14 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream4) {
   // removes it on open if it is empty.  Reopen, ensure that the file is
   // deleted, and that there's no data in the third stream.
   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
-  EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1, kHalfSize, true));
-  EXPECT_EQ(0, WriteData(entry, 2, 0, buffer1, 0, true));
+  EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1.get(), kHalfSize, true));
+  EXPECT_EQ(0, WriteData(entry, 2, 0, buffer1.get(), 0, true));
   entry->Close();
   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
 
   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
-  EXPECT_EQ(0, ReadData(entry, 2, 0, buffer2, kSize));
+  EXPECT_EQ(0, ReadData(entry, 2, 0, buffer2.get(), kSize));
   entry->Close();
   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
 
@@ -3855,7 +3855,7 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream5) {
   // that it doesn't cause the file to be created on disk.)
   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   entry->Doom();
-  WriteData(entry, 2, 0, buffer, kHalfSize, true);
+  WriteData(entry, 2, 0, buffer.get(), kHalfSize, true);
   entry->Close();
   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
 }
@@ -3910,6 +3910,70 @@ TEST_F(DiskCacheEntryTest, SimpleCacheDoomOptimisticWritesRace) {
   }
 }
 
+// Tests for a regression in crbug.com/317138 , in which deleting an already
+// doomed entry was removing the active entry from the index.
+TEST_F(DiskCacheEntryTest, SimpleCachePreserveActiveEntries) {
+  SetSimpleCacheMode();
+  InitCache();
+
+  disk_cache::Entry* null = NULL;
+
+  const char key[] = "this is a key";
+
+  disk_cache::Entry* entry1 = NULL;
+  ASSERT_EQ(net::OK, CreateEntry(key, &entry1));
+  ScopedEntryPtr entry1_closer(entry1);
+  EXPECT_NE(null, entry1);
+  entry1->Doom();
+
+  disk_cache::Entry* entry2 = NULL;
+  ASSERT_EQ(net::OK, CreateEntry(key, &entry2));
+  ScopedEntryPtr entry2_closer(entry2);
+  EXPECT_NE(null, entry2);
+  entry2_closer.reset();
+
+  // Closing then reopening entry2 insures that entry2 is serialized, and so
+  // it can be opened from files without error.
+  entry2 = NULL;
+  ASSERT_EQ(net::OK, OpenEntry(key, &entry2));
+  EXPECT_NE(null, entry2);
+  entry2_closer.reset(entry2);
+
+  scoped_refptr<disk_cache::SimpleEntryImpl>
+      entry1_refptr = static_cast<disk_cache::SimpleEntryImpl*>(entry1);
+
+  // If crbug.com/317138 has regressed, this will remove |entry2| from
+  // the backend's |active_entries_| while |entry2| is still alive and its
+  // files are still on disk.
+  entry1_closer.reset();
+  entry1 = NULL;
+
+  // Close does not have a callback. However, we need to be sure the close is
+  // finished before we continue the test. We can take advantage of how the ref
+  // counting of a SimpleEntryImpl works to fake out a callback: When the
+  // last Close() call is made to an entry, an IO operation is sent to the
+  // synchronous entry to close the platform files. This IO operation holds a
+  // ref pointer to the entry, which expires when the operation is done. So,
+  // we take a refpointer, and watch the SimpleEntry object until it has only
+  // one ref; this indicates the IO operation is complete.
+  while (!entry1_refptr->HasOneRef()) {
+    base::PlatformThread::YieldCurrentThread();
+    base::MessageLoop::current()->RunUntilIdle();
+  }
+  entry1_refptr = NULL;
+
+  // In the bug case, this new entry ends up being a duplicate object pointing
+  // at the same underlying files.
+  disk_cache::Entry* entry3 = NULL;
+  EXPECT_EQ(net::OK, OpenEntry(key, &entry3));
+  ScopedEntryPtr entry3_closer(entry3);
+  EXPECT_NE(null, entry3);
+
+  // The test passes if these two dooms do not crash.
+  entry2->Doom();
+  entry3->Doom();
+}
+
 TEST_F(DiskCacheEntryTest, SimpleCacheBasicSparseIO) {
   SetSimpleCacheMode();
   InitCache();
@@ -3973,28 +4037,28 @@ TEST_F(DiskCacheEntryTest, SimpleCacheTruncateLargeSparseFile) {
   int ret;
 
   // Verify initial conditions.
-  ret = entry->ReadSparseData(0, buffer, kSize, callback.callback());
+  ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
   EXPECT_EQ(0, callback.GetResult(ret));
 
-  ret = entry->ReadSparseData(kSize, buffer, kSize, callback.callback());
+  ret = entry->ReadSparseData(kSize, buffer.get(), kSize, callback.callback());
   EXPECT_EQ(0, callback.GetResult(ret));
 
   // Write a range and make sure it reads back.
-  ret = entry->WriteSparseData(0, buffer, kSize, callback.callback());
+  ret = entry->WriteSparseData(0, buffer.get(), kSize, callback.callback());
   EXPECT_EQ(kSize, callback.GetResult(ret));
 
-  ret = entry->ReadSparseData(0, buffer, kSize, callback.callback());
+  ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
   EXPECT_EQ(kSize, callback.GetResult(ret));
 
   // Write another range and make sure it reads back.
-  ret = entry->WriteSparseData(kSize, buffer, kSize, callback.callback());
+  ret = entry->WriteSparseData(kSize, buffer.get(), kSize, callback.callback());
   EXPECT_EQ(kSize, callback.GetResult(ret));
 
-  ret = entry->ReadSparseData(kSize, buffer, kSize, callback.callback());
+  ret = entry->ReadSparseData(kSize, buffer.get(), kSize, callback.callback());
   EXPECT_EQ(kSize, callback.GetResult(ret));
 
   // Make sure the first range was removed when the second was written.
-  ret = entry->ReadSparseData(0, buffer, kSize, callback.callback());
+  ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
   EXPECT_EQ(0, callback.GetResult(ret));
 
   entry->Close();