| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "memory_manager.h" |
| #include "mock_resource_provider.h" |
| #include "resource_in_memory_cache.h" |
| #include "resource_provider.h" |
| #include "server_connection.h" |
| #include "test_utilities.h" |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include <memory> |
| #include <vector> |
| |
| using ::testing::_; |
| using ::testing::ContainerEq; |
| using ::testing::DoAll; |
| using ::testing::Eq; |
| using ::testing::Return; |
| using ::testing::ReturnArg; |
| using ::testing::StrictMock; |
| using ::testing::WithArg; |
| |
| namespace gapir { |
| namespace test { |
| namespace { |
| |
| const uint32_t MEMORY_SIZE = 4096; |
| const uint32_t CACHE_SIZE = 2048; |
| |
| class ResourceInMemoryCacheTest : public ::testing::Test { |
| protected: |
| virtual void SetUp() { |
| std::vector<uint32_t> memorySizes = {MEMORY_SIZE}; |
| mMemoryManager.reset(new MemoryManager(memorySizes)); |
| mMemoryManager->setVolatileMemory(MEMORY_SIZE - CACHE_SIZE); |
| |
| mFallbackProvider = new StrictMock<MockResourceProvider>(); |
| |
| mResourceInMemoryCache = ResourceInMemoryCache::create( |
| std::unique_ptr<StrictMock<MockResourceProvider>>(mFallbackProvider), |
| mMemoryManager->getBaseAddress()); |
| mResourceInMemoryCache->updateSize(CACHE_SIZE); |
| mServer = createServerConnection("", 0); |
| } |
| |
| StrictMock<MockResourceProvider>* mFallbackProvider; |
| |
| std::unique_ptr<MemoryManager> mMemoryManager; |
| std::unique_ptr<ResourceInMemoryCache> mResourceInMemoryCache; |
| std::unique_ptr<ServerConnection> mServer; |
| }; |
| |
| } // anonymous namespace |
| |
| TEST_F(ResourceInMemoryCacheTest, Prefetch) { |
| ResourceProvider::ResourceList expected{{"A", 64}, {"D", 1024}, {"E", 2048}}; |
| |
| EXPECT_CALL(*mFallbackProvider, get(_, _, _, _)).WillRepeatedly(Return(true)); |
| EXPECT_CALL(*mFallbackProvider, prefetch(ContainerEq(expected), _, _, _)) |
| .WillOnce(Return(true)); |
| |
| mResourceInMemoryCache->get("C", *mServer, mMemoryManager->getVolatileAddress(), 512); |
| mResourceInMemoryCache->get("B", *mServer, mMemoryManager->getVolatileAddress(), 256); |
| mResourceInMemoryCache->prefetch({{"A", 64}, {"B", 256}, {"C", 512}, {"D", 1024}, {"E", 2048}}, |
| *mServer, mMemoryManager->getVolatileAddress(), |
| MEMORY_SIZE - CACHE_SIZE); |
| } |
| |
| TEST_F(ResourceInMemoryCacheTest, Resize) { |
| bool res; |
| |
| // Fill the cache with three element |
| EXPECT_CALL(*mFallbackProvider, get(_, _, _, _)).WillRepeatedly(Return(true)); |
| |
| res = mResourceInMemoryCache->get("A", *mServer, mMemoryManager->getVolatileAddress(), 256); |
| EXPECT_TRUE(res); |
| |
| res = mResourceInMemoryCache->get("B", *mServer, mMemoryManager->getVolatileAddress(), 512); |
| EXPECT_TRUE(res); |
| |
| res = mResourceInMemoryCache->get("C", *mServer, mMemoryManager->getVolatileAddress(), 1024); |
| EXPECT_TRUE(res); |
| |
| // New elements are not loaded |
| EXPECT_CALL(*mFallbackProvider, get(_, _, _, _)).WillRepeatedly(Return(false)); |
| |
| // Reduce cache size what removes the last two element from the cache |
| mResourceInMemoryCache->updateSize(512); |
| |
| res = mResourceInMemoryCache->get("A", *mServer, mMemoryManager->getVolatileAddress(), 256); |
| EXPECT_TRUE(res); |
| |
| res = mResourceInMemoryCache->get("B", *mServer, mMemoryManager->getVolatileAddress(), 512); |
| EXPECT_FALSE(res); |
| |
| res = mResourceInMemoryCache->get("C", *mServer, mMemoryManager->getVolatileAddress(), 1024); |
| EXPECT_FALSE(res); |
| |
| // Reduce cache size what removes all remaining element from the cache |
| mResourceInMemoryCache->updateSize(128); |
| |
| res = mResourceInMemoryCache->get("A", *mServer, mMemoryManager->getVolatileAddress(), 256); |
| EXPECT_FALSE(res); |
| |
| res = mResourceInMemoryCache->get("B", *mServer, mMemoryManager->getVolatileAddress(), 512); |
| EXPECT_FALSE(res); |
| |
| res = mResourceInMemoryCache->get("C", *mServer, mMemoryManager->getVolatileAddress(), 1024); |
| EXPECT_FALSE(res); |
| } |
| |
| TEST_F(ResourceInMemoryCacheTest, CachingLogic) { |
| bool res; |
| |
| EXPECT_CALL(*mFallbackProvider, get(_, _, _, _)).Times(6).WillRepeatedly(Return(true)); |
| |
| // Call get {1st} (not save to cache because not fit) |
| res = mResourceInMemoryCache->get("A", *mServer, mMemoryManager->getVolatileAddress(), 4096); |
| EXPECT_TRUE(res); |
| |
| // Call get {2nd} |
| res = mResourceInMemoryCache->get("A", *mServer, mMemoryManager->getVolatileAddress(), 512); |
| EXPECT_TRUE(res); |
| |
| // Not call get |
| res = mResourceInMemoryCache->get("A", *mServer, mMemoryManager->getVolatileAddress(), 512); |
| EXPECT_TRUE(res); |
| |
| // Call get {3rd} |
| res = mResourceInMemoryCache->get("B", *mServer, mMemoryManager->getVolatileAddress(), 1024); |
| EXPECT_TRUE(res); |
| |
| // Not call get |
| res = mResourceInMemoryCache->get("A", *mServer, mMemoryManager->getVolatileAddress(), 512); |
| EXPECT_TRUE(res); |
| |
| // Not call get |
| res = mResourceInMemoryCache->get("B", *mServer, mMemoryManager->getVolatileAddress(), 1024); |
| EXPECT_TRUE(res); |
| |
| // Call get {4th} |
| res = mResourceInMemoryCache->get("C", *mServer, mMemoryManager->getVolatileAddress(), 128); |
| EXPECT_TRUE(res); |
| |
| // Not call get |
| res = mResourceInMemoryCache->get("A", *mServer, mMemoryManager->getVolatileAddress(), 512); |
| EXPECT_TRUE(res); |
| |
| // Not call get |
| res = mResourceInMemoryCache->get("B", *mServer, mMemoryManager->getVolatileAddress(), 1024); |
| EXPECT_TRUE(res); |
| |
| // Not call get |
| res = mResourceInMemoryCache->get("C", *mServer, mMemoryManager->getVolatileAddress(), 128); |
| EXPECT_TRUE(res); |
| |
| // Call get {5th} |
| res = mResourceInMemoryCache->get("D", *mServer, mMemoryManager->getVolatileAddress(), 768); |
| EXPECT_TRUE(res); |
| |
| // Not call get |
| res = mResourceInMemoryCache->get("C", *mServer, mMemoryManager->getVolatileAddress(), 128); |
| EXPECT_TRUE(res); |
| |
| // Call get {6th} |
| res = mResourceInMemoryCache->get("E", *mServer, mMemoryManager->getVolatileAddress(), 1024); |
| EXPECT_TRUE(res); |
| |
| // Not call get |
| res = mResourceInMemoryCache->get("D", *mServer, mMemoryManager->getVolatileAddress(), 768); |
| EXPECT_TRUE(res); |
| } |
| |
| } // namespace test |
| } // namespace gapir |