[core] Update ImageManager's unit test for onRemoveUnusedStyleImages API

This commit is contained in:
Alexander Shalamov
2019-05-06 18:40:22 +03:00
parent 100eb61fa4
commit dcf1a4efb3

View File

@@ -169,11 +169,16 @@ class StubImageManagerObserver : public ImageManagerObserver {
public:
int count = 0;
std::function<void (const std::string&)> imageMissing = [](const std::string&){};
virtual void onStyleImageMissing(const std::string& id, std::function<void()> done) override {
void onStyleImageMissing(const std::string& id, std::function<void()> done) override {
count++;
imageMissing(id);
done();
}
std::function<void (const std::vector<std::string>&)> removeUnusedStyleImages = [](const std::vector<std::string>&){};
void onRemoveUnusedStyleImages(const std::vector<std::string>& unusedImageIDs) override {
removeUnusedStyleImages(unusedImageIDs);
}
};
TEST(ImageManager, OnStyleImageMissingBeforeSpriteLoaded) {
@@ -249,18 +254,30 @@ TEST(ImageManager, OnStyleImageMissingAfterSpriteLoaded) {
ASSERT_TRUE(notified);
}
TEST(ImageManager, ReduceMemoryUsage) {
TEST(ImageManager, RemoveUnusedStyleImages) {
util::RunLoop runLoop;
ImageManager imageManager;
StubImageManagerObserver observer;
observer.imageMissing = [&imageManager] (const std::string& id) {
imageManager.addImage(makeMutable<style::Image::Impl>(id, PremultipliedImage({ 16, 16 }), 1));
};
imageManager.setObserver(&observer);
imageManager.setLoaded(true);
runLoop.runOnce();
observer.imageMissing = [&imageManager] (const std::string& id) {
if (id == "1024px") {
imageManager.addImage(makeMutable<style::Image::Impl>(id, PremultipliedImage({ 1024, 1024 }), 1));
} else {
imageManager.addImage(makeMutable<style::Image::Impl>(id, PremultipliedImage({ 16, 16 }), 1));
}
};
observer.removeUnusedStyleImages = [&imageManager](const std::vector<std::string>& ids) {
for (const auto& id : ids) {
assert(imageManager.getImage(id));
imageManager.removeImage(id);
}
};
// Style sprite.
imageManager.addImage(makeMutable<style::Image::Impl>("sprite", PremultipliedImage({ 16, 16 }), 1));
// Single requestor
{
@@ -271,10 +288,31 @@ TEST(ImageManager, ReduceMemoryUsage) {
ASSERT_FALSE(imageManager.getImage("missing") == nullptr);
}
// Reduce memory usage and check that unused image was deleted.
// Within cache limits, no need to notify client.
imageManager.reduceMemoryUseIfCacheSizeExceedsLimit();
runLoop.runOnce();
ASSERT_FALSE(imageManager.getImage("missing") == nullptr);
// Simulate OOM case, forces client notification to be issued.
imageManager.reduceMemoryUse();
runLoop.runOnce();
ASSERT_TRUE(imageManager.getImage("missing") == nullptr);
ASSERT_FALSE(imageManager.getImage("sprite") == nullptr);
// Single requestor, exceed cache size limit.
{
std::unique_ptr<StubImageRequestor> requestor = std::make_unique<StubImageRequestor>(imageManager);
imageManager.getImages(*requestor, std::make_pair(ImageDependencies{{"1024px", ImageType::Icon}}, 0ull));
runLoop.runOnce();
EXPECT_EQ(observer.count, 2);
ASSERT_FALSE(imageManager.getImage("1024px") == nullptr);
}
// Over cache limits, need to notify client.
imageManager.reduceMemoryUseIfCacheSizeExceedsLimit();
runLoop.runOnce();
ASSERT_TRUE(imageManager.getImage("1024px") == nullptr);
ASSERT_FALSE(imageManager.getImage("sprite") == nullptr);
// Multiple requestors
{
@@ -283,11 +321,14 @@ TEST(ImageManager, ReduceMemoryUsage) {
imageManager.getImages(*requestor1, std::make_pair(ImageDependencies{{"missing", ImageType::Icon}}, 0ull));
imageManager.getImages(*requestor2, std::make_pair(ImageDependencies{{"missing", ImageType::Icon}}, 1ull));
runLoop.runOnce();
EXPECT_EQ(observer.count, 2);
EXPECT_EQ(observer.count, 3);
ASSERT_FALSE(imageManager.getImage("missing") == nullptr);
}
// Reduce memory usage and check that unused image was deleted when all requestors are destructed.
imageManager.reduceMemoryUseIfCacheSizeExceedsLimit();
runLoop.runOnce();
ASSERT_FALSE(imageManager.getImage("missing") == nullptr);
imageManager.reduceMemoryUse();
runLoop.runOnce();
ASSERT_TRUE(imageManager.getImage("missing") == nullptr);
@@ -296,21 +337,25 @@ TEST(ImageManager, ReduceMemoryUsage) {
std::unique_ptr<StubImageRequestor> requestor = std::make_unique<StubImageRequestor>(imageManager);
{
std::unique_ptr<StubImageRequestor> requestor1 = std::make_unique<StubImageRequestor>(imageManager);
imageManager.getImages(*requestor, std::make_pair(ImageDependencies{{"missing", ImageType::Icon}}, 0ull));
imageManager.getImages(*requestor, std::make_pair(ImageDependencies{{"missing", ImageType::Icon}, {"1024px", ImageType::Icon}}, 0ull));
imageManager.getImages(*requestor1, std::make_pair(ImageDependencies{{"missing", ImageType::Icon}}, 1ull));
runLoop.runOnce();
EXPECT_EQ(observer.count, 3);
EXPECT_EQ(observer.count, 5);
ASSERT_FALSE(imageManager.getImage("missing") == nullptr);
ASSERT_FALSE(imageManager.getImage("1024px") == nullptr);
}
// Reduce memory usage and check that requested image is not destructed.
imageManager.reduceMemoryUse();
imageManager.reduceMemoryUseIfCacheSizeExceedsLimit();
runLoop.runOnce();
ASSERT_FALSE(imageManager.getImage("missing") == nullptr);
ASSERT_FALSE(imageManager.getImage("1024px") == nullptr);
// Release last requestor and check if resource was released after reduceMemoryUse().
// Release last requestor and check if resource was released when cache size is over the limit.
requestor.reset();
imageManager.reduceMemoryUse();
imageManager.reduceMemoryUseIfCacheSizeExceedsLimit();
runLoop.runOnce();
ASSERT_TRUE(imageManager.getImage("missing") == nullptr);
ASSERT_TRUE(imageManager.getImage("1024px") == nullptr);
ASSERT_FALSE(imageManager.getImage("sprite") == nullptr);
}