1e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)/*
2e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * Copyright (c) 2013, Google Inc. All rights reserved.
3e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *
4e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
5e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * modification, are permitted provided that the following conditions are
6e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * met:
7e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *
8e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *     * Redistributions of source code must retain the above copyright
9e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * notice, this list of conditions and the following disclaimer.
10e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *     * Redistributions in binary form must reproduce the above
11e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
12e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * in the documentation and/or other materials provided with the
13e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * distribution.
14e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
15e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * contributors may be used to endorse or promote products derived from
16e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * this software without specific prior written permission.
17e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *
18e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) */
30e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
31e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "config.h"
32e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/MemoryCache.h"
33e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
34e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/MockImageResourceClient.h"
35e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/RawResource.h"
36e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ResourcePtr.h"
37bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/network/ResourceRequest.h"
38e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "public/platform/Platform.h"
39e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "wtf/OwnPtr.h"
40e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
41e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include <gtest/gtest.h>
42e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
44e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
45e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)class MemoryCacheTest : public ::testing::Test {
46e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)public:
47c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    class FakeDecodedResource : public blink::Resource {
48e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    public:
49e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        FakeDecodedResource(const ResourceRequest& request, Type type)
50e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            : Resource(request, type)
51e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        {
52e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
53e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
54e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        virtual void appendData(const char* data, int len)
55e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        {
56e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            Resource::appendData(data, len);
57e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            setDecodedSize(this->size());
58e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
59e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    protected:
6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        virtual void destroyDecodedDataIfPossible() OVERRIDE
62e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        {
63e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            setDecodedSize(0);
64e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
65e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    };
66e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
67c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    class FakeResource : public blink::Resource {
6809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    public:
6909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        FakeResource(const ResourceRequest& request, Type type)
7009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            : Resource(request, type)
7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        {
7209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
7309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        void fakeEncodedSize(size_t size)
7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        {
7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            setEncodedSize(size);
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    };
7909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
80e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)protected:
81e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    virtual void SetUp()
82e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    {
83e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        // Save the global memory cache to restore it upon teardown.
84c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_globalMemoryCache = replaceMemoryCacheForTesting(MemoryCache::create());
85e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
86e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
87e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    virtual void TearDown()
88e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    {
89c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        replaceMemoryCacheForTesting(m_globalMemoryCache.release());
90e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
91e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
92c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    OwnPtrWillBePersistent<MemoryCache> m_globalMemoryCache;
93e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)};
94e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
95e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// Verifies that setters and getters for cache capacities work correcty.
96e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)TEST_F(MemoryCacheTest, CapacityAccounting)
97e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const size_t sizeMax = ~static_cast<size_t>(0);
9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const size_t totalCapacity = sizeMax / 4;
10009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const size_t minDeadCapacity = sizeMax / 16;
10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const size_t maxDeadCapacity = sizeMax / 8;
102e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->setCapacities(minDeadCapacity, maxDeadCapacity, totalCapacity);
103e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(totalCapacity, memoryCache()->capacity());
104e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(minDeadCapacity, memoryCache()->minDeadCapacity());
105e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(maxDeadCapacity, memoryCache()->maxDeadCapacity());
106e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
107e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)TEST_F(MemoryCacheTest, VeryLargeResourceAccounting)
10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const size_t sizeMax = ~static_cast<size_t>(0);
11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const size_t totalCapacity = sizeMax / 4;
11209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const size_t minDeadCapacity = sizeMax / 16;
11309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const size_t maxDeadCapacity = sizeMax / 8;
11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const size_t resourceSize1 = sizeMax / 16;
11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const size_t resourceSize2 = sizeMax / 20;
11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    memoryCache()->setCapacities(minDeadCapacity, maxDeadCapacity, totalCapacity);
11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ResourcePtr<FakeResource> cachedResource =
118197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw);
11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedResource->fakeEncodedSize(resourceSize1);
12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_EQ(0u, memoryCache()->deadSize());
12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_EQ(0u, memoryCache()->liveSize());
12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    memoryCache()->add(cachedResource.get());
12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_EQ(cachedResource->size(), memoryCache()->deadSize());
12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_EQ(0u, memoryCache()->liveSize());
12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    MockImageResourceClient client;
12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedResource->addClient(&client);
12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_EQ(0u, memoryCache()->deadSize());
13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_EQ(cachedResource->size(), memoryCache()->liveSize());
13109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cachedResource->fakeEncodedSize(resourceSize2);
13309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_EQ(0u, memoryCache()->deadSize());
13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT_EQ(cachedResource->size(), memoryCache()->liveSize());
135c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
136c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    cachedResource->removeClient(&client);
13709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
13809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
139e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// Verifies that dead resources that exceed dead resource capacity are evicted
140e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// from cache when pruning.
141e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)TEST_F(MemoryCacheTest, DeadResourceEviction)
142e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
143e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->setDelayBeforeLiveDecodedPrune(0);
144e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->setMaxPruneDeferralDelay(0);
145e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned totalCapacity = 1000000;
146e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned minDeadCapacity = 0;
147e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned maxDeadCapacity = 0;
148e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->setCapacities(minDeadCapacity, maxDeadCapacity, totalCapacity);
149e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
150f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    Resource* cachedResource =
151197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        new Resource(ResourceRequest("http://test/resource"), Resource::Raw);
152e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const char data[5] = "abcd";
153e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    cachedResource->appendData(data, 3);
154e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // The resource size has to be nonzero for this test to be meaningful, but
155e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // we do not rely on it having any particular value.
156e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_GT(cachedResource->size(), 0u);
157e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
158e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(0u, memoryCache()->deadSize());
159e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(0u, memoryCache()->liveSize());
160e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
161f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    memoryCache()->add(cachedResource);
162e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(cachedResource->size(), memoryCache()->deadSize());
163e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(0u, memoryCache()->liveSize());
164e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
165e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->prune();
166e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(0u, memoryCache()->deadSize());
167e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(0u, memoryCache()->liveSize());
168e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
169e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
170e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// Verified that when ordering a prune in a runLoop task, the prune
171e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// is deferred to the end of the task.
172e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)TEST_F(MemoryCacheTest, LiveResourceEvictionAtEndOfTask)
173e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
174e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->setDelayBeforeLiveDecodedPrune(0);
175e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned totalCapacity = 1;
176e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned minDeadCapacity = 0;
177e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned maxDeadCapacity = 0;
178e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->setCapacities(minDeadCapacity, maxDeadCapacity, totalCapacity);
179e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const char data[6] = "abcde";
180f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    Resource* cachedDeadResource =
181f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        new Resource(ResourceRequest("hhtp://foo"), Resource::Raw);
182e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    cachedDeadResource->appendData(data, 3);
183e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ResourcePtr<Resource> cachedLiveResource =
184197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw);
185e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    MockImageResourceClient client;
186e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    cachedLiveResource->addClient(&client);
187e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    cachedLiveResource->appendData(data, 4);
188e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
18951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    class Task1 : public blink::WebThread::Task {
190e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    public:
191f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        Task1(const ResourcePtr<Resource>& live, Resource* dead)
192e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            : m_live(live)
193e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            , m_dead(dead)
194e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        { }
195e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
196e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        virtual void run() OVERRIDE
197e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        {
198e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // The resource size has to be nonzero for this test to be meaningful, but
199e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // we do not rely on it having any particular value.
200e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_GT(m_live->size(), 0u);
201e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_GT(m_dead->size(), 0u);
202e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
203e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_EQ(0u, memoryCache()->deadSize());
204e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_EQ(0u, memoryCache()->liveSize());
205e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
206f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            memoryCache()->add(m_dead);
207e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            memoryCache()->add(m_live.get());
208a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            memoryCache()->updateDecodedResource(m_live.get(), UpdateForPropertyChange);
209e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_EQ(m_dead->size(), memoryCache()->deadSize());
210e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_EQ(m_live->size(), memoryCache()->liveSize());
211e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_GT(m_live->decodedSize(), 0u);
212e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
213e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            memoryCache()->prune(); // Dead resources are pruned immediately
214e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_EQ(m_dead->size(), memoryCache()->deadSize());
215e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_EQ(m_live->size(), memoryCache()->liveSize());
216e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_GT(m_live->decodedSize(), 0u);
217e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
218e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
219e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    private:
220f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        ResourcePtr<Resource> m_live;
221f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        Resource* m_dead;
222e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    };
223e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
22451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    class Task2 : public blink::WebThread::Task {
225e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    public:
226e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        Task2(unsigned liveSizeWithoutDecode)
227e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            : m_liveSizeWithoutDecode(liveSizeWithoutDecode) { }
228e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
229e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        virtual void run() OVERRIDE
230e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        {
231e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // Next task: now, the live resource was evicted.
232e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_EQ(0u, memoryCache()->deadSize());
233e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            ASSERT_EQ(m_liveSizeWithoutDecode, memoryCache()->liveSize());
23451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            blink::Platform::current()->currentThread()->exitRunLoop();
235e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
236e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
237e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    private:
238e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        unsigned m_liveSizeWithoutDecode;
239e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    };
240e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
241e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
24251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    blink::Platform::current()->currentThread()->postTask(new Task1(cachedLiveResource, cachedDeadResource));
24351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    blink::Platform::current()->currentThread()->postTask(new Task2(cachedLiveResource->encodedSize() + cachedLiveResource->overheadSize()));
24451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    blink::Platform::current()->currentThread()->enterRunLoop();
245e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    cachedLiveResource->removeClient(&client);
246e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
247e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
248e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// Verifies that cached resources are evicted immediately after release when
249e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// the total dead resource size is more than double the dead resource capacity.
250e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)TEST_F(MemoryCacheTest, ClientRemoval)
251e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
252e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const char data[6] = "abcde";
253e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ResourcePtr<Resource> resource1 =
25409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw);
255e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    MockImageResourceClient client1;
256e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    resource1->addClient(&client1);
257e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    resource1->appendData(data, 4);
258e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ResourcePtr<Resource> resource2 =
259197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw);
260e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    MockImageResourceClient client2;
261e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    resource2->addClient(&client2);
262e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    resource2->appendData(data, 4);
263e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
264e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned minDeadCapacity = 0;
26509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const unsigned maxDeadCapacity = ((resource1->size() + resource2->size()) / 2) - 1;
266e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned totalCapacity = maxDeadCapacity;
267e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->setCapacities(minDeadCapacity, maxDeadCapacity, totalCapacity);
268e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->add(resource1.get());
269e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->add(resource2.get());
270e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Call prune. There is nothing to prune, but this will initialize
271e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // the prune timestamp, allowing future prunes to be deferred.
272e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->prune();
273e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_GT(resource1->decodedSize(), 0u);
274e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_GT(resource2->decodedSize(), 0u);
275e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->deadSize(), 0u);
276e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->liveSize(), resource1->size() + resource2->size());
277e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
278e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Removing the client from resource1 should result in all resources
279e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // remaining in cache since the prune is deferred.
280e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    resource1->removeClient(&client1);
281e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_GT(resource1->decodedSize(), 0u);
282e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_GT(resource2->decodedSize(), 0u);
283e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->deadSize(), resource1->size());
284e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->liveSize(), resource2->size());
28507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    ASSERT_TRUE(memoryCache()->contains(resource1.get()));
28607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    ASSERT_TRUE(memoryCache()->contains(resource2.get()));
287e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
288e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Removing the client from resource2 should result in immediate
289e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // eviction of resource2 because we are over the prune deferral limit.
290e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    resource2->removeClient(&client2);
291e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_GT(resource1->decodedSize(), 0u);
292e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_GT(resource2->decodedSize(), 0u);
293e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->deadSize(), resource1->size());
294e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->liveSize(), 0u);
29507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    ASSERT_TRUE(memoryCache()->contains(resource1.get()));
29607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    ASSERT_FALSE(memoryCache()->contains(resource2.get()));
297e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
298e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
299e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// Verifies that CachedResources are evicted from the decode cache
300e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// according to their DecodeCachePriority.
301e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)TEST_F(MemoryCacheTest, DecodeCacheOrder)
302e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
303e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->setDelayBeforeLiveDecodedPrune(0);
304e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->setMaxPruneDeferralDelay(0);
305e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ResourcePtr<FakeDecodedResource> cachedImageLowPriority =
30609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw);
307e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ResourcePtr<FakeDecodedResource> cachedImageHighPriority =
308197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        new FakeDecodedResource(ResourceRequest("http://test/resource"), Resource::Raw);
309e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
310e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    MockImageResourceClient clientLowPriority;
311e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    MockImageResourceClient clientHighPriority;
312e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    cachedImageLowPriority->addClient(&clientLowPriority);
313e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    cachedImageHighPriority->addClient(&clientHighPriority);
314e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
315e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const char data[5] = "abcd";
316e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    cachedImageLowPriority->appendData(data, 1);
317e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    cachedImageHighPriority->appendData(data, 4);
318e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned lowPrioritySize = cachedImageLowPriority->size();
319e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned highPrioritySize = cachedImageHighPriority->size();
320e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned lowPriorityMockDecodeSize = cachedImageLowPriority->decodedSize();
321e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned highPriorityMockDecodeSize = cachedImageHighPriority->decodedSize();
322e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const unsigned totalSize = lowPrioritySize + highPrioritySize;
323e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
324e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Verify that the sizes are different to ensure that we can test eviction order.
325e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_GT(lowPrioritySize, 0u);
326e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_NE(lowPrioritySize, highPrioritySize);
327e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_GT(lowPriorityMockDecodeSize, 0u);
328e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_NE(lowPriorityMockDecodeSize, highPriorityMockDecodeSize);
329e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
330e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->deadSize(), 0u);
331e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->liveSize(), 0u);
332e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
333e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Add the items. The item added first would normally be evicted first.
334e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->add(cachedImageHighPriority.get());
335e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->deadSize(), 0u);
336e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->liveSize(), highPrioritySize);
337e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
338e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->add(cachedImageLowPriority.get());
339e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->deadSize(), 0u);
340e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->liveSize(), highPrioritySize + lowPrioritySize);
341e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
342e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Insert all items in the decoded items list with the same priority
343a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    memoryCache()->updateDecodedResource(cachedImageHighPriority.get(), UpdateForPropertyChange);
344a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    memoryCache()->updateDecodedResource(cachedImageLowPriority.get(), UpdateForPropertyChange);
345e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->deadSize(), 0u);
346e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->liveSize(), totalSize);
347e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
348e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Now we will assign their priority and make sure they are moved to the correct buckets.
349a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    memoryCache()->updateDecodedResource(cachedImageLowPriority.get(), UpdateForPropertyChange, MemoryCacheLiveResourcePriorityLow);
350a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    memoryCache()->updateDecodedResource(cachedImageHighPriority.get(), UpdateForPropertyChange, MemoryCacheLiveResourcePriorityHigh);
351e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
352e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Should first prune the LowPriority item.
353e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->setCapacities(memoryCache()->minDeadCapacity(), memoryCache()->liveSize() - 10, memoryCache()->liveSize() - 10);
354e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->prune();
355e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->deadSize(), 0u);
356e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->liveSize(), totalSize - lowPriorityMockDecodeSize);
357e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
358e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Should prune the HighPriority item.
359e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->setCapacities(memoryCache()->minDeadCapacity(), memoryCache()->liveSize() - 10, memoryCache()->liveSize() - 10);
360e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    memoryCache()->prune();
361e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->deadSize(), 0u);
362e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT_EQ(memoryCache()->liveSize(), totalSize - lowPriorityMockDecodeSize - highPriorityMockDecodeSize);
363c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
364c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    cachedImageLowPriority->removeClient(&clientLowPriority);
365c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    cachedImageHighPriority->removeClient(&clientHighPriority);
366e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
36743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
36843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)TEST_F(MemoryCacheTest, MultipleReplace)
36943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles){
370197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ResourcePtr<FakeResource> resource1 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw);
37143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    memoryCache()->add(resource1.get());
37243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
373197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ResourcePtr<FakeResource> resource2 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw);
37443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    memoryCache()->replace(resource2.get(), resource1.get());
37507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_TRUE(memoryCache()->contains(resource2.get()));
37607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_FALSE(memoryCache()->contains(resource1.get()));
37743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
378197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ResourcePtr<FakeResource> resource3 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw);
37943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    memoryCache()->replace(resource3.get(), resource2.get());
38007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_TRUE(memoryCache()->contains(resource3.get()));
38107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_FALSE(memoryCache()->contains(resource2.get()));
38207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
38307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
38407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben MurdochTEST_F(MemoryCacheTest, RemoveDuringRevalidation)
38507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
386197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ResourcePtr<FakeResource> resource1 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw);
38707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    memoryCache()->add(resource1.get());
38807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
389197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ResourcePtr<FakeResource> resource2 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw);
39007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    memoryCache()->remove(resource1.get());
39107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    memoryCache()->add(resource2.get());
39207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_TRUE(memoryCache()->contains(resource2.get()));
39307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_FALSE(memoryCache()->contains(resource1.get()));
39407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
395197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ResourcePtr<FakeResource> resource3 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw);
39607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    memoryCache()->remove(resource2.get());
39707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    memoryCache()->add(resource3.get());
39807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_TRUE(memoryCache()->contains(resource3.get()));
39907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_FALSE(memoryCache()->contains(resource2.get()));
40007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
40107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    memoryCache()->replace(resource1.get(), resource2.get());
40207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_TRUE(memoryCache()->contains(resource1.get()));
40307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_FALSE(memoryCache()->contains(resource2.get()));
40407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    EXPECT_FALSE(memoryCache()->contains(resource3.get()));
40543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)}
40643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
407e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)} // namespace
408