Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(379)

Side by Side Diff: third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp

Issue 2558033002: Loading: move ImageResource and related classes to core/loader/resource (Closed)
Patch Set: rebase and format Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "core/fetch/ImageResource.h"
32
33 #include "core/fetch/FetchInitiatorInfo.h"
34 #include "core/fetch/FetchRequest.h"
35 #include "core/fetch/MemoryCache.h"
36 #include "core/fetch/MockImageResourceClient.h"
37 #include "core/fetch/MockResourceClient.h"
38 #include "core/fetch/ResourceFetcher.h"
39 #include "core/fetch/ResourceLoader.h"
40 #include "core/fetch/UniqueIdentifier.h"
41 #include "platform/SharedBuffer.h"
42 #include "platform/exported/WrappedResourceResponse.h"
43 #include "platform/graphics/BitmapImage.h"
44 #include "platform/graphics/Image.h"
45 #include "platform/scheduler/test/fake_web_task_runner.h"
46 #include "platform/testing/TestingPlatformSupport.h"
47 #include "platform/testing/URLTestHelpers.h"
48 #include "platform/testing/UnitTestHelpers.h"
49 #include "public/platform/Platform.h"
50 #include "public/platform/WebCachePolicy.h"
51 #include "public/platform/WebURL.h"
52 #include "public/platform/WebURLLoaderMockFactory.h"
53 #include "public/platform/WebURLResponse.h"
54 #include "testing/gtest/include/gtest/gtest.h"
55 #include "wtf/PtrUtil.h"
56 #include "wtf/text/Base64.h"
57 #include <memory>
58
59 namespace blink {
60
61 namespace {
62
63 // An image of size 1x1.
64 const unsigned char kJpegImage[] = {
65 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01,
66 0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x13,
67 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68,
68 0x20, 0x47, 0x49, 0x4d, 0x50, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x05, 0x03,
69 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06,
70 0x07, 0x0c, 0x08, 0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09, 0x0c,
71 0x11, 0x0f, 0x12, 0x12, 0x11, 0x0f, 0x11, 0x11, 0x13, 0x16, 0x1c, 0x17,
72 0x13, 0x14, 0x1a, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1a, 0x1d, 0x1d,
73 0x1f, 0x1f, 0x1f, 0x13, 0x17, 0x22, 0x24, 0x22, 0x1e, 0x24, 0x1c, 0x1e,
74 0x1f, 0x1e, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x05, 0x05, 0x05, 0x07, 0x06,
75 0x07, 0x0e, 0x08, 0x08, 0x0e, 0x1e, 0x14, 0x11, 0x14, 0x1e, 0x1e, 0x1e,
76 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
77 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
78 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
79 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0xff,
80 0xc0, 0x00, 0x11, 0x08, 0x00, 0x01, 0x00, 0x01, 0x03, 0x01, 0x22, 0x00,
81 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, 0x15, 0x00, 0x01,
82 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x01, 0x01, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
89 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f,
90 0x00, 0xb2, 0xc0, 0x07, 0xff, 0xd9};
91
92 const size_t kJpegImageSubrangeWithDimensionsLength = sizeof(kJpegImage) - 1;
93
94 // Ensure that the image decoder can determine the dimensions of kJpegImage from
95 // just the first kJpegImageSubrangeWithDimensionsLength bytes. If this test
96 // fails, then the test data here probably needs to be updated.
97 TEST(ImageResourceTest, DimensionsDecodableFromPartialTestImage) {
98 RefPtr<Image> image = BitmapImage::create();
99 EXPECT_EQ(
100 Image::SizeAvailable,
101 image->setData(SharedBuffer::create(
102 kJpegImage, kJpegImageSubrangeWithDimensionsLength),
103 true));
104 EXPECT_TRUE(image->isBitmapImage());
105 EXPECT_EQ(1, image->width());
106 EXPECT_EQ(1, image->height());
107 }
108
109 // An image of size 50x50.
110 const unsigned char kJpegImage2[] = {
111 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01,
112 0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43,
113 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
114 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
115 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
116 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
117 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
118 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff,
119 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
120 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
121 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
122 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
123 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
124 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x32, 0x00, 0x32, 0x03,
125 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00,
126 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x10,
128 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x15, 0x01, 0x01, 0x01,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03,
134 0x11, 0x00, 0x3f, 0x00, 0x00, 0x94, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xd9};
137
138 const char kSvgImage[] =
139 "<svg width=\"200\" height=\"200\" xmlns=\"http://www.w3.org/2000/svg\" "
140 "xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
141 "<rect x=\"0\" y=\"0\" width=\"100px\" height=\"100px\" fill=\"red\"/>"
142 "</svg>";
143
144 const char kSvgImage2[] =
145 "<svg width=\"300\" height=\"300\" xmlns=\"http://www.w3.org/2000/svg\" "
146 "xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
147 "<rect x=\"0\" y=\"0\" width=\"200px\" height=\"200px\" fill=\"green\"/>"
148 "</svg>";
149
150 void receiveResponse(ImageResource* imageResource,
151 const KURL& url,
152 const AtomicString& mimeType,
153 const char* data,
154 size_t dataSize) {
155 ResourceResponse response;
156 response.setURL(url);
157 response.setHTTPStatusCode(200);
158 response.setMimeType(mimeType);
159 imageResource->responseReceived(response, nullptr);
160 imageResource->appendData(data, dataSize);
161 imageResource->finish();
162 }
163
164 class ImageResourceTestMockFetchContext : public FetchContext {
165 public:
166 static ImageResourceTestMockFetchContext* create() {
167 return new ImageResourceTestMockFetchContext;
168 }
169
170 virtual ~ImageResourceTestMockFetchContext() {}
171
172 bool allowImage(bool imagesEnabled, const KURL&) const override {
173 return true;
174 }
175 ResourceRequestBlockedReason canRequest(
176 Resource::Type,
177 const ResourceRequest&,
178 const KURL&,
179 const ResourceLoaderOptions&,
180 bool forPreload,
181 FetchRequest::OriginRestriction) const override {
182 return ResourceRequestBlockedReason::None;
183 }
184 bool shouldLoadNewResource(Resource::Type) const override { return true; }
185 WebTaskRunner* loadingTaskRunner() const override { return m_runner.get(); }
186
187 private:
188 ImageResourceTestMockFetchContext()
189 : m_runner(WTF::wrapUnique(new scheduler::FakeWebTaskRunner)) {}
190
191 std::unique_ptr<scheduler::FakeWebTaskRunner> m_runner;
192 };
193
194 // Convenience class that registers a mocked URL load on construction, and
195 // unregisters it on destruction. This allows for a test to use constructs like
196 // ASSERT_TRUE() without needing to worry about unregistering the mocked URL
197 // load to avoid putting other tests into inconsistent states in case the
198 // assertion fails.
199 class ScopedRegisteredURL {
200 public:
201 ScopedRegisteredURL(const KURL& url,
202 const String& fileName = "cancelTest.html",
203 const String& mimeType = "text/html")
204 : m_url(url) {
205 URLTestHelpers::registerMockedURLLoad(m_url, fileName, mimeType);
206 }
207
208 ~ScopedRegisteredURL() {
209 Platform::current()->getURLLoaderMockFactory()->unregisterURL(m_url);
210 }
211
212 private:
213 KURL m_url;
214 };
215
216 AtomicString buildContentRange(size_t rangeLength, size_t totalLength) {
217 return AtomicString(String("bytes 0-" + String::number(rangeLength) + "/" +
218 String::number(totalLength)));
219 }
220
221 TEST(ImageResourceTest, MultipartImage) {
222 ResourceFetcher* fetcher =
223 ResourceFetcher::create(ImageResourceTestMockFetchContext::create());
224 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
225 ScopedRegisteredURL scopedRegisteredURL(testURL);
226
227 // Emulate starting a real load, but don't expect any "real"
228 // WebURLLoaderClient callbacks.
229 ImageResource* cachedImage = ImageResource::create(ResourceRequest(testURL));
230 cachedImage->setIdentifier(createUniqueIdentifier());
231 fetcher->startLoad(cachedImage);
232
233 Persistent<MockImageResourceClient> client =
234 new MockImageResourceClient(cachedImage);
235 EXPECT_EQ(Resource::Pending, cachedImage->getStatus());
236
237 // Send the multipart response. No image or data buffer is created. Note that
238 // the response must be routed through ResourceLoader to ensure the load is
239 // flagged as multipart.
240 ResourceResponse multipartResponse(KURL(), "multipart/x-mixed-replace", 0,
241 nullAtom, String());
242 multipartResponse.setMultipartBoundary("boundary", strlen("boundary"));
243 cachedImage->loader()->didReceiveResponse(
244 WrappedResourceResponse(multipartResponse), nullptr);
245 EXPECT_FALSE(cachedImage->resourceBuffer());
246 EXPECT_FALSE(cachedImage->getContent()->hasImage());
247 EXPECT_EQ(0, client->imageChangedCount());
248 EXPECT_FALSE(client->notifyFinishedCalled());
249 EXPECT_EQ("multipart/x-mixed-replace", cachedImage->response().mimeType());
250
251 const char firstPart[] =
252 "--boundary\n"
253 "Content-Type: image/svg+xml\n\n";
254 cachedImage->appendData(firstPart, strlen(firstPart));
255 // Send the response for the first real part. No image or data buffer is
256 // created.
257 EXPECT_FALSE(cachedImage->resourceBuffer());
258 EXPECT_FALSE(cachedImage->getContent()->hasImage());
259 EXPECT_EQ(0, client->imageChangedCount());
260 EXPECT_FALSE(client->notifyFinishedCalled());
261 EXPECT_EQ("image/svg+xml", cachedImage->response().mimeType());
262
263 const char secondPart[] =
264 "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'><rect "
265 "width='1' height='1' fill='green'/></svg>\n";
266 // The first bytes arrive. The data buffer is created, but no image is
267 // created.
268 cachedImage->appendData(secondPart, strlen(secondPart));
269 EXPECT_TRUE(cachedImage->resourceBuffer());
270 EXPECT_FALSE(cachedImage->getContent()->hasImage());
271 EXPECT_EQ(0, client->imageChangedCount());
272 EXPECT_FALSE(client->notifyFinishedCalled());
273
274 // Add a client to check an assertion error doesn't happen
275 // (crbug.com/630983).
276 Persistent<MockImageResourceClient> client2 =
277 new MockImageResourceClient(cachedImage);
278 EXPECT_EQ(0, client2->imageChangedCount());
279 EXPECT_FALSE(client2->notifyFinishedCalled());
280
281 const char thirdPart[] = "--boundary";
282 cachedImage->appendData(thirdPart, strlen(thirdPart));
283 ASSERT_TRUE(cachedImage->resourceBuffer());
284 EXPECT_EQ(strlen(secondPart) - 1, cachedImage->resourceBuffer()->size());
285
286 // This part finishes. The image is created, callbacks are sent, and the data
287 // buffer is cleared.
288 cachedImage->loader()->didFinishLoading(0.0, 0, 0);
289 EXPECT_TRUE(cachedImage->resourceBuffer());
290 EXPECT_FALSE(cachedImage->errorOccurred());
291 ASSERT_TRUE(cachedImage->getContent()->hasImage());
292 EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
293 EXPECT_EQ(1, cachedImage->getContent()->getImage()->width());
294 EXPECT_EQ(1, cachedImage->getContent()->getImage()->height());
295 EXPECT_EQ(1, client->imageChangedCount());
296 EXPECT_TRUE(client->notifyFinishedCalled());
297 EXPECT_EQ(1, client2->imageChangedCount());
298 EXPECT_TRUE(client2->notifyFinishedCalled());
299 }
300
301 TEST(ImageResourceTest, CancelOnDetach) {
302 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
303 ScopedRegisteredURL scopedRegisteredURL(testURL);
304
305 ResourceFetcher* fetcher =
306 ResourceFetcher::create(ImageResourceTestMockFetchContext::create());
307
308 // Emulate starting a real load.
309 ImageResource* cachedImage = ImageResource::create(ResourceRequest(testURL));
310 cachedImage->setIdentifier(createUniqueIdentifier());
311
312 fetcher->startLoad(cachedImage);
313 memoryCache()->add(cachedImage);
314
315 Persistent<MockImageResourceClient> client =
316 new MockImageResourceClient(cachedImage);
317 EXPECT_EQ(Resource::Pending, cachedImage->getStatus());
318
319 // The load should still be alive, but a timer should be started to cancel the
320 // load inside removeClient().
321 client->removeAsClient();
322 EXPECT_EQ(Resource::Pending, cachedImage->getStatus());
323 EXPECT_TRUE(memoryCache()->resourceForURL(testURL));
324
325 // Trigger the cancel timer, ensure the load was cancelled and the resource
326 // was evicted from the cache.
327 blink::testing::runPendingTasks();
328 EXPECT_EQ(Resource::LoadError, cachedImage->getStatus());
329 EXPECT_FALSE(memoryCache()->resourceForURL(testURL));
330 }
331
332 TEST(ImageResourceTest, DecodedDataRemainsWhileHasClients) {
333 ImageResource* cachedImage = ImageResource::create(ResourceRequest());
334 cachedImage->setStatus(Resource::Pending);
335
336 Persistent<MockImageResourceClient> client =
337 new MockImageResourceClient(cachedImage);
338
339 // Send the image response.
340 cachedImage->responseReceived(
341 ResourceResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom,
342 String()),
343 nullptr);
344
345 cachedImage->responseReceived(
346 ResourceResponse(KURL(), "image/jpeg", sizeof(kJpegImage), nullAtom,
347 String()),
348 nullptr);
349 cachedImage->appendData(reinterpret_cast<const char*>(kJpegImage),
350 sizeof(kJpegImage));
351 EXPECT_NE(0u, cachedImage->encodedSizeMemoryUsageForTesting());
352 cachedImage->finish();
353 EXPECT_EQ(0u, cachedImage->encodedSizeMemoryUsageForTesting());
354 EXPECT_FALSE(cachedImage->errorOccurred());
355 ASSERT_TRUE(cachedImage->getContent()->hasImage());
356 EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
357 EXPECT_TRUE(client->notifyFinishedCalled());
358
359 // The prune comes when the ImageResource still has clients. The image should
360 // not be deleted.
361 cachedImage->prune();
362 EXPECT_TRUE(cachedImage->isAlive());
363 ASSERT_TRUE(cachedImage->getContent()->hasImage());
364 EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
365
366 // The ImageResource no longer has clients. The decoded image data should be
367 // deleted by prune.
368 client->removeAsClient();
369 cachedImage->prune();
370 EXPECT_FALSE(cachedImage->isAlive());
371 EXPECT_TRUE(cachedImage->getContent()->hasImage());
372 // TODO(hajimehoshi): Should check cachedImage doesn't have decoded image
373 // data.
374 }
375
376 TEST(ImageResourceTest, UpdateBitmapImages) {
377 ImageResource* cachedImage = ImageResource::create(ResourceRequest());
378 cachedImage->setStatus(Resource::Pending);
379
380 Persistent<MockImageResourceClient> client =
381 new MockImageResourceClient(cachedImage);
382
383 // Send the image response.
384 cachedImage->responseReceived(
385 ResourceResponse(KURL(), "image/jpeg", sizeof(kJpegImage), nullAtom,
386 String()),
387 nullptr);
388 cachedImage->appendData(reinterpret_cast<const char*>(kJpegImage),
389 sizeof(kJpegImage));
390 cachedImage->finish();
391 EXPECT_FALSE(cachedImage->errorOccurred());
392 ASSERT_TRUE(cachedImage->getContent()->hasImage());
393 EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
394 EXPECT_EQ(2, client->imageChangedCount());
395 EXPECT_TRUE(client->notifyFinishedCalled());
396 EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
397 }
398
399 TEST(ImageResourceTest, ReloadIfLoFiOrPlaceholderAfterFinished) {
400 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
401 ScopedRegisteredURL scopedRegisteredURL(testURL);
402 ResourceRequest request = ResourceRequest(testURL);
403 request.setLoFiState(WebURLRequest::LoFiOn);
404 ImageResource* cachedImage = ImageResource::create(request);
405 cachedImage->setStatus(Resource::Pending);
406
407 Persistent<MockImageResourceClient> client =
408 new MockImageResourceClient(cachedImage);
409 ResourceFetcher* fetcher =
410 ResourceFetcher::create(ImageResourceTestMockFetchContext::create());
411
412 // Send the image response.
413 ResourceResponse resourceResponse(KURL(), "image/jpeg", sizeof(kJpegImage),
414 nullAtom, String());
415 resourceResponse.addHTTPHeaderField("chrome-proxy-content-transform",
416 "empty-image");
417
418 cachedImage->responseReceived(resourceResponse, nullptr);
419 cachedImage->appendData(reinterpret_cast<const char*>(kJpegImage),
420 sizeof(kJpegImage));
421 cachedImage->finish();
422 EXPECT_FALSE(cachedImage->errorOccurred());
423 ASSERT_TRUE(cachedImage->getContent()->hasImage());
424 EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
425 EXPECT_EQ(2, client->imageChangedCount());
426 EXPECT_EQ(1, client->imageNotifyFinishedCount());
427 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnLastImageChanged());
428 // The client should have been notified that the image load completed.
429 EXPECT_TRUE(client->notifyFinishedCalled());
430 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnNotifyFinished());
431 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnImageNotifyFinished());
432 EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
433 EXPECT_EQ(1, cachedImage->getContent()->getImage()->width());
434 EXPECT_EQ(1, cachedImage->getContent()->getImage()->height());
435
436 // Call reloadIfLoFiOrPlaceholderImage() after the image has finished loading.
437 cachedImage->reloadIfLoFiOrPlaceholderImage(fetcher, Resource::kReloadAlways);
438 EXPECT_FALSE(cachedImage->errorOccurred());
439 EXPECT_FALSE(cachedImage->resourceBuffer());
440 EXPECT_FALSE(cachedImage->getContent()->hasImage());
441 EXPECT_EQ(3, client->imageChangedCount());
442 EXPECT_EQ(1, client->imageNotifyFinishedCount());
443
444 cachedImage->loader()->didReceiveResponse(
445 WrappedResourceResponse(resourceResponse), nullptr);
446 cachedImage->loader()->didReceiveData(
447 reinterpret_cast<const char*>(kJpegImage2), sizeof(kJpegImage2));
448 cachedImage->loader()->didFinishLoading(0.0, sizeof(kJpegImage2),
449 sizeof(kJpegImage2));
450 EXPECT_FALSE(cachedImage->errorOccurred());
451 ASSERT_TRUE(cachedImage->getContent()->hasImage());
452 EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
453 EXPECT_EQ(sizeof(kJpegImage2), client->encodedSizeOnLastImageChanged());
454 EXPECT_TRUE(client->notifyFinishedCalled());
455
456 // The client should not have been notified of completion again.
457 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnNotifyFinished());
458 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnImageNotifyFinished());
459
460 EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
461 EXPECT_EQ(50, cachedImage->getContent()->getImage()->width());
462 EXPECT_EQ(50, cachedImage->getContent()->getImage()->height());
463 }
464
465 TEST(ImageResourceTest, ReloadIfLoFiOrPlaceholderDuringFetch) {
466 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
467 ScopedRegisteredURL scopedRegisteredURL(testURL);
468
469 ResourceRequest request(testURL);
470 request.setLoFiState(WebURLRequest::LoFiOn);
471 FetchRequest fetchRequest(request, FetchInitiatorInfo());
472 ResourceFetcher* fetcher =
473 ResourceFetcher::create(ImageResourceTestMockFetchContext::create());
474
475 ImageResource* cachedImage = ImageResource::fetch(fetchRequest, fetcher);
476 Persistent<MockImageResourceClient> client =
477 new MockImageResourceClient(cachedImage);
478
479 // Send the image response.
480 ResourceResponse initialResourceResponse(
481 testURL, "image/jpeg", sizeof(kJpegImage), nullAtom, String());
482 initialResourceResponse.addHTTPHeaderField("chrome-proxy", "q=low");
483
484 cachedImage->loader()->didReceiveResponse(
485 WrappedResourceResponse(initialResourceResponse));
486 cachedImage->loader()->didReceiveData(
487 reinterpret_cast<const char*>(kJpegImage), sizeof(kJpegImage));
488
489 EXPECT_FALSE(cachedImage->errorOccurred());
490 ASSERT_TRUE(cachedImage->getContent()->hasImage());
491 EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
492 EXPECT_EQ(1, client->imageChangedCount());
493 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnLastImageChanged());
494 EXPECT_FALSE(client->notifyFinishedCalled());
495 EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
496 EXPECT_EQ(1, cachedImage->getContent()->getImage()->width());
497 EXPECT_EQ(1, cachedImage->getContent()->getImage()->height());
498
499 // Call reloadIfLoFiOrPlaceholderImage() while the image is still loading.
500 cachedImage->reloadIfLoFiOrPlaceholderImage(fetcher, Resource::kReloadAlways);
501 EXPECT_FALSE(cachedImage->errorOccurred());
502 EXPECT_FALSE(cachedImage->resourceBuffer());
503 EXPECT_FALSE(cachedImage->getContent()->hasImage());
504 EXPECT_EQ(2, client->imageChangedCount());
505 EXPECT_EQ(0U, client->encodedSizeOnLastImageChanged());
506 // The client should not have been notified of completion yet, since the image
507 // is still loading.
508 EXPECT_FALSE(client->notifyFinishedCalled());
509
510 cachedImage->loader()->didReceiveResponse(
511 WrappedResourceResponse(ResourceResponse(
512 testURL, "image/jpeg", sizeof(kJpegImage2), nullAtom, String())),
513 nullptr);
514 cachedImage->loader()->didReceiveData(
515 reinterpret_cast<const char*>(kJpegImage2), sizeof(kJpegImage2));
516 cachedImage->loader()->didFinishLoading(0.0, sizeof(kJpegImage2),
517 sizeof(kJpegImage2));
518
519 EXPECT_FALSE(cachedImage->errorOccurred());
520 ASSERT_TRUE(cachedImage->getContent()->hasImage());
521 EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
522 EXPECT_EQ(sizeof(kJpegImage2), client->encodedSizeOnLastImageChanged());
523 // The client should have been notified of completion only after the reload
524 // completed.
525 EXPECT_TRUE(client->notifyFinishedCalled());
526 EXPECT_EQ(sizeof(kJpegImage2), client->encodedSizeOnNotifyFinished());
527 EXPECT_EQ(sizeof(kJpegImage2), client->encodedSizeOnImageNotifyFinished());
528 EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
529 EXPECT_EQ(50, cachedImage->getContent()->getImage()->width());
530 EXPECT_EQ(50, cachedImage->getContent()->getImage()->height());
531 }
532
533 TEST(ImageResourceTest, ReloadIfLoFiOrPlaceholderForPlaceholder) {
534 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
535 ScopedRegisteredURL scopedRegisteredURL(testURL);
536
537 ResourceFetcher* fetcher =
538 ResourceFetcher::create(ImageResourceTestMockFetchContext::create());
539 FetchRequest request(testURL, FetchInitiatorInfo());
540 request.setAllowImagePlaceholder();
541 ImageResource* image = ImageResource::fetch(request, fetcher);
542 EXPECT_EQ(FetchRequest::AllowPlaceholder,
543 request.placeholderImageRequestType());
544 EXPECT_EQ("bytes=0-2047", image->resourceRequest().httpHeaderField("range"));
545 Persistent<MockImageResourceClient> client =
546 new MockImageResourceClient(image);
547
548 ResourceResponse response(testURL, "image/jpeg",
549 kJpegImageSubrangeWithDimensionsLength, nullAtom,
550 String());
551 response.setHTTPStatusCode(206);
552 response.setHTTPHeaderField(
553 "content-range", buildContentRange(kJpegImageSubrangeWithDimensionsLength,
554 sizeof(kJpegImage)));
555 image->loader()->didReceiveResponse(WrappedResourceResponse(response));
556 image->loader()->didReceiveData(reinterpret_cast<const char*>(kJpegImage),
557 kJpegImageSubrangeWithDimensionsLength);
558 image->loader()->didFinishLoading(0.0, kJpegImageSubrangeWithDimensionsLength,
559 kJpegImageSubrangeWithDimensionsLength);
560
561 EXPECT_EQ(Resource::Cached, image->getStatus());
562 EXPECT_TRUE(image->isPlaceholder());
563
564 image->reloadIfLoFiOrPlaceholderImage(fetcher, Resource::kReloadAlways);
565
566 EXPECT_EQ(Resource::Pending, image->getStatus());
567 EXPECT_FALSE(image->isPlaceholder());
568 EXPECT_EQ(nullAtom, image->resourceRequest().httpHeaderField("range"));
569 EXPECT_EQ(static_cast<int>(WebCachePolicy::BypassingCache),
570 static_cast<int>(image->resourceRequest().getCachePolicy()));
571
572 image->loader()->cancel();
573 }
574
575 TEST(ImageResourceTest, SVGImage) {
576 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo");
577 ImageResource* imageResource = ImageResource::create(ResourceRequest(url));
578 Persistent<MockImageResourceClient> client =
579 new MockImageResourceClient(imageResource);
580
581 receiveResponse(imageResource, url, "image/svg+xml", kSvgImage,
582 strlen(kSvgImage));
583
584 EXPECT_FALSE(imageResource->errorOccurred());
585 ASSERT_TRUE(imageResource->getContent()->hasImage());
586 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
587 EXPECT_EQ(1, client->imageChangedCount());
588 EXPECT_TRUE(client->notifyFinishedCalled());
589 EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
590 }
591
592 TEST(ImageResourceTest, SuccessfulRevalidationJpeg) {
593 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo");
594 ImageResource* imageResource = ImageResource::create(ResourceRequest(url));
595 Persistent<MockImageResourceClient> client =
596 new MockImageResourceClient(imageResource);
597
598 receiveResponse(imageResource, url, "image/jpeg",
599 reinterpret_cast<const char*>(kJpegImage),
600 sizeof(kJpegImage));
601
602 EXPECT_FALSE(imageResource->errorOccurred());
603 ASSERT_TRUE(imageResource->getContent()->hasImage());
604 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
605 EXPECT_EQ(2, client->imageChangedCount());
606 EXPECT_EQ(1, client->imageNotifyFinishedCount());
607 EXPECT_TRUE(client->notifyFinishedCalled());
608 EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
609 EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
610 EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
611
612 imageResource->setRevalidatingRequest(ResourceRequest(url));
613 ResourceResponse response;
614 response.setURL(url);
615 response.setHTTPStatusCode(304);
616
617 imageResource->responseReceived(response, nullptr);
618
619 EXPECT_FALSE(imageResource->errorOccurred());
620 ASSERT_TRUE(imageResource->getContent()->hasImage());
621 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
622 EXPECT_EQ(2, client->imageChangedCount());
623 EXPECT_EQ(1, client->imageNotifyFinishedCount());
624 EXPECT_TRUE(client->notifyFinishedCalled());
625 EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
626 EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
627 EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
628 }
629
630 TEST(ImageResourceTest, SuccessfulRevalidationSvg) {
631 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo");
632 ImageResource* imageResource = ImageResource::create(ResourceRequest(url));
633 Persistent<MockImageResourceClient> client =
634 new MockImageResourceClient(imageResource);
635
636 receiveResponse(imageResource, url, "image/svg+xml", kSvgImage,
637 strlen(kSvgImage));
638
639 EXPECT_FALSE(imageResource->errorOccurred());
640 ASSERT_TRUE(imageResource->getContent()->hasImage());
641 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
642 EXPECT_EQ(1, client->imageChangedCount());
643 EXPECT_EQ(1, client->imageNotifyFinishedCount());
644 EXPECT_TRUE(client->notifyFinishedCalled());
645 EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
646 EXPECT_EQ(200, imageResource->getContent()->getImage()->width());
647 EXPECT_EQ(200, imageResource->getContent()->getImage()->height());
648
649 imageResource->setRevalidatingRequest(ResourceRequest(url));
650 ResourceResponse response;
651 response.setURL(url);
652 response.setHTTPStatusCode(304);
653 imageResource->responseReceived(response, nullptr);
654
655 EXPECT_FALSE(imageResource->errorOccurred());
656 ASSERT_TRUE(imageResource->getContent()->hasImage());
657 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
658 EXPECT_EQ(1, client->imageChangedCount());
659 EXPECT_EQ(1, client->imageNotifyFinishedCount());
660 EXPECT_TRUE(client->notifyFinishedCalled());
661 EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
662 EXPECT_EQ(200, imageResource->getContent()->getImage()->width());
663 EXPECT_EQ(200, imageResource->getContent()->getImage()->height());
664 }
665
666 TEST(ImageResourceTest, FailedRevalidationJpegToJpeg) {
667 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo");
668 ImageResource* imageResource = ImageResource::create(ResourceRequest(url));
669 Persistent<MockImageResourceClient> client =
670 new MockImageResourceClient(imageResource);
671
672 receiveResponse(imageResource, url, "image/jpeg",
673 reinterpret_cast<const char*>(kJpegImage),
674 sizeof(kJpegImage));
675
676 EXPECT_FALSE(imageResource->errorOccurred());
677 ASSERT_TRUE(imageResource->getContent()->hasImage());
678 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
679 EXPECT_EQ(2, client->imageChangedCount());
680 EXPECT_EQ(1, client->imageNotifyFinishedCount());
681 EXPECT_TRUE(client->notifyFinishedCalled());
682 EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
683 EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
684 EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
685
686 imageResource->setRevalidatingRequest(ResourceRequest(url));
687 receiveResponse(imageResource, url, "image/jpeg",
688 reinterpret_cast<const char*>(kJpegImage2),
689 sizeof(kJpegImage2));
690
691 EXPECT_FALSE(imageResource->errorOccurred());
692 ASSERT_TRUE(imageResource->getContent()->hasImage());
693 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
694 EXPECT_EQ(4, client->imageChangedCount());
695 EXPECT_EQ(1, client->imageNotifyFinishedCount());
696 EXPECT_TRUE(client->notifyFinishedCalled());
697 EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
698 EXPECT_EQ(50, imageResource->getContent()->getImage()->width());
699 EXPECT_EQ(50, imageResource->getContent()->getImage()->height());
700 }
701
702 TEST(ImageResourceTest, FailedRevalidationJpegToSvg) {
703 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo");
704 ImageResource* imageResource = ImageResource::create(ResourceRequest(url));
705 Persistent<MockImageResourceClient> client =
706 new MockImageResourceClient(imageResource);
707
708 receiveResponse(imageResource, url, "image/jpeg",
709 reinterpret_cast<const char*>(kJpegImage),
710 sizeof(kJpegImage));
711
712 EXPECT_FALSE(imageResource->errorOccurred());
713 ASSERT_TRUE(imageResource->getContent()->hasImage());
714 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
715 EXPECT_EQ(2, client->imageChangedCount());
716 EXPECT_EQ(1, client->imageNotifyFinishedCount());
717 EXPECT_TRUE(client->notifyFinishedCalled());
718 EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
719 EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
720 EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
721
722 imageResource->setRevalidatingRequest(ResourceRequest(url));
723 receiveResponse(imageResource, url, "image/svg+xml", kSvgImage,
724 strlen(kSvgImage));
725
726 EXPECT_FALSE(imageResource->errorOccurred());
727 ASSERT_TRUE(imageResource->getContent()->hasImage());
728 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
729 EXPECT_EQ(3, client->imageChangedCount());
730 EXPECT_EQ(1, client->imageNotifyFinishedCount());
731 EXPECT_TRUE(client->notifyFinishedCalled());
732 EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
733 EXPECT_EQ(200, imageResource->getContent()->getImage()->width());
734 EXPECT_EQ(200, imageResource->getContent()->getImage()->height());
735 }
736
737 TEST(ImageResourceTest, FailedRevalidationSvgToJpeg) {
738 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo");
739 ImageResource* imageResource = ImageResource::create(ResourceRequest(url));
740 Persistent<MockImageResourceClient> client =
741 new MockImageResourceClient(imageResource);
742
743 receiveResponse(imageResource, url, "image/svg+xml", kSvgImage,
744 strlen(kSvgImage));
745
746 EXPECT_FALSE(imageResource->errorOccurred());
747 ASSERT_TRUE(imageResource->getContent()->hasImage());
748 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
749 EXPECT_EQ(1, client->imageChangedCount());
750 EXPECT_EQ(1, client->imageNotifyFinishedCount());
751 EXPECT_TRUE(client->notifyFinishedCalled());
752 EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
753 EXPECT_EQ(200, imageResource->getContent()->getImage()->width());
754 EXPECT_EQ(200, imageResource->getContent()->getImage()->height());
755
756 imageResource->setRevalidatingRequest(ResourceRequest(url));
757 receiveResponse(imageResource, url, "image/jpeg",
758 reinterpret_cast<const char*>(kJpegImage),
759 sizeof(kJpegImage));
760
761 EXPECT_FALSE(imageResource->errorOccurred());
762 ASSERT_TRUE(imageResource->getContent()->hasImage());
763 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
764 EXPECT_EQ(3, client->imageChangedCount());
765 EXPECT_EQ(1, client->imageNotifyFinishedCount());
766 EXPECT_TRUE(client->notifyFinishedCalled());
767 EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
768 EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
769 EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
770 }
771
772 TEST(ImageResourceTest, FailedRevalidationSvgToSvg) {
773 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo");
774 ImageResource* imageResource = ImageResource::create(ResourceRequest(url));
775 Persistent<MockImageResourceClient> client =
776 new MockImageResourceClient(imageResource);
777
778 receiveResponse(imageResource, url, "image/svg+xml", kSvgImage,
779 strlen(kSvgImage));
780
781 EXPECT_FALSE(imageResource->errorOccurred());
782 ASSERT_TRUE(imageResource->getContent()->hasImage());
783 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
784 EXPECT_EQ(1, client->imageChangedCount());
785 EXPECT_EQ(1, client->imageNotifyFinishedCount());
786 EXPECT_TRUE(client->notifyFinishedCalled());
787 EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
788 EXPECT_EQ(200, imageResource->getContent()->getImage()->width());
789 EXPECT_EQ(200, imageResource->getContent()->getImage()->height());
790
791 imageResource->setRevalidatingRequest(ResourceRequest(url));
792 receiveResponse(imageResource, url, "image/svg+xml", kSvgImage2,
793 strlen(kSvgImage2));
794
795 EXPECT_FALSE(imageResource->errorOccurred());
796 ASSERT_TRUE(imageResource->getContent()->hasImage());
797 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
798 EXPECT_EQ(2, client->imageChangedCount());
799 EXPECT_EQ(1, client->imageNotifyFinishedCount());
800 EXPECT_TRUE(client->notifyFinishedCalled());
801 EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
802 EXPECT_EQ(300, imageResource->getContent()->getImage()->width());
803 EXPECT_EQ(300, imageResource->getContent()->getImage()->height());
804 }
805
806 // Tests for pruning.
807
808 TEST(ImageResourceTest, AddClientAfterPrune) {
809 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo");
810 ImageResource* imageResource = ImageResource::create(ResourceRequest(url));
811
812 // Adds a ResourceClient but not ImageResourceObserver.
813 Persistent<MockResourceClient> client1 =
814 new MockResourceClient(imageResource);
815
816 receiveResponse(imageResource, url, "image/jpeg",
817 reinterpret_cast<const char*>(kJpegImage),
818 sizeof(kJpegImage));
819
820 EXPECT_FALSE(imageResource->errorOccurred());
821 ASSERT_TRUE(imageResource->getContent()->hasImage());
822 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
823 EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
824 EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
825 EXPECT_TRUE(client1->notifyFinishedCalled());
826
827 client1->removeAsClient();
828
829 EXPECT_FALSE(imageResource->isAlive());
830
831 imageResource->prune();
832
833 EXPECT_TRUE(imageResource->getContent()->hasImage());
834
835 // Re-adds a ResourceClient but not ImageResourceObserver.
836 Persistent<MockResourceClient> client2 =
837 new MockResourceClient(imageResource);
838
839 ASSERT_TRUE(imageResource->getContent()->hasImage());
840 EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
841 EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
842 EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
843 EXPECT_TRUE(client2->notifyFinishedCalled());
844 }
845
846 TEST(ImageResourceTest, CancelOnDecodeError) {
847 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
848 ScopedRegisteredURL scopedRegisteredURL(testURL);
849
850 ResourceFetcher* fetcher =
851 ResourceFetcher::create(ImageResourceTestMockFetchContext::create());
852 FetchRequest request(testURL, FetchInitiatorInfo());
853 ImageResource* cachedImage = ImageResource::fetch(request, fetcher);
854
855 cachedImage->loader()->didReceiveResponse(
856 WrappedResourceResponse(
857 ResourceResponse(testURL, "image/jpeg", 18, nullAtom, String())),
858 nullptr);
859 cachedImage->loader()->didReceiveData("notactuallyanimage", 18);
860 EXPECT_EQ(Resource::DecodeError, cachedImage->getStatus());
861 EXPECT_FALSE(cachedImage->isLoading());
862 }
863
864 TEST(ImageResourceTest, FetchDisallowPlaceholder) {
865 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
866 ScopedRegisteredURL scopedRegisteredURL(testURL);
867
868 FetchRequest request(testURL, FetchInitiatorInfo());
869 ImageResource* image = ImageResource::fetch(
870 request,
871 ResourceFetcher::create(ImageResourceTestMockFetchContext::create()));
872 EXPECT_EQ(FetchRequest::DisallowPlaceholder,
873 request.placeholderImageRequestType());
874 EXPECT_EQ(nullAtom, image->resourceRequest().httpHeaderField("range"));
875 EXPECT_FALSE(image->isPlaceholder());
876 Persistent<MockImageResourceClient> client =
877 new MockImageResourceClient(image);
878
879 image->loader()->didReceiveResponse(
880 WrappedResourceResponse(ResourceResponse(
881 testURL, "image/jpeg", sizeof(kJpegImage), nullAtom, String())));
882 image->loader()->didReceiveData(reinterpret_cast<const char*>(kJpegImage),
883 sizeof(kJpegImage));
884 image->loader()->didFinishLoading(0.0, sizeof(kJpegImage),
885 sizeof(kJpegImage));
886
887 EXPECT_EQ(Resource::Cached, image->getStatus());
888 EXPECT_EQ(sizeof(kJpegImage), image->encodedSize());
889 EXPECT_FALSE(image->isPlaceholder());
890 EXPECT_LT(0, client->imageChangedCount());
891 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnLastImageChanged());
892 EXPECT_TRUE(client->notifyFinishedCalled());
893 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnNotifyFinished());
894 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnImageNotifyFinished());
895
896 ASSERT_TRUE(image->getContent()->hasImage());
897 EXPECT_EQ(1, image->getContent()->getImage()->width());
898 EXPECT_EQ(1, image->getContent()->getImage()->height());
899 EXPECT_TRUE(image->getContent()->getImage()->isBitmapImage());
900 }
901
902 TEST(ImageResourceTest, FetchAllowPlaceholderDataURL) {
903 KURL testURL(ParsedURLString,
904 "data:image/jpeg;base64," +
905 base64Encode(reinterpret_cast<const char*>(kJpegImage),
906 sizeof(kJpegImage)));
907 FetchRequest request(testURL, FetchInitiatorInfo());
908 request.setAllowImagePlaceholder();
909 ImageResource* image = ImageResource::fetch(
910 request,
911 ResourceFetcher::create(ImageResourceTestMockFetchContext::create()));
912 EXPECT_EQ(FetchRequest::DisallowPlaceholder,
913 request.placeholderImageRequestType());
914 EXPECT_EQ(nullAtom, image->resourceRequest().httpHeaderField("range"));
915 EXPECT_FALSE(image->isPlaceholder());
916 }
917
918 TEST(ImageResourceTest, FetchAllowPlaceholderPostRequest) {
919 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
920 ScopedRegisteredURL scopedRegisteredURL(testURL);
921 ResourceRequest resourceRequest(testURL);
922 resourceRequest.setHTTPMethod("POST");
923 FetchRequest request(resourceRequest, FetchInitiatorInfo());
924 request.setAllowImagePlaceholder();
925 ImageResource* image = ImageResource::fetch(
926 request,
927 ResourceFetcher::create(ImageResourceTestMockFetchContext::create()));
928 EXPECT_EQ(FetchRequest::DisallowPlaceholder,
929 request.placeholderImageRequestType());
930 EXPECT_EQ(nullAtom, image->resourceRequest().httpHeaderField("range"));
931 EXPECT_FALSE(image->isPlaceholder());
932
933 image->loader()->cancel();
934 }
935
936 TEST(ImageResourceTest, FetchAllowPlaceholderExistingRangeHeader) {
937 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
938 ScopedRegisteredURL scopedRegisteredURL(testURL);
939 ResourceRequest resourceRequest(testURL);
940 resourceRequest.setHTTPHeaderField("range", "bytes=128-255");
941 FetchRequest request(resourceRequest, FetchInitiatorInfo());
942 request.setAllowImagePlaceholder();
943 ImageResource* image = ImageResource::fetch(
944 request,
945 ResourceFetcher::create(ImageResourceTestMockFetchContext::create()));
946 EXPECT_EQ(FetchRequest::DisallowPlaceholder,
947 request.placeholderImageRequestType());
948 EXPECT_EQ("bytes=128-255", image->resourceRequest().httpHeaderField("range"));
949 EXPECT_FALSE(image->isPlaceholder());
950
951 image->loader()->cancel();
952 }
953
954 TEST(ImageResourceTest, FetchAllowPlaceholderSuccessful) {
955 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
956 ScopedRegisteredURL scopedRegisteredURL(testURL);
957
958 FetchRequest request(testURL, FetchInitiatorInfo());
959 request.setAllowImagePlaceholder();
960 ImageResource* image = ImageResource::fetch(
961 request,
962 ResourceFetcher::create(ImageResourceTestMockFetchContext::create()));
963 EXPECT_EQ(FetchRequest::AllowPlaceholder,
964 request.placeholderImageRequestType());
965 EXPECT_EQ("bytes=0-2047", image->resourceRequest().httpHeaderField("range"));
966 EXPECT_TRUE(image->isPlaceholder());
967 Persistent<MockImageResourceClient> client =
968 new MockImageResourceClient(image);
969
970 ResourceResponse response(testURL, "image/jpeg",
971 kJpegImageSubrangeWithDimensionsLength, nullAtom,
972 String());
973 response.setHTTPStatusCode(206);
974 response.setHTTPHeaderField(
975 "content-range", buildContentRange(kJpegImageSubrangeWithDimensionsLength,
976 sizeof(kJpegImage)));
977 image->loader()->didReceiveResponse(WrappedResourceResponse(response));
978 image->loader()->didReceiveData(reinterpret_cast<const char*>(kJpegImage),
979 kJpegImageSubrangeWithDimensionsLength);
980 image->loader()->didFinishLoading(0.0, kJpegImageSubrangeWithDimensionsLength,
981 kJpegImageSubrangeWithDimensionsLength);
982
983 EXPECT_EQ(Resource::Cached, image->getStatus());
984 EXPECT_EQ(kJpegImageSubrangeWithDimensionsLength, image->encodedSize());
985 EXPECT_TRUE(image->isPlaceholder());
986 EXPECT_LT(0, client->imageChangedCount());
987 EXPECT_EQ(kJpegImageSubrangeWithDimensionsLength,
988 client->encodedSizeOnLastImageChanged());
989 EXPECT_TRUE(client->notifyFinishedCalled());
990 EXPECT_EQ(kJpegImageSubrangeWithDimensionsLength,
991 client->encodedSizeOnNotifyFinished());
992 EXPECT_EQ(kJpegImageSubrangeWithDimensionsLength,
993 client->encodedSizeOnImageNotifyFinished());
994
995 ASSERT_TRUE(image->getContent()->hasImage());
996 EXPECT_EQ(1, image->getContent()->getImage()->width());
997 EXPECT_EQ(1, image->getContent()->getImage()->height());
998 EXPECT_FALSE(image->getContent()->getImage()->isBitmapImage());
999 EXPECT_FALSE(image->getContent()->getImage()->isSVGImage());
1000 }
1001
1002 TEST(ImageResourceTest, FetchAllowPlaceholderUnsuccessful) {
1003 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
1004 ScopedRegisteredURL scopedRegisteredURL(testURL);
1005
1006 FetchRequest request(testURL, FetchInitiatorInfo());
1007 request.setAllowImagePlaceholder();
1008 ImageResource* image = ImageResource::fetch(
1009 request,
1010 ResourceFetcher::create(ImageResourceTestMockFetchContext::create()));
1011 EXPECT_EQ(FetchRequest::AllowPlaceholder,
1012 request.placeholderImageRequestType());
1013 EXPECT_EQ("bytes=0-2047", image->resourceRequest().httpHeaderField("range"));
1014 EXPECT_TRUE(image->isPlaceholder());
1015 Persistent<MockImageResourceClient> client =
1016 new MockImageResourceClient(image);
1017
1018 const char kBadData[] = "notanimageresponse";
1019
1020 image->loader()->didReceiveResponse(
1021 WrappedResourceResponse(ResourceResponse(
1022 testURL, "image/jpeg", sizeof(kBadData), nullAtom, String())));
1023 image->loader()->didReceiveData(kBadData, sizeof(kBadData));
1024
1025 // The dimensions could not be extracted, so the full original image should be
1026 // loading.
1027 EXPECT_EQ(Resource::Pending, image->getStatus());
1028 EXPECT_FALSE(image->isPlaceholder());
1029 EXPECT_EQ(nullAtom, image->resourceRequest().httpHeaderField("range"));
1030 EXPECT_EQ(static_cast<int>(WebCachePolicy::BypassingCache),
1031 static_cast<int>(image->resourceRequest().getCachePolicy()));
1032 EXPECT_FALSE(client->notifyFinishedCalled());
1033 EXPECT_EQ(0, client->imageNotifyFinishedCount());
1034
1035 image->loader()->didReceiveResponse(
1036 WrappedResourceResponse(ResourceResponse(
1037 testURL, "image/jpeg", sizeof(kJpegImage), nullAtom, String())));
1038 image->loader()->didReceiveData(reinterpret_cast<const char*>(kJpegImage),
1039 sizeof(kJpegImage));
1040 image->loader()->didFinishLoading(0.0, sizeof(kJpegImage),
1041 sizeof(kJpegImage));
1042
1043 EXPECT_EQ(Resource::Cached, image->getStatus());
1044 EXPECT_EQ(sizeof(kJpegImage), image->encodedSize());
1045 EXPECT_FALSE(image->isPlaceholder());
1046 EXPECT_LT(0, client->imageChangedCount());
1047 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnLastImageChanged());
1048 EXPECT_TRUE(client->notifyFinishedCalled());
1049 EXPECT_EQ(1, client->imageNotifyFinishedCount());
1050 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnNotifyFinished());
1051 EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnImageNotifyFinished());
1052
1053 ASSERT_TRUE(image->getContent()->hasImage());
1054 EXPECT_EQ(1, image->getContent()->getImage()->width());
1055 EXPECT_EQ(1, image->getContent()->getImage()->height());
1056 EXPECT_TRUE(image->getContent()->getImage()->isBitmapImage());
1057 }
1058
1059 TEST(ImageResourceTest, FetchAllowPlaceholderThenDisallowPlaceholder) {
1060 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
1061 ScopedRegisteredURL scopedRegisteredURL(testURL);
1062
1063 ResourceFetcher* fetcher =
1064 ResourceFetcher::create(ImageResourceTestMockFetchContext::create());
1065 FetchRequest placeholderRequest(testURL, FetchInitiatorInfo());
1066 placeholderRequest.setAllowImagePlaceholder();
1067 ImageResource* image = ImageResource::fetch(placeholderRequest, fetcher);
1068 Persistent<MockImageResourceClient> client =
1069 new MockImageResourceClient(image);
1070
1071 FetchRequest nonPlaceholderRequest(testURL, FetchInitiatorInfo());
1072 ImageResource* secondImage =
1073 ImageResource::fetch(nonPlaceholderRequest, fetcher);
1074 EXPECT_EQ(image, secondImage);
1075 EXPECT_EQ(Resource::Pending, image->getStatus());
1076 EXPECT_FALSE(image->isPlaceholder());
1077 EXPECT_EQ(nullAtom, image->resourceRequest().httpHeaderField("range"));
1078 EXPECT_EQ(static_cast<int>(WebCachePolicy::UseProtocolCachePolicy),
1079 static_cast<int>(image->resourceRequest().getCachePolicy()));
1080 EXPECT_FALSE(client->notifyFinishedCalled());
1081
1082 image->loader()->cancel();
1083 }
1084
1085 TEST(ImageResourceTest,
1086 FetchAllowPlaceholderThenDisallowPlaceholderAfterLoaded) {
1087 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
1088 ScopedRegisteredURL scopedRegisteredURL(testURL);
1089
1090 ResourceFetcher* fetcher =
1091 ResourceFetcher::create(ImageResourceTestMockFetchContext::create());
1092 FetchRequest placeholderRequest(testURL, FetchInitiatorInfo());
1093 placeholderRequest.setAllowImagePlaceholder();
1094 ImageResource* image = ImageResource::fetch(placeholderRequest, fetcher);
1095 Persistent<MockImageResourceClient> client =
1096 new MockImageResourceClient(image);
1097
1098 ResourceResponse response(testURL, "image/jpeg",
1099 kJpegImageSubrangeWithDimensionsLength, nullAtom,
1100 String());
1101 response.setHTTPStatusCode(206);
1102 response.setHTTPHeaderField(
1103 "content-range", buildContentRange(kJpegImageSubrangeWithDimensionsLength,
1104 sizeof(kJpegImage)));
1105 image->loader()->didReceiveResponse(WrappedResourceResponse(response));
1106 image->loader()->didReceiveData(reinterpret_cast<const char*>(kJpegImage),
1107 kJpegImageSubrangeWithDimensionsLength);
1108 image->loader()->didFinishLoading(0.0, kJpegImageSubrangeWithDimensionsLength,
1109 kJpegImageSubrangeWithDimensionsLength);
1110
1111 EXPECT_EQ(Resource::Cached, image->getStatus());
1112 EXPECT_EQ(kJpegImageSubrangeWithDimensionsLength, image->encodedSize());
1113 EXPECT_TRUE(image->isPlaceholder());
1114 EXPECT_LT(0, client->imageChangedCount());
1115 EXPECT_TRUE(client->notifyFinishedCalled());
1116
1117 FetchRequest nonPlaceholderRequest(testURL, FetchInitiatorInfo());
1118 ImageResource* secondImage =
1119 ImageResource::fetch(nonPlaceholderRequest, fetcher);
1120 EXPECT_EQ(image, secondImage);
1121 EXPECT_EQ(Resource::Pending, image->getStatus());
1122 EXPECT_FALSE(image->isPlaceholder());
1123 EXPECT_EQ(nullAtom, image->resourceRequest().httpHeaderField("range"));
1124 EXPECT_EQ(static_cast<int>(WebCachePolicy::UseProtocolCachePolicy),
1125 static_cast<int>(image->resourceRequest().getCachePolicy()));
1126
1127 image->loader()->cancel();
1128 }
1129
1130 TEST(ImageResourceTest, PeriodicFlushTest) {
1131 TestingPlatformSupportWithMockScheduler platform;
1132 KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
1133 URLTestHelpers::registerMockedURLLoad(testURL, "cancelTest.html",
1134 "text/html");
1135 ResourceRequest request = ResourceRequest(testURL);
1136 ImageResource* cachedImage = ImageResource::create(request);
1137 cachedImage->setStatus(Resource::Pending);
1138
1139 Persistent<MockImageResourceClient> client =
1140 new MockImageResourceClient(cachedImage);
1141
1142 // Send the image response.
1143 ResourceResponse resourceResponse(KURL(), "image/jpeg", sizeof(kJpegImage2),
1144 nullAtom, String());
1145 resourceResponse.addHTTPHeaderField("chrome-proxy", "q=low");
1146
1147 cachedImage->responseReceived(resourceResponse, nullptr);
1148
1149 // This is number is sufficiently large amount of bytes necessary for the
1150 // image to be created (since the size is known). This was determined by
1151 // appending one byte at a time (with flushes) until the image was decoded.
1152 size_t meaningfulImageSize = 280;
1153 cachedImage->appendData(reinterpret_cast<const char*>(kJpegImage2),
1154 meaningfulImageSize);
1155 size_t bytesSent = meaningfulImageSize;
1156
1157 EXPECT_FALSE(cachedImage->errorOccurred());
1158 EXPECT_TRUE(cachedImage->getContent()->hasImage());
1159 EXPECT_EQ(1, client->imageChangedCount());
1160
1161 platform.runForPeriodSeconds(1.);
1162 platform.advanceClockSeconds(1.);
1163
1164 // Sanity check that we created an image after appending |meaningfulImageSize|
1165 // bytes just once.
1166 EXPECT_FALSE(cachedImage->errorOccurred());
1167 ASSERT_TRUE(cachedImage->getContent()->hasImage());
1168 EXPECT_EQ(1, client->imageChangedCount());
1169
1170 for (int flushCount = 1; flushCount <= 3; ++flushCount) {
1171 // For each of the iteration that appends data, we don't expect
1172 // |imageChangeCount()| to change, since the time is adjusted by 0.2001
1173 // seconds (it's greater than 0.2 to avoid double precision problems).
1174 // After 5 appends, we breach the flush interval and the flush count
1175 // increases.
1176 for (int i = 0; i < 5; ++i) {
1177 SCOPED_TRACE(i);
1178 cachedImage->appendData(
1179 reinterpret_cast<const char*>(kJpegImage2) + bytesSent, 1);
1180
1181 EXPECT_FALSE(cachedImage->errorOccurred());
1182 ASSERT_TRUE(cachedImage->getContent()->hasImage());
1183 EXPECT_EQ(flushCount, client->imageChangedCount());
1184
1185 ++bytesSent;
1186 platform.runForPeriodSeconds(0.2001);
1187 }
1188 }
1189
1190 // Increasing time by a large number only causes one extra flush.
1191 platform.runForPeriodSeconds(10.);
1192 platform.advanceClockSeconds(10.);
1193 EXPECT_FALSE(cachedImage->errorOccurred());
1194 ASSERT_TRUE(cachedImage->getContent()->hasImage());
1195 EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
1196 EXPECT_EQ(4, client->imageChangedCount());
1197
1198 // Append the rest of the data and finish (which causes another flush).
1199 cachedImage->appendData(
1200 reinterpret_cast<const char*>(kJpegImage2) + bytesSent,
1201 sizeof(kJpegImage2) - bytesSent);
1202 cachedImage->finish();
1203
1204 EXPECT_FALSE(cachedImage->errorOccurred());
1205 ASSERT_TRUE(cachedImage->getContent()->hasImage());
1206 EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
1207 EXPECT_EQ(5, client->imageChangedCount());
1208 EXPECT_TRUE(client->notifyFinishedCalled());
1209 EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
1210 EXPECT_EQ(50, cachedImage->getContent()->getImage()->width());
1211 EXPECT_EQ(50, cachedImage->getContent()->getImage()->height());
1212
1213 WTF::setTimeFunctionsForTesting(nullptr);
1214 }
1215
1216 } // namespace
1217 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698