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 "distributeddb_nb_test_tools.h"
16 #include <fstream>
17
18 #if defined(RUNNING_ON_LINUX)
19 #include <unistd.h>
20 #elif defined RUNNING_ON_WIN
21 #include <windows.h>
22 #endif
23
24 #ifndef USING_SQLITE_SYMBOLS
25 #include "sqlite3.h"
26 #else
27 #include "sqlite3sym.h"
28 #endif
29 using namespace std;
30 using namespace std::placeholders;
31 using namespace DistributedDB;
32 using namespace DistributedDBDataGenerator;
33
Callback(DBStatus status,KvStoreNbDelegate * kvStoreNbDelegate)34 void DelegateMgrNbCallback::Callback(DBStatus status, KvStoreNbDelegate *kvStoreNbDelegate)
35 {
36 this->status_ = status;
37 this->kvStoreNbDelegate_ = kvStoreNbDelegate;
38 MST_LOG("DelegateMgrNbCallback status:%d, kvStoreNbDelegate_null: %d", status, (kvStoreNbDelegate == nullptr));
39 }
40
GetStatus()41 DBStatus DelegateMgrNbCallback::GetStatus()
42 {
43 return status_;
44 }
45
GetKvStore()46 KvStoreNbDelegate *DelegateMgrNbCallback::GetKvStore()
47 {
48 return kvStoreNbDelegate_;
49 }
50
GetNbDelegateSuccess(KvStoreDelegateManager * & outManager,const DBParameters & param,const Option & optionParam,const string & dbPath)51 KvStoreNbDelegate* DistributedDBNbTestTools::GetNbDelegateSuccess(KvStoreDelegateManager *&outManager,
52 const DBParameters ¶m, const Option &optionParam, const string &dbPath)
53 {
54 MST_LOG("GetNbDelegate isMemoryDb= %d, isEncryptedDb= %d", optionParam.isMemoryDb,
55 optionParam.isEncryptedDb);
56 SetDir(dbPath);
57 if (param.storeId.empty() || param.appId.empty() || param.userId.empty()) {
58 return nullptr;
59 }
60
61 // define a Callback to hold the KvStoreNbDelegate and status.
62 DelegateMgrNbCallback delegateMgrCallback;
63 function<void(DBStatus, KvStoreNbDelegate*)> function
64 = bind(&DelegateMgrNbCallback::Callback, &delegateMgrCallback, _1, _2);
65
66 // use appid and userid to initialize a kvStoreDelegateManager, and set the default cfg.
67 if (outManager != nullptr) {
68 delete outManager;
69 outManager = nullptr;
70 }
71 KvStoreDelegateManager *manager = new (std::nothrow) KvStoreDelegateManager(param.appId, param.userId);
72 if (manager == nullptr) {
73 return nullptr;
74 }
75 DBStatus status = manager->SetKvStoreConfig({ .dataDir = dbPath});
76 if (status != DBStatus::OK) {
77 MST_LOG("%s SetConfig failed! Status= %d", TAG.c_str(), status);
78 delete manager;
79 manager = nullptr;
80 return nullptr;
81 }
82
83 KvStoreNbDelegate::Option option = TransferNbOptionType(optionParam);
84 // get kv store, then the Callback will save the status and delegate.
85 manager->GetKvStore(param.storeId, option, function);
86 status = delegateMgrCallback.GetStatus();
87 if (status != DBStatus::OK) {
88 MST_LOG("%s GetKvStore failed! Status= %d", TAG.c_str(), status);
89 delete manager;
90 manager = nullptr;
91 return nullptr;
92 }
93 const KvStoreNbDelegate* delegate = const_cast<KvStoreNbDelegate *>(delegateMgrCallback.GetKvStore());
94 if (delegate == nullptr) {
95 MST_LOG("%s GetKvStore failed! delegate nullptr.", TAG.c_str());
96 delete manager;
97 manager = nullptr;
98 return nullptr;
99 }
100
101 MST_LOG("%s GetKvStore success: %s %s %s %d", TAG.c_str(),
102 param.storeId.c_str(), param.appId.c_str(), param.userId.c_str(), option.createIfNecessary);
103 outManager = manager;
104 return const_cast<KvStoreNbDelegate *>(delegate);
105 }
106
GetNbDelegateStatus(KvStoreDelegateManager * & outManager,DBStatus & statusReturn,const DBParameters & param,const Option & optionParam)107 KvStoreNbDelegate* DistributedDBNbTestTools::GetNbDelegateStatus(KvStoreDelegateManager *&outManager,
108 DBStatus &statusReturn, const DBParameters ¶m, const Option &optionParam)
109 {
110 MST_LOG("GetNbDelegate isMemoryDb= %d, isEncryptedDb= %d", optionParam.isMemoryDb,
111 optionParam.isEncryptedDb);
112 SetDir(DistributedDBConstant::NB_DIRECTOR);
113 if (param.storeId.empty() || param.appId.empty() || param.userId.empty()) {
114 return nullptr;
115 }
116
117 // define a Callback to hold the KvStoreNbDelegate and status.
118 DelegateMgrNbCallback delegateMgrCallback;
119 function<void(DBStatus, KvStoreNbDelegate*)> function
120 = bind(&DelegateMgrNbCallback::Callback, &delegateMgrCallback, _1, _2);
121
122 // use appid and userid to initialize a kvStoreDelegateManager, and set the default cfg.
123 if (outManager != nullptr) {
124 delete outManager;
125 outManager = nullptr;
126 }
127 KvStoreDelegateManager *manager1 = new (std::nothrow) KvStoreDelegateManager(param.appId, param.userId);
128 if (manager1 == nullptr) {
129 return nullptr;
130 }
131 statusReturn = manager1->SetKvStoreConfig({ .dataDir = DistributedDBConstant::NB_DIRECTOR });
132 if (statusReturn != DBStatus::OK) {
133 MST_LOG("%s SetConfig failed! Status= %d", TAG.c_str(), statusReturn);
134 delete manager1;
135 manager1 = nullptr;
136 return nullptr;
137 }
138
139 KvStoreNbDelegate::Option option = TransferNbOptionType(optionParam);
140 // get kv store, then the Callback will save the status and delegate.
141 manager1->GetKvStore(param.storeId, option, function);
142 statusReturn = delegateMgrCallback.GetStatus();
143 if (statusReturn != DBStatus::OK) {
144 MST_LOG("%s GetKvStore failed! Status= %d", TAG.c_str(), statusReturn);
145 delete manager1;
146 manager1 = nullptr;
147 return nullptr;
148 }
149 const KvStoreNbDelegate* delegate = const_cast<KvStoreNbDelegate *>(delegateMgrCallback.GetKvStore());
150 if (delegate == nullptr) {
151 MST_LOG("%s GetKvStore failed! delegate nullptr.", TAG.c_str());
152 delete manager1;
153 manager1 = nullptr;
154 return nullptr;
155 }
156
157 MST_LOG("%s GetKvStore success: %s %s %s %d", TAG.c_str(),
158 param.storeId.c_str(), param.appId.c_str(), param.userId.c_str(), option.createIfNecessary);
159 outManager = manager1;
160 return const_cast<KvStoreNbDelegate *>(delegate);
161 }
162
GetNbDelegateStoresSuccess(KvStoreDelegateManager * & outManager,vector<KvStoreNbDelegate * > & outDelegateVec,const vector<string> & storeIds,const string & appId,const string & userId,const Option & optionParam)163 DBStatus DistributedDBNbTestTools::GetNbDelegateStoresSuccess(KvStoreDelegateManager *&outManager,
164 vector<KvStoreNbDelegate *> &outDelegateVec,
165 const vector<string> &storeIds, const string &appId, const string &userId, const Option &optionParam)
166 {
167 SetDir(DistributedDBConstant::NB_DIRECTOR);
168 unsigned long opCnt;
169 DBStatus status = DBStatus::OK;
170 for (opCnt = 0; opCnt < storeIds.size(); ++opCnt) {
171 if (storeIds[opCnt].empty() || appId.empty() || userId.empty()) {
172 return INVALID_ARGS;
173 }
174 }
175
176 // use appid and userid to initialize a kvStoreDelegateManager, and set the default cfg.
177 KvStoreDelegateManager *manager = new (std::nothrow) KvStoreDelegateManager(appId, userId);
178 if (manager == nullptr) {
179 return DBStatus::DB_ERROR;
180 }
181 outDelegateVec.clear();
182 KvStoreNbDelegate::Option option = TransferNbOptionType(optionParam);
183 for (opCnt = 0; opCnt < storeIds.size(); ++opCnt) {
184 // define a Callback to hold the KvStoreNbDelegate and status.
185 DelegateMgrNbCallback delegateMgrCallback;
186 function<void(DBStatus, KvStoreNbDelegate*)> function
187 = bind(&DelegateMgrNbCallback::Callback, &delegateMgrCallback, _1, _2);
188
189 status = manager->SetKvStoreConfig(DistributedDBConstant::CONFIG);
190 if (status != DBStatus::OK) {
191 MST_LOG("%s SetConfig failed! Status= %d", TAG.c_str(), status);
192 goto END;
193 }
194
195 // get kv store, then the Callback will save the status and delegate.
196 manager->GetKvStore(storeIds[opCnt], option, function);
197 status = delegateMgrCallback.GetStatus();
198 if (status != DBStatus::OK) {
199 MST_LOG("%s GetKvStore failed! Status= %d", TAG.c_str(), status);
200 goto END;
201 }
202 const KvStoreNbDelegate *delegate = const_cast<KvStoreNbDelegate *>(delegateMgrCallback.GetKvStore());
203 if (delegate == nullptr) {
204 MST_LOG("%s GetKvStore failed! delegate nullptr.", TAG.c_str());
205 goto END;
206 }
207 outDelegateVec.push_back(const_cast<KvStoreNbDelegate *>(delegate));
208 }
209 outManager = manager;
210 return OK;
211 END:
212 delete manager;
213 manager = nullptr;
214 return status;
215 }
216
TransferNbOptionType(const Option & optionParam)217 KvStoreNbDelegate::Option DistributedDBNbTestTools::TransferNbOptionType(const Option &optionParam)
218 {
219 KvStoreNbDelegate::Option option;
220 option.createIfNecessary = optionParam.createIfNecessary;
221 option.isMemoryDb = optionParam.isMemoryDb;
222 option.isEncryptedDb = optionParam.isEncryptedDb;
223 option.cipher = optionParam.cipher;
224 #ifdef RELEASE_MODE_V2
225 option.schema = optionParam.schema;
226 #endif // endif of RELEASE_MODE_V2
227 (void)option.passwd.SetValue(optionParam.passwd.data(), optionParam.passwd.size());
228 #ifdef RELEASE_MODE_V3
229 option.secOption.securityLabel = optionParam.secOption.securityLabel;
230 option.secOption.securityFlag = optionParam.secOption.securityFlag;
231 option.observer = optionParam.observer;
232 option.key = optionParam.key;
233 option.mode = optionParam.mode;
234 option.conflictType = optionParam.conflictType;
235 option.notifier = optionParam.notifier;
236 option.conflictResolvePolicy = optionParam.conflictResolvePolicy;
237 option.isNeedIntegrityCheck = optionParam.isNeedIntegrityCheck;
238 option.isNeedRmCorruptedDb = optionParam.isNeedRmCorruptedDb;
239 option.isNeedCompressOnSync = optionParam.isNeedCompressOnSync;
240 option.compressionRate = optionParam.compressionRate;
241 #endif // end of RELEASE_MODE_V3
242 return option;
243 }
244
245 // this static method is to compare if the two Value has the same data.
isValueEquals(const DistributedDB::Value & v1,const DistributedDB::Value & v2)246 bool DistributedDBNbTestTools::isValueEquals(const DistributedDB::Value &v1, const DistributedDB::Value &v2)
247 {
248 // just return false if the sizes are not the same.
249 if (v1.size() != v2.size()) {
250 return false;
251 }
252
253 // compare two Values char by char.
254 return v1 == v2;
255 }
256
Get(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const DistributedDB::Key & key,DistributedDB::Value & value)257 DistributedDB::DBStatus DistributedDBNbTestTools::Get(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
258 const DistributedDB::Key &key, DistributedDB::Value &value)
259 {
260 return kvStoreNbDelegate.Get(key, value);
261 }
262
GetEntries(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const DistributedDB::Key & keyPrefix,std::vector<DistributedDB::Entry> & entries)263 DistributedDB::DBStatus DistributedDBNbTestTools::GetEntries(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
264 const DistributedDB::Key &keyPrefix, std::vector<DistributedDB::Entry> &entries)
265 {
266 return kvStoreNbDelegate.GetEntries(keyPrefix, entries);
267 }
268
Put(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const DistributedDB::Key & key,const DistributedDB::Value & value,bool isNeedRetry,int waitTime)269 DistributedDB::DBStatus DistributedDBNbTestTools::Put(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
270 const DistributedDB::Key &key, const DistributedDB::Value &value, bool isNeedRetry, int waitTime)
271 {
272 if (isNeedRetry) {
273 DBStatus status = kvStoreNbDelegate.Put(key, value);
274 if (status != OK && waitTime-- > 0) {
275 MST_LOG("put records status: %d, and retry!", status);
276 return DistributedDBNbTestTools::Put(kvStoreNbDelegate, key, value, isNeedRetry, waitTime);
277 } else {
278 return status;
279 }
280 }
281 return kvStoreNbDelegate.Put(key, value);
282 }
283
PutBatch(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const std::vector<DistributedDB::Entry> & entries,bool isNeedRetry)284 DistributedDB::DBStatus DistributedDBNbTestTools::PutBatch(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
285 const std::vector<DistributedDB::Entry> &entries, bool isNeedRetry)
286 {
287 #ifdef RELEASE_MODE_V2
288 DistributedDB::DBStatus status;
289 for (int cnt = 0; cnt < static_cast<int>(entries.size()); cnt += 128) { // 128 is the max records of deleteBatch.
290 auto last = std::min(static_cast<int>(entries.size()), cnt + 128); // 128 is the max records of deleteBatch.
291 std::vector<DistributedDB::Entry> entriesBatch(entries.begin() + cnt, entries.begin() + last);
292
293 int retryTimes = 1000;
294 do {
295 status = kvStoreNbDelegate.PutBatch(entriesBatch);
296 if (status == OK) {
297 break;
298 } else if (status != BUSY && status != OK) {
299 return status;
300 }
301 } while (isNeedRetry && retryTimes-- > 0);
302 }
303 return status;
304 #else
305 MST_LOG("[DistributedDBNbTestTools::PutBatch] is NeedRetry is %d", isNeedRetry);
306 DBStatus status;
307 for (const auto &iter : entries) {
308 status = kvStoreNbDelegate.Put(iter.key, iter.value);
309 if (status != OK) {
310 return status;
311 }
312 }
313 return DBStatus::OK;
314 #endif // endif of RELEASE_MODE_V2
315 }
316
Delete(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const DistributedDB::Key & key)317 DistributedDB::DBStatus DistributedDBNbTestTools::Delete(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
318 const DistributedDB::Key &key)
319 {
320 return kvStoreNbDelegate.Delete(key);
321 }
322
DeleteBatch(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const std::vector<DistributedDB::Key> & keys,bool isNeedRetry)323 DistributedDB::DBStatus DistributedDBNbTestTools::DeleteBatch(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
324 const std::vector<DistributedDB::Key> &keys, bool isNeedRetry)
325 {
326 #ifdef RELEASE_MODE_V2
327 DistributedDB::DBStatus status;
328 for (int cnt = 0; cnt < static_cast<int>(keys.size()); cnt = cnt + 128) { // 128 is the max records of deleteBatch.
329 auto last = std::min(static_cast<int>(keys.size()), cnt + 128); // 128 is the max records of deleteBatch.
330 std::vector<DistributedDB::Key> keysBatch(keys.begin() + cnt, keys.begin() + last);
331
332 int retryTimes = 1000;
333 do {
334 status = kvStoreNbDelegate.DeleteBatch(keysBatch);
335 if (status == OK) {
336 break;
337 } else if (status != BUSY && status != OK) {
338 return status;
339 }
340 } while (isNeedRetry && retryTimes-- > 0);
341 }
342 return status;
343 #else
344 MST_LOG("[DistributedDBNbTestTools::DeleteBatch] is NeedRetry is %d", isNeedRetry);
345 DBStatus status;
346 for (const auto &iter : keys) {
347 status = kvStoreNbDelegate.Delete(iter);
348 if (status != OK) {
349 return status;
350 }
351 }
352 return DBStatus::OK;
353 #endif // endif of RELEASE_MODE_V2
354 }
355
GetLocal(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const DistributedDB::Key & key,DistributedDB::Value & value)356 DistributedDB::DBStatus DistributedDBNbTestTools::GetLocal(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
357 const DistributedDB::Key &key, DistributedDB::Value &value)
358 {
359 return kvStoreNbDelegate.GetLocal(key, value);
360 }
361
PutLocal(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const DistributedDB::Key & key,const DistributedDB::Value & value,bool isNeedRetry,int waitTime)362 DistributedDB::DBStatus DistributedDBNbTestTools::PutLocal(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
363 const DistributedDB::Key &key, const DistributedDB::Value &value, bool isNeedRetry, int waitTime)
364 {
365 if (isNeedRetry) {
366 DBStatus status = kvStoreNbDelegate.PutLocal(key, value);
367 if (status != OK && waitTime-- > 0) {
368 MST_LOG("PutLocal records status: %d, and retry!", status);
369 return DistributedDBNbTestTools::PutLocal(kvStoreNbDelegate, key, value, isNeedRetry, waitTime);
370 } else {
371 return status;
372 }
373 }
374 return kvStoreNbDelegate.PutLocal(key, value);
375 }
376
PutLocalBatch(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const std::vector<DistributedDB::Entry> & entries)377 DistributedDB::DBStatus DistributedDBNbTestTools::PutLocalBatch(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
378 const std::vector<DistributedDB::Entry> &entries)
379 {
380 #ifdef RELEASE_MODE_V3
381 int cnt = 0;
382 std::vector<DistributedDB::Entry> entriesBatch;
383 DistributedDB::DBStatus status;
384 for (const auto &iter : entries) {
385 entriesBatch.push_back(iter);
386 cnt++;
387 if (cnt % BATCH_RECORDS == 0 || cnt == static_cast<int>(entries.size())) {
388 status = kvStoreNbDelegate.PutLocalBatch(entriesBatch);
389 if (status != DBStatus::OK) {
390 return status;
391 }
392 entriesBatch.clear();
393 }
394 }
395 return DBStatus::OK;
396 #else
397 DistributedDB::DBStatus status;
398 for (auto entry : entries) {
399 status = kvStoreNbDelegate.PutLocal(entry.key, entry.value);
400 if (status != DBStatus::OK) {
401 return status;
402 }
403 }
404 return DBStatus::OK;
405 #endif
406 }
407
DeleteLocal(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const DistributedDB::Key & key)408 DistributedDB::DBStatus DistributedDBNbTestTools::DeleteLocal(
409 DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate, const DistributedDB::Key &key)
410 {
411 return kvStoreNbDelegate.DeleteLocal(key);
412 }
413
DeleteLocalBatch(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const std::vector<DistributedDB::Key> & keys)414 DistributedDB::DBStatus DistributedDBNbTestTools::DeleteLocalBatch(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
415 const std::vector<DistributedDB::Key> &keys)
416 {
417 #ifdef RELEASE_MODE_V3
418 int cnt = 0;
419 std::vector<DistributedDB::Key> keysBatch;
420 DistributedDB::DBStatus status;
421 for (const auto &iter : keys) {
422 keysBatch.push_back(iter);
423 cnt++;
424 if (cnt % BATCH_RECORDS == 0 || cnt == static_cast<int>(keys.size())) {
425 status = kvStoreNbDelegate.DeleteLocalBatch(keysBatch);
426 if (status != DBStatus::OK) {
427 return status;
428 }
429 keysBatch.clear();
430 }
431 }
432 return DBStatus::OK;
433 #else
434 DistributedDB::DBStatus status;
435 for (auto key : keys) {
436 status = kvStoreNbDelegate.DeleteLocal(key);
437 if (status != DBStatus::OK) {
438 return status;
439 }
440 }
441 return DBStatus::OK;
442 #endif
443 }
444
RegisterObserver(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const DistributedDB::Key & key,unsigned int mode,DistributedDB::KvStoreObserver * observer)445 DistributedDB::DBStatus DistributedDBNbTestTools::RegisterObserver(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
446 const DistributedDB::Key &key, unsigned int mode, DistributedDB::KvStoreObserver *observer)
447 {
448 return kvStoreNbDelegate.RegisterObserver(key, mode, observer);
449 }
450
UnRegisterObserver(DistributedDB::KvStoreNbDelegate & kvStoreNbDelegate,const DistributedDB::KvStoreObserver * observer)451 DistributedDB::DBStatus DistributedDBNbTestTools::UnRegisterObserver(
452 DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate, const DistributedDB::KvStoreObserver *observer)
453 {
454 return kvStoreNbDelegate.UnRegisterObserver(observer);
455 }
456
CloseNbAndRelease(KvStoreDelegateManager * & manager,KvStoreNbDelegate * & delegate)457 bool DistributedDBNbTestTools::CloseNbAndRelease(KvStoreDelegateManager *&manager, KvStoreNbDelegate *&delegate)
458 {
459 bool result = true;
460 if (delegate != nullptr && manager != nullptr) {
461 result = (manager->CloseKvStore(delegate) == OK);
462 delegate = nullptr;
463 delete manager;
464 manager = nullptr;
465 } else {
466 MST_LOG("Close Failed");
467 return false;
468 }
469 return result;
470 }
471
EndCaseDeleteDB(DistributedDB::KvStoreDelegateManager * & manager,DistributedDB::KvStoreNbDelegate * & nbDelegate,const std::string base,bool isMemoryDb)472 bool EndCaseDeleteDB(DistributedDB::KvStoreDelegateManager *&manager,
473 DistributedDB::KvStoreNbDelegate *&nbDelegate, const std::string base, bool isMemoryDb)
474 {
475 bool isResult = true;
476 isResult = (manager->CloseKvStore(nbDelegate) == OK);
477 MST_LOG("CloseKvStore result:%d", isResult);
478 nbDelegate = nullptr;
479
480 if (!isMemoryDb) {
481 isResult = isResult && (manager->DeleteKvStore(base) == OK);
482 }
483 MST_LOG("DeleteKvStore result:%d", isResult);
484 delete manager;
485 manager = nullptr;
486 return isResult;
487 }
488
NotifyCallBack(const DistributedDB::KvStoreNbConflictData & data,std::vector<ConflictData> * & conflictData)489 void ConflictNbCallback::NotifyCallBack(const DistributedDB::KvStoreNbConflictData &data,
490 std::vector<ConflictData> *&conflictData)
491 {
492 MST_LOG("[ConflictCallback] Calling CallBack...");
493 Key key;
494 Value oldValue;
495 Value newValue;
496 data.GetKey(key);
497 data.GetValue(KvStoreNbConflictData::ValueType::OLD_VALUE, oldValue);
498 data.GetValue(KvStoreNbConflictData::ValueType::NEW_VALUE, newValue);
499 conflictData->push_back({data.GetType(), key, oldValue, newValue,
500 data.IsDeleted(KvStoreNbConflictData::ValueType::OLD_VALUE),
501 data.IsDeleted(KvStoreNbConflictData::ValueType::NEW_VALUE),
502 data.IsNative(KvStoreNbConflictData::ValueType::OLD_VALUE),
503 data.IsNative(KvStoreNbConflictData::ValueType::NEW_VALUE)});
504 }
505
ModifyDatabaseFile(const std::string & fileDir)506 bool DistributedDBNbTestTools::ModifyDatabaseFile(const std::string &fileDir)
507 {
508 MST_LOG("Modify file:%s", fileDir.c_str());
509 std::fstream dataFile(fileDir, std::fstream::binary | std::fstream::out | std::fstream::in);
510 if (!dataFile.is_open()) {
511 MST_LOG("Open the database file failed");
512 return false;
513 }
514
515 if (!dataFile.seekg(0, std::fstream::end)) {
516 return false;
517 }
518
519 uint64_t fileSize;
520 std::ios::pos_type pos = dataFile.tellg();
521 if (pos < 0) {
522 return false;
523 } else {
524 fileSize = static_cast<uint64_t>(pos);
525 if (fileSize < 1024) { // the least page size is 1024 bytes.
526 MST_LOG("Invalid database file:%lld.", static_cast<long long>(fileSize));
527 return false;
528 }
529 }
530
531 uint32_t currentCount = 0x1F1F1F1F; // add the random value to corrupt the head.
532 if (!dataFile.seekp(0)) {
533 return false;
534 }
535 for (uint32_t i = 0; i < pos / sizeof(uint32_t); i++) {
536 if (!dataFile.write(reinterpret_cast<char *>(¤tCount), sizeof(uint32_t))) {
537 return false;
538 }
539 }
540 dataFile.flush();
541 dataFile.close();
542 return true;
543 }
GetKvNbStoreDirectory(const DBParameters & param,const std::string & dbFilePath,const std::string & dbDir)544 std::string DistributedDBNbTestTools::GetKvNbStoreDirectory(const DBParameters ¶m, const std::string &dbFilePath,
545 const std::string &dbDir)
546 {
547 std::string identifier = param.userId + "-" + param.appId + "-" + param.storeId;
548 std::string identifierName = TransferStringToHashHexString(identifier);
549 std::string filePath = dbDir + identifierName + "/" + dbFilePath;
550 return filePath;
551 }
MoveToNextFromBegin(KvStoreResultSet & resultSet,const vector<DistributedDB::Entry> & entries,int recordCnt)552 bool DistributedDBNbTestTools::MoveToNextFromBegin(KvStoreResultSet &resultSet,
553 const vector<DistributedDB::Entry> &entries, int recordCnt)
554 {
555 bool result = (static_cast<int>(entries.size()) >= recordCnt);
556 if (!result) {
557 MST_LOG("entries.size()) < recordCnt!!!");
558 return result;
559 }
560 Entry entry;
561 int positionGot;
562 for (int position = -1; position < recordCnt; ++position) { // the first pos after getentries is -1.
563 bool expectRes = resultSet.MoveToNext();
564 if (position < (recordCnt - 1)) {
565 result = result && expectRes;
566 } else {
567 result = result && (!expectRes);
568 }
569 if (!result) {
570 MST_LOG("resultSet.MoveToNext() doesn't meet expectations!!!");
571 break;
572 }
573 positionGot = position + 1;
574 result = result && (resultSet.GetPosition() == positionGot);
575 if (!result) {
576 MST_LOG("resultSet.GetPosition() != positionGot!!!");
577 break;
578 }
579 if (position < (recordCnt - 1)) {
580 result = result && (resultSet.GetEntry(entry) == OK);
581 if (!result) {
582 MST_LOG("resultSet.GetEntry() != OK");
583 break;
584 }
585 result = result && (entry.key == entries[positionGot].key) && (entry.value == entries[positionGot].value);
586 if (!result) {
587 MST_LOG("entry != entries[positionGot]");
588 break;
589 }
590 } else {
591 result = result && (resultSet.GetEntry(entry) == NOT_FOUND);
592 }
593 }
594 return result;
595 }
596
GetResourceDir()597 std::string DistributedDBNbTestTools::GetResourceDir()
598 {
599 std::string dir;
600 bool result = GetCurrentDir(dir);
601 if (!result) {
602 MST_LOG("[GetResourceDir] FAILED!");
603 return "";
604 }
605 #ifdef DB_DEBUG_ENV
606 dir = dir + "resource/";
607 #endif
608 return dir;
609 }
610
GetCurrentDir(std::string & dir)611 bool DistributedDBNbTestTools::GetCurrentDir(std::string &dir)
612 {
613 static const int maxFileLength = 1024;
614 dir = "";
615 char buffer[maxFileLength] = {0};
616 #if defined(RUNNING_ON_LINUX)
617 int length = readlink("/proc/self/exe", buffer, maxFileLength);
618 #elif defined RUNNING_ON_WIN
619 int length = -1;
620 if (_getcwd(buffer, maxFileLength) != nullptr) {
621 length = strlen(buffer);
622 }
623 #endif
624 if (length < 0 || length >= maxFileLength) {
625 MST_LOG("read directory err length:%d", length);
626 return false;
627 }
628 MST_LOG("DIR = %s", buffer);
629 dir = buffer;
630 if (dir.rfind("/") != std::string::npos) {
631 dir.erase(dir.rfind("/") + 1);
632 }
633 if ((access(dir.c_str(), F_OK)) != E_OK) {
634 return false;
635 }
636 return true;
637 }
CheckNbNoRecord(KvStoreNbDelegate * & delegate,const Key & key,bool bIsLocalQuery)638 bool DistributedDBNbTestTools::CheckNbNoRecord(KvStoreNbDelegate *&delegate, const Key &key, bool bIsLocalQuery)
639 {
640 Value realValue;
641 bool result = true;
642 DBStatus status;
643 if (!bIsLocalQuery) {
644 status = delegate->Get(key, realValue);
645 } else {
646 status = delegate->GetLocal(key, realValue);
647 }
648 result = result && (status == NOT_FOUND);
649 if (!result) {
650 MST_LOG("[DistributedDBNbTestTools] bIsLocalQuery:%d, status: %d, realValue.size() is: %zd",
651 bIsLocalQuery, status, realValue.size());
652 return result;
653 }
654 return (realValue.size() == 0);
655 }
656
CheckNbRecord(KvStoreNbDelegate * & delegate,const Key & key,const Value & value,bool bIsLocalQuery)657 bool DistributedDBNbTestTools::CheckNbRecord(KvStoreNbDelegate *&delegate,
658 const Key &key, const Value &value, bool bIsLocalQuery)
659 {
660 Value realValue;
661 bool result = true;
662 if (!bIsLocalQuery) {
663 if (value.empty()) {
664 return (delegate->Get(key, realValue) == NOT_FOUND);
665 } else {
666 result = result && (delegate->Get(key, realValue) == OK);
667 }
668 } else {
669 if (value.empty()) {
670 return (delegate->GetLocal(key, realValue) == NOT_FOUND);
671 } else {
672 result = result && (delegate->GetLocal(key, realValue) == OK);
673 }
674 }
675
676 if (!result) {
677 MST_LOG("[DistributedDBNbTestTools] Get Record failed");
678 return result;
679 }
680 result = result && (realValue == value);
681 if (!result) {
682 string realString(realValue.begin(), realValue.end());
683 MST_LOG("[DistributedDBNbTestTools] check the value(LocalQuery:%d) failed, and the realGetValue is %s",
684 bIsLocalQuery, realString.c_str());
685 return result;
686 }
687 return result;
688 }
CorruptNewCallBack(const std::string & appId,const std::string & userId,const std::string & storeId,DistributedDB::KvStoreDelegateManager * & manager,CallBackParam & pathResult)689 void KvStoreNbCorruptInfo::CorruptNewCallBack(const std::string &appId, const std::string &userId,
690 const std::string &storeId, DistributedDB::KvStoreDelegateManager *&manager, CallBackParam &pathResult)
691 {
692 MST_LOG("Begin to recover the corrupt DB.");
693 manager->DeleteKvStore(storeId);
694 delete manager;
695 manager = nullptr;
696 DBParameters param(storeId, appId, userId);
697 KvStoreNbDelegate *delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(manager, param, g_option);
698 if (manager == nullptr || delegate == nullptr) {
699 MST_LOG("[KvStoreNbCorruptInfo::CorruptNewCallBack] Get delegate or manager failed!");
700 pathResult.result = false;
701 return;
702 } else {
703 if (delegate->Import(pathResult.path, NULL_PASSWD) != OK) {
704 MST_LOG("[KvStoreNbCorruptInfo::CorruptNewCallBack] Import failed!");
705 pathResult.result = false;
706 }
707 if (manager->CloseKvStore(delegate) != OK) {
708 MST_LOG("[KvStoreNbCorruptInfo::CorruptNewCallBack] CloseKvStore(delegate) failed!");
709 pathResult.result = false;
710 }
711 }
712 delegate = nullptr;
713 delete manager;
714 manager = nullptr;
715 }
716
CorruptCallBackOfImport(const std::string & appId,const std::string & userId,const std::string & storeId,DistributedDB::KvStoreNbDelegate * & delegate,CallBackParam & pathResult)717 void KvStoreNbCorruptInfo::CorruptCallBackOfImport(const std::string &appId, const std::string &userId,
718 const std::string &storeId, DistributedDB::KvStoreNbDelegate *&delegate, CallBackParam &pathResult)
719 {
720 MST_LOG("Begin to Import the recover db files.");
721 MST_LOG("The corrupt Db is %s, %s, %s", appId.c_str(), userId.c_str(), storeId.c_str());
722 CipherPassword password;
723 (void)password.SetValue(FILE_PASSWD_VECTOR_1.data(), FILE_PASSWD_VECTOR_1.size());
724 if (delegate->Import(pathResult.path, password) != OK) {
725 MST_LOG("[KvStoreNbCorruptInfo::CorruptCallBackOfImport] Import failed!");
726 pathResult.result = false;
727 }
728 }
729
CorruptCallBackOfExport(const std::string & appId,const std::string & userId,const std::string & storeId,DistributedDB::KvStoreNbDelegate * & delegate,CallBackParam & pathResult)730 void KvStoreNbCorruptInfo::CorruptCallBackOfExport(const std::string &appId, const std::string &userId,
731 const std::string &storeId, DistributedDB::KvStoreNbDelegate *&delegate, CallBackParam &pathResult)
732 {
733 MST_LOG("The corrupt Db is %s, %s, %s", appId.c_str(), userId.c_str(), storeId.c_str());
734 MST_LOG("Begin to Export the DB data.");
735 if (delegate->Export(pathResult.path, NULL_PASSWD) != INVALID_PASSWD_OR_CORRUPTED_DB) {
736 MST_LOG("[KvStoreNbCorruptInfo::CorruptCallBackOfExport] Export failed!");
737 pathResult.result = false;
738 }
739 }
740