1 /* 2 * Copyright (c) 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 #define LOG_TAG "LRUBucketTest" 17 18 #include "lru_bucket.h" 19 #include "gtest/gtest.h" 20 namespace OHOS::Test { 21 using namespace testing::ext; 22 template<typename _Key, typename _Tp> using LRUBucket = OHOS::LRUBucket<_Key, _Tp>; 23 24 class LRUBucketTest : public testing::Test { 25 public: 26 struct TestValue { 27 std::string id; 28 std::string name; 29 std::string testCase; 30 }; 31 static constexpr size_t TEST_CAPACITY = 10; 32 SetUpTestCase(void)33 static void SetUpTestCase(void) {} 34 TearDownTestCase(void)35 static void TearDownTestCase(void) {} 36 37 protected: SetUp()38 void SetUp() 39 { 40 bucket_.ResetCapacity(0); 41 bucket_.ResetCapacity(TEST_CAPACITY); 42 for (size_t i = 0; i < TEST_CAPACITY; ++i) { 43 std::string key = std::string("test_") + std::to_string(i); 44 TestValue value = {key, key, "case"}; 45 bucket_.Set(key, value); 46 } 47 } 48 TearDown()49 void TearDown() {} 50 51 LRUBucket<std::string, TestValue> bucket_{TEST_CAPACITY}; 52 }; 53 54 /** 55 * @tc.name: insert 56 * @tc.desc: Set the value to the lru bucket, whose capacity is more than one. 57 * @tc.type: FUNC 58 * @tc.require: 59 * @tc.author: Sven Wang 60 */ 61 HWTEST_F(LRUBucketTest, insert, TestSize.Level0) 62 { 63 bucket_.Set("test_10", {"test_10", "test_10", "case"}); 64 TestValue value; 65 ASSERT_TRUE(!bucket_.Get("test_0", value)); 66 ASSERT_TRUE(bucket_.Get("test_6", value)); 67 ASSERT_TRUE(bucket_.ResetCapacity(1)); 68 ASSERT_TRUE(bucket_.Capacity() == 1); 69 ASSERT_TRUE(bucket_.Size() <= 1); 70 ASSERT_TRUE(bucket_.Get("test_6", value)); 71 } 72 73 /** 74 * @tc.name: cap_one_insert 75 * @tc.desc: Set the value to the lru bucket, whose capacity is one. 76 * @tc.type: FUNC 77 * @tc.require: 78 * @tc.author: Sven Wang 79 */ 80 HWTEST_F(LRUBucketTest, cap_one_insert, TestSize.Level0) 81 { 82 bucket_.ResetCapacity(1); 83 for (size_t i = 0; i <= TEST_CAPACITY; ++i) { 84 std::string key = std::string("test_") + std::to_string(i); 85 TestValue value = {key, key, "find"}; 86 bucket_.Set(key, value); 87 } 88 TestValue value; 89 ASSERT_TRUE(!bucket_.Get("test_0", value)); 90 ASSERT_TRUE(bucket_.Get("test_10", value)); 91 } 92 93 /** 94 * @tc.name: cap_zero_insert 95 * @tc.desc: Set the value to the lru bucket, whose capacity is zero. 96 * @tc.type: FUNC 97 * @tc.require: 98 * @tc.author: Sven Wang 99 */ 100 HWTEST_F(LRUBucketTest, cap_zero_insert, TestSize.Level0) 101 { 102 bucket_.ResetCapacity(0); 103 for (size_t i = 0; i <= TEST_CAPACITY; ++i) { 104 std::string key = std::string("test_") + std::to_string(i); 105 TestValue value = {key, key, "find"}; 106 bucket_.Set(key, value); 107 } 108 TestValue value; 109 ASSERT_TRUE(!bucket_.Get("test_10", value)); 110 } 111 112 /** 113 * @tc.name: find_head 114 * @tc.desc: find the head element from the lru bucket. 115 * @tc.type: FUNC 116 * @tc.require: 117 * @tc.author: Sven Wang 118 */ 119 HWTEST_F(LRUBucketTest, find_head, TestSize.Level0) 120 { 121 TestValue value; 122 ASSERT_TRUE(bucket_.ResetCapacity(1)); 123 ASSERT_TRUE(bucket_.Capacity() == 1); 124 ASSERT_TRUE(bucket_.Size() <= 1); 125 ASSERT_TRUE(bucket_.Get("test_9", value)); 126 } 127 128 /** 129 * @tc.name: find_tail 130 * @tc.desc: find the tail element, then the element will move to head. 131 * @tc.type: FUNC 132 * @tc.require: 133 * @tc.author: Sven Wang 134 */ 135 HWTEST_F(LRUBucketTest, find_tail, TestSize.Level0) 136 { 137 TestValue value; 138 ASSERT_TRUE(bucket_.Get("test_0", value)); 139 ASSERT_TRUE(bucket_.ResetCapacity(1)); 140 ASSERT_TRUE(bucket_.Capacity() == 1); 141 ASSERT_TRUE(bucket_.Size() <= 1); 142 ASSERT_TRUE(bucket_.Get("test_0", value)); 143 } 144 145 /** 146 * @tc.name: find_mid 147 * @tc.desc: find the mid element, then the element will move to head. 148 * @tc.type: FUNC 149 * @tc.require: 150 * @tc.author: Sven Wang 151 */ 152 HWTEST_F(LRUBucketTest, find_mid, TestSize.Level0) 153 { 154 TestValue value; 155 ASSERT_TRUE(bucket_.Get("test_5", value)); 156 ASSERT_TRUE(bucket_.ResetCapacity(1)); 157 ASSERT_TRUE(bucket_.Capacity() == 1); 158 ASSERT_TRUE(bucket_.Size() <= 1); 159 ASSERT_TRUE(bucket_.Get("test_5", value)); 160 } 161 162 /** 163 * @tc.name: find_and_insert 164 * @tc.desc: find the tail element, then the element will move to head. 165 * @tc.type: FUNC 166 * @tc.require: 167 * @tc.author: Sven Wang 168 */ 169 HWTEST_F(LRUBucketTest, find_and_insert, TestSize.Level0) 170 { 171 TestValue value; 172 if (!bucket_.Get("MyTest", value)) { 173 bucket_.Set("MyTest", {"MyTest", "MyTest", "case"}); 174 } 175 ASSERT_TRUE(bucket_.Get("MyTest", value)); 176 177 if (!bucket_.Get("test_0", value)) { 178 bucket_.Set("test_0", {"test_0", "test_0", "case"}); 179 } 180 ASSERT_TRUE(bucket_.Get("test_0", value)); 181 ASSERT_TRUE(bucket_.Get("test_5", value)); 182 ASSERT_TRUE(bucket_.Get("test_4", value)); 183 ASSERT_TRUE(!bucket_.Get("test_1", value)); 184 ASSERT_TRUE(bucket_.Get("test_2", value)); 185 } 186 187 /** 188 * @tc.name: del_head 189 * @tc.desc: delete the head element, then the next element will move to head. 190 * @tc.type: FUNC 191 * @tc.require: 192 * @tc.author: Sven Wang 193 */ 194 HWTEST_F(LRUBucketTest, del_head, TestSize.Level0) 195 { 196 TestValue value; 197 ASSERT_TRUE(bucket_.Delete("test_9")); 198 ASSERT_TRUE(!bucket_.Get("test_9", value)); 199 ASSERT_TRUE(bucket_.ResetCapacity(1)); 200 ASSERT_TRUE(bucket_.Capacity() == 1); 201 ASSERT_TRUE(bucket_.Size() <= 1); 202 ASSERT_TRUE(bucket_.Get("test_8", value)); 203 } 204 205 /** 206 * @tc.name: del_head 207 * @tc.desc: delete the tail element, then the lru chain keep valid. 208 * @tc.type: FUNC 209 * @tc.require: 210 * @tc.author: Sven Wang 211 */ 212 HWTEST_F(LRUBucketTest, del_tail, TestSize.Level0) 213 { 214 TestValue value; 215 ASSERT_TRUE(bucket_.Delete("test_0")); 216 ASSERT_TRUE(!bucket_.Get("test_0", value)); 217 ASSERT_TRUE(bucket_.Get("test_4", value)); 218 ASSERT_TRUE(bucket_.ResetCapacity(1)); 219 ASSERT_TRUE(bucket_.Capacity() == 1); 220 ASSERT_TRUE(bucket_.Size() <= 1); 221 ASSERT_TRUE(bucket_.Get("test_4", value)); 222 } 223 224 /** 225 * @tc.name: del_mid 226 * @tc.desc: delete the mid element, then the lru chain keep valid. 227 * @tc.type: FUNC 228 * @tc.require: 229 * @tc.author: Sven Wang 230 */ 231 HWTEST_F(LRUBucketTest, del_mid, TestSize.Level0) 232 { 233 TestValue value; 234 ASSERT_TRUE(bucket_.Delete("test_5")); 235 ASSERT_TRUE(!bucket_.Get("test_5", value)); 236 ASSERT_TRUE(bucket_.Get("test_4", value)); 237 ASSERT_TRUE(bucket_.Get("test_6", value)); 238 ASSERT_TRUE(bucket_.ResetCapacity(2)); 239 ASSERT_TRUE(bucket_.Capacity() == 2); 240 ASSERT_TRUE(bucket_.Size() <= 2); 241 ASSERT_TRUE(bucket_.Get("test_4", value)); 242 ASSERT_TRUE(bucket_.Get("test_6", value)); 243 } 244 245 /** 246 * @tc.name: del_mid 247 * @tc.desc: the lru bucket has only one element, then delete it. 248 * @tc.type: FUNC 249 * @tc.require: 250 * @tc.author: Sven Wang 251 */ 252 HWTEST_F(LRUBucketTest, cap_one_del, TestSize.Level0) 253 { 254 TestValue value; 255 bucket_.ResetCapacity(1); 256 ASSERT_TRUE(bucket_.Delete("test_9")); 257 ASSERT_TRUE(!bucket_.Get("test_9", value)); 258 } 259 260 /** 261 * @tc.name: del_mid 262 * @tc.desc: the lru bucket has no element. 263 * @tc.type: FUNC 264 * @tc.require: 265 * @tc.author: Sven Wang 266 */ 267 HWTEST_F(LRUBucketTest, cap_zero_del, TestSize.Level0) 268 { 269 TestValue value; 270 bucket_.ResetCapacity(0); 271 ASSERT_TRUE(!bucket_.Delete("test_9")); 272 ASSERT_TRUE(!bucket_.Get("test_9", value)); 273 } 274 275 /** 276 * @tc.name: update_one 277 * @tc.desc: update the value and the lru chain won't change. 278 * @tc.type: FUNC 279 * @tc.require: 280 * @tc.author: Sven Wang 281 */ 282 HWTEST_F(LRUBucketTest, update_one, TestSize.Level0) 283 { 284 TestValue value; 285 ASSERT_TRUE(bucket_.Update("test_4", {"test_4", "test_4", "update"})); 286 ASSERT_TRUE(bucket_.Get("test_4", value)); 287 ASSERT_TRUE(value.testCase == "update"); 288 ASSERT_TRUE(bucket_.Update("test_9", {"test_9", "test_9", "update"})); 289 ASSERT_TRUE(bucket_.ResetCapacity(1)); 290 ASSERT_TRUE(bucket_.Capacity() == 1); 291 ASSERT_TRUE(bucket_.Size() <= 1); 292 ASSERT_TRUE(bucket_.Get("test_4", value)); 293 ASSERT_TRUE(!bucket_.Get("test_9", value)); 294 } 295 296 /** 297 * @tc.name: update_several 298 * @tc.desc: update several values and the lru chain won't change. 299 * @tc.type: FUNC 300 * @tc.require: 301 * @tc.author: Sven Wang 302 */ 303 HWTEST_F(LRUBucketTest, update_several, TestSize.Level0) 304 { 305 TestValue value; 306 std::map<std::string, TestValue> values = {{"test_2", {"test_2", "test_2", "update"}}, 307 {"test_3", {"test_3", "test_3", "update"}}, 308 {"test_6", {"test_6", "test_6", "update"}}}; 309 ASSERT_TRUE(bucket_.Update(values)); 310 ASSERT_TRUE(bucket_.ResetCapacity(3)); 311 ASSERT_TRUE(bucket_.Capacity() == 3); 312 ASSERT_TRUE(bucket_.Size() <= 3); 313 ASSERT_TRUE(!bucket_.Get("test_2", value)); 314 ASSERT_TRUE(!bucket_.Get("test_3", value)); 315 ASSERT_TRUE(!bucket_.Get("test_6", value)); 316 ASSERT_TRUE(bucket_.Get("test_9", value)); 317 ASSERT_TRUE(bucket_.Get("test_8", value)); 318 ASSERT_TRUE(bucket_.Get("test_7", value)); 319 } 320 } // namespace OHOS::Test