OLD | NEW |
| (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 | |
OLD | NEW |