| Index: ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
|
| diff --git a/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..728bbcc6ff61b6ee7a573a67b961d5b256325ace
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
|
| @@ -0,0 +1,587 @@
|
| +// Copyright 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#import "ios/chrome/browser/snapshots/snapshot_cache.h"
|
| +
|
| +#import <Foundation/Foundation.h>
|
| +
|
| +#include "base/files/file_path.h"
|
| +#include "base/files/file_util.h"
|
| +#include "base/format_macros.h"
|
| +#include "base/location.h"
|
| +#include "base/mac/bind_objc_block.h"
|
| +#include "base/mac/scoped_nsautorelease_pool.h"
|
| +#include "base/ios/ios_util.h"
|
| +#include "base/run_loop.h"
|
| +#include "base/strings/sys_string_conversions.h"
|
| +#include "base/time/time.h"
|
| +#include "ios/chrome/browser/ui/ui_util.h"
|
| +#include "ios/web/public/test/test_web_thread_bundle.h"
|
| +#include "ios/web/public/web_thread.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "testing/gtest_mac.h"
|
| +#include "testing/platform_test.h"
|
| +
|
| +static const NSUInteger kSessionCount = 10;
|
| +static const NSUInteger kSnapshotPixelSize = 8;
|
| +
|
| +// Promote some implementation methods to public.
|
| +@interface SnapshotCache (Testing)
|
| ++ (base::FilePath)imagePathForSessionID:(NSString*)sessionID;
|
| ++ (base::FilePath)greyImagePathForSessionID:(NSString*)sessionID;
|
| +- (void)handleLowMemory;
|
| +@end
|
| +
|
| +@interface SnapshotCache (TestingAdditions)
|
| +- (BOOL)hasImageInMemory:(NSString*)sessionID;
|
| +- (BOOL)hasGreyImageInMemory:(NSString*)sessionID;
|
| +@end
|
| +
|
| +@implementation SnapshotCache (TestingAdditions)
|
| +- (BOOL)hasImageInMemory:(NSString*)sessionID {
|
| + return [imageDictionary_ objectForKey:sessionID] != nil;
|
| +}
|
| +- (BOOL)hasGreyImageInMemory:(NSString*)sessionID {
|
| + return [greyImageDictionary_ objectForKey:sessionID] != nil;
|
| +}
|
| +@end
|
| +
|
| +namespace {
|
| +
|
| +class SnapshotCacheTest : public PlatformTest {
|
| + protected:
|
| + // Build an array of session names and an array of UIImages filled with
|
| + // random colors.
|
| + void SetUp() override {
|
| + PlatformTest::SetUp();
|
| + testImages_.reset([[NSMutableArray alloc] initWithCapacity:kSessionCount]);
|
| + testSessions_.reset(
|
| + [[NSMutableArray alloc] initWithCapacity:kSessionCount]);
|
| +
|
| + CGFloat scale = [SnapshotCache snapshotScaleForDevice];
|
| + UIGraphicsBeginImageContextWithOptions(
|
| + CGSizeMake(kSnapshotPixelSize, kSnapshotPixelSize), NO, scale);
|
| + CGContextRef context = UIGraphicsGetCurrentContext();
|
| + srand(1);
|
| +
|
| + for (NSUInteger i = 0; i < kSessionCount; ++i) {
|
| + UIImage* image = GenerateRandomImage(context);
|
| + [testImages_ addObject:image];
|
| + [testSessions_
|
| + addObject:[NSString stringWithFormat:@"SessionId-%" PRIuNS, i]];
|
| + }
|
| +
|
| + UIGraphicsEndImageContext();
|
| +
|
| + ClearDumpedImages();
|
| + }
|
| +
|
| + void TearDown() override {
|
| + ClearDumpedImages();
|
| + PlatformTest::TearDown();
|
| + }
|
| +
|
| + // Generates an image filled with a random color.
|
| + UIImage* GenerateRandomImage(CGContextRef context) {
|
| + CGFloat r = rand() / CGFloat(RAND_MAX);
|
| + CGFloat g = rand() / CGFloat(RAND_MAX);
|
| + CGFloat b = rand() / CGFloat(RAND_MAX);
|
| + CGContextSetRGBStrokeColor(context, r, g, b, 1.0);
|
| + CGContextSetRGBFillColor(context, r, g, b, 1.0);
|
| + CGContextFillRect(
|
| + context, CGRectMake(0.0, 0.0, kSnapshotPixelSize, kSnapshotPixelSize));
|
| + return UIGraphicsGetImageFromCurrentImageContext();
|
| + }
|
| +
|
| + // Flushes all the runloops internally used by the snapshot cache.
|
| + void FlushRunLoops() {
|
| + base::RunLoop().RunUntilIdle();
|
| + web::WebThread::GetBlockingPool()->FlushForTesting();
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| + // This function removes the snapshots both from dictionary and from disk.
|
| + void ClearDumpedImages() {
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| +
|
| + NSString* sessionID;
|
| + for (sessionID in testSessions_.get())
|
| + [cache removeImageWithSessionID:sessionID];
|
| +
|
| + FlushRunLoops();
|
| + // The above calls to -removeImageWithSessionID remove both the color
|
| + // and grey snapshots for each sessionID, if they are on disk. However,
|
| + // ensure we also get rid of the grey snapshots in memory.
|
| + [cache removeGreyCache];
|
| +
|
| + __block BOOL foundImage = NO;
|
| + __block NSUInteger numCallbacks = 0;
|
| + for (sessionID in testSessions_.get()) {
|
| + base::FilePath path([SnapshotCache imagePathForSessionID:sessionID]);
|
| +
|
| + // Checks that the snapshot is not on disk.
|
| + EXPECT_FALSE(base::PathExists(path));
|
| +
|
| + // Check that the snapshot is not in the dictionary.
|
| + [cache retrieveImageForSessionID:sessionID
|
| + callback:^(UIImage* image) {
|
| + ++numCallbacks;
|
| + if (image)
|
| + foundImage = YES;
|
| + }];
|
| + }
|
| +
|
| + // Expect that all the callbacks ran and that none retrieved an image.
|
| + FlushRunLoops();
|
| + EXPECT_EQ([testSessions_ count], numCallbacks);
|
| + EXPECT_FALSE(foundImage);
|
| + }
|
| +
|
| + // Loads kSessionCount color images into the cache. If |waitForFilesOnDisk|
|
| + // is YES, will not return until the images have been written to disk.
|
| + void LoadAllColorImagesIntoCache(bool waitForFilesOnDisk) {
|
| + LoadColorImagesIntoCache(kSessionCount, waitForFilesOnDisk);
|
| + }
|
| +
|
| + // Loads |count| color images into the cache. If |waitForFilesOnDisk|
|
| + // is YES, will not return until the images have been written to disk.
|
| + void LoadColorImagesIntoCache(NSUInteger count, bool waitForFilesOnDisk) {
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| + // Put color images in the cache.
|
| + for (NSUInteger i = 0; i < count; ++i) {
|
| + base::mac::ScopedNSAutoreleasePool pool;
|
| + UIImage* image = [testImages_ objectAtIndex:i];
|
| + NSString* sessionID = [testSessions_ objectAtIndex:i];
|
| + [cache setImage:image withSessionID:sessionID];
|
| + }
|
| + if (waitForFilesOnDisk) {
|
| + FlushRunLoops();
|
| + for (NSUInteger i = 0; i < count; ++i) {
|
| + // Check that images are on the disk.
|
| + NSString* sessionID = [testSessions_ objectAtIndex:i];
|
| + base::FilePath path([SnapshotCache imagePathForSessionID:sessionID]);
|
| + EXPECT_TRUE(base::PathExists(path));
|
| + }
|
| + }
|
| + }
|
| +
|
| + // Waits for the first |count| grey images for sessions in |testSessions_|
|
| + // to be placed in the cache.
|
| + void WaitForGreyImagesInCache(NSUInteger count) {
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| + FlushRunLoops();
|
| + for (NSUInteger i = 0; i < count; i++)
|
| + EXPECT_TRUE([cache hasGreyImageInMemory:testSessions_[i]]);
|
| + }
|
| +
|
| + // Guesses the order of the color channels in the image.
|
| + // Supports RGB, BGR, RGBA, BGRA, ARGB, ABGR.
|
| + // Returns the position of each channel between 0 and 3.
|
| + void ComputeColorComponents(CGImageRef cgImage,
|
| + int* red,
|
| + int* green,
|
| + int* blue) {
|
| + CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(cgImage);
|
| + CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(cgImage);
|
| + int byteOrder = bitmapInfo & kCGBitmapByteOrderMask;
|
| +
|
| + *red = 0;
|
| + *green = 1;
|
| + *blue = 2;
|
| +
|
| + if (alphaInfo == kCGImageAlphaLast ||
|
| + alphaInfo == kCGImageAlphaPremultipliedLast ||
|
| + alphaInfo == kCGImageAlphaNoneSkipLast) {
|
| + *red = 1;
|
| + *green = 2;
|
| + *blue = 3;
|
| + }
|
| +
|
| + if (byteOrder != kCGBitmapByteOrder32Host) {
|
| + int lastChannel = (CGImageGetBitsPerPixel(cgImage) == 24) ? 2 : 3;
|
| + *red = lastChannel - *red;
|
| + *green = lastChannel - *green;
|
| + *blue = lastChannel - *blue;
|
| + }
|
| + }
|
| +
|
| + const char* GetPixelData(CGImageRef cgImage) {
|
| + CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(cgImage));
|
| + return reinterpret_cast<const char*>(CFDataGetBytePtr(data));
|
| + }
|
| +
|
| + web::TestWebThreadBundle thread_bundle_;
|
| + base::scoped_nsobject<NSMutableArray> testSessions_;
|
| + base::scoped_nsobject<NSMutableArray> testImages_;
|
| +};
|
| +
|
| +// This test simply put all the snapshots in the cache and then gets them back
|
| +// As the snapshots are kept in memory, the same pointer can be retrieved.
|
| +// This test also checks that images are correctly removed from the disk.
|
| +TEST_F(SnapshotCacheTest, Cache) {
|
| + // Don't run on tablets because color snapshots are not cached so this test
|
| + // can't compare the UIImage pointers directly.
|
| + if (IsIPadIdiom()) {
|
| + return;
|
| + }
|
| +
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| +
|
| + // Put all images in the cache.
|
| + for (NSUInteger i = 0; i < kSessionCount; ++i) {
|
| + UIImage* image = [testImages_ objectAtIndex:i];
|
| + NSString* sessionID = [testSessions_ objectAtIndex:i];
|
| + [cache setImage:image withSessionID:sessionID];
|
| + }
|
| +
|
| + // Get images back.
|
| + __block NSUInteger numberOfCallbacks = 0;
|
| + for (NSUInteger i = 0; i < kSessionCount; ++i) {
|
| + NSString* sessionID = [testSessions_ objectAtIndex:i];
|
| + UIImage* expectedImage = [testImages_ objectAtIndex:i];
|
| + EXPECT_TRUE(expectedImage != nil);
|
| + [cache retrieveImageForSessionID:sessionID
|
| + callback:^(UIImage* image) {
|
| + // Images have not been removed from the
|
| + // dictionnary. We expect the same pointer.
|
| + EXPECT_EQ(expectedImage, image);
|
| + ++numberOfCallbacks;
|
| + }];
|
| + }
|
| + EXPECT_EQ(kSessionCount, numberOfCallbacks);
|
| +}
|
| +
|
| +// This test puts all the snapshots in the cache and flushes them to disk.
|
| +// The snapshots are then reloaded from the disk, and the colors are compared.
|
| +TEST_F(SnapshotCacheTest, SaveToDisk) {
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| +
|
| + // Put all images in the cache.
|
| + for (NSUInteger i = 0; i < kSessionCount; ++i) {
|
| + UIImage* image = [testImages_ objectAtIndex:i];
|
| + NSString* sessionID = [testSessions_ objectAtIndex:i];
|
| + [cache setImage:image withSessionID:sessionID];
|
| + }
|
| + FlushRunLoops();
|
| +
|
| + for (NSUInteger i = 0; i < kSessionCount; ++i) {
|
| + // Check that images are on the disk.
|
| + NSString* sessionID = [testSessions_ objectAtIndex:i];
|
| +
|
| + base::FilePath path([SnapshotCache imagePathForSessionID:sessionID]);
|
| + EXPECT_TRUE(base::PathExists(path));
|
| +
|
| + // Check image colors by comparing the first pixel against the reference
|
| + // image.
|
| + UIImage* image =
|
| + [UIImage imageWithContentsOfFile:base::SysUTF8ToNSString(path.value())];
|
| + CGImageRef cgImage = [image CGImage];
|
| + const char* pixels = GetPixelData(cgImage);
|
| + EXPECT_TRUE(pixels);
|
| +
|
| + UIImage* referenceImage = [testImages_ objectAtIndex:i];
|
| + CGImageRef referenceCgImage = [referenceImage CGImage];
|
| + const char* referencePixels = GetPixelData(referenceCgImage);
|
| + EXPECT_TRUE(referencePixels);
|
| +
|
| + if (pixels != nil && referencePixels != nil) {
|
| + // Color components may not be in the same order,
|
| + // because of writing to disk and reloading.
|
| + int red, green, blue;
|
| + ComputeColorComponents(cgImage, &red, &green, &blue);
|
| +
|
| + int referenceRed, referenceGreen, referenceBlue;
|
| + ComputeColorComponents(referenceCgImage, &referenceRed, &referenceGreen,
|
| + &referenceBlue);
|
| +
|
| + // Colors may not be exactly the same (compression or rounding errors)
|
| + // thus a small difference is allowed.
|
| + EXPECT_NEAR(referencePixels[referenceRed], pixels[red], 1);
|
| + EXPECT_NEAR(referencePixels[referenceGreen], pixels[green], 1);
|
| + EXPECT_NEAR(referencePixels[referenceBlue], pixels[blue], 1);
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST_F(SnapshotCacheTest, Purge) {
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| +
|
| + // Put all images in the cache.
|
| + for (NSUInteger i = 0; i < kSessionCount; ++i) {
|
| + UIImage* image = [testImages_ objectAtIndex:i];
|
| + NSString* sessionID = [testSessions_ objectAtIndex:i];
|
| + [cache setImage:image withSessionID:sessionID];
|
| + }
|
| +
|
| + NSMutableSet* liveSessions = [NSMutableSet setWithCapacity:1];
|
| + [liveSessions addObject:[testSessions_ objectAtIndex:0]];
|
| +
|
| + // Purge the cache.
|
| + [cache purgeCacheOlderThan:(base::Time::Now() - base::TimeDelta::FromHours(1))
|
| + keeping:liveSessions];
|
| + FlushRunLoops();
|
| +
|
| + // Check that nothing has been deleted.
|
| + for (NSUInteger i = 0; i < kSessionCount; ++i) {
|
| + // Check that images are on the disk.
|
| + NSString* sessionID = [testSessions_ objectAtIndex:i];
|
| +
|
| + base::FilePath path([SnapshotCache imagePathForSessionID:sessionID]);
|
| + EXPECT_TRUE(base::PathExists(path));
|
| + }
|
| +
|
| + // Purge the cache.
|
| + [cache purgeCacheOlderThan:base::Time::Now() keeping:liveSessions];
|
| + FlushRunLoops();
|
| +
|
| + // Check that the file have been deleted.
|
| + for (NSUInteger i = 0; i < kSessionCount; ++i) {
|
| + // Check that images are on the disk.
|
| + NSString* sessionID = [testSessions_ objectAtIndex:i];
|
| +
|
| + base::FilePath path([SnapshotCache imagePathForSessionID:sessionID]);
|
| + if (i == 0)
|
| + EXPECT_TRUE(base::PathExists(path));
|
| + else
|
| + EXPECT_FALSE(base::PathExists(path));
|
| + }
|
| +}
|
| +
|
| +// Loads the color images into the cache, and pins two of them. Ensures that
|
| +// only the two pinned IDs remain in memory after a call to -handleLowMemory.
|
| +TEST_F(SnapshotCacheTest, HandleLowMemory) {
|
| +// TODO(droger): This test fails on iPad iOS8 device: http://crbug.com/455209
|
| +#if !TARGET_IPHONE_SIMULATOR
|
| + if (IsIPadIdiom() && base::ios::IsRunningOnIOS8OrLater()) {
|
| + LOG(WARNING) << "Test disabled on iPad iOS8 device.";
|
| + return;
|
| + }
|
| +#endif
|
| +
|
| + LoadAllColorImagesIntoCache(true);
|
| +
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| +
|
| + NSString* firstPinnedID = [testSessions_ objectAtIndex:4];
|
| + NSString* secondPinnedID = [testSessions_ objectAtIndex:6];
|
| + NSMutableSet* set = [NSMutableSet set];
|
| + [set addObject:firstPinnedID];
|
| + [set addObject:secondPinnedID];
|
| + cache.pinnedIDs = set;
|
| +
|
| + [cache handleLowMemory];
|
| +
|
| + BOOL expectedValue = YES;
|
| + if (IsIPadIdiom()) {
|
| + expectedValue = NO;
|
| + }
|
| + EXPECT_EQ(expectedValue, [cache hasImageInMemory:firstPinnedID]);
|
| + EXPECT_EQ(expectedValue, [cache hasImageInMemory:secondPinnedID]);
|
| +
|
| + NSString* notPinnedID = [testSessions_ objectAtIndex:2];
|
| + EXPECT_FALSE([cache hasImageInMemory:notPinnedID]);
|
| +
|
| + // Wait for the final image to be pulled off disk.
|
| + FlushRunLoops();
|
| +}
|
| +
|
| +// Tests that createGreyCache creates the grey snapshots in the background,
|
| +// from color images in the in-memory cache. When the grey images are all
|
| +// loaded into memory, tests that the request to retrieve the grey snapshot
|
| +// calls the callback immediately.
|
| +// Disabled on simulators because it sometimes crashes. crbug/421425
|
| +#if !TARGET_IPHONE_SIMULATOR
|
| +TEST_F(SnapshotCacheTest, CreateGreyCache) {
|
| + LoadAllColorImagesIntoCache(true);
|
| +
|
| + // Request the creation of a grey image cache for all images.
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| + [cache createGreyCache:testSessions_];
|
| +
|
| + // Wait for them to be put into the grey image cache.
|
| + WaitForGreyImagesInCache(kSessionCount);
|
| +
|
| + __block NSUInteger numberOfCallbacks = 0;
|
| + for (NSUInteger i = 0; i < kSessionCount; ++i) {
|
| + NSString* sessionID = [testSessions_ objectAtIndex:i];
|
| + [cache retrieveGreyImageForSessionID:sessionID
|
| + callback:^(UIImage* image) {
|
| + EXPECT_TRUE(image);
|
| + ++numberOfCallbacks;
|
| + }];
|
| + }
|
| +
|
| + EXPECT_EQ(numberOfCallbacks, kSessionCount);
|
| +}
|
| +
|
| +// Same as previous test, except that all the color images are on disk,
|
| +// rather than in memory.
|
| +// Disabled due to the greyImage crash. b/8048597
|
| +TEST_F(SnapshotCacheTest, CreateGreyCacheFromDisk) {
|
| + LoadAllColorImagesIntoCache(true);
|
| +
|
| + // Remove color images from in-memory cache.
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| + [cache handleLowMemory];
|
| +
|
| + // Request the creation of a grey image cache for all images.
|
| + [cache createGreyCache:testSessions_];
|
| +
|
| + // Wait for them to be put into the grey image cache.
|
| + WaitForGreyImagesInCache(kSessionCount);
|
| +
|
| + __block NSUInteger numberOfCallbacks = 0;
|
| + for (NSUInteger i = 0; i < kSessionCount; ++i) {
|
| + NSString* sessionID = [testSessions_ objectAtIndex:i];
|
| + [cache retrieveGreyImageForSessionID:sessionID
|
| + callback:^(UIImage* image) {
|
| + EXPECT_TRUE(image);
|
| + ++numberOfCallbacks;
|
| + }];
|
| + }
|
| +
|
| + EXPECT_EQ(numberOfCallbacks, kSessionCount);
|
| +}
|
| +#endif // !TARGET_IPHONE_SIMULATOR
|
| +
|
| +// Tests mostRecentGreyBlock, which is a block to be called when the most
|
| +// recently requested grey image is finally loaded.
|
| +// The test requests three images be cached as grey images. Only the final
|
| +// callback of the three requests should be called.
|
| +// Disabled due to the greyImage crash. b/8048597
|
| +TEST_F(SnapshotCacheTest, MostRecentGreyBlock) {
|
| + const NSUInteger kNumImages = 3;
|
| + base::scoped_nsobject<NSMutableArray> sessionIDs(
|
| + [[NSMutableArray alloc] initWithCapacity:kNumImages]);
|
| + [sessionIDs addObject:[testSessions_ objectAtIndex:0]];
|
| + [sessionIDs addObject:[testSessions_ objectAtIndex:1]];
|
| + [sessionIDs addObject:[testSessions_ objectAtIndex:2]];
|
| +
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| +
|
| + // Put 3 images in the cache.
|
| + LoadColorImagesIntoCache(kNumImages, true);
|
| + // Make sure the color images are only on disk, to ensure the background
|
| + // thread is slow enough to queue up the requests.
|
| + [cache handleLowMemory];
|
| +
|
| + // Enable the grey image cache.
|
| + [cache createGreyCache:sessionIDs];
|
| +
|
| + // Request the grey versions
|
| + __block BOOL firstCallbackCalled = NO;
|
| + __block BOOL secondCallbackCalled = NO;
|
| + __block BOOL thirdCallbackCalled = NO;
|
| + [cache greyImageForSessionID:[testSessions_ objectAtIndex:0]
|
| + callback:^(UIImage*) {
|
| + firstCallbackCalled = YES;
|
| + }];
|
| + [cache greyImageForSessionID:[testSessions_ objectAtIndex:1]
|
| + callback:^(UIImage*) {
|
| + secondCallbackCalled = YES;
|
| + }];
|
| + [cache greyImageForSessionID:[testSessions_ objectAtIndex:2]
|
| + callback:^(UIImage*) {
|
| + thirdCallbackCalled = YES;
|
| + }];
|
| +
|
| + // Wait for them to be loaded.
|
| + WaitForGreyImagesInCache(kNumImages);
|
| +
|
| + EXPECT_FALSE(firstCallbackCalled);
|
| + EXPECT_FALSE(secondCallbackCalled);
|
| + EXPECT_TRUE(thirdCallbackCalled);
|
| +}
|
| +
|
| +// Test the function used to save a grey copy of a color snapshot fully on a
|
| +// background thread when the application is backgrounded.
|
| +// Disabled due to the greyImage crash. b/8048597
|
| +TEST_F(SnapshotCacheTest, GreyImageAllInBackground) {
|
| + LoadAllColorImagesIntoCache(true);
|
| +
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| +
|
| + // Now convert every image into a grey image, on disk, in the background.
|
| + for (NSUInteger i = 0; i < kSessionCount; ++i) {
|
| + [cache saveGreyInBackgroundForSessionID:[testSessions_ objectAtIndex:i]];
|
| + }
|
| +
|
| + // Waits for the grey images for the sessions in |testSessions_| to be written
|
| + // to disk, which happens in a background thread.
|
| + FlushRunLoops();
|
| +
|
| + for (NSString* sessionID in testSessions_.get()) {
|
| + base::FilePath path([SnapshotCache greyImagePathForSessionID:sessionID]);
|
| + EXPECT_TRUE(base::PathExists(path));
|
| + base::DeleteFile(path, false);
|
| + }
|
| +}
|
| +
|
| +// Verifies that image size and scale are preserved when writing and reading
|
| +// from disk.
|
| +TEST_F(SnapshotCacheTest, SizeAndScalePreservation) {
|
| + // Create an image with the expected snapshot scale.
|
| + CGFloat scale = [SnapshotCache snapshotScaleForDevice];
|
| + UIGraphicsBeginImageContextWithOptions(
|
| + CGSizeMake(kSnapshotPixelSize, kSnapshotPixelSize), NO, scale);
|
| + CGContextRef context = UIGraphicsGetCurrentContext();
|
| + UIImage* image = GenerateRandomImage(context);
|
| + UIGraphicsEndImageContext();
|
| +
|
| + // Add the image to the cache then call handle low memory to ensure the image
|
| + // is read from disk instead of the in-memory cache.
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| + NSString* const kSession = @"foo";
|
| + [cache setImage:image withSessionID:kSession];
|
| + FlushRunLoops(); // ensure the file is written to disk.
|
| + [cache handleLowMemory];
|
| +
|
| + // Retrive the image and have the callback verify the size and scale.
|
| + __block BOOL callbackComplete = NO;
|
| + [cache retrieveImageForSessionID:kSession
|
| + callback:^(UIImage* imageFromDisk) {
|
| + EXPECT_EQ(image.size.width,
|
| + imageFromDisk.size.width);
|
| + EXPECT_EQ(image.size.height,
|
| + imageFromDisk.size.height);
|
| + EXPECT_EQ(image.scale, imageFromDisk.scale);
|
| + callbackComplete = YES;
|
| + }];
|
| + FlushRunLoops();
|
| + EXPECT_TRUE(callbackComplete);
|
| +}
|
| +
|
| +// Verifies that retina-scale images are deleted properly.
|
| +TEST_F(SnapshotCacheTest, DeleteRetinaImages) {
|
| + if ([SnapshotCache snapshotScaleForDevice] != 2.0) {
|
| + return;
|
| + }
|
| +
|
| + // Create an image with retina scale.
|
| + UIGraphicsBeginImageContextWithOptions(
|
| + CGSizeMake(kSnapshotPixelSize, kSnapshotPixelSize), NO, 2.0);
|
| + CGContextRef context = UIGraphicsGetCurrentContext();
|
| + UIImage* image = GenerateRandomImage(context);
|
| + UIGraphicsEndImageContext();
|
| +
|
| + // Add the image to the cache then call handle low memory to ensure the image
|
| + // is read from disk instead of the in-memory cache.
|
| + SnapshotCache* cache = [SnapshotCache sharedInstance];
|
| + NSString* const kSession = @"foo";
|
| + [cache setImage:image withSessionID:kSession];
|
| + FlushRunLoops(); // ensure the file is written to disk.
|
| + [cache handleLowMemory];
|
| +
|
| + // Verify the file was writted with @2x in the file name.
|
| + base::FilePath retinaFile = [SnapshotCache imagePathForSessionID:kSession];
|
| + EXPECT_TRUE(base::PathExists(retinaFile));
|
| +
|
| + // Delete the image.
|
| + [cache removeImageWithSessionID:kSession];
|
| + FlushRunLoops(); // ensure the file is removed.
|
| +
|
| + EXPECT_FALSE(base::PathExists(retinaFile));
|
| +}
|
| +
|
| +} // namespace
|
|
|