1 /*
2 * Copyright (c) 2021 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 "distributed_test_tools.h"
16
17 #include <algorithm>
18 #include <chrono>
19 #include <cmath>
20 #include <cstdio>
21 #include <cstring>
22 #include <dirent.h>
23 #include <fcntl.h>
24 #include <functional>
25 #include <openssl/sha.h>
26 #include <random>
27 #include <string>
28 #include <sys/stat.h>
29 #include <unistd.h>
30
31 #ifndef USE_SQLITE_SYMBOLS
32 #include "sqlite3.h"
33 #else
34 #include "sqlite3sym.h"
35 #endif
36 #include "delegate_callback.h"
37 #include "delegate_kv_mgr_callback.h"
38 #include "distributeddb_data_generator.h"
39 #include "distributed_test_sysinfo.h"
40 #include "kv_store_delegate.h"
41 #include "kv_store_delegate_manager.h"
42 #include "platform_specific.h"
43 #include "securec.h"
44
45 using namespace std;
46 using namespace chrono;
47 using namespace std::placeholders;
48 using namespace DistributedDB;
49 using namespace DistributedDBDataGenerator;
50
51 namespace {
52 #ifndef USE_SQLITE_CODEC_CIPHER
53 const std::string CIPHER_CONFIG_SQL = "PRAGMA cipher='aes-256-gcm';";
54 const std::string KDF_ITER_CONFIG_SQL = "PRAGMA kdf_iter=5000;";
55 #else
56 const std::string CIPHER_CONFIG_SQL = "PRAGMA codec_cipher='aes-256-gcm';";
57 const std::string KDF_ITER_CONFIG_SQL = "PRAGMA codec_kdf_iter=5000;";
58 #endif
59 const int RAND_BOOL_MIN = 0;
60 const int RAND_BOOL_MAX = 1;
61 }
62
CompareVector(const std::vector<uint8_t> & first,const std::vector<uint8_t> & second)63 bool CompareVector(const std::vector<uint8_t>& first, const std::vector<uint8_t>& second)
64 {
65 if (first.size() != second.size()) {
66 MST_LOG("[CompareVector] first.size[%zu] != second.size[%zu]", first.size(), second.size());
67 return false;
68 }
69 return first == second;
70 }
71
CompareEntriesVector(std::vector<DistributedDB::Entry> & retVec,std::vector<DistributedDB::Entry> & expectVec)72 bool CompareEntriesVector(std::vector<DistributedDB::Entry>& retVec,
73 std::vector<DistributedDB::Entry>& expectVec)
74 {
75 if (retVec.size() != expectVec.size()) {
76 MST_LOG("retVec.size() = %zd, expectVec.size() = %zd", retVec.size(), expectVec.size());
77 return false;
78 }
79
80 // for retVec and expectVec are reference, don't want to change the value of them
81 vector<std::reference_wrapper<Entry>> retVector(retVec.begin(), retVec.end());
82 vector<std::reference_wrapper<Entry>> expVec(expectVec.begin(), expectVec.end());
83 sort(retVector.begin(), retVector.end(), DistributedTestTools::CompareKey);
84 sort(expVec.begin(), expVec.end(), DistributedTestTools::CompareKey);
85 bool result = true;
86 for (uint64_t at = 0; at < retVector.size(); at++) {
87 result = ((retVector[at].get().key == expVec[at].get().key) &&
88 (retVector[at].get().value == expVec[at].get().value));
89 if (!result) {
90 MST_LOG("[CompareEntriesVector] compare list failed at the position: %llu", ULL(at));
91 string retKey(retVector[at].get().key.begin(), retVector[at].get().key.end());
92 string retValue(retVector[at].get().value.begin(), retVector[at].get().value.end());
93 string expKey(expVec[at].get().key.begin(), expVec[at].get().key.end());
94 string expValue(expVec[at].get().value.begin(), expVec[at].get().value.end());
95 MST_LOG("[CompareEntriesVector] the actual Key: %s\n", retKey.c_str());
96 MST_LOG("[CompareEntriesVector] the expect key: %s\n", expKey.c_str());
97 // retValue num lessThan 10, expValue num lessThan 10,
98 if (retValue.size() > 10 && expValue.size() > 10) {
99 MST_LOG("[CompareEntriesVector] the actual value: %s...%s\n",
100 // retValue substr num as 10, the index of retKey.size() - 10
101 retValue.substr(0, 10).c_str(), retValue.substr((retValue.size() - 10), 10).c_str());
102 MST_LOG("[CompareEntriesVector] the expect value: %s...%s\n",
103 // expValue substr num as 10, the index of retKey.size() - 10
104 expValue.substr(0, 10).c_str(), expValue.substr((expValue.size() - 10), 10).c_str());
105 } else {
106 MST_LOG("[CompareEntriesVector] the actual value: %s\n", retValue.c_str());
107 MST_LOG("[CompareEntriesVector] the expect value: %s\n", expValue.c_str());
108 }
109 return result;
110 }
111 }
112 return true;
113 }
114
PutUniqueKey(vector<Entry> & entryVec,const Key & putKey,const Value & putValue)115 void PutUniqueKey(vector<Entry> &entryVec, const Key &putKey, const Value &putValue)
116 {
117 bool findEachEntry = false;
118 for (unsigned int idxEntry = 0; idxEntry < entryVec.size(); ++idxEntry) {
119 if (CompareVector(entryVec[idxEntry].key, putKey)) {
120 findEachEntry = true;
121 entryVec[idxEntry].value = putValue;
122 break;
123 }
124 }
125 Entry entry = { putKey, putValue };
126 if (!findEachEntry) {
127 entryVec.push_back(entry);
128 }
129 }
130
Uint8VecToString(std::vector<uint8_t> & vec,std::string & str)131 int Uint8VecToString(std::vector<uint8_t> &vec, std::string &str)
132 {
133 int len = 0;
134 str.clear();
135
136 for (auto vecIt = vec.begin(); vecIt != vec.end(); ++vecIt) {
137 str.push_back(static_cast<char>(*vecIt));
138 ++len;
139 }
140
141 return len;
142 }
143
GenRanKeyVal(int putGetTimes,int keyLength,int valueLength,char val)144 vector<Entry> GenRanKeyVal(int putGetTimes, int keyLength, int valueLength, char val)
145 {
146 // random gen the key
147 std::random_device randDevKeyNo;
148 std::mt19937 genRandKeyNo(randDevKeyNo());
149 std::uniform_int_distribution<uint8_t> disRandKeyNo(CHAR_SPAN_MIN, CHAR_SPAN_MAX);
150
151 DistributedDB::Entry entryCurrent;
152 vector<Entry> entriesBatch;
153
154 for (int cnt = 0; cnt < putGetTimes; ++cnt) {
155 DistributedDB::Key tempKey = PERFORMANCEKEY;
156 for (int kIndex = 0; kIndex < keyLength; ++kIndex) {
157 tempKey.push_back(disRandKeyNo(genRandKeyNo));
158 }
159 entryCurrent.key = tempKey;
160 entryCurrent.value.assign(valueLength, val);
161
162 entriesBatch.push_back(entryCurrent);
163 }
164 return entriesBatch;
165 }
166
GetRandBool()167 bool GetRandBool()
168 {
169 std::random_device randDev;
170 std::mt19937 genRand(randDev());
171 std::uniform_int_distribution<int> disRand(RAND_BOOL_MIN, RAND_BOOL_MAX);
172 return disRand(genRand);
173 }
174
PutEntries(KvStoreNbDelegate * & delegate,vector<Entry> & entries)175 bool PutEntries(KvStoreNbDelegate *&delegate, vector<Entry> &entries)
176 {
177 for (const auto &entry : entries) {
178 if (delegate->Put(entry.key, entry.value) != OK) {
179 return false;
180 }
181 }
182 return true;
183 }
184
GetKeysFromEntries(std::vector<DistributedDB::Entry> entries,bool random)185 vector<Key> GetKeysFromEntries(std::vector < DistributedDB::Entry > entries, bool random)
186 {
187 vector<Key> result;
188 vector<Entry> old;
189 old.assign(entries.begin(), entries.end());
190 if (random) {
191 for (int i = entries.size(); i > 0; i--) {
192 int index = GetRandInt(0, ONE_HUNDRED_SECONDS * MILLSECONDS_PER_SECOND) % i;
193 result.push_back(old[index].key);
194 old.erase(old.begin() + index);
195 }
196 } else {
197 for (auto entry = entries.begin(); entry != entries.end(); ++entry) {
198 result.push_back(entry->key);
199 }
200 }
201 return result;
202 }
203
GetIntValue(Value & value)204 int GetIntValue(Value &value)
205 {
206 if (value.size() == 0) {
207 return 0;
208 }
209 string strVal;
210 Uint8VecToString(value, strVal);
211 int number;
212 if (sscanf_s(strVal.c_str(), "%d", &number) != 1) {
213 return 0;
214 }
215 return number;
216 }
217
GetValueWithInt(int val)218 Value GetValueWithInt(int val)
219 {
220 string strVal = std::to_string(val);
221 Value result;
222 result.assign(strVal.begin(), strVal.end());
223 return result;
224 }
225
GetGroupEntries(vector<Entry> entries,int pageSize,int valueLength,uint8_t c)226 vector< vector<Entry> > GetGroupEntries(vector<Entry> entries, int pageSize, int valueLength, uint8_t c)
227 {
228 vector< vector<Entry> > result;
229 if (pageSize <= 0) {
230 MST_LOG("pageSize can't be zero or negative number!");
231 } else {
232 int pages = (entries.size() - 1) / pageSize + 1;
233 for (int pageIndex = 0; pageIndex < pages; ++pageIndex) {
234 vector<Entry> temp;
235 int pageStart = pageSize * pageIndex;
236 int pageEnd = (pageSize * (pageIndex + 1)) - 1;
237 if (pageEnd + 1 > static_cast<int>(entries.size())) {
238 pageEnd = entries.size() - 1;
239 }
240 MST_LOG("The %d page start position: %d, end position: %d", pageIndex, pageStart, pageEnd);
241 temp.assign(entries.begin() + pageStart, entries.begin() + pageEnd);
242 result.push_back(temp);
243 }
244 for (auto iter = result.begin(); iter != result.end(); ++iter) {
245 for (auto entry = iter->begin(); entry != iter->end(); ++entry) {
246 entry->value.assign(valueLength, c);
247 }
248 }
249 }
250 return result;
251 }
252
253 // KvCallback conclude the Callback of function <void(DBStatus, Value)> and <void(DBStatus, vector<Entry>)>
254 class KvCallback {
255 public:
KvCallback()256 KvCallback() {}
~KvCallback()257 ~KvCallback() {}
258
259 // Delete the copy and assign constructors
260 KvCallback(const KvCallback &callback) = delete;
261 KvCallback& operator=(const KvCallback &callback) = delete;
262 KvCallback(KvCallback &&callback) = delete;
263 KvCallback& operator=(KvCallback &&callback) = delete;
264
Callback(DBStatus status,const Value & value)265 void Callback(DBStatus status, const Value &value)
266 {
267 this->status_ = status;
268 this->value_ = value;
269 }
270
CallbackPrefix(DBStatus status,const vector<Entry> & entries)271 void CallbackPrefix(DBStatus status, const vector<Entry> &entries)
272 {
273 this->status_ = status;
274 this->entries_ = entries;
275 }
276
GetStatus()277 DBStatus GetStatus()
278 {
279 return status_;
280 }
281
GetValue()282 const Value &GetValue()
283 {
284 return value_;
285 }
286
GetValueVector()287 const vector<Entry> &GetValueVector()
288 {
289 return entries_;
290 }
291
292 private:
293 DBStatus status_ = DBStatus::INVALID_ARGS;
294 Value value_ = { };
295 vector<Entry> entries_ = {};
296 };
297
298 // delete dir(directory) recursively
RemoveDir(const std::string & dirSrc)299 int RemoveDir(const std::string &dirSrc)
300 {
301 string directory = dirSrc;
302 char curDir[] = ".";
303 char upDir[] = "..";
304 char dirName[MAX_DIR_LENGTH] = { 0 };
305 DIR *dirp = nullptr;
306 struct dirent *dp = nullptr;
307 struct stat dirStat;
308
309 while (directory.at(directory.length() - 1) == '/') {
310 directory.pop_back();
311 }
312
313 const char *dir = directory.c_str();
314 // if dir is not existed
315 if (access(dir, F_OK) != 0) {
316 return 0;
317 }
318 // getting dir attribution fails
319 if (stat(dir, &dirStat) < 0) {
320 perror("get directory stat error");
321 return -1;
322 }
323 // if dir is a common file
324 if (S_ISREG(dirStat.st_mode)) {
325 remove(dir);
326 } else if (S_ISDIR(dirStat.st_mode)) {
327 // if dir is directory, delete it recursively
328 dirp = opendir(dir);
329 if (dirp == nullptr) {
330 perror("open directory error");
331 return -1;
332 }
333 while ((dp = readdir(dirp)) != nullptr) {
334 // ignore . and ..
335 if ((strcmp(curDir, dp->d_name) == 0) || (strcmp(upDir, dp->d_name)) == 0) {
336 continue;
337 }
338 int result = sprintf_s(dirName, sizeof(dirName) - 1, "%s/%s", dir, dp->d_name);
339 if (result < 0) {
340 closedir(dirp);
341 return -1;
342 }
343 MST_LOG("delete dirName = %s", dirName);
344 RemoveDir(std::string(dirName));
345 }
346 closedir(dirp);
347 remove(directory.c_str());
348 } else {
349 perror("unknown file type!");
350 }
351 return 0;
352 }
353
354 // If the test cases' related dir in system is not exist, create it.
SetDir(const std::string & directory,const int authRight)355 int SetDir(const std::string &directory, const int authRight)
356 {
357 MST_LOG("create directory: %s", directory.c_str());
358 char dir[MAX_DIR_LENGTH] = { 0 };
359 int i, len;
360
361 errno_t ret = strcpy_s(dir, MAX_DIR_LENGTH, directory.c_str());
362 if (ret != E_OK) {
363 MST_LOG("strcpy_s failed(%d)!", ret);
364 return -1;
365 }
366 len = strlen(dir);
367 if (dir[len - 1] != '/') {
368 ret = strcat_s(dir, sizeof(dir) - strlen(dir) - 1, "/");
369 if (ret != E_OK) {
370 MST_LOG("strcat_s failed(%d)!", ret);
371 return -1;
372 }
373 len++;
374 }
375
376 for (i = 1; i < len; i++) {
377 if (dir[i] != '/') {
378 continue;
379 }
380 dir[i] = '\0';
381 if (access(dir, F_OK) != E_OK) {
382 mode_t mode = umask(0);
383 #if defined(RUNNING_ON_LINUX)
384 if (mkdir(dir, authRight) == E_ERROR) {
385 #else
386 std::string stringDir = dir;
387 if (OS::MakeDBDirectory(stringDir) == E_ERROR) {
388 #endif
389 MST_LOG("mkdir(%s) failed(%d)!", dir, errno);
390 return -1;
391 }
392 if (chdir(dir) == E_ERROR) {
393 MST_LOG("chdir(%s) failed(%d)!", dir, errno);
394 }
395 umask(mode);
396 }
397 dir[i] = '/';
398 }
399 MST_LOG("check dir = %s", dir);
400 return 0;
401 }
402
403 void CopyFile(const string &srcFile, const string &destFile)
404 {
405 int len = 0;
406 char buff[BUF_LEN] = { 0 };
407
408 FILE *pIn = fopen(srcFile.c_str(), "r");
409 if (pIn == nullptr) {
410 perror("pIn");
411 return;
412 }
413
414 FILE *pOut = fopen(destFile.c_str(), "w");
415 if (pOut == nullptr) {
416 perror("pOut");
417 fclose(pIn);
418 return;
419 }
420
421 while ((len = fread(buff, sizeof(char), sizeof(buff), pIn)) > 0) {
422 fwrite(buff, sizeof(char), len, pOut);
423 }
424 fclose(pOut);
425 fclose(pIn);
426 }
427
428 void CopyDir(const string &srcDir, const string &destDir, const int authRight)
429 {
430 string srcFullDir = srcDir;
431 string destFullDir = destDir;
432 struct dirent *filename = nullptr;
433 DIR *dpDest = opendir(destFullDir.c_str());
434 if (dpDest == nullptr) {
435 if (SetDir(destFullDir.c_str(), authRight)) {
436 MST_LOG("[CopyDir] SetDir(%s) failed(%d)!", destFullDir.c_str(), errno);
437 return;
438 }
439 } else {
440 closedir(dpDest);
441 }
442 string path = srcFullDir;
443 if (srcFullDir.back() != '/') {
444 srcFullDir += "/";
445 }
446 if (destFullDir.back() != '/') {
447 destFullDir += "/";
448 }
449
450 DIR *dpSrc = opendir(path.c_str());
451 if (dpSrc == nullptr) {
452 MST_LOG("[CopyDir] please make sure srcDir(%s) is valid.", srcDir.c_str());
453 return;
454 }
455 while ((filename = readdir(dpSrc)) != nullptr) {
456 string fileSourceDir = srcFullDir;
457 string fileDestDir = destFullDir;
458
459 fileSourceDir += filename->d_name;
460 fileDestDir += filename->d_name;
461 if (filename->d_type == DT_DIR) {
462 if ((string(filename->d_name).compare(0, strlen("."), ".") != 0) &&
463 (string(filename->d_name).compare(0, strlen(".."), "..") != 0)) {
464 CopyDir(fileSourceDir, fileDestDir);
465 }
466 } else {
467 CopyFile(fileSourceDir, fileDestDir);
468 }
469 }
470 closedir(dpSrc);
471 MST_LOG("[CopyDir] copy file from %s to %s successfully.", srcDir.c_str(), destDir.c_str());
472 }
473
474 void CheckFileNumber(const string &filePath, int &fileCount)
475 {
476 std::string cmd = "cd " + filePath + ";ls -l |grep " + "^-" + "|wc -l";
477 FILE *pipe = popen(cmd.c_str(), "r");
478 if (pipe == nullptr) {
479 MST_LOG("Check file number filed.");
480 return;
481 }
482
483 char buffer[128]; // set pipe buffer length as 128B
484 std::string result = "";
485 while (!feof(pipe)) {
486 if (fgets(buffer, 128, pipe) != nullptr) { // set pipe buffer length as 128B
487 result += buffer;
488 }
489 }
490 pclose(pipe);
491 fileCount = std::stoi(result);
492 MST_LOG("Check file number is %d", fileCount);
493 }
494
495 // this static method is to compare if the two Value has the same data.
496 bool DistributedTestTools::IsValueEquals(const DistributedDB::Value &v1, const DistributedDB::Value &v2)
497 {
498 // just return false if the sizes are not the same.
499 if (v1.size() != v2.size()) {
500 return false;
501 }
502
503 // compare two Values char by char.
504 return v1 == v2;
505 }
506
507 // This static method is for moduleTest of distributed to get KvStoreDelegate with valid ids.
508 KvStoreDelegate* DistributedTestTools::GetDelegateSuccess(KvStoreDelegateManager *&outManager,
509 const KvDBParameters ¶m, const KvOption &optionParam)
510 {
511 MST_LOG("GetDelegateSuccess isEncryptedDb= %d", optionParam.isEncryptedDb);
512 SetDir(DIRECTOR);
513 if (param.storeId.empty() || param.appId.empty() || param.userId.empty()) {
514 return nullptr;
515 }
516
517 // define a Callback to hold the kvStoreDelegate and status.
518 DelegateKvMgrCallback delegateKvMgrCallback;
519 function<void(DBStatus, KvStoreDelegate*)> callFunction
520 = bind(&DelegateKvMgrCallback::Callback, &delegateKvMgrCallback, _1, _2);
521
522 // use appid and userid to initialize a kvStoreDelegateManager, and set the default cfg.
523 if (outManager != nullptr) {
524 delete outManager;
525 outManager = nullptr;
526 }
527 KvStoreDelegateManager *manager = new (std::nothrow) KvStoreDelegateManager(param.appId, param.userId);
528 if (manager == nullptr) {
529 MST_LOG("new delegate failed nullptr.");
530 return nullptr;
531 }
532 DBStatus status = manager->SetKvStoreConfig(KV_CONFIG);
533 if (status != DBStatus::OK) {
534 MST_LOG("%s SetConfig failed! Status= %d", TAG.c_str(), status);
535 delete manager;
536 manager = nullptr;
537 return nullptr;
538 }
539
540 KvStoreDelegate::Option option = TransferKvOptionType(optionParam);
541 // get kv store, then the Callback will save the status and delegate.
542 manager->GetKvStore(param.storeId, option, callFunction);
543 status = delegateKvMgrCallback.GetStatus();
544 if (status != DBStatus::OK) {
545 MST_LOG("%s GetKvStore failed! Status= %d", TAG.c_str(), status);
546 delete manager;
547 manager = nullptr;
548 return nullptr;
549 }
550 const KvStoreDelegate* delegate = const_cast<KvStoreDelegate*>(delegateKvMgrCallback.GetKvStore());
551 if (delegate == nullptr) {
552 MST_LOG("%s GetKvStore failed! delegate nullptr.", TAG.c_str());
553 delete manager;
554 manager = nullptr;
555 return nullptr;
556 }
557
558 MST_LOG("%s GetKvStore success: %s %s %s %d %d", TAG.c_str(),
559 param.storeId.c_str(), param.appId.c_str(), param.userId.c_str(), option.createIfNecessary, option.localOnly);
560 outManager = manager;
561 return const_cast<KvStoreDelegate*>(delegate);
562 }
563
564 KvStoreDelegate* DistributedTestTools::GetDelegateStatus(KvStoreDelegateManager *&outManager, DBStatus &statusReturn,
565 const KvDBParameters ¶m, const KvOption &optionParam)
566 {
567 MST_LOG("Delegate isEncryptedDb : %s", (optionParam.isEncryptedDb ? "true" : "false"));
568 SetDir(DIRECTOR);
569 if (param.storeId.empty() || param.appId.empty() || param.userId.empty()) {
570 return nullptr;
571 }
572
573 // define a Callback to hold the kvStoreDelegate and status.
574 DelegateKvMgrCallback delegateKvMgrCallback;
575 function<void(DBStatus, KvStoreDelegate*)> functionCallback
576 = bind(&DelegateKvMgrCallback::Callback, &delegateKvMgrCallback, _1, _2);
577
578 // use appid and userid to initialize a kvStoreDelegateManager, and set the default cfg.
579 if (outManager != nullptr) {
580 delete outManager;
581 outManager = nullptr;
582 }
583 KvStoreDelegateManager *manager = new (std::nothrow) KvStoreDelegateManager(param.appId, param.userId);
584 if (manager == nullptr) {
585 MST_LOG("new delegate failed nullptr.");
586 return nullptr;
587 }
588 DBStatus status = manager->SetKvStoreConfig(KV_CONFIG);
589 if (status != DBStatus::OK) {
590 MST_LOG("%s SetConfig failed! Status= %d", TAG.c_str(), status);
591 delete manager;
592 manager = nullptr;
593 return nullptr;
594 }
595
596 KvStoreDelegate::Option option = TransferKvOptionType(optionParam);
597 // get kv store, then the Callback will save the status and delegate.
598 manager->GetKvStore(param.storeId, option, functionCallback);
599 statusReturn = delegateKvMgrCallback.GetStatus();
600 if (statusReturn != DBStatus::OK) {
601 MST_LOG("%s GetKvStore failed! Status= %d", TAG.c_str(), statusReturn);
602 delete manager;
603 manager = nullptr;
604 return nullptr;
605 }
606 const KvStoreDelegate* delegate = const_cast<KvStoreDelegate*>(delegateKvMgrCallback.GetKvStore());
607 if (delegate == nullptr) {
608 MST_LOG("%s GetDelegate failed! delegate is nullptr.", TAG.c_str());
609 delete manager;
610 manager = nullptr;
611 return nullptr;
612 }
613
614 MST_LOG("%s GetKvStore success : %s %s %s %d %d", TAG.c_str(), param.storeId.c_str(), param.appId.c_str(),
615 param.userId.c_str(), option.createIfNecessary, option.localOnly);
616 outManager = manager;
617 return const_cast<KvStoreDelegate*>(delegate);
618 }
619
620 // This static method is for moduleTest of distributed to try-get KvStoreDelegate with invalid params.
621 DBStatus DistributedTestTools::GetDelegateNotGood(KvStoreDelegateManager *&manager, KvStoreDelegate *&outDelegate,
622 const string &storeId, const string &appId, const string &userId, const KvOption &optionParam)
623 {
624 SetDir(DIRECTOR);
625
626 // define a Callback to hold the kvStoreDelegate and status.
627 DelegateKvMgrCallback delegateKvMgrCallback;
628 function<void(DBStatus, KvStoreDelegate*)> callFunction
629 = bind(&DelegateKvMgrCallback::Callback, &delegateKvMgrCallback, _1, _2);
630
631 // use appid and userid to initialize a kvStoreDelegateManager, and set the default cfg.
632 manager = new (std::nothrow) KvStoreDelegateManager(appId, userId);
633 if (manager == nullptr) {
634 MST_LOG("new delegate failed nullptr.");
635 return DBStatus::DB_ERROR;
636 }
637 DBStatus status = manager->SetKvStoreConfig(KV_CONFIG);
638 if (status != DBStatus::OK) {
639 MST_LOG("%s SetConfig failed! Status= %d", TAG.c_str(), status);
640 status = DBStatus::INVALID_ARGS;
641 delete manager;
642 manager = nullptr;
643 return status;
644 }
645
646 KvStoreDelegate::Option option = TransferKvOptionType(optionParam);
647 // get kv store, then the Callback will save the status and delegate.
648 manager->GetKvStore(storeId, option, callFunction);
649 status = delegateKvMgrCallback.GetStatus();
650 outDelegate = const_cast<KvStoreDelegate*>(delegateKvMgrCallback.GetKvStore());
651 if (outDelegate != nullptr) {
652 MST_LOG("%s GetKvStore failed! delegate nullptr.", TAG.c_str());
653 delete manager;
654 manager = nullptr;
655 return status;
656 }
657 if (status == DBStatus::NOT_FOUND) {
658 MST_LOG("%s GetKvStore failed! Status= %d", TAG.c_str(), status);
659 delete manager;
660 manager = nullptr;
661 return status;
662 }
663
664 MST_LOG("%s GetKvStore failed, Status = %d", TAG.c_str(), status);
665 return status;
666 }
667
668 // This static method is for moduleTest to put value with kvStoreDelegate.
669 DBStatus DistributedTestTools::Put(KvStoreDelegate &kvStoreDelegate, const Key &key, const Value &value)
670 {
671 return kvStoreDelegate.Put(key, value);
672 }
673
674 // This static method is for moduleTest to putBatch value with kvStoreDelegate.
675 DBStatus DistributedTestTools::PutBatch(KvStoreDelegate &kvStoreDelegate, const vector<Entry> &entries)
676 {
677 DistributedDB::DBStatus status;
678 unsigned int cnt = entries.size();
679 int index = 0;
680 while (cnt > BATCH_RECORDS) {
681 cnt -= BATCH_RECORDS;
682 std::vector<DistributedDB::Entry> entriesBatch(entries.begin() + index * BATCH_RECORDS,
683 entries.begin() + (index + 1) * BATCH_RECORDS);
684 status = kvStoreDelegate.PutBatch(entriesBatch);
685 index++;
686 if (status != DBStatus::OK) {
687 return status;
688 }
689 }
690 std::vector<DistributedDB::Entry> entriesBatch(entries.begin() + index * BATCH_RECORDS, entries.end());
691 status = kvStoreDelegate.PutBatch(entriesBatch);
692
693 return status;
694 }
695
696 // This static method is for moduleTest to delete value with kvStoreDelegate.
697 DBStatus DistributedTestTools::Delete(KvStoreDelegate &kvStoreDelegate, const Key &key)
698 {
699 return kvStoreDelegate.Delete(key);
700 }
701
702 // This static method is for moduleTest to deleteBatch value with kvStoreDelegate.
703 DBStatus DistributedTestTools::DeleteBatch(KvStoreDelegate &kvStoreDelegate, const vector<Key> &keys)
704 {
705 if (keys.size() > BATCH_RECORDS) {
706 int cnt = 0;
707 std::vector<DistributedDB::Key> keyBatch;
708 DistributedDB::DBStatus status;
709 for (const auto &iter : keys) {
710 keyBatch.push_back(iter);
711 cnt++;
712 if (cnt % BATCH_RECORDS == 0 || cnt == static_cast<int>(keys.size())) {
713 status = kvStoreDelegate.DeleteBatch(keyBatch);
714 if (status != DBStatus::OK) {
715 return status;
716 }
717 keyBatch.clear();
718 }
719 }
720 return status;
721 } else {
722 return kvStoreDelegate.DeleteBatch(keys);
723 }
724 }
725
726 // This static method is for moduleTest to clear value with kvStoreDelegate.
727 DBStatus DistributedTestTools::Clear(KvStoreDelegate &kvStoreDelegate)
728 {
729 return kvStoreDelegate.Clear();
730 }
731
732 // This static method is for moduleTest to try-get snapshot with kvStoreDelegate.
733 KvStoreSnapshotDelegate *DistributedTestTools::GetKvStoreSnapshot(KvStoreDelegate &kvStoreDelegate)
734 {
735 DelegateCallback delegateCallback;
736 function<void(DBStatus, KvStoreSnapshotDelegate *)> callFunction
737 = bind(&DelegateCallback::Callback, &delegateCallback, _1, _2);
738
739 // no need to use obsever, so param1 is nullptr;
740 kvStoreDelegate.GetKvStoreSnapshot(nullptr, callFunction);
741 DBStatus status = delegateCallback.GetStatus();
742 if (status != DBStatus::OK) {
743 MST_LOG("%s Get Callback failed! Status= %d", TAG.c_str(), status);
744 return nullptr;
745 }
746 KvStoreSnapshotDelegate *snapshot
747 = const_cast<KvStoreSnapshotDelegate *>(delegateCallback.GetKvStoreSnapshot());
748 if (snapshot == nullptr) {
749 MST_LOG("%s Get KvStoreSnapshot null! Status= %d", TAG.c_str(), status);
750 return nullptr;
751 }
752 return snapshot;
753 }
754
755 // This static method is for moduleTest to get value with kvStoreDelegate.
756 Value DistributedTestTools::Get(KvStoreDelegate &kvStoreDelegate, const Key &key)
757 {
758 // initialize the result value.
759 Value result = { };
760 DelegateCallback delegateCallback;
761 function<void(DBStatus, KvStoreSnapshotDelegate *)> callFunction
762 = bind(&DelegateCallback::Callback, &delegateCallback, _1, _2);
763 kvStoreDelegate.GetKvStoreSnapshot(nullptr, callFunction);
764 DBStatus status = delegateCallback.GetStatus();
765 if (status != DBStatus::OK) {
766 MST_LOG("%s Get failed! Status= %d", TAG.c_str(), status);
767 return result;
768 }
769
770 // the first Callback's kvStoreDelegate is used to get snapshot.
771 KvStoreSnapshotDelegate *snapshot
772 = const_cast<KvStoreSnapshotDelegate*>(delegateCallback.GetKvStoreSnapshot());
773 if (snapshot == nullptr) {
774 MST_LOG("%s Get snapshot null! Status= %d", TAG.c_str(), status);
775 return result;
776 }
777
778 // the second Callback is used in Snapshot.
779 KvCallback kvCallback;
780 function < void(DBStatus, Value) > function2
781 = bind(&KvCallback::Callback, &kvCallback, _1, _2);
782 snapshot->Get(key, function2);
783 status = kvCallback.GetStatus();
784 if (status != DBStatus::OK) {
785 kvStoreDelegate.ReleaseKvStoreSnapshot(snapshot);
786 snapshot = nullptr;
787 MST_LOG("%s Get value failed! Status= %d", TAG.c_str(), status);
788 return result;
789 }
790 result = kvCallback.GetValue();
791 kvStoreDelegate.ReleaseKvStoreSnapshot(snapshot);
792 snapshot = nullptr;
793 return result;
794 }
795
796 Value DistributedTestTools::Get(KvStoreSnapshotDelegate &kvStoreSnapshotDelegate, const Key &key)
797 {
798 KvCallback kvCallback;
799 function < void(DBStatus, Value) > function2
800 = bind(&KvCallback::Callback, &kvCallback, _1, _2);
801 kvStoreSnapshotDelegate.Get(key, function2);
802 return kvCallback.GetValue();
803 }
804
805 vector<Entry> DistributedTestTools::GetEntries(KvStoreSnapshotDelegate &kvStoreSnapshotDelegate, const Key &key)
806 {
807 KvCallback kvCallback;
808 function<void(DBStatus, vector<Entry>)> function2
809 = bind(&KvCallback::CallbackPrefix, &kvCallback, _1, _2);
810 kvStoreSnapshotDelegate.GetEntries(key, function2);
811 return kvCallback.GetValueVector();
812 }
813
814 // This static method is for moduleTest to get values with kvStoreDelegate and keyPrefix.
815 vector<Entry> DistributedTestTools::GetEntries(KvStoreDelegate &kvStoreDelegate, const Key &keyPrefix)
816 {
817 DelegateCallback delegateCallback;
818 function<void(DBStatus, KvStoreSnapshotDelegate *)> callFunction
819 = bind(&DelegateCallback::Callback, &delegateCallback, _1, _2);
820 kvStoreDelegate.GetKvStoreSnapshot(nullptr, callFunction);
821 DBStatus status = delegateCallback.GetStatus();
822 if (status != DBStatus::OK) {
823 MST_LOG("%s Get failed! Status= %d", TAG.c_str(), status);
824 return {};
825 }
826
827 KvStoreSnapshotDelegate *snapshot
828 = const_cast<KvStoreSnapshotDelegate*>(delegateCallback.GetKvStoreSnapshot());
829 if (snapshot == nullptr) {
830 MST_LOG("%s Get snapshot null! Status= %d", TAG.c_str(), status);
831 return {};
832 }
833
834 KvCallback kvCallback;
835 function<void(DBStatus, vector<Entry>)> function2 = bind(&KvCallback::CallbackPrefix, &kvCallback, _1, _2);
836 snapshot->GetEntries(keyPrefix, function2);
837 status = kvCallback.GetStatus();
838 if (status != DBStatus::OK) {
839 kvStoreDelegate.ReleaseKvStoreSnapshot(snapshot);
840 snapshot = nullptr;
841 MST_LOG("%s GetEntries failed! Status= %d", TAG.c_str(), status);
842 return {};
843 }
844 kvStoreDelegate.ReleaseKvStoreSnapshot(snapshot);
845 snapshot = nullptr;
846 return kvCallback.GetValueVector();
847 }
848
849 void TickTock(steady_clock::time_point &tick, double &duration)
850 {
851 steady_clock::time_point tock = steady_clock::now();
852 auto durate = duration_cast<microseconds>(tock - tick);
853 tick = tock;
854 duration = static_cast<double>(durate.count());
855 }
856
857 bool TickTock1(steady_clock::time_point &tick, int putGetTimes, double &duration)
858 {
859 if (putGetTimes <= 0) {
860 MST_LOG("putGetTimes is 0!");
861 return false;
862 }
863 TickTock(tick, duration);
864 duration /= putGetTimes;
865 return true;
866 }
867
868 void GetSysInfo(DistributedTestSysInfo &si, SeqNo seqNo)
869 {
870 si.GetSysMemOccpy(seqNo);
871 si.GetSysCpuUsage(seqNo, DEFAULT_INTEVAL);
872 si.GetSysCurrentPower(seqNo, DEFAULT_COUNT, DEFAULT_INTEVAL);
873 }
874
875 void CheckBeforeOpenDB(bool getSysInfo, steady_clock::time_point &tick,
876 vector<Entry> data1, vector<Key> keys, DistributedTestSysInfo &si)
877 {
878 if (!getSysInfo) {
879 MST_LOG("[gen data]:%zu, %zu.", data1.size(), keys.size());
880 tick = time_point_cast<microseconds>(steady_clock::now());
881 } else {
882 MST_LOG("System info before opening a db:");
883 GetSysInfo(si, FIRST);
884 }
885 }
886
887 void CheckAfterOperateDB(bool getSysInfo, steady_clock::time_point &tick,
888 double &duration, DistributedTestSysInfo &si)
889 {
890 if (!getSysInfo) {
891 TickTock(tick, duration);
892 MST_LOG("[time calculator]this operate cost %f us.", duration);
893 } else {
894 MST_LOG("System info after opening db, or before inserting records:");
895 GetSysInfo(si, SECOND);
896 si.SaveSecondToFirst();
897 }
898 }
899
900 void PutDuration(steady_clock::time_point &tick, PerformanceData &performanceData,
901 int keyLength, DistributedTestSysInfo &si)
902 {
903 bool getSysInfo = performanceData.getSysInfo;
904 int putGetTimes = performanceData.putGetTimes;
905 double duration;
906 if (!getSysInfo) {
907 TickTock(tick, duration);
908 performanceData.putDuration = duration / putGetTimes;
909 MST_LOG("[time calculator]put first [%d]keys,\tvalue[%dB-length],\tcost[%fus],\tper[%fus].",
910 putGetTimes, keyLength, duration, performanceData.putDuration);
911 TickTock(tick, duration);
912 } else {
913 MST_LOG("System info after inserting records, or before querying records:");
914 GetSysInfo(si, SECOND);
915 si.SaveSecondToFirst();
916 }
917 }
918
919 void ReadDuration(steady_clock::time_point &tick, PerformanceData &performanceData,
920 int keyLength, DistributedTestSysInfo &si)
921 {
922 bool getSysInfo = performanceData.getSysInfo;
923 int putGetTimes = performanceData.putGetTimes;
924 double duration;
925 if (!getSysInfo) {
926 TickTock(tick, duration);
927 performanceData.readPutDuration = duration / putGetTimes;
928 MST_LOG("[time calculator]get first [%d]keys,\tvalue[%dB-length],\tcost[%fus],\tper[%fus].",
929 putGetTimes, keyLength, duration, performanceData.readPutDuration);
930 TickTock(tick, duration);
931 } else {
932 MST_LOG("System info after querying records, or before updating records:");
933 GetSysInfo(si, SECOND);
934 si.SaveSecondToFirst();
935 }
936 }
937
938 void UpdateDuration(steady_clock::time_point &tick, PerformanceData &performanceData,
939 int keyLength, DistributedTestSysInfo &si)
940 {
941 bool getSysInfo = performanceData.getSysInfo;
942 int putGetTimes = performanceData.putGetTimes;
943 double duration;
944 if (!getSysInfo) {
945 TickTock(tick, duration);
946 performanceData.updateDuration = duration / putGetTimes;
947 MST_LOG("[time calculator]put second [%d]keys,\tvalue[%dB-length],\tcost[%fus],\tper[%fus].",
948 putGetTimes, keyLength, duration, performanceData.updateDuration);
949 TickTock(tick, duration);
950 } else {
951 MST_LOG("System info after updating records, or before querying records one by one:");
952 GetSysInfo(si, SECOND);
953 si.SaveSecondToFirst();
954 }
955 }
956
957 void ReadUpdateDuration(steady_clock::time_point &tick, PerformanceData &performanceData,
958 int keyLength, DistributedTestSysInfo &si)
959 {
960 bool getSysInfo = performanceData.getSysInfo;
961 int putGetTimes = performanceData.putGetTimes;
962 double duration;
963 if (!getSysInfo) {
964 TickTock(tick, duration);
965 performanceData.readUpdateDuration = duration / putGetTimes;
966 MST_LOG("[time calculator]get second [%d]keys,\tvalue[%dB-length],\tcost[%fus],\tper[%fus].",
967 putGetTimes, keyLength, duration, performanceData.readUpdateDuration);
968 TickTock(tick, duration);
969 } else {
970 MST_LOG("System info after querying records one by one, or before deleting records one by one:");
971 GetSysInfo(si, SECOND);
972 si.SaveSecondToFirst();
973 }
974 }
975
976 void ClearDuration(steady_clock::time_point &tick, PerformanceData &performanceData,
977 int keyLength, DistributedTestSysInfo &si)
978 {
979 bool getSysInfo = performanceData.getSysInfo;
980 int putGetTimes = performanceData.putGetTimes;
981 double duration;
982 if (!getSysInfo) {
983 TickTock(tick, duration);
984 performanceData.deleteDuration = duration / putGetTimes;
985 MST_LOG("[time calculator]delete [%d]keys,\tvalue[%dB-length],\tcost[%fus],\tper[%fus].",
986 putGetTimes, keyLength, duration, performanceData.deleteDuration);
987 TickTock(tick, duration);
988 } else {
989 MST_LOG("System info after deleting records one by one, or before closing a db:");
990 GetSysInfo(si, SECOND);
991 si.SaveSecondToFirst();
992 }
993 }
994
995 bool DistributedTestTools::CalculateOpenPerformance(PerformanceData &performanceData)
996 {
997 int putGetTimes = performanceData.putGetTimes;
998 int keyLength = performanceData.keyLength;
999 int valueLength = performanceData.valueLength;
1000 bool getSysInfo = performanceData.getSysInfo;
1001 DistributedTestSysInfo si;
1002 steady_clock::time_point tick;
1003
1004 vector<Entry> data1 = GenRanKeyVal(putGetTimes, keyLength, valueLength, 'a');
1005 vector<Key> keys = GetKeysFromEntries(data1, false);
1006
1007 CheckBeforeOpenDB(getSysInfo, tick, data1, keys, si);
1008 // print the opened time.
1009 KvStoreDelegate *store1 = nullptr;
1010 KvStoreDelegateManager *manager = nullptr;
1011
1012 KvOption option = g_kvOption;
1013 option.localOnly = performanceData.isLocal;
1014 store1 = DistributedTestTools::GetDelegateSuccess(manager, KVDB_PARAMETER_PERFORM, option);
1015 if (store1 == nullptr) {
1016 return false;
1017 }
1018 CheckAfterOperateDB(getSysInfo, tick, performanceData.closeDuration, si);
1019
1020 // close the base db
1021 if (manager->CloseKvStore(store1) != DistributedDB::DBStatus::OK) {
1022 return false;
1023 }
1024 if (manager->DeleteKvStore(STORE_ID_PERFORM) != OK) {
1025 return false;
1026 }
1027 store1 = nullptr;
1028 delete manager;
1029 manager = nullptr;
1030 CheckAfterOperateDB(getSysInfo, tick, performanceData.closeDuration, si);
1031
1032 return true;
1033 }
1034
1035 bool DistributedTestTools::CalculateInsertPerformance(PerformanceData &performanceData)
1036 {
1037 int putGetTimes = performanceData.putGetTimes;
1038 int keyLength = performanceData.keyLength;
1039 int valueLength = performanceData.valueLength;
1040 bool putBatch = performanceData.putBatch;
1041 bool getSysInfo = performanceData.getSysInfo;
1042 DistributedTestSysInfo si;
1043 steady_clock::time_point tick;
1044
1045 vector<Entry> data1 = GenRanKeyVal(putGetTimes, keyLength, valueLength, 'a');
1046 vector<Key> keys = GetKeysFromEntries(data1, false);
1047 vector< vector<Entry> > groupEntries = GetGroupEntries(data1, BATCH_RECORDS, valueLength, 'a');
1048 CheckBeforeOpenDB(getSysInfo, tick, data1, keys, si);
1049
1050 KvStoreDelegate *store1 = nullptr;
1051 KvStoreDelegateManager *manager = nullptr;
1052
1053 KvOption option = g_kvOption;
1054 option.localOnly = performanceData.isLocal;
1055 store1 = DistributedTestTools::GetDelegateSuccess(manager, KVDB_PARAMETER_PERFORM, option);
1056 if (store1 == nullptr) {
1057 return false;
1058 }
1059 // print the insert time.
1060 if (putBatch) {
1061 for (auto entries = groupEntries.begin(); entries != groupEntries.end(); ++entries) {
1062 DistributedTestTools::PutBatch(*store1, *entries);
1063 }
1064 } else {
1065 for (auto entry = data1.begin(); entry != data1.end(); ++entry) {
1066 DistributedTestTools::Put(*store1, entry->key, entry->value);
1067 }
1068 }
1069
1070 PutDuration(tick, performanceData, keyLength, si);
1071
1072 // close the base db
1073 if (manager->CloseKvStore(store1) != DistributedDB::DBStatus::OK) {
1074 return false;
1075 }
1076 if (manager->DeleteKvStore(STORE_ID_PERFORM) != OK) {
1077 return false;
1078 }
1079 store1 = nullptr;
1080 delete manager;
1081 manager = nullptr;
1082 CheckAfterOperateDB(getSysInfo, tick, performanceData.closeDuration, si);
1083
1084 return true;
1085 }
1086
1087 bool DistributedTestTools::CalculateGetPutPerformance(PerformanceData &performanceData)
1088 {
1089 int putGetTimes = performanceData.putGetTimes;
1090 int keyLength = performanceData.keyLength;
1091 int valueLength = performanceData.valueLength;
1092 bool getBatch = performanceData.getBatch;
1093 bool getSysInfo = performanceData.getSysInfo;
1094 DistributedTestSysInfo si;
1095 steady_clock::time_point tick;
1096
1097 vector<Entry> data1 = GenRanKeyVal(putGetTimes, keyLength, valueLength, 'a');
1098 vector<Key> keys = GetKeysFromEntries(data1, false);
1099
1100 CheckBeforeOpenDB(getSysInfo, tick, data1, keys, si);
1101
1102 // print the get put time.
1103 KvStoreDelegate *store1 = nullptr;
1104 KvStoreDelegateManager *manager = nullptr;
1105
1106 KvOption option = g_kvOption;
1107 option.localOnly = performanceData.isLocal;
1108 store1 = DistributedTestTools::GetDelegateSuccess(manager, KVDB_PARAMETER_PERFORM, option);
1109 if (store1 == nullptr) {
1110 return false;
1111 }
1112 KvStoreSnapshotDelegate *snapShot = DistributedTestTools::GetKvStoreSnapshot(*store1);
1113 if (snapShot == nullptr) {
1114 return false;
1115 }
1116 if (getBatch) {
1117 std::vector<Entry> ev = DistributedTestTools::GetEntries(*snapShot, PERFORMANCEKEY);
1118 } else {
1119 for (auto key = keys.begin(); key != keys.end(); ++key) {
1120 Value valueResult = DistributedTestTools::Get(*snapShot, *key);
1121 }
1122 }
1123 store1->ReleaseKvStoreSnapshot(snapShot);
1124 snapShot = nullptr;
1125 ReadDuration(tick, performanceData, keyLength, si);
1126
1127 // close the base db
1128 if (manager->CloseKvStore(store1) != DistributedDB::DBStatus::OK) {
1129 return false;
1130 }
1131 if (manager->DeleteKvStore(STORE_ID_PERFORM) != OK) {
1132 return false;
1133 }
1134 store1 = nullptr;
1135 delete manager;
1136 manager = nullptr;
1137 CheckAfterOperateDB(getSysInfo, tick, performanceData.closeDuration, si);
1138
1139 return true;
1140 }
1141
1142 bool DistributedTestTools::CalculateUpdatePerformance(PerformanceData &performanceData)
1143 {
1144 int putGetTimes = performanceData.putGetTimes;
1145 int keyLength = performanceData.keyLength;
1146 int valueLength = performanceData.valueLength;
1147 bool putBatch = performanceData.putBatch;
1148 bool getSysInfo = performanceData.getSysInfo;
1149 DistributedTestSysInfo si;
1150 steady_clock::time_point tick;
1151
1152 vector<Entry> data1 = GenRanKeyVal(putGetTimes, keyLength, valueLength, 'a');
1153 vector<Key> keys = GetKeysFromEntries(data1, false);
1154 Value updateVal;
1155 updateVal.assign(valueLength, 'b');
1156 vector< vector<Entry> > groupEntriesUp = GetGroupEntries(data1, BATCH_RECORDS, valueLength, 'b');
1157 CheckBeforeOpenDB(getSysInfo, tick, data1, keys, si);
1158
1159 // print the update time.
1160 KvStoreDelegate *store1 = nullptr;
1161 KvStoreDelegateManager *manager = nullptr;
1162
1163 KvOption option = g_kvOption;
1164 option.localOnly = performanceData.isLocal;
1165 store1 = DistributedTestTools::GetDelegateSuccess(manager, KVDB_PARAMETER_PERFORM, option);
1166 if (store1 == nullptr) {
1167 return false;
1168 }
1169 if (putBatch) {
1170 for (auto entries = groupEntriesUp.begin(); entries != groupEntriesUp.end(); ++entries) {
1171 DistributedTestTools::PutBatch(*store1, *entries);
1172 }
1173 } else {
1174 for (auto entry = data1.begin(); entry != data1.end(); ++entry) {
1175 DistributedTestTools::Put(*store1, entry->key, updateVal);
1176 }
1177 }
1178 UpdateDuration(tick, performanceData, keyLength, si);
1179
1180 // close the base db
1181 if (manager->CloseKvStore(store1) != DistributedDB::DBStatus::OK) {
1182 return false;
1183 }
1184 if (manager->DeleteKvStore(STORE_ID_PERFORM) != OK) {
1185 return false;
1186 }
1187 store1 = nullptr;
1188 delete manager;
1189 manager = nullptr;
1190 CheckAfterOperateDB(getSysInfo, tick, performanceData.closeDuration, si);
1191
1192 return true;
1193 }
1194
1195 bool DistributedTestTools::CalculateGetUpdatePerformance(PerformanceData &performanceData)
1196 {
1197 int putGetTimes = performanceData.putGetTimes;
1198 int keyLength = performanceData.keyLength;
1199 int valueLength = performanceData.valueLength;
1200 bool getSysInfo = performanceData.getSysInfo;
1201 DistributedTestSysInfo si;
1202 steady_clock::time_point tick;
1203
1204 vector<Entry> data1 = GenRanKeyVal(putGetTimes, keyLength, valueLength, 'a');
1205 vector<Key> keys = GetKeysFromEntries(data1, false);
1206
1207 CheckBeforeOpenDB(getSysInfo, tick, data1, keys, si);
1208
1209 // print the get update time.
1210 KvStoreDelegate *store1 = nullptr;
1211 KvStoreDelegateManager *manager = nullptr;
1212
1213 KvOption option = g_kvOption;
1214 option.localOnly = performanceData.isLocal;
1215 store1 = DistributedTestTools::GetDelegateSuccess(manager, KVDB_PARAMETER_PERFORM, option);
1216 if (store1 == nullptr) {
1217 return false;
1218 }
1219 KvStoreSnapshotDelegate *snapShot = DistributedTestTools::GetKvStoreSnapshot(*store1);
1220 if (snapShot == nullptr) {
1221 return false;
1222 }
1223 for (auto key = keys.begin(); key != keys.end(); ++key) {
1224 Value valueResult = DistributedTestTools::Get(*snapShot, *key);
1225 }
1226 store1->ReleaseKvStoreSnapshot(snapShot);
1227 snapShot = nullptr;
1228 ReadUpdateDuration(tick, performanceData, keyLength, si);
1229
1230 // close the base db
1231 if (manager->CloseKvStore(store1) != DistributedDB::DBStatus::OK) {
1232 return false;
1233 }
1234 if (manager->DeleteKvStore(STORE_ID_PERFORM) != OK) {
1235 return false;
1236 }
1237 store1 = nullptr;
1238 delete manager;
1239 manager = nullptr;
1240 CheckAfterOperateDB(getSysInfo, tick, performanceData.closeDuration, si);
1241 return true;
1242 }
1243
1244 bool DistributedTestTools::CalculateUseClearPerformance(PerformanceData &performanceData)
1245 {
1246 int putGetTimes = performanceData.putGetTimes;
1247 int keyLength = performanceData.keyLength;
1248 int valueLength = performanceData.valueLength;
1249 bool useClear = performanceData.useClear;
1250 bool getSysInfo = performanceData.getSysInfo;
1251 DistributedTestSysInfo si;
1252 steady_clock::time_point tick;
1253
1254 vector<Entry> data1 = GenRanKeyVal(putGetTimes, keyLength, valueLength, 'a');
1255 vector<Key> keys = GetKeysFromEntries(data1, false);
1256
1257 CheckBeforeOpenDB(getSysInfo, tick, data1, keys, si);
1258
1259 // print the get update time.
1260 KvStoreDelegate *store1 = nullptr;
1261 KvStoreDelegateManager *manager = nullptr;
1262
1263 KvOption option = g_kvOption;
1264 option.localOnly = performanceData.isLocal;
1265 store1 = DistributedTestTools::GetDelegateSuccess(manager, KVDB_PARAMETER_PERFORM, option);
1266 if (store1 == nullptr) {
1267 return false;
1268 }
1269 if (useClear) {
1270 DistributedTestTools::Clear(*store1);
1271 } else {
1272 for (auto key = keys.begin(); key != keys.end(); ++key) {
1273 DistributedTestTools::Delete(*store1, *key);
1274 }
1275 }
1276 ClearDuration(tick, performanceData, keyLength, si);
1277
1278 // close the base db
1279 if (manager->CloseKvStore(store1) != DistributedDB::DBStatus::OK) {
1280 return false;
1281 }
1282 if (manager->DeleteKvStore(STORE_ID_PERFORM) != OK) {
1283 return false;
1284 }
1285 store1 = nullptr;
1286 delete manager;
1287 manager = nullptr;
1288 CheckAfterOperateDB(getSysInfo, tick, performanceData.closeDuration, si);
1289 return true;
1290 }
1291
1292 bool DistributedTestTools::CloseAndRelease(KvStoreDelegateManager *&manager, KvStoreDelegate *&delegate)
1293 {
1294 bool result = true;
1295 DBStatus status;
1296 if (delegate != nullptr && manager != nullptr) {
1297 status = manager->CloseKvStore(delegate);
1298 MST_LOG("[CloseAndRelease] status = %d", status);
1299 result = (status == OK);
1300 delegate = nullptr;
1301 delete manager;
1302 manager = nullptr;
1303 } else {
1304 MST_LOG("Close Failed");
1305 return false;
1306 }
1307 return result;
1308 }
1309
1310 bool DistributedTestTools::CloseAndRelease(KvStoreDelegateManager *&manager, KvStoreNbDelegate *&delegate)
1311 {
1312 bool result = true;
1313 if (delegate != nullptr && manager != nullptr) {
1314 result = (manager->CloseKvStore(delegate) == OK);
1315 delegate = nullptr;
1316 delete manager;
1317 manager = nullptr;
1318 } else {
1319 MST_LOG("Close Failed");
1320 return false;
1321 }
1322 return result;
1323 }
1324
1325 bool DistributedTestTools::VerifyDbRecordCnt(KvStoreNbDelegate *&delegate, unsigned int recordCnt, bool isLocal)
1326 {
1327 if (delegate == nullptr) {
1328 MST_LOG("The delegate is nullptr!");
1329 return false;
1330 }
1331 DBStatus status = OK;
1332 vector<Entry> entries;
1333 if (isLocal) {
1334 #ifdef RELEASE_MODE_V2
1335 status = delegate->GetLocalEntries(KEY_EMPTY, entries);
1336 #endif // end of RELEASE_MODE_V2
1337 } else {
1338 status = delegate->GetEntries(KEY_EMPTY, entries);
1339 }
1340
1341 if (status == OK && entries.size() == recordCnt) {
1342 return true;
1343 } else {
1344 MST_LOG("The real status is %d, real recordCnt is %zu", status, entries.size());
1345 return false;
1346 }
1347 }
1348
1349 bool DistributedTestTools::VerifyRecordsInDb(DistributedDB::KvStoreNbDelegate *&delegate,
1350 std::vector<DistributedDB::Entry> &entriesExpected, const std::vector<uint8_t> &keyPrefix, bool isLocal)
1351 {
1352 DBStatus status = OK;
1353 vector<Entry> entries;
1354 if (isLocal) {
1355 #ifdef RELEASE_MODE_V2
1356 status = delegate->GetLocalEntries(keyPrefix, entries);
1357 #endif // end of RELEASE_MODE_V2
1358 } else {
1359 status = delegate->GetEntries(keyPrefix, entries);
1360 }
1361 if (status == OK && CompareEntriesVector(entries, entriesExpected)) {
1362 return true;
1363 }
1364 MST_LOG("[VerifyRecordsInDb] status = %d, entries.size() = %zu\n", status, entries.size());
1365 return false;
1366 }
1367
1368 void ReleaseSqliteResource(sqlite3_stmt *&statement, sqlite3 *&db)
1369 {
1370 sqlite3_finalize(statement);
1371 statement = nullptr;
1372 sqlite3_close(db);
1373 }
1374
1375 bool SqliteBindToStatement(sqlite3_stmt *&statement, sqlite3 *&db, std::vector<DistributedDB::Key> &sqlParam)
1376 {
1377 int errCode = 0;
1378 for (unsigned int index = 0; index < sqlParam.size(); index++) {
1379 if (sqlParam[index].empty()) {
1380 errCode = sqlite3_bind_zeroblob(statement, index, -1); // -1 for zero-length blob.
1381 } else {
1382 errCode = sqlite3_bind_blob(statement, index + 1, static_cast<const void*>(sqlParam[index].data()),
1383 sqlParam[index].size(), SQLITE_TRANSIENT);
1384 }
1385 if (errCode != SQLITE_OK) {
1386 MST_LOG("[SqliteBindToStatement] Failed to bind the SQLite blob: %d", errCode);
1387 ReleaseSqliteResource(statement, db);
1388 return false;
1389 }
1390 }
1391 return true;
1392 }
1393
1394 static bool SetSQLiteKey(sqlite3 *db, const std::vector<uint8_t> &passwd)
1395 {
1396 int errCode = sqlite3_key(db, static_cast<const void *>(passwd.data()),
1397 static_cast<int>(passwd.size()));
1398 if (errCode != SQLITE_OK) {
1399 MST_LOG("[DistributedTestTools::SetSQLiteKey] sqlite3_key failed: %d", errCode);
1400 return false;
1401 }
1402 char *errMsg = nullptr;
1403 bool result = false;
1404 errCode = sqlite3_exec(db, CIPHER_CONFIG_SQL.c_str(), nullptr, nullptr, &errMsg);
1405 if (errCode != SQLITE_OK) {
1406 MST_LOG("[DistributedTestTools::SetSQLiteKey] config cipher failed: %d", errCode);
1407 goto END;
1408 }
1409
1410 errCode = sqlite3_exec(db, KDF_ITER_CONFIG_SQL.c_str(), nullptr, nullptr, &errMsg);
1411 if (errCode != SQLITE_OK) {
1412 MST_LOG("[DistributedTestTools::SetSQLiteKey] config kdf iter failed: %d", errCode);
1413 goto END;
1414 }
1415 result = true;
1416 END:
1417 if (errMsg != nullptr) {
1418 sqlite3_free(errMsg);
1419 errMsg = nullptr;
1420 }
1421 return result;
1422 }
1423
1424 bool DistributedTestTools::GetRecordCntByKey(const std::string &dbName,
1425 const std::string &strSql, std::vector<DistributedDB::Key> &sqlParam, KvOption &option, int &count)
1426 {
1427 sqlite3 *db = nullptr;
1428 std::string dbOpenName = dbName;
1429 uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE;
1430 int errCode = sqlite3_open_v2(dbOpenName.c_str(), &db, flag, nullptr);
1431 if (errCode != SQLITE_OK) {
1432 MST_LOG("[DistributedTestTools::GetRecordCntByKey] sqlite3_open failed: %d", errCode);
1433 return false;
1434 }
1435
1436 if (option.isEncryptedDb) {
1437 if (SetSQLiteKey(db, option.passwd) != true) {
1438 MST_LOG("[DistributedTestTools::GetRecordCntByKey] sqlite3 set key failed");
1439 sqlite3_close(db);
1440 return false;
1441 }
1442 }
1443
1444 sqlite3_stmt *statement = nullptr;
1445 errCode = sqlite3_prepare(db, strSql.c_str(), -1, &statement, nullptr);
1446 if (errCode != SQLITE_OK) {
1447 MST_LOG("[DistributedTestTools::GetRecordCntByKey] sqlite3_prepare failed: %d", errCode);
1448 ReleaseSqliteResource(statement, db);
1449 return false;
1450 }
1451 if (!SqliteBindToStatement(statement, db, sqlParam)) {
1452 return false;
1453 }
1454 errCode = sqlite3_step(statement);
1455 if (errCode == SQLITE_ROW) {
1456 count = static_cast<uint64_t>(sqlite3_column_int64(statement, 0));
1457 } else {
1458 MST_LOG("[DistributedTestTools::GetRecordCntByKey] sqlite3_step failed: %d", errCode);
1459 ReleaseSqliteResource(statement, db);
1460 count = 0;
1461 return false;
1462 }
1463
1464 ReleaseSqliteResource(statement, db);
1465 return true;
1466 }
1467
1468 bool DistributedTestTools::QuerySpecifiedData(const std::string &dbName,
1469 const std::string &strSql, EncrypteAttribute &attribute, int &count)
1470 {
1471 sqlite3 *db = nullptr;
1472 std::string dbOpenName = dbName;
1473 uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE;
1474 int nResult = sqlite3_open_v2(dbOpenName.c_str(), &db, flag, nullptr);
1475 if (nResult != SQLITE_OK) {
1476 MST_LOG("[sqlite3_open] failed: %d.", nResult);
1477 return false;
1478 }
1479
1480 if (attribute.isEncryptedDb) {
1481 if (SetSQLiteKey(db, attribute.passwd) != true) {
1482 MST_LOG("[DistributedTestTools::QuerySpecifiedData] sqlite3 set key failed");
1483 sqlite3_close(db);
1484 return false;
1485 }
1486 }
1487
1488 sqlite3_stmt *statement = nullptr;
1489 nResult = sqlite3_prepare(db, strSql.c_str(), -1, &statement, nullptr);
1490 if (nResult != SQLITE_OK) {
1491 MST_LOG("[sqlite3_prepare] failed %d.", nResult);
1492 sqlite3_finalize(statement);
1493 statement = nullptr;
1494 sqlite3_close(db);
1495 return false;
1496 }
1497 int errCode = sqlite3_step(statement);
1498 if (errCode != SQLITE_ROW) {
1499 MST_LOG("[sqlite3_step] failed, errCode: %d.", errCode);
1500 sqlite3_finalize(statement);
1501 statement = nullptr;
1502 sqlite3_close(db);
1503 return false;
1504 }
1505 count = static_cast<uint64_t>(sqlite3_column_int64(statement, 0));
1506 MST_LOG("The query count is %d\n.", count);
1507 sqlite3_finalize(statement);
1508 statement = nullptr;
1509 sqlite3_close(db);
1510 return true;
1511 }
1512
1513 bool DistributedTestTools::RepeatCheckAsyncResult(const std::function<bool(void)> &inPred, int repeatLimit,
1514 uint32_t repeatInterval)
1515 {
1516 int limit = repeatLimit;
1517 while (limit != 0) {
1518 if (inPred()) {
1519 return true;
1520 }
1521 if (--limit <= 0) {
1522 MST_LOG("BREAK RepeatCheckAsyncResult :: limit %d\n", limit);
1523 break;
1524 }
1525 std::this_thread::sleep_for(std::chrono::milliseconds(repeatInterval));
1526 }
1527 return false;
1528 }
1529
1530 bool DistributedTestTools::CompareKey(const Entry &entry1, const Entry &entry2)
1531 {
1532 return entry1.key < entry2.key;
1533 }
1534 void DistributedTestTools::CopyFile(const string &srcFile, const string &destFile)
1535 {
1536 int len = 0;
1537 char buff[BUF_LEN] = { 0 };
1538
1539 FILE *pIn = fopen(srcFile.c_str(), "r");
1540 if (pIn == nullptr) {
1541 MST_LOG("Open srcFile failed!");
1542 return;
1543 }
1544 FILE *pOut = fopen(destFile.c_str(), "w");
1545 if (pOut == nullptr) {
1546 MST_LOG("Open destFile failed!");
1547 fclose(pIn);
1548 return;
1549 }
1550
1551 while ((len = fread(buff, sizeof(char), sizeof(buff), pIn)) > 0) {
1552 fwrite(buff, sizeof(char), len, pOut);
1553 }
1554 fclose(pOut);
1555 fclose(pIn);
1556 }
1557
1558 void TransactionBeforOpenDB(bool getSysInfo, steady_clock::time_point &tick,
1559 vector<Entry> &data1, vector<Key> &keys, DistributedTestSysInfo &si)
1560 {
1561 if (!getSysInfo) {
1562 MST_LOG("[gen data]:%zu, %zu.", data1.size(), keys.size());
1563 tick = time_point_cast<microseconds>(steady_clock::now());
1564 } else {
1565 MST_LOG("System info before opening a db:");
1566 GetSysInfo(si, FIRST);
1567 }
1568 }
1569
1570 void TransactionAfterOpenDB(bool getSysInfo, steady_clock::time_point &tick,
1571 PerformanceData &performanceData, DistributedTestSysInfo &si)
1572 {
1573 if (!getSysInfo) {
1574 TickTock(tick, performanceData.openDuration);
1575 MST_LOG("[time calculator]open a new db cost %f us.", static_cast<double>(performanceData.openDuration));
1576 } else {
1577 MST_LOG("System info after opening db, or before inserting records of a transaction:");
1578 GetSysInfo(si, SECOND);
1579 si.SaveSecondToFirst();
1580 }
1581 }
1582
1583 void TransactionAfterPutData(steady_clock::time_point &tick, PerformanceData &performanceData,
1584 int keyLength, DistributedTestSysInfo &si)
1585 {
1586 bool getSysInfo = performanceData.getSysInfo;
1587 int putGetTimes = performanceData.putGetTimes;
1588 if (!getSysInfo) {
1589 if (!TickTock1(tick, putGetTimes, performanceData.putDuration)) {
1590 MST_LOG("[time calculator]put first [%d]keys,\tvalue[%dB-length],\tcost[%fus],\tper[%fus].",
1591 putGetTimes, keyLength, (performanceData.putDuration) * putGetTimes,
1592 performanceData.putDuration);
1593 }
1594 } else {
1595 MST_LOG("System info after inserting records of a transaction, or before querying records one by one:");
1596 GetSysInfo(si, SECOND);
1597 si.SaveSecondToFirst();
1598 }
1599 }
1600
1601 void TransactionAfterQueryPutData(steady_clock::time_point &tick, PerformanceData &performanceData,
1602 int keyLength, DistributedTestSysInfo &si)
1603 {
1604 bool getSysInfo = performanceData.getSysInfo;
1605 int putGetTimes = performanceData.putGetTimes;
1606 if (!getSysInfo) {
1607 if (!TickTock1(tick, putGetTimes, performanceData.readPutDuration)) {
1608 MST_LOG("[time calculator]get first [%d]keys,\tvalue[%dB-length],\tcost[%fus],\tper[%fus].",
1609 putGetTimes, keyLength, (performanceData.readPutDuration) * putGetTimes,
1610 performanceData.readPutDuration);
1611 }
1612 } else {
1613 MST_LOG("System info after querying records one by one, or before updating records in a transaction:");
1614 GetSysInfo(si, SECOND);
1615 si.SaveSecondToFirst();
1616 }
1617 }
1618
1619 void TransactionAfterUpdateData(steady_clock::time_point &tick, PerformanceData &performanceData,
1620 int keyLength, DistributedTestSysInfo &si)
1621 {
1622 bool getSysInfo = performanceData.getSysInfo;
1623 int putGetTimes = performanceData.putGetTimes;
1624 if (!getSysInfo) {
1625 if (!TickTock1(tick, putGetTimes, performanceData.updateDuration)) {
1626 MST_LOG("[time calculator]put second [%d]keys,\tvalue[%dB-length],\tcost[%fus],\tper[%fus].",
1627 putGetTimes, keyLength, (performanceData.updateDuration) * putGetTimes,
1628 performanceData.updateDuration);
1629 }
1630 } else {
1631 MST_LOG("System info after updating records in a transaction, or before updating records one by one:");
1632 GetSysInfo(si, SECOND);
1633 si.SaveSecondToFirst();
1634 }
1635 }
1636
1637 void TransactionAfterQueryUpdateData(steady_clock::time_point &tick, PerformanceData &performanceData,
1638 int keyLength, DistributedTestSysInfo &si)
1639 {
1640 bool getSysInfo = performanceData.getSysInfo;
1641 int putGetTimes = performanceData.putGetTimes;
1642 if (!getSysInfo) {
1643 if (!TickTock1(tick, putGetTimes, performanceData.readUpdateDuration)) {
1644 MST_LOG("[time calculator]get second [%d]keys,\tvalue[%dB-length],\tcost[%fus],\tper[%fus].",
1645 putGetTimes, keyLength, (performanceData.readUpdateDuration) * putGetTimes,
1646 performanceData.readUpdateDuration);
1647 }
1648 } else {
1649 MST_LOG("System info after updating records one by one, or before deleting records in a transaction:");
1650 GetSysInfo(si, SECOND);
1651 si.SaveSecondToFirst();
1652 }
1653 }
1654
1655 void TransactionAfterDeleteData(steady_clock::time_point &tick, PerformanceData &performanceData,
1656 int keyLength, DistributedTestSysInfo &si)
1657 {
1658 bool getSysInfo = performanceData.getSysInfo;
1659 int putGetTimes = performanceData.putGetTimes;
1660 if (!getSysInfo) {
1661 if (!TickTock1(tick, putGetTimes, performanceData.deleteDuration)) {
1662 MST_LOG("[time calculator]delete [%d]keys,\tvalue[%dB-length],\tcost[%fus],\tper[%fus].",
1663 putGetTimes, keyLength, (performanceData.deleteDuration) * putGetTimes,
1664 performanceData.deleteDuration);
1665 }
1666 } else {
1667 MST_LOG("System info after deleting records in a transaction, or before closing a db:");
1668 GetSysInfo(si, SECOND);
1669 si.SaveSecondToFirst();
1670 }
1671 }
1672
1673 void TransactionAfterCloseDB(steady_clock::time_point &tick, PerformanceData &performanceData,
1674 DistributedTestSysInfo &si)
1675 {
1676 bool getSysInfo = performanceData.getSysInfo;
1677 int putGetTimes = performanceData.putGetTimes;
1678 if (!getSysInfo) {
1679 if (!TickTock1(tick, putGetTimes, performanceData.closeDuration)) {
1680 MST_LOG("[time calculator]close a db cost %f us.", static_cast<double>(performanceData.closeDuration));
1681 }
1682 } else {
1683 MST_LOG("System info after closing a db:");
1684 GetSysInfo(si, SECOND);
1685 si.SaveSecondToFirst();
1686 }
1687 }
1688
1689 bool BeginTransaction1(vector<Entry> &data1, KvStoreDelegate *store1)
1690 {
1691 bool result = true;
1692 result = result && (store1->StartTransaction() == DBStatus::OK);
1693 for (auto entry = data1.begin(); entry != data1.end(); ++entry) {
1694 result = result && (DistributedTestTools::Put(*store1, entry->key, entry->value) == DBStatus::OK);
1695 }
1696 result = result && (store1->Commit() == DBStatus::OK);
1697 return result;
1698 }
1699
1700 bool BeginTransaction2(vector<Entry> &data1, KvStoreDelegate *store1, Value updateVal)
1701 {
1702 bool result = true;
1703 result = result && (store1->StartTransaction() == DBStatus::OK);
1704 for (auto entry = data1.begin(); entry != data1.end(); ++entry) {
1705 result = result && (DistributedTestTools::Put(*store1, entry->key, updateVal) == DBStatus::OK);
1706 }
1707 result = result && (store1->Commit() == DBStatus::OK);
1708 return result;
1709 }
1710
1711 bool BeginTransaction3(KvStoreDelegate *store1, vector<Key> &keys)
1712 {
1713 bool result = true;
1714 result = result && (store1->StartTransaction() == DBStatus::OK);
1715 for (auto key = keys.begin(); key != keys.end(); ++key) {
1716 result = result && (DistributedTestTools::Delete(*store1, *key) == DBStatus::OK);
1717 }
1718 result = result && (store1->Commit() == DBStatus::OK);
1719 return result;
1720 }
1721
1722 bool CheckSnapShot1(KvStoreSnapshotDelegate *snapShot, KvStoreDelegate *store1, vector<Key> &keys)
1723 {
1724 if (snapShot == nullptr) {
1725 return false;
1726 }
1727 for (auto key = keys.begin(); key != keys.end(); ++key) {
1728 Value valueResult = DistributedTestTools::Get(*snapShot, *key);
1729 }
1730 store1->ReleaseKvStoreSnapshot(snapShot);
1731 snapShot = nullptr;
1732 return true;
1733 }
1734
1735 bool CheckSnapShot2(KvStoreSnapshotDelegate *snapShot, KvStoreDelegate *store1, vector<Key> &keys)
1736 {
1737 snapShot = DistributedTestTools::GetKvStoreSnapshot(*store1);
1738 if (snapShot == nullptr) {
1739 return false;
1740 }
1741 for (auto key = keys.begin(); key != keys.end(); ++key) {
1742 Value valueResult = DistributedTestTools::Get(*snapShot, *key);
1743 }
1744 store1->ReleaseKvStoreSnapshot(snapShot);
1745 snapShot = nullptr;
1746 return true;
1747 }
1748
1749 bool CloseDB(KvStoreDelegateManager *manager, KvStoreDelegate *store1)
1750 {
1751 DBStatus status = manager->CloseKvStore(store1);
1752 if (status != DistributedDB::DBStatus::OK) {
1753 return false;
1754 }
1755 store1 = nullptr;
1756 status = manager->DeleteKvStore(STORE_ID_PERFORM);
1757 if (status != DistributedDB::DBStatus::OK) {
1758 return false;
1759 }
1760 delete manager;
1761 manager = nullptr;
1762 return true;
1763 }
1764
1765 bool DistributedTestTools::CalculateTransactionPerformance(PerformanceData &performanceData)
1766 {
1767 int putGetTimes = performanceData.putGetTimes;
1768 int keyLength = performanceData.keyLength;
1769 int valueLength = performanceData.valueLength;
1770 bool getSysInfo = performanceData.getSysInfo;
1771 DistributedTestSysInfo si;
1772 steady_clock::time_point tick;
1773 vector<Entry> data1 = GenRanKeyVal(putGetTimes, keyLength, valueLength, 'a');
1774 vector<Key> keys = GetKeysFromEntries(data1, false);
1775 Value updateVal;
1776 updateVal.assign(valueLength, 'b');
1777 TransactionBeforOpenDB(getSysInfo, tick, data1, keys, si);
1778 // print the opened time.
1779 KvStoreDelegate *store1 = nullptr;
1780 KvStoreDelegateManager *manager = nullptr;
1781 KvOption option = g_kvOption;
1782 option.localOnly = performanceData.isLocal;
1783 store1 = GetDelegateSuccess(manager, KVDB_PARAMETER_PERFORM, option);
1784 if (store1 == nullptr) {
1785 return false;
1786 }
1787 TransactionAfterOpenDB(getSysInfo, tick, performanceData, si);
1788 // print the insert time.
1789 BeginTransaction1(data1, store1);
1790 TransactionAfterPutData(tick, performanceData, keyLength, si);
1791 // print the get time.
1792 KvStoreSnapshotDelegate *snapShot;
1793 snapShot = DistributedTestTools::GetKvStoreSnapshot(*store1);
1794 if (!(CheckSnapShot1(snapShot, store1, keys))) {
1795 return false;
1796 }
1797 TransactionAfterQueryPutData(tick, performanceData, keyLength, si);
1798 // print the update time.
1799 BeginTransaction2(data1, store1, updateVal);
1800 TransactionAfterUpdateData(tick, performanceData, keyLength, si);
1801 // print the get time.
1802 if (!(CheckSnapShot2(snapShot, store1, keys))) {
1803 return false;
1804 }
1805 TransactionAfterQueryUpdateData(tick, performanceData, keyLength, si);
1806 BeginTransaction3(store1, keys);
1807 TransactionAfterDeleteData(tick, performanceData, keyLength, si);
1808 // close the base db
1809 if (!(CloseDB(manager, store1))) {
1810 return false;
1811 }
1812 TransactionAfterCloseDB(tick, performanceData, si);
1813 return true;
1814 }
1815
1816 KvStoreSnapshotDelegate *DistributedTestTools::RegisterSnapObserver(KvStoreDelegate *delegate,
1817 KvStoreObserver *observer)
1818 {
1819 DelegateCallback delegateCallback;
1820 function<void(DBStatus, KvStoreSnapshotDelegate *)> callFunction
1821 = bind(&DelegateCallback::Callback, &delegateCallback, _1, _2);
1822
1823 delegate->GetKvStoreSnapshot(observer, callFunction);
1824 DBStatus status = delegateCallback.GetStatus();
1825 if (status != DBStatus::OK) {
1826 MST_LOG("%s Get failed! Status= %d", TAG.c_str(), status);
1827 return nullptr;
1828 }
1829
1830 KvStoreSnapshotDelegate *snapshot
1831 = const_cast<KvStoreSnapshotDelegate *>(delegateCallback.GetKvStoreSnapshot());
1832 if (snapshot == nullptr) {
1833 MST_LOG("%s Get snapshot null! Status= %d", TAG.c_str(), status);
1834 return nullptr;
1835 }
1836 return snapshot;
1837 }
1838
1839 DBStatus DistributedTestTools::RegisterObserver(KvStoreDelegate *delegate, KvStoreObserver *observer)
1840 {
1841 return delegate->RegisterObserver(observer);
1842 }
1843
1844 DBStatus DistributedTestTools::UnRegisterObserver(KvStoreDelegate *delegate, KvStoreObserver *observer)
1845 {
1846 return delegate->UnRegisterObserver(observer);
1847 }
1848
1849 KvStoreDelegate::Option DistributedTestTools::TransferKvOptionType(const KvOption &optionParam)
1850 {
1851 KvStoreDelegate::Option option;
1852 option.createIfNecessary = optionParam.createIfNecessary;
1853 option.localOnly = optionParam.localOnly;
1854 option.isEncryptedDb = optionParam.isEncryptedDb;
1855 option.cipher = optionParam.cipher;
1856 (void)option.passwd.SetValue(optionParam.passwd.data(), optionParam.passwd.size());
1857 return option;
1858 }
1859
1860 std::string TransferStringToHashHexString(const std::string &origStr)
1861 {
1862 SHA256_CTX context;
1863 SHA256_Init(&context);
1864 SHA256_Update(&context, origStr.data(), origStr.size());
1865 std::vector<uint8_t> hashVect(SHA256_DIGEST_LENGTH, 0);
1866 SHA256_Final(hashVect.data(), &context);
1867
1868 const char *hex = "0123456789abcdef";
1869 std::string tmp;
1870 for (size_t i = 0; i < SHA256_DIGEST_LENGTH; i++) {
1871 tmp.push_back(hex[hashVect[i] >> 4]); // high 4 bit to one hex.
1872 tmp.push_back(hex[hashVect[i] & 0x0F]); // low 4 bit to one hex.
1873 }
1874 return tmp;
1875 }
1876
1877 #if defined(RUNNING_ON_LINUX)
1878 int RemoveDatabaseDirectory(const std::string &directory)
1879 {
1880 #ifdef DB_DEBUG_ENV
1881 MST_LOG("---> remove db directory: %s", directory.c_str());
1882 #endif
1883 return remove(directory.c_str());
1884 }
1885 #else
1886 int RemoveDatabaseDirectory(const std::string &directory)
1887 {
1888 return rmdir(directory.c_str());
1889 }
1890 #endif
1891
1892 bool VerifyObserverResult(const KvStoreObserverImpl &pObserver,
1893 int changedTimes, ListType type, const list<Entry> &lst, uint32_t timeout)
1894 {
1895 MST_LOG("[VerifyObserverResult] pObserver.GetCumulatedFlag() = %d, pObserver.GetChanged() = %d, type = %d",
1896 pObserver.GetCumulatedFlag(), pObserver.GetChanged(), type);
1897 if (pObserver.GetCumulatedFlag()) {
1898 int expectListSize = lst.size();
1899 pObserver.WaitUntilReachRecordCount(expectListSize, type, timeout);
1900 } else {
1901 pObserver.WaitUntilReachChangeCount(changedTimes, timeout);
1902 }
1903
1904 list<Entry> retLst;
1905 if (pObserver.GetCumulatedFlag()) {
1906 if (type == INSERT_LIST) {
1907 MST_LOG("type == INSERT_LIST");
1908 retLst = pObserver.GetCumulatedInsertList();
1909 } else if (type == UPDATE_LIST) {
1910 MST_LOG("type == UPDATE_LIST");
1911 retLst = pObserver.GetCumulatedUpdateList();
1912 } else {
1913 MST_LOG("type == DELETE_LIST");
1914 retLst = pObserver.GetCumulatedDeleteList();
1915 }
1916 } else {
1917 if (type == INSERT_LIST) {
1918 MST_LOG("type == INSERT_LIST");
1919 retLst = pObserver.GetInsertList();
1920 } else if (type == UPDATE_LIST) {
1921 MST_LOG("type == UPDATE_LIST");
1922 retLst = pObserver.GetUpdateList();
1923 } else {
1924 MST_LOG("type == DELETE_LIST");
1925 retLst = pObserver.GetDeleteList();
1926 }
1927 }
1928
1929 bool result = true;
1930 vector<Entry> retVec(retLst.begin(), retLst.end());
1931 vector<Entry> expectVec(lst.begin(), lst.end());
1932 result = CompareEntriesVector(retVec, expectVec);
1933 MST_LOG("VerifyObserverResult CompareEntriesVector result is %d", result);
1934 return result;
1935 }
1936
1937 bool VerifyObserverResult(const KvStoreObserverImpl &pObserver, int changedTimes, ListType type,
1938 const vector<Entry> &vec, uint32_t timeout)
1939 {
1940 list<Entry> entriesList(vec.begin(), vec.end());
1941 return VerifyObserverResult(pObserver, changedTimes, type, entriesList, timeout);
1942 }
1943
1944 bool VerifyObserverForSchema(const KvStoreObserverImpl &pObserver,
1945 int changedTimes, ListType type, const vector<Entry> &expectEntry, uint32_t timeout)
1946 {
1947 MST_LOG("[VerifyObserverForSchema] pObserver.GetCumulatedFlag() = %d, pObserver.GetChanged() = %d, type = %d",
1948 pObserver.GetCumulatedFlag(), pObserver.GetChanged(), type);
1949 if (pObserver.GetCumulatedFlag()) {
1950 int expectListSize = expectEntry.size();
1951 pObserver.WaitUntilReachRecordCount(expectListSize, type, timeout);
1952 } else {
1953 pObserver.WaitUntilReachChangeCount(changedTimes, timeout);
1954 }
1955
1956 list<Entry> retLst;
1957 if (pObserver.GetCumulatedFlag()) {
1958 if (type == INSERT_LIST) {
1959 MST_LOG("type == INSERT_LIST");
1960 retLst = pObserver.GetCumulatedInsertList();
1961 } else if (type == UPDATE_LIST) {
1962 MST_LOG("type == UPDATE_LIST");
1963 retLst = pObserver.GetCumulatedUpdateList();
1964 } else {
1965 MST_LOG("type == DELETE_LIST");
1966 retLst = pObserver.GetCumulatedDeleteList();
1967 }
1968 } else {
1969 if (type == INSERT_LIST) {
1970 MST_LOG("type == INSERT_LIST");
1971 retLst = pObserver.GetInsertList();
1972 } else if (type == UPDATE_LIST) {
1973 MST_LOG("type == UPDATE_LIST");
1974 retLst = pObserver.GetUpdateList();
1975 } else {
1976 MST_LOG("type == DELETE_LIST");
1977 retLst = pObserver.GetDeleteList();
1978 }
1979 }
1980
1981 vector<Entry> retVec(retLst.begin(), retLst.end());
1982 if (retVec.size() != expectEntry.size()) {
1983 MST_LOG("[VerifyObserverForSchema] the expect value size is not equal to the retVec size and return");
1984 return false;
1985 }
1986
1987 for (uint64_t index = 0; index < expectEntry.size(); index++) {
1988 bool result = ((retVec[index].key == expectEntry[index].key) &&
1989 (retVec[index].value == expectEntry[index].value));
1990 if (!result) {
1991 MST_LOG("[VerifyObserverForSchema] compare list failed at the position: %llu", ULL(index));
1992 return false;
1993 }
1994 }
1995 return true;
1996 }