• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/image/test/unittest/image_cache_test.h"
17 
18 #include "gtest/gtest.h"
19 #include "core/image/sk_image_cache.h"
20 #include "core/components_ng/image_provider/adapter/skia_image_data.h"
21 
22 using namespace testing;
23 using namespace testing::ext;
24 
25 namespace OHOS::Ace {
26 const int32_t FILE_SIZE = 15;
27 const std::string CACHE_FILE_PATH = "/data/test/resource/imagecache/images";
28 const std::string CACHE_IMAGE_FILE_1 = "/data/test/resource/imagecache/images/748621363886323660";
29 const std::string CACHE_IMAGE_FILE_2 = "/data/test/resource/imagecache/images/8819493328252140263";
30 const std::string CACHE_IMAGE_FILE_3 = "/data/test/resource/imagecache/images/1008157312073340586";
31 const std::string CACHE_IMAGE_FILE_4 = "/data/test/resource/imagecache/images/13610839755484614436";
32 const std::string CACHE_IMAGE_FILE_5 = "/data/test/resource/imagecache/images/5841967474238710136";
33 const std::vector<std::string> CACHE_FILES = { CACHE_IMAGE_FILE_1, CACHE_IMAGE_FILE_2, CACHE_IMAGE_FILE_3,
34     CACHE_IMAGE_FILE_4, CACHE_IMAGE_FILE_5 };
35 const size_t TEST_COUNT = CACHE_FILES.size();
36 
37 const std::string KEY_1 = "key1";
38 const std::string KEY_2 = "key2";
39 const std::string KEY_3 = "key3";
40 const std::string KEY_4 = "key4";
41 const std::string KEY_5 = "key5";
42 const std::string KEY_6 = "key6";
43 const std::vector<std::string> FILE_KEYS = { KEY_1, KEY_2, KEY_3, KEY_4, KEY_5 };
44 
45 
46 class ImageCacheTest : public testing::Test {
47 public:
SetUpTestCase()48     static void SetUpTestCase() {}
TearDownTestCase()49     static void TearDownTestCase() {}
SetUp()50     void SetUp()
51     {
52         imageCache->SetCapacity(80);
53     }
TearDown()54     void TearDown() {}
55 
56     RefPtr<ImageCache> imageCache = ImageCache::Create();
57 };
58 
59 /**
60  * @tc.name: MemoryCache001
61  * @tc.desc: new image success insert into cache with LRU.
62  * @tc.type: FUNC
63  */
64 HWTEST_F(ImageCacheTest, MemoryCache001, TestSize.Level1)
65 {
66     /**
67      * @tc.steps: step1. cache images one by one.
68      * @tc.expected: new item should at begin of cacheList_ and imagCache has right iters.
69      */
70     for (size_t i = 0; i < CACHE_FILES.size(); i++) {
71         imageCache->CacheImage(FILE_KEYS[i], std::make_shared<CachedImage>(nullptr));
72         std::string frontKey = (imageCache->cacheList_).front().cacheKey;
73         ASSERT_EQ(frontKey, FILE_KEYS[i]);
74         ASSERT_EQ(frontKey, imageCache->imageCache_[FILE_KEYS[i]]->cacheKey);
75     }
76 
77     /**
78      * @tc.steps: step2. cache a image already in cache for example FILE_KEYS[3] e.t. "key4".
79      * @tc.expected: the cached item should at begin of cacheList_ and imagCache has right iters.
80      */
81     imageCache->CacheImage(FILE_KEYS[3], std::make_shared<CachedImage>(nullptr));
82     ASSERT_EQ(imageCache->cacheList_.front().cacheKey, FILE_KEYS[3]);
83     ASSERT_EQ(imageCache->imageCache_[FILE_KEYS[3]]->cacheKey, FILE_KEYS[3]);
84 }
85 
86 /**
87  * @tc.name: MemoryCache002
88  * @tc.desc: get image success in cache with LRU.
89  * @tc.type: FUNC
90  */
91 HWTEST_F(ImageCacheTest, MemoryCache002, TestSize.Level1)
92 {
93     /**
94      * @tc.steps: step1. cache images one by one.
95      */
96     for (size_t i = 0; i < CACHE_FILES.size(); i++) {
97         imageCache->CacheImage(FILE_KEYS[i], std::make_shared<CachedImage>(nullptr));
98         std::string frontKey = (imageCache->cacheList_).front().cacheKey;
99     }
100     /**
101      * @tc.steps: step2. find a image already in cache for example FILE_KEYS[2] e.t. "key3".
102      * @tc.expected: the cached iterator should not at end() of cacheList_ and imagCache.
103      *              after GetImageCache(), the item should at begin() of cacheList_.
104      */
105     auto iter = (imageCache->imageCache_).find(FILE_KEYS[2]);
106     ASSERT_NE(iter, imageCache->imageCache_.end());
107     imageCache->GetCacheImage(FILE_KEYS[2]);
108     ASSERT_EQ(imageCache->cacheList_.front().cacheKey, FILE_KEYS[2]);
109     ASSERT_EQ(imageCache->imageCache_[FILE_KEYS[2]]->cacheKey, FILE_KEYS[2]);
110 
111     /**
112      * @tc.steps: step3. find a image not in cache for example "key8".
113      * @tc.expected: return null.
114      */
115     auto image = imageCache->GetCacheImage("key8");
116     ASSERT_EQ(image, nullptr);
117 }
118 
119 /**
120  * @tc.name: MemoryCache003
121  * @tc.desc: Set memory cache capacity success.
122  * @tc.type: FUNC
123  */
124 HWTEST_F(ImageCacheTest, MemoryCache003, TestSize.Level1)
125 {
126     /**
127      * @tc.steps: step1. call set capacity.
128      * @tc.expected: capacity set to 1000.
129      */
130     imageCache->SetCapacity(1000);
131     ASSERT_EQ(static_cast<int32_t>(imageCache->capacity_), 1000);
132 }
133 
134 /**
135  * @tc.name: MemoryCache004
136  * @tc.desc: memory cache of image data.
137  * @tc.type: FUNC
138  */
139 HWTEST_F(ImageCacheTest, MemoryCache004, TestSize.Level1)
140 {
141     /**
142      * @tc.steps: step1. set data limit to 10 bytes, cache some data.check result
143      * @tc.expected: result is right.
144      */
145     imageCache->dataSizeLimit_ = 10;
146 
147     // create 3 bytes data, cache it, current size is 3
148     const uint8_t data1[] = {'a', 'b', 'c' };
149     sk_sp<SkData> skData1 = SkData::MakeWithCopy(data1, 3);
150     auto cachedData1 = AceType::MakeRefPtr<NG::SkiaImageData>(skData1);
151     imageCache->CacheImageData(KEY_1, cachedData1);
152     ASSERT_EQ(imageCache->curDataSize_, 3u);
153 
154     // create 2 bytes data, cache it, current size is 5. {abc} {de}
155     const uint8_t data2[] = {'d', 'e' };
156     sk_sp<SkData> skData2 = SkData::MakeWithCopy(data2, 2);
157     auto cachedData2 = AceType::MakeRefPtr<NG::SkiaImageData>(skData2);
158     imageCache->CacheImageData(KEY_2, cachedData2);
159     ASSERT_EQ(imageCache->curDataSize_, 5u);
160 
161     // create 7 bytes data, cache it, current size is 5. new data not cached.
162     const uint8_t data3[] = { 'f', 'g', 'h', 'i', 'j', 'k', 'l' };
163     sk_sp<SkData> skData3 = SkData::MakeWithCopy(data3, 7);
164     auto cachedData3 = AceType::MakeRefPtr<NG::SkiaImageData>(skData3);
165     imageCache->CacheImageData(KEY_3, cachedData3);
166     ASSERT_EQ(imageCache->curDataSize_, 5u);
167     auto data = imageCache->GetCacheImageData(KEY_3);
168     ASSERT_EQ(data, nullptr);
169 
170     // create 5 bytes data, cache it, current size is 10 {abc} {de} {mnopq}
171     const uint8_t data4[] = { 'm', 'n', 'o', 'p', 'q' };
172     sk_sp<SkData> skData4 = SkData::MakeWithCopy(data4, 5);
173     auto cachedData4 = AceType::MakeRefPtr<NG::SkiaImageData>(skData4);
174     imageCache->CacheImageData(KEY_4, cachedData4);
175     ASSERT_EQ(imageCache->curDataSize_, 10u);
176 
177     // create 2 bytes data, cache it, current size is 9 {de}{mnopq}{rs}
178     const uint8_t data5[] = { 'r', 's' };
179     sk_sp<SkData> skData5 = SkData::MakeWithCopy(data5, 2);
180     auto cachedData5 = AceType::MakeRefPtr<NG::SkiaImageData>(skData5);
181     imageCache->CacheImageData(KEY_5, cachedData5);
182     ASSERT_EQ(imageCache->curDataSize_, 9u);
183 
184     // create 5 bytes, cache it, current size is 7 {rs}{tuvwx}
185     const uint8_t data6[] = { 't', 'u', 'v', 'w', 'x' };
186     sk_sp<SkData> skData6 = SkData::MakeWithCopy(data6, 5);
187     auto cachedData6 = AceType::MakeRefPtr<NG::SkiaImageData>(skData6);
188     imageCache->CacheImageData(KEY_6, cachedData6);
189     ASSERT_EQ(imageCache->curDataSize_, 7u);
190 
191     // cache data witch is already cached. {rs}{y}
192     const uint8_t data7[] = { 'y' };
193     sk_sp<SkData> skData7 = SkData::MakeWithCopy(data7, 1);
194     auto cachedData7 = AceType::MakeRefPtr<NG::SkiaImageData>(skData7);
195     imageCache->CacheImageData(KEY_6, cachedData7);
196     ASSERT_EQ(imageCache->curDataSize_, 3u);
197 
198     // cache data witch is already cached. {y}{fg}
199     const uint8_t data8[] = { 'f', 'g' };
200     sk_sp<SkData> skData8 = SkData::MakeWithCopy(data8, 2);
201     auto cachedData8 = AceType::MakeRefPtr<NG::SkiaImageData>(skData8);
202     imageCache->CacheImageData(KEY_5, cachedData8);
203     ASSERT_EQ(imageCache->curDataSize_, 3u);
204     auto dataFront = imageCache->dataCacheList_.front().imageDataPtr->GetData();
205     for (int i = 0; i < 2; ++i) {
206         ASSERT_EQ(dataFront[i], data8[i]);
207     }
208     auto dataKey5 = imageCache->GetCacheImageData(KEY_5);
209     auto dataRaw5 = dataKey5->GetData();
210     ASSERT_EQ(dataFront, dataRaw5);
211 
212     // Get key6
213     auto dataKey6 = imageCache->GetCacheImageData(KEY_6);
214     auto dataRaw6 = dataKey6->GetData();
215     ASSERT_EQ(dataRaw6[0], 'y');
216     dataFront = imageCache->dataCacheList_.front().imageDataPtr->GetData();
217     ASSERT_EQ(dataFront, dataRaw6);
218 }
219 
220 /**
221  * @tc.name: FileCache001
222  * @tc.desc: init cacheFilePath and cacheFileInfo success.
223  * @tc.type: FUNC
224  */
225 HWTEST_F(ImageCacheTest, FileCache001, TestSize.Level1)
226 {
227     /**
228      * @tc.steps: step1.call SetImageCacheFilePath().
229      * @tc.expected: cache file size init right and cache file Info init right.
230      */
231     ImageCache::SetImageCacheFilePath(CACHE_FILE_PATH);
232     ASSERT_EQ(ImageCache::cacheFilePath_, CACHE_FILE_PATH);
233 
234     /**
235      * @tc.steps: step2. call SetCacheFileInfo().
236      * @tc.expected: file info init right.
237      */
238     ImageCache::SetCacheFileInfo();
239     ASSERT_EQ(ImageCache::cacheFileSize_, FILE_SIZE);
240     ASSERT_EQ(static_cast<int32_t>(ImageCache::cacheFileInfo_.size()), 5);
241     size_t i = 0;
242     auto iter = ImageCache::cacheFileInfo_.begin();
243     while (i < TEST_COUNT - 1) {
244         ASSERT_LE(iter->accessTime, (++iter)->accessTime);
245         i++;
246     }
247 }
248 
249 /**
250  * @tc.name: FileCache002
251  * @tc.desc: write data into cacheFilePath success.
252  * @tc.type: FUNC
253  */
254 HWTEST_F(ImageCacheTest, FileCache002, TestSize.Level1)
255 {
256     /**
257      * @tc.steps: step1.construct a data.
258      */
259     std::vector<uint8_t> imageData = { 1, 2, 3, 4, 5, 6 };
260     std::string url = "http:/testfilecache002/image";
261 
262     /**
263      * @tc.steps: step2. call WriteCacheFile().
264      * @tc.expected: file write into filePath and file info update right.
265      */
266     ImageFileCache::GetInstance().WriteCacheFile(url, imageData.data(), imageData.size());
267     ASSERT_EQ(ImageCache::cacheFileSize_, static_cast<int32_t>(FILE_SIZE + imageData.size()));
268     ASSERT_EQ(ImageCache::cacheFileInfo_.size(), TEST_COUNT + 1);
269     auto iter = ImageCache::cacheFileInfo_.rbegin();
270 
271     ASSERT_EQ(iter->filePath, ImageFileCache::GetInstance().GetImageCacheFilePath(url));
272 }
273 
274 /**
275  * @tc.name: FileCache003
276  * @tc.desc: Get data from cacheFilePath success with right url. but null with wrong url.
277  * @tc.type: FUNC
278  */
279 HWTEST_F(ImageCacheTest, FileCache003, TestSize.Level1)
280 {
281     /**
282      * @tc.steps: step1.set cacheFileLimit_ to 0.
283      */
284     std::string wrongFilePath = "/data/wrong_data";
285     /**
286      * @tc.steps: step2. call GetFromCacheFile().
287      * @tc.expected:data != nullptr.
288      */
289     auto data = ImageCache::GetFromCacheFile(CACHE_IMAGE_FILE_2);
290     ASSERT_TRUE(data);
291     auto nullData = ImageCache::GetFromCacheFile(wrongFilePath);
292     ASSERT_TRUE(!nullData);
293 }
294 
295 /**
296  * @tc.name: FileCache004
297  * @tc.desc: clear files from cacheFilePath success while write file exceed limit.
298  * @tc.type: FUNC
299  */
300 HWTEST_F(ImageCacheTest, FileCache004, TestSize.Level1)
301 {
302     /**
303      * @tc.steps: step1.set cacheFileLimit_ to 0.
304      */
305     ImageCache::SetCacheFileLimit(0);
306     ASSERT_EQ(static_cast<int32_t>(ImageCache::cacheFileLimit_), 0);
307 
308     /**
309      * @tc.steps: step2. call WriteCacheFile().
310      * @tc.expected: file write into filePath and file info update right.
311      */
312     std::vector<uint8_t> imageData = { 1, 2, 3 };
313     std::string url = "http:/testfilecache003/image";
314     ImageFileCache::GetInstance().WriteCacheFile(url, imageData.data(), imageData.size());
315     float ratio = ImageCache::clearCacheFileRatio_;
316     ASSERT_EQ(ImageCache::cacheFileInfo_.size(), static_cast<size_t>((TEST_COUNT + 2) * ratio + 1));
317     ASSERT_LE(ImageCache::cacheFileSize_, FILE_SIZE);
318 }
319 
320 } // namespace OHOS::Ace