1 /*
2 * Copyright (c) 2024 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 #include <condition_variable>
16 #include <gtest/gtest.h>
17 #include <random>
18 #include <vector>
19
20 #include "block_data.h"
21 #include "dev_manager.h"
22 #include "distributed_kv_data_manager.h"
23 #include "file_ex.h"
24 #include "kv_store_nb_delegate.h"
25 #include "store_manager.h"
26 #include "sys/stat.h"
27 #include "types.h"
28 #include "log_print.h"
29 using namespace testing::ext;
30 using namespace OHOS::DistributedKv;
31 namespace OHOS::Test {
32 static constexpr int THUMBNBIL_MAX_SIZE = 130;
33 class SingleStorePerfPcTest : public testing::Test {
34 public:
35 static void SetUpTestCase(void);
36 static void TearDownTestCase(void);
37 void SetUp();
38 void TearDown();
39
40 std::shared_ptr<SingleKvStore> CreateKVStore(std::string storeIdTest, KvStoreType type, bool encrypt, bool backup);
41 static std::shared_ptr<SingleKvStore> CreateHashKVStore(std::string storeIdTest, KvStoreType type,
42 bool encrypt, bool backup);
43 static std::shared_ptr<SingleKvStore> kvStore_;
44 };
45
46 std::shared_ptr<SingleKvStore> SingleStorePerfPcTest::kvStore_;
47
SetUpTestCase(void)48 void SingleStorePerfPcTest::SetUpTestCase(void)
49 {
50 printf("SetUpTestCase BEGIN\n");
51 std::string baseDir = "/data/service/el1/public/database/SingleStorePerfPcTest";
52 mkdir(baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
53 kvStore_ = CreateHashKVStore("SingleKVStore", LOCAL_ONLY, false, false);
54 if (kvStore_ == nullptr) {
55 kvStore_ = CreateHashKVStore("SingleKVStore", LOCAL_ONLY, false, false);
56 }
57 EXPECT_NE(kvStore_, nullptr);
58 //kvstore Insert 1 million PC file management thumbnail data
59 std::string strKey(8, 'k'); // The length is 8
60 std::string strValue(4592, 'v'); // The length is 4592
61 int count = 1000000;
62 std::vector<Key> keyVec;
63 /// set key,value
64 for (int i = 0; i < count; ++i) {
65 std::string tmpKey = std::to_string(i);
66 tmpKey = strKey.replace(0, tmpKey.size(), tmpKey);
67 Key key(tmpKey);
68 Value value(strValue);
69 auto status = kvStore_->Put(key, value);
70 EXPECT_EQ(status, SUCCESS);
71 }
72 printf("SetUpTestCase END\n");
73 }
74
TearDownTestCase(void)75 void SingleStorePerfPcTest::TearDownTestCase(void)
76 {
77 printf("TearDownTestCase BEGIN\n");
78 AppId appId = { "SingleStorePerfPcTest" };
79 StoreId storeId = { "SingleKVStore" };
80 kvStore_ = nullptr;
81 auto status = StoreManager::GetInstance().CloseKVStore(appId, storeId);
82 EXPECT_EQ(status, SUCCESS);
83 std::string baseDir = "/data/service/el1/public/database/SingleStorePerfPcTest";
84 status = StoreManager::GetInstance().Delete(appId, storeId, baseDir);
85 EXPECT_EQ(status, SUCCESS);
86
87 printf("remove key kvdb SingleStorePerfPcTest BEGIN\n");
88 (void)remove("/data/service/el1/public/database/SingleStorePerfPcTest/key");
89 (void)remove("/data/service/el1/public/database/SingleStorePerfPcTest/kvdb");
90 (void)remove("/data/service/el1/public/database/SingleStorePerfPcTest");
91 printf("remove key kvdb SingleStorePerfPcTest END\n");
92 printf("TearDownTestCase END\n");
93 }
94
SetUp(void)95 void SingleStorePerfPcTest::SetUp(void)
96 {
97 printf("SetUp BEGIN\n");
98 printf("SetUp END\n");
99 }
100
TearDown(void)101 void SingleStorePerfPcTest::TearDown(void)
102 {
103 printf("TearDown BEGIN\n");
104 printf("TearDown END\n");
105 }
106
CreateKVStore(std::string storeIdTest,KvStoreType type,bool encrypt,bool backup)107 std::shared_ptr<SingleKvStore> SingleStorePerfPcTest::CreateKVStore(std::string storeIdTest, KvStoreType type,
108 bool encrypt, bool backup)
109 {
110 Options options;
111 options.kvStoreType = type;
112 options.securityLevel = S1;
113 options.encrypt = encrypt;
114 options.area = EL1;
115 options.backup = backup;
116 options.baseDir = "/data/service/el1/public/database/SingleStorePerfPcTest";
117
118 AppId appId = { "SingleStorePerfPcTest" };
119 StoreId storeId = { storeIdTest };
120 Status status = StoreManager::GetInstance().Delete(appId, storeId, options.baseDir);
121 return StoreManager::GetInstance().GetKVStore(appId, storeId, options, status);
122 }
123
CreateHashKVStore(std::string storeIdTest,KvStoreType type,bool encrypt,bool backup)124 std::shared_ptr<SingleKvStore> SingleStorePerfPcTest::CreateHashKVStore(std::string storeIdTest, KvStoreType type,
125 bool encrypt, bool backup)
126 {
127 Options options;
128 options.kvStoreType = type;
129 options.securityLevel = S1;
130 options.encrypt = encrypt;
131 options.area = EL1;
132 options.backup = backup;
133 options.baseDir = "/data/service/el1/public/database/SingleStorePerfPcTest";
134 options.config.type = HASH;
135 options.config.pageSize = 32u;
136 options.config.cacheSize = 4096u;
137
138 AppId appId = { "SingleStorePerfPcTest" };
139 StoreId storeId = { storeIdTest };
140 Status status = StoreManager::GetInstance().Delete(appId, storeId, options.baseDir);
141 return StoreManager::GetInstance().GetKVStore(appId, storeId, options, status);
142 }
143
GetTime(void)144 static struct timespec GetTime(void)
145 {
146 struct timespec now;
147 clock_gettime(CLOCK_REALTIME, &now);
148 return now;
149 }
150
TimeDiff(const struct timespec * beg,const struct timespec * end)151 static double TimeDiff(const struct timespec *beg, const struct timespec *end)
152 {
153 // 1000000000.0 to convert nanoseconds to seconds
154 return (end->tv_sec - beg->tv_sec) + ((end->tv_nsec - beg->tv_nsec) / 1000000000.0);
155 }
156
157 /**
158 * @tc.name: HashIndexKVStoreTest001
159 * @tc.desc: PC File Management simulation:1 threads use vector 2000 keys 500 batches one by one
160 * Get the value of the kv store, and the average delay of each key is calculated in 2000 keys.
161 * Then, the average delay of a screen is calculated by multiplying the delay by 130.
162 * @tc.type: PERF
163 * @tc.require:
164 * @tc.author: Gang Wang
165 */
166 HWTEST_F(SingleStorePerfPcTest, HashIndexKVStoreTest001, TestSize.Level0)
167 {
168 printf("HashIndexKVStoreTest001 BEGIN\n");
169 std::string strKey(8, 'k');
170 int count = 1000000;
171 // We can't divide 130. We use 2000
172 int batchCount = 2000;
173 int failCount = 0;
174 std::vector<Key> keyVec;
175 double dur = 0;
176 double avrTime130 = 0;
177
178 keyVec.clear();
179 for (int j = 0; j < count / batchCount; j++) {
180 keyVec.clear();
181 for (int i = j * batchCount; i < (j + 1) * batchCount; i++) {
182 std::string tmpKey = std::to_string(i);
183 tmpKey = strKey.replace(0, tmpKey.size(), tmpKey);
184 Key key(tmpKey);
185 keyVec.emplace_back(key);
186 }
187 timespec beg = GetTime();
188 for (auto &item : keyVec) {
189 Value value;
190 kvStore_->Get(item, value);
191 }
192 timespec end = GetTime();
193 double tmp = TimeDiff(&beg, &end);
194 dur += tmp;
195 avrTime130 = tmp * THUMBNBIL_MAX_SIZE * 1000 / keyVec.size();
196 if (avrTime130 >= 3.0) {
197 failCount += 1;
198 }
199 printf("platform:HAD_OH_Native_innerKitAPI_Get index[%d] keyLen[%d] valueLen[%d],\n"
200 "batch_time[%lfs], avrTime130[%lfms], failCount[%u]\n",
201 j, 8, 4592, tmp, avrTime130, failCount);
202 }
203 avrTime130 = dur * THUMBNBIL_MAX_SIZE * 1000 / count;
204 printf("batchCount[%d] keyLen[%d] valueLen[%d], sum_time[%lfs], avrTime130[%lfms],\n"
205 "HashIndexKVStoreTest001 failCount[%u]\n",
206 batchCount, 8, 4592, dur, avrTime130, failCount);
207 EXPECT_LT(avrTime130, 3.0);
208 printf("HashIndexKVStoreTest001 END\n");
209 }
210
211 /**
212 * @tc.name: HashIndexKVStoreTest002
213 * @tc.desc: PC File Management simulation:1 threads use vector 1000000 keys one by one Get the value of the kv store,
214 * and the average delay of each key is calculated.
215 * Then, the average delay of a screen is calculated by multiplying the delay by 130.
216 * @tc.type: PERF
217 * @tc.require:
218 * @tc.author: Gang Wang
219 */
220 HWTEST_F(SingleStorePerfPcTest, HashIndexKVStoreTest002, TestSize.Level0)
221 {
222 printf("HashIndexKVStoreTest002 BEGIN\n");
223 std::string strKey(8, 'k');
224 int count = 1000000;
225
226 std::vector<Key> keyVec;
227 double dur = 0;
228 double avrTime130 = 0;
229 keyVec.clear();
230 for (int i = 0; i < count; ++i) {
231 std::string tmpKey = std::to_string(i);
232 tmpKey = strKey.replace(0, tmpKey.size(), tmpKey);
233 Key key(tmpKey);
234 keyVec.emplace_back(key);
235 }
236 timespec beg = GetTime();
237 for (auto &item : keyVec) {
238 Value value;
239 kvStore_->Get(item, value);
240 }
241 timespec end = GetTime();
242 dur = TimeDiff(&beg, &end);
243 avrTime130 = dur * THUMBNBIL_MAX_SIZE * 1000 / count;
244 printf("count[%d] platform:HAD_OH_Native_innerKitAPI_Get keyLen[%d] valueLen[%d], time[%lfs],\n"
245 "avrTime130[%lfms]\n",
246 count, 8, 4592, dur, avrTime130);
247 EXPECT_LT(avrTime130, 3.0);
248 printf("HashIndexKVStoreTest002 END\n");
249 }
250 } // namespace OHOS::Test
251