15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (c) 2013, Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
3251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/fetch/RawResource.h"
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/fetch/ImageResourceClient.h"
3551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/fetch/MemoryCache.h"
3651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/fetch/MockImageResourceClient.h"
3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/fetch/ResourceFetcher.h"
3851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/fetch/ResourcePtr.h"
3951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/loader/DocumentLoader.h"
4051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/testing/DummyPageHolder.h"
4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/testing/UnitTestHelpers.h"
4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/SharedBuffer.h"
4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/Platform.h"
4451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/WebURL.h"
4551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/WebURLResponse.h"
4651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/WebUnitTestSupport.h"
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)using namespace blink;
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
50c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)TEST(RawResourceTest, DontIgnoreAcceptForCacheReuse)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ResourceRequest jpegRequest;
5551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    jpegRequest.setHTTPAccept("image/jpeg");
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
57c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ResourcePtr<RawResource> jpegResource(new RawResource(jpegRequest, Resource::Raw));
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ResourceRequest pngRequest;
6051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    pngRequest.setHTTPAccept("image/png");
6151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT_FALSE(jpegResource->canReuse(pngRequest));
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)TEST(RawResourceTest, RevalidationSucceeded)
6609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
6709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Create two RawResources and set one to revalidate the other.
6809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RawResource* oldResourcePointer = new RawResource(ResourceRequest("data:text/html,"), Resource::Raw);
6909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RawResource* newResourcePointer = new RawResource(ResourceRequest("data:text/html,"), Resource::Raw);
7009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    newResourcePointer->setResourceToRevalidate(oldResourcePointer);
7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ResourcePtr<Resource> oldResource = oldResourcePointer;
7209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ResourcePtr<Resource> newResource = newResourcePointer;
7309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    memoryCache()->add(oldResource.get());
7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    memoryCache()->remove(oldResource.get());
7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    memoryCache()->add(newResource.get());
7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Simulate a successful revalidation.
7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // The revalidated resource (oldResource) should now be in the cache, newResource
7909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // should have been sliently switched to point to the revalidated resource, and
8009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // we shouldn't hit any ASSERTs.
8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ResourceResponse response;
8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    response.setHTTPStatusCode(304);
8309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    newResource->responseReceived(response);
8409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    EXPECT_EQ(memoryCache()->resourceForURL(KURL(ParsedURLString, "data:text/html,")), oldResource.get());
8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    EXPECT_EQ(oldResource.get(), newResource.get());
8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    EXPECT_NE(newResource.get(), newResourcePointer);
8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
8809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
896f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochclass DummyClient : public RawResourceClient {
906f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochpublic:
916f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    DummyClient() : m_called(false) { }
926f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    virtual ~DummyClient() { }
936f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
946f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // ResourceClient implementation.
956f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    virtual void notifyFinished(Resource* resource)
966f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    {
976f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        m_called = true;
986f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    }
996f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1006f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    bool called() { return m_called; }
1016f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochprivate:
1026f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    bool m_called;
1036f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch};
1046f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1056f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch// This client adds another client when notified.
1066f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochclass AddingClient : public RawResourceClient {
1076f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochpublic:
1086f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    AddingClient(DummyClient* client, Resource* resource)
1096f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        : m_dummyClient(client)
1106f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        , m_resource(resource)
1116f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        , m_removeClientTimer(this, &AddingClient::removeClient) { }
1126f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1136f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    virtual ~AddingClient() { }
1146f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1156f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // ResourceClient implementation.
1166f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    virtual void notifyFinished(Resource* resource)
1176f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    {
1186f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        // First schedule an asynchronous task to remove the client.
1196f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        // We do not expect the client to be called.
1206f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        m_removeClientTimer.startOneShot(0, FROM_HERE);
1216f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        resource->addClient(m_dummyClient);
1226f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    }
1236f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    void removeClient(Timer<AddingClient>* timer)
1246f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    {
1256f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        m_resource->removeClient(m_dummyClient);
1266f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    }
1276f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochprivate:
1286f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    DummyClient* m_dummyClient;
1296f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    Resource* m_resource;
1306f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    Timer<AddingClient> m_removeClientTimer;
1316f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch};
1326f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1336f543c786fc42989f552b4daa774ca5ff32fa697Ben MurdochTEST(RawResourceTest, AddClientDuringCallback)
1346f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{
1356f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    ResourcePtr<Resource> raw = new RawResource(ResourceRequest("data:text/html,"), Resource::Raw);
1366f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    raw->setLoading(false);
1376f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1386f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // Create a non-null response.
1396f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    ResourceResponse response = raw->response();
1406f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    response.setURL(KURL(ParsedURLString, "http://600.613/"));
1416f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    raw->setResponse(response);
1426f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    EXPECT_FALSE(raw->response().isNull());
1436f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1446f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    OwnPtr<DummyClient> dummyClient = adoptPtr(new DummyClient());
1456f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    OwnPtr<AddingClient> addingClient = adoptPtr(new AddingClient(dummyClient.get(), raw.get()));
1466f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    raw->addClient(addingClient.get());
1476f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    testing::runPendingTasks();
1486f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    raw->removeClient(addingClient.get());
1496f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    EXPECT_FALSE(dummyClient->called());
1506f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    EXPECT_FALSE(raw->hasClients());
1516f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch}
1526f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1536f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch// This client removes another client when notified.
1546f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochclass RemovingClient : public RawResourceClient {
1556f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochpublic:
1566f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    RemovingClient(DummyClient* client)
1576f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        : m_dummyClient(client) { }
1586f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1596f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    virtual ~RemovingClient() { }
1606f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1616f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // ResourceClient implementation.
1626f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    virtual void notifyFinished(Resource* resource)
1636f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    {
1646f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        resource->removeClient(m_dummyClient);
1656f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        resource->removeClient(this);
1666f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    }
1676f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochprivate:
1686f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    DummyClient* m_dummyClient;
1696f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch};
1706f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1716f543c786fc42989f552b4daa774ca5ff32fa697Ben MurdochTEST(RawResourceTest, RemoveClientDuringCallback)
1726f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{
1736f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    ResourcePtr<Resource> raw = new RawResource(ResourceRequest("data:text/html,"), Resource::Raw);
1746f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    raw->setLoading(false);
1756f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1766f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // Create a non-null response.
1776f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    ResourceResponse response = raw->response();
1786f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    response.setURL(KURL(ParsedURLString, "http://600.613/"));
1796f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    raw->setResponse(response);
1806f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    EXPECT_FALSE(raw->response().isNull());
1816f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1826f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    OwnPtr<DummyClient> dummyClient = adoptPtr(new DummyClient());
1836f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    OwnPtr<RemovingClient> removingClient = adoptPtr(new RemovingClient(dummyClient.get()));
1846f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    raw->addClient(dummyClient.get());
1856f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    raw->addClient(removingClient.get());
1866f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    testing::runPendingTasks();
1876f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    EXPECT_FALSE(raw->hasClients());
1886f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch}
1896f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
190c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
191