From dcf1a4efb3cae2b9a9ed339761ceeb226a0180f8 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Mon, 6 May 2019 18:40:22 +0300 Subject: [core] Update ImageManager's unit test for onRemoveUnusedStyleImages API --- test/renderer/image_manager.test.cpp | 71 +++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 13 deletions(-) (limited to 'test') diff --git a/test/renderer/image_manager.test.cpp b/test/renderer/image_manager.test.cpp index 87a24e3bd3..443a8539b6 100644 --- a/test/renderer/image_manager.test.cpp +++ b/test/renderer/image_manager.test.cpp @@ -169,11 +169,16 @@ class StubImageManagerObserver : public ImageManagerObserver { public: int count = 0; std::function imageMissing = [](const std::string&){}; - virtual void onStyleImageMissing(const std::string& id, std::function done) override { + void onStyleImageMissing(const std::string& id, std::function done) override { count++; imageMissing(id); done(); } + + std::function&)> removeUnusedStyleImages = [](const std::vector&){}; + void onRemoveUnusedStyleImages(const std::vector& 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; + imageManager.setObserver(&observer); + imageManager.setLoaded(true); observer.imageMissing = [&imageManager] (const std::string& id) { - imageManager.addImage(makeMutable(id, PremultipliedImage({ 16, 16 }), 1)); + if (id == "1024px") { + imageManager.addImage(makeMutable(id, PremultipliedImage({ 1024, 1024 }), 1)); + } else { + imageManager.addImage(makeMutable(id, PremultipliedImage({ 16, 16 }), 1)); + } }; - imageManager.setObserver(&observer); - imageManager.setLoaded(true); - runLoop.runOnce(); + observer.removeUnusedStyleImages = [&imageManager](const std::vector& ids) { + for (const auto& id : ids) { + assert(imageManager.getImage(id)); + imageManager.removeImage(id); + } + }; + + // Style sprite. + imageManager.addImage(makeMutable("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 requestor = std::make_unique(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 requestor = std::make_unique(imageManager); { std::unique_ptr requestor1 = std::make_unique(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); } -- cgit v1.2.1