Index: Source/core/fetch/MemoryCacheTest.cpp |
diff --git a/Source/core/fetch/MemoryCacheTest.cpp b/Source/core/fetch/MemoryCacheTest.cpp |
index 20f7f978502230b8e40cc185d7af1b7320172c4c..ef17ff7977feecab2253300aa9fb0bf1011e0493 100644 |
--- a/Source/core/fetch/MemoryCacheTest.cpp |
+++ b/Source/core/fetch/MemoryCacheTest.cpp |
@@ -138,7 +138,7 @@ TEST_F(MemoryCacheTest, VeryLargeResourceAccounting) |
// Verifies that dead resources that exceed dead resource capacity are evicted |
// from cache when pruning. |
-TEST_F(MemoryCacheTest, DeadResourceEviction) |
+static void TestDeadResourceEviction(Resource* resource1, Resource* resource2) |
{ |
memoryCache()->setDelayBeforeLiveDecodedPrune(0); |
memoryCache()->setMaxPruneDeferralDelay(0); |
@@ -147,19 +147,24 @@ TEST_F(MemoryCacheTest, DeadResourceEviction) |
const unsigned maxDeadCapacity = 0; |
memoryCache()->setCapacities(minDeadCapacity, maxDeadCapacity, totalCapacity); |
- Resource* cachedResource = |
- new Resource(ResourceRequest("http://test/resource"), Resource::Raw); |
const char data[5] = "abcd"; |
- cachedResource->appendData(data, 3u); |
+ resource1->appendData(data, 3u); |
+ resource2->appendData(data, 2u); |
+ |
// The resource size has to be nonzero for this test to be meaningful, but |
// we do not rely on it having any particular value. |
- ASSERT_GT(cachedResource->size(), 0u); |
+ ASSERT_GT(resource1->size(), 0u); |
+ ASSERT_GT(resource2->size(), 0u); |
ASSERT_EQ(0u, memoryCache()->deadSize()); |
ASSERT_EQ(0u, memoryCache()->liveSize()); |
- memoryCache()->add(cachedResource); |
- ASSERT_EQ(cachedResource->size(), memoryCache()->deadSize()); |
+ memoryCache()->add(resource1); |
+ ASSERT_EQ(resource1->size(), memoryCache()->deadSize()); |
+ ASSERT_EQ(0u, memoryCache()->liveSize()); |
+ |
+ memoryCache()->add(resource2); |
+ ASSERT_EQ(resource1->size() + resource2->size(), memoryCache()->deadSize()); |
ASSERT_EQ(0u, memoryCache()->liveSize()); |
memoryCache()->prune(); |
@@ -167,9 +172,26 @@ TEST_F(MemoryCacheTest, DeadResourceEviction) |
ASSERT_EQ(0u, memoryCache()->liveSize()); |
} |
-// Verified that when ordering a prune in a runLoop task, the prune |
-// is deferred to the end of the task. |
-TEST_F(MemoryCacheTest, LiveResourceEvictionAtEndOfTask) |
+TEST_F(MemoryCacheTest, DeadResourceEviction_Basic) |
+{ |
+ Resource* resource1 = |
+ new Resource(ResourceRequest("http://test/resource1"), Resource::Raw); |
+ Resource* resource2 = |
+ new Resource(ResourceRequest("http://test/resource2"), Resource::Raw); |
+ TestDeadResourceEviction(resource1, resource2); |
+} |
+ |
+TEST_F(MemoryCacheTest, DeadResourceEviction_MultipleResourceMaps) |
+{ |
+ Resource* resource1 = |
+ new Resource(ResourceRequest("http://test/resource1"), Resource::Raw); |
+ Resource* resource2 = |
+ new Resource(ResourceRequest("http://test/resource2"), Resource::Raw); |
+ resource2->setCacheIdentifier("foo"); |
+ TestDeadResourceEviction(resource1, resource2); |
+} |
+ |
+static void TestLiveResourceEvictionAtEndOfTask(Resource* cachedDeadResource, const ResourcePtr<Resource>& cachedLiveResource) |
{ |
memoryCache()->setDelayBeforeLiveDecodedPrune(0); |
const unsigned totalCapacity = 1; |
@@ -177,11 +199,7 @@ TEST_F(MemoryCacheTest, LiveResourceEvictionAtEndOfTask) |
const unsigned maxDeadCapacity = 0; |
memoryCache()->setCapacities(minDeadCapacity, maxDeadCapacity, totalCapacity); |
const char data[6] = "abcde"; |
- Resource* cachedDeadResource = |
- new Resource(ResourceRequest("hhtp://foo"), Resource::Raw); |
cachedDeadResource->appendData(data, 3u); |
- ResourcePtr<Resource> cachedLiveResource = |
- new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
MockImageResourceClient client; |
cachedLiveResource->addClient(&client); |
cachedLiveResource->appendData(data, 4u); |
@@ -245,18 +263,57 @@ TEST_F(MemoryCacheTest, LiveResourceEvictionAtEndOfTask) |
cachedLiveResource->removeClient(&client); |
} |
+// Verified that when ordering a prune in a runLoop task, the prune |
+// is deferred to the end of the task. |
+TEST_F(MemoryCacheTest, LiveResourceEvictionAtEndOfTask_Basic) |
+{ |
+ Resource* cachedDeadResource = |
+ new Resource(ResourceRequest("hhtp://foo"), Resource::Raw); |
+ ResourcePtr<Resource> cachedLiveResource = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ TestLiveResourceEvictionAtEndOfTask(cachedDeadResource, cachedLiveResource); |
+} |
+ |
+TEST_F(MemoryCacheTest, LiveResourceEvictionAtEndOfTask_MultipleResourceMaps) |
+{ |
+ { |
+ Resource* cachedDeadResource = |
+ new Resource(ResourceRequest("hhtp://foo"), Resource::Raw); |
+ cachedDeadResource->setCacheIdentifier("foo"); |
+ ResourcePtr<Resource> cachedLiveResource = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ TestLiveResourceEvictionAtEndOfTask(cachedDeadResource, cachedLiveResource); |
+ memoryCache()->evictResources(); |
+ } |
+ { |
+ Resource* cachedDeadResource = |
+ new Resource(ResourceRequest("hhtp://foo"), Resource::Raw); |
+ ResourcePtr<Resource> cachedLiveResource = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ cachedLiveResource->setCacheIdentifier("foo"); |
+ TestLiveResourceEvictionAtEndOfTask(cachedDeadResource, cachedLiveResource); |
+ memoryCache()->evictResources(); |
+ } |
+ { |
+ Resource* cachedDeadResource = |
+ new Resource(ResourceRequest("hhtp://test/resource"), Resource::Raw); |
+ cachedDeadResource->setCacheIdentifier("foo"); |
+ ResourcePtr<Resource> cachedLiveResource = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ cachedLiveResource->setCacheIdentifier("bar"); |
+ TestLiveResourceEvictionAtEndOfTask(cachedDeadResource, cachedLiveResource); |
+ memoryCache()->evictResources(); |
+ } |
+} |
+ |
// Verifies that cached resources are evicted immediately after release when |
// the total dead resource size is more than double the dead resource capacity. |
-TEST_F(MemoryCacheTest, ClientRemoval) |
+static void TestClientRemoval(const ResourcePtr<Resource>& resource1, const ResourcePtr<Resource>& resource2) |
{ |
const char data[6] = "abcde"; |
- ResourcePtr<Resource> resource1 = |
- new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw); |
MockImageResourceClient client1; |
resource1->addClient(&client1); |
resource1->appendData(data, 4u); |
- ResourcePtr<Resource> resource2 = |
- new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
MockImageResourceClient client2; |
resource2->addClient(&client2); |
resource2->appendData(data, 4u); |
@@ -296,16 +353,53 @@ TEST_F(MemoryCacheTest, ClientRemoval) |
ASSERT_FALSE(memoryCache()->contains(resource2.get())); |
} |
+TEST_F(MemoryCacheTest, ClientRemoval_Basic) |
+{ |
+ ResourcePtr<Resource> resource1 = |
+ new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw); |
+ ResourcePtr<Resource> resource2 = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ TestClientRemoval(resource1, resource2); |
+} |
+ |
+TEST_F(MemoryCacheTest, ClientRemoval_MultipleResourceMaps) |
+{ |
+ { |
+ ResourcePtr<Resource> resource1 = |
+ new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw); |
+ resource1->setCacheIdentifier("foo"); |
+ ResourcePtr<Resource> resource2 = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ TestClientRemoval(resource1, resource2); |
+ memoryCache()->evictResources(); |
+ } |
+ { |
+ ResourcePtr<Resource> resource1 = |
+ new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw); |
+ ResourcePtr<Resource> resource2 = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ resource2->setCacheIdentifier("foo"); |
+ TestClientRemoval(resource1, resource2); |
+ memoryCache()->evictResources(); |
+ } |
+ { |
+ ResourcePtr<Resource> resource1 = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ resource1->setCacheIdentifier("foo"); |
+ ResourcePtr<Resource> resource2 = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ resource2->setCacheIdentifier("bar"); |
+ TestClientRemoval(resource1, resource2); |
+ memoryCache()->evictResources(); |
+ } |
+} |
+ |
// Verifies that CachedResources are evicted from the decode cache |
// according to their DecodeCachePriority. |
-TEST_F(MemoryCacheTest, DecodeCacheOrder) |
+static void TestDecodeCacheOrder(const ResourcePtr<Resource>& cachedImageLowPriority, const ResourcePtr<Resource>& cachedImageHighPriority) |
{ |
memoryCache()->setDelayBeforeLiveDecodedPrune(0); |
memoryCache()->setMaxPruneDeferralDelay(0); |
- ResourcePtr<FakeDecodedResource> cachedImageLowPriority = |
- new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw); |
- ResourcePtr<FakeDecodedResource> cachedImageHighPriority = |
- new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
MockImageResourceClient clientLowPriority; |
MockImageResourceClient clientHighPriority; |
@@ -365,6 +459,47 @@ TEST_F(MemoryCacheTest, DecodeCacheOrder) |
cachedImageHighPriority->removeClient(&clientHighPriority); |
} |
+TEST_F(MemoryCacheTest, DecodeCacheOrder_Basic) |
+{ |
+ ResourcePtr<FakeDecodedResource> cachedImageLowPriority = |
+ new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw); |
+ ResourcePtr<FakeDecodedResource> cachedImageHighPriority = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ TestDecodeCacheOrder(cachedImageLowPriority, cachedImageHighPriority); |
+} |
+ |
+TEST_F(MemoryCacheTest, DecodeCacheOrder_MultipleResourceMaps) |
+{ |
+ { |
+ ResourcePtr<FakeDecodedResource> cachedImageLowPriority = |
+ new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw); |
+ ResourcePtr<FakeDecodedResource> cachedImageHighPriority = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ cachedImageLowPriority->setCacheIdentifier("foo"); |
+ TestDecodeCacheOrder(cachedImageLowPriority, cachedImageHighPriority); |
+ memoryCache()->evictResources(); |
+ } |
+ { |
+ ResourcePtr<FakeDecodedResource> cachedImageLowPriority = |
+ new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw); |
+ ResourcePtr<FakeDecodedResource> cachedImageHighPriority = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ cachedImageHighPriority->setCacheIdentifier("foo"); |
+ TestDecodeCacheOrder(cachedImageLowPriority, cachedImageHighPriority); |
+ memoryCache()->evictResources(); |
+ } |
+ { |
+ ResourcePtr<FakeDecodedResource> cachedImageLowPriority = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ cachedImageLowPriority->setCacheIdentifier("foo"); |
+ ResourcePtr<FakeDecodedResource> cachedImageHighPriority = |
+ new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ cachedImageHighPriority->setCacheIdentifier("bar"); |
+ TestDecodeCacheOrder(cachedImageLowPriority, cachedImageHighPriority); |
+ memoryCache()->evictResources(); |
+ } |
+} |
+ |
TEST_F(MemoryCacheTest, MultipleReplace) |
{ |
ResourcePtr<FakeResource> resource1 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw); |
@@ -404,4 +539,43 @@ TEST_F(MemoryCacheTest, RemoveDuringRevalidation) |
EXPECT_FALSE(memoryCache()->contains(resource3.get())); |
} |
+TEST_F(MemoryCacheTest, ResourceMapIsolation) |
+{ |
+ ResourcePtr<FakeResource> resource1 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ memoryCache()->add(resource1.get()); |
+ |
+ ResourcePtr<FakeResource> resource2 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ resource2->setCacheIdentifier("foo"); |
+ memoryCache()->add(resource2.get()); |
+ EXPECT_TRUE(memoryCache()->contains(resource1.get())); |
+ EXPECT_TRUE(memoryCache()->contains(resource2.get())); |
+ |
+ const KURL url = KURL(ParsedURLString, "http://test/resource"); |
+ EXPECT_EQ(resource1.get(), memoryCache()->resourceForURL(url)); |
+ EXPECT_EQ(resource1.get(), memoryCache()->resourceForURL(url, memoryCache()->defaultCacheIdentifier())); |
+ EXPECT_EQ(resource2.get(), memoryCache()->resourceForURL(url, "foo")); |
+ |
+ ResourcePtr<FakeResource> resource3 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ resource3->setCacheIdentifier("foo"); |
+ memoryCache()->remove(resource2.get()); |
+ memoryCache()->add(resource3.get()); |
+ EXPECT_TRUE(memoryCache()->contains(resource1.get())); |
+ EXPECT_FALSE(memoryCache()->contains(resource2.get())); |
+ EXPECT_TRUE(memoryCache()->contains(resource3.get())); |
+ |
+ ResourcePtr<FakeResource> resource4 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw); |
+ resource4->setCacheIdentifier("foo"); |
+ memoryCache()->replace(resource4.get(), resource3.get()); |
+ EXPECT_TRUE(memoryCache()->contains(resource1.get())); |
+ EXPECT_FALSE(memoryCache()->contains(resource3.get())); |
+ EXPECT_TRUE(memoryCache()->contains(resource4.get())); |
+ |
+ WillBeHeapVector<Member<Resource>> resources = memoryCache()->resourcesForURL(url); |
+ EXPECT_EQ(2u, resources.size()); |
+ |
+ memoryCache()->evictResources(); |
+ EXPECT_FALSE(memoryCache()->contains(resource1.get())); |
+ EXPECT_FALSE(memoryCache()->contains(resource3.get())); |
+} |
+ |
} // namespace |