summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgavinp <gavinp@chromium.org>2014-08-28 09:48:24 -0700
committerCommit bot <commit-bot@chromium.org>2014-08-28 16:49:35 +0000
commit219ac0b8461239768efa1cad3bca720bbaf065d1 (patch)
tree0f8751e59d73aa84e35243c8070927b584dc1f6b
parentab7555f4979feef26b9c9c4f9f74aa462ce9927f (diff)
downloadchromium_src-219ac0b8461239768efa1cad3bca720bbaf065d1.zip
chromium_src-219ac0b8461239768efa1cad3bca720bbaf065d1.tar.gz
chromium_src-219ac0b8461239768efa1cad3bca720bbaf065d1.tar.bz2
New SimpleCache Entry test for duplicate dooms.
Adds a regression test for bug 317138. This test is interesting because it generates exactly the same stacks that we're seeing in crash reports on that bug. This is a good regression test, so I suggest we land it, as well as look at it for more confidence that our fix to bug 317138 is the right fix. R=ttuttle@chromium.org,jkarlin@chromium.org BUG=317138 Review URL: https://codereview.chromium.org/509973002 Cr-Commit-Position: refs/heads/master@{#292399}
-rw-r--r--net/disk_cache/entry_unittest.cc64
1 files changed, 64 insertions, 0 deletions
diff --git a/net/disk_cache/entry_unittest.cc b/net/disk_cache/entry_unittest.cc
index 5fd6db0..0701311 100644
--- a/net/disk_cache/entry_unittest.cc
+++ b/net/disk_cache/entry_unittest.cc
@@ -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();