Home | History | Annotate | Download | only in fetch
      1 /*
      2  * Copyright (c) 2013, Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "core/fetch/RawResource.h"
     33 
     34 #include "core/fetch/ImageResourceClient.h"
     35 #include "core/fetch/MemoryCache.h"
     36 #include "core/fetch/MockImageResourceClient.h"
     37 #include "core/fetch/ResourceFetcher.h"
     38 #include "core/fetch/ResourcePtr.h"
     39 #include "core/loader/DocumentLoader.h"
     40 #include "core/testing/DummyPageHolder.h"
     41 #include "core/testing/UnitTestHelpers.h"
     42 #include "platform/SharedBuffer.h"
     43 #include "public/platform/Platform.h"
     44 #include "public/platform/WebURL.h"
     45 #include "public/platform/WebURLResponse.h"
     46 #include "public/platform/WebUnitTestSupport.h"
     47 
     48 using namespace WebCore;
     49 
     50 namespace WebCore {
     51 
     52 TEST(RawResourceTest, DontIgnoreAcceptForCacheReuse)
     53 {
     54     ResourceRequest jpegRequest;
     55     jpegRequest.setHTTPAccept("image/jpeg");
     56 
     57     RawResource jpegResource(jpegRequest, Resource::Raw);
     58 
     59     ResourceRequest pngRequest;
     60     pngRequest.setHTTPAccept("image/png");
     61 
     62     ASSERT_FALSE(jpegResource.canReuse(pngRequest));
     63 }
     64 
     65 TEST(RawResourceTest, RevalidationSucceeded)
     66 {
     67     // Create two RawResources and set one to revalidate the other.
     68     RawResource* oldResourcePointer = new RawResource(ResourceRequest("data:text/html,"), Resource::Raw);
     69     RawResource* newResourcePointer = new RawResource(ResourceRequest("data:text/html,"), Resource::Raw);
     70     newResourcePointer->setResourceToRevalidate(oldResourcePointer);
     71     ResourcePtr<Resource> oldResource = oldResourcePointer;
     72     ResourcePtr<Resource> newResource = newResourcePointer;
     73     memoryCache()->add(oldResource.get());
     74     memoryCache()->remove(oldResource.get());
     75     memoryCache()->add(newResource.get());
     76 
     77     // Simulate a successful revalidation.
     78     // The revalidated resource (oldResource) should now be in the cache, newResource
     79     // should have been sliently switched to point to the revalidated resource, and
     80     // we shouldn't hit any ASSERTs.
     81     ResourceResponse response;
     82     response.setHTTPStatusCode(304);
     83     newResource->responseReceived(response);
     84     EXPECT_EQ(memoryCache()->resourceForURL(KURL(ParsedURLString, "data:text/html,")), oldResource.get());
     85     EXPECT_EQ(oldResource.get(), newResource.get());
     86     EXPECT_NE(newResource.get(), newResourcePointer);
     87 }
     88 
     89 class DummyClient : public RawResourceClient {
     90 public:
     91     DummyClient() : m_called(false) { }
     92     virtual ~DummyClient() { }
     93 
     94     // ResourceClient implementation.
     95     virtual void notifyFinished(Resource* resource)
     96     {
     97         m_called = true;
     98     }
     99 
    100     bool called() { return m_called; }
    101 private:
    102     bool m_called;
    103 };
    104 
    105 // This client adds another client when notified.
    106 class AddingClient : public RawResourceClient {
    107 public:
    108     AddingClient(DummyClient* client, Resource* resource)
    109         : m_dummyClient(client)
    110         , m_resource(resource)
    111         , m_removeClientTimer(this, &AddingClient::removeClient) { }
    112 
    113     virtual ~AddingClient() { }
    114 
    115     // ResourceClient implementation.
    116     virtual void notifyFinished(Resource* resource)
    117     {
    118         // First schedule an asynchronous task to remove the client.
    119         // We do not expect the client to be called.
    120         m_removeClientTimer.startOneShot(0, FROM_HERE);
    121         resource->addClient(m_dummyClient);
    122     }
    123     void removeClient(Timer<AddingClient>* timer)
    124     {
    125         m_resource->removeClient(m_dummyClient);
    126     }
    127 private:
    128     DummyClient* m_dummyClient;
    129     Resource* m_resource;
    130     Timer<AddingClient> m_removeClientTimer;
    131 };
    132 
    133 TEST(RawResourceTest, AddClientDuringCallback)
    134 {
    135     ResourcePtr<Resource> raw = new RawResource(ResourceRequest("data:text/html,"), Resource::Raw);
    136     raw->setLoading(false);
    137 
    138     // Create a non-null response.
    139     ResourceResponse response = raw->response();
    140     response.setURL(KURL(ParsedURLString, "http://600.613/"));
    141     raw->setResponse(response);
    142     EXPECT_FALSE(raw->response().isNull());
    143 
    144     OwnPtr<DummyClient> dummyClient = adoptPtr(new DummyClient());
    145     OwnPtr<AddingClient> addingClient = adoptPtr(new AddingClient(dummyClient.get(), raw.get()));
    146     raw->addClient(addingClient.get());
    147     testing::runPendingTasks();
    148     raw->removeClient(addingClient.get());
    149     EXPECT_FALSE(dummyClient->called());
    150     EXPECT_FALSE(raw->hasClients());
    151 }
    152 
    153 // This client removes another client when notified.
    154 class RemovingClient : public RawResourceClient {
    155 public:
    156     RemovingClient(DummyClient* client)
    157         : m_dummyClient(client) { }
    158 
    159     virtual ~RemovingClient() { }
    160 
    161     // ResourceClient implementation.
    162     virtual void notifyFinished(Resource* resource)
    163     {
    164         resource->removeClient(m_dummyClient);
    165         resource->removeClient(this);
    166     }
    167 private:
    168     DummyClient* m_dummyClient;
    169 };
    170 
    171 TEST(RawResourceTest, RemoveClientDuringCallback)
    172 {
    173     ResourcePtr<Resource> raw = new RawResource(ResourceRequest("data:text/html,"), Resource::Raw);
    174     raw->setLoading(false);
    175 
    176     // Create a non-null response.
    177     ResourceResponse response = raw->response();
    178     response.setURL(KURL(ParsedURLString, "http://600.613/"));
    179     raw->setResponse(response);
    180     EXPECT_FALSE(raw->response().isNull());
    181 
    182     OwnPtr<DummyClient> dummyClient = adoptPtr(new DummyClient());
    183     OwnPtr<RemovingClient> removingClient = adoptPtr(new RemovingClient(dummyClient.get()));
    184     raw->addClient(dummyClient.get());
    185     raw->addClient(removingClient.get());
    186     testing::runPendingTasks();
    187     EXPECT_FALSE(raw->hasClients());
    188 }
    189 
    190 } // namespace WebCore
    191