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 std::ios::pos_type pos = dataFile.tellg();
520 if (pos < 0) {
521 return false;
522 } else {
523 uint64_t fileSize = static_cast<uint64_t>(pos);
524 if (fileSize < 1024) { // the least page size is 1024 bytes.
525 MST_LOG("Invalid database file:%lld.", static_cast<long long>(fileSize));
526 return false;
527 }
528 }
529
530 uint32_t currentCount = 0x1F1F1F1F; // add the random value to corrupt the head.
531 if (!dataFile.seekp(0)) {
532 return false;
533 }
534 for (uint32_t i = 0; i < pos / sizeof(uint32_t); i++) {
535 if (!dataFile.write(reinterpret_cast<char *>(¤tCount), sizeof(uint32_t))) {
536 return false;
537 }
538 }
539 dataFile.flush();
540 dataFile.close();
541 return true;
542 }
GetKvNbStoreDirectory(const DBParameters & param,const std::string & dbFilePath,const std::string & dbDir)543 std::string DistributedDBNbTestTools::GetKvNbStoreDirectory(const DBParameters ¶m, const std::string &dbFilePath,
544 const std::string &dbDir)
545 {
546 std::string identifier = param.userId + "-" + param.appId + "-" + param.storeId;
547 std::string identifierName = TransferStringToHashHexString(identifier);
548 std::string filePath = dbDir + identifierName + "/" + dbFilePath;
549 return filePath;
550 }
MoveToNextFromBegin(KvStoreResultSet & resultSet,const vector<DistributedDB::Entry> & entries,int recordCnt)551 bool DistributedDBNbTestTools::MoveToNextFromBegin(KvStoreResultSet &resultSet,
552 const vector<DistributedDB::Entry> &entries, int recordCnt)
553 {
554 bool result = (static_cast<int>(entries.size()) >= recordCnt);
555 if (!result) {
556 MST_LOG("entries.size()) < recordCnt!!!");
557 return result;
558 }
559 Entry entry;
560 for (int position = -1; position < recordCnt; ++position) { // the first pos after getentries is -1.
561 bool expectRes = resultSet.MoveToNext();
562 if (position < (recordCnt - 1)) {
563 result = result && expectRes;
564 } else {
565 result = result && (!expectRes);
566 }
567 if (!result) {
568 MST_LOG("resultSet.MoveToNext() doesn't meet expectations!!!");
569 break;
570 }
571 int positionGot = position + 1;
572 result = result && (resultSet.GetPosition() == positionGot);
573 if (!result) {
574 MST_LOG("resultSet.GetPosition() != positionGot!!!");
575 break;
576 }
577 if (position < (recordCnt - 1)) {
578 result = result && (resultSet.GetEntry(entry) == OK);
579 if (!result) {
580 MST_LOG("resultSet.GetEntry() != OK");
581 break;
582 }
583 result = result && (entry.key == entries[positionGot].key) && (entry.value == entries[positionGot].value);
584 if (!result) {
585 MST_LOG("entry != entries[positionGot]");
586 break;
587 }
588 } else {
589 result = result && (resultSet.GetEntry(entry) == NOT_FOUND);
590 }
591 }
592 return result;
593 }
594
GetResourceDir()595 std::string DistributedDBNbTestTools::GetResourceDir()
596 {
597 std::string dir;
598 bool result = GetCurrentDir(dir);
599 if (!result) {
600 MST_LOG("[GetResourceDir] FAILED!");
601 return "";
602 }
603 #ifdef RUNNING_ON_SIMULATED_ENV
604 dir = dir + "resource/";
605 #endif
606 return dir;
607 }
608
GetCurrentDir(std::string & dir)609 bool DistributedDBNbTestTools::GetCurrentDir(std::string &dir)
610 {
611 static const int maxFileLength = 1024;
612 dir = "";
613 char buffer[maxFileLength] = {0};
614 #if defined(RUNNING_ON_LINUX)
615 int length = readlink("/proc/self/exe", buffer, maxFileLength);
616 #elif defined RUNNING_ON_WIN
617 int length = -1;
618 if (_getcwd(buffer, maxFileLength) != nullptr) {
619 length = strlen(buffer);
620 }
621 #endif
622 if (length < 0 || length >= maxFileLength) {
623 MST_LOG("read directory err length:%d", length);
624 return false;
625 }
626 MST_LOG("DIR = %s", buffer);
627 dir = buffer;
628 if (dir.rfind("/") != std::string::npos) {
629 dir.erase(dir.rfind("/") + 1);
630 }
631 if ((access(dir.c_str(), F_OK)) != E_OK) {
632 return false;
633 }
634 return true;
635 }
CheckNbNoRecord(KvStoreNbDelegate * & delegate,const Key & key,bool bIsLocalQuery)636 bool DistributedDBNbTestTools::CheckNbNoRecord(KvStoreNbDelegate *&delegate, const Key &key, bool bIsLocalQuery)
637 {
638 Value realValue;
639 bool result = true;
640 DBStatus status;
641 if (!bIsLocalQuery) {
642 status = delegate->Get(key, realValue);
643 } else {
644 status = delegate->GetLocal(key, realValue);
645 }
646 result = result && (status == NOT_FOUND);
647 if (!result) {
648 MST_LOG("[DistributedDBNbTestTools] bIsLocalQuery:%d, status: %d, realValue.size() is: %zd",
649 bIsLocalQuery, status, realValue.size());
650 return result;
651 }
652 return (realValue.size() == 0);
653 }
654
CheckNbRecord(KvStoreNbDelegate * & delegate,const Key & key,const Value & value,bool bIsLocalQuery)655 bool DistributedDBNbTestTools::CheckNbRecord(KvStoreNbDelegate *&delegate,
656 const Key &key, const Value &value, bool bIsLocalQuery)
657 {
658 Value realValue;
659 bool result = true;
660 if (!bIsLocalQuery) {
661 if (value.empty()) {
662 return (delegate->Get(key, realValue) == NOT_FOUND);
663 } else {
664 result = result && (delegate->Get(key, realValue) == OK);
665 }
666 } else {
667 if (value.empty()) {
668 return (delegate->GetLocal(key, realValue) == NOT_FOUND);
669 } else {
670 result = result && (delegate->GetLocal(key, realValue) == OK);
671 }
672 }
673
674 if (!result) {
675 MST_LOG("[DistributedDBNbTestTools] Get Record failed");
676 return result;
677 }
678 result = result && (realValue == value);
679 if (!result) {
680 string realString(realValue.begin(), realValue.end());
681 MST_LOG("[DistributedDBNbTestTools] check the value(LocalQuery:%d) failed, and the realGetValue is %s",
682 bIsLocalQuery, realString.c_str());
683 return result;
684 }
685 return result;
686 }
CorruptNewCallBack(const std::string & appId,const std::string & userId,const std::string & storeId,DistributedDB::KvStoreDelegateManager * & manager,CallBackParam & pathResult)687 void KvStoreNbCorruptInfo::CorruptNewCallBack(const std::string &appId, const std::string &userId,
688 const std::string &storeId, DistributedDB::KvStoreDelegateManager *&manager, CallBackParam &pathResult)
689 {
690 MST_LOG("Begin to recover the corrupt DB.");
691 manager->DeleteKvStore(storeId);
692 delete manager;
693 manager = nullptr;
694 DBParameters param(storeId, appId, userId);
695 KvStoreNbDelegate *delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(manager, param, g_option);
696 if (manager == nullptr || delegate == nullptr) {
697 MST_LOG("[KvStoreNbCorruptInfo::CorruptNewCallBack] Get delegate or manager failed!");
698 pathResult.result = false;
699 return;
700 } else {
701 if (delegate->Import(pathResult.path, NULL_PASSWD) != OK) {
702 MST_LOG("[KvStoreNbCorruptInfo::CorruptNewCallBack] Import failed!");
703 pathResult.result = false;
704 }
705 if (manager->CloseKvStore(delegate) != OK) {
706 MST_LOG("[KvStoreNbCorruptInfo::CorruptNewCallBack] CloseKvStore(delegate) failed!");
707 pathResult.result = false;
708 }
709 }
710 delegate = nullptr;
711 delete manager;
712 manager = nullptr;
713 }
714
CorruptCallBackOfImport(const std::string & appId,const std::string & userId,const std::string & storeId,DistributedDB::KvStoreNbDelegate * & delegate,CallBackParam & pathResult)715 void KvStoreNbCorruptInfo::CorruptCallBackOfImport(const std::string &appId, const std::string &userId,
716 const std::string &storeId, DistributedDB::KvStoreNbDelegate *&delegate, CallBackParam &pathResult)
717 {
718 MST_LOG("Begin to Import the recover db files.");
719 MST_LOG("The corrupt Db is %s, %s, %s", appId.c_str(), userId.c_str(), storeId.c_str());
720 CipherPassword password;
721 (void)password.SetValue(FILE_PASSWD_VECTOR_1.data(), FILE_PASSWD_VECTOR_1.size());
722 if (delegate->Import(pathResult.path, password) != OK) {
723 MST_LOG("[KvStoreNbCorruptInfo::CorruptCallBackOfImport] Import failed!");
724 pathResult.result = false;
725 }
726 }
727
CorruptCallBackOfExport(const std::string & appId,const std::string & userId,const std::string & storeId,DistributedDB::KvStoreNbDelegate * & delegate,CallBackParam & pathResult)728 void KvStoreNbCorruptInfo::CorruptCallBackOfExport(const std::string &appId, const std::string &userId,
729 const std::string &storeId, DistributedDB::KvStoreNbDelegate *&delegate, CallBackParam &pathResult)
730 {
731 MST_LOG("The corrupt Db is %s, %s, %s", appId.c_str(), userId.c_str(), storeId.c_str());
732 MST_LOG("Begin to Export the DB data.");
733 if (delegate->Export(pathResult.path, NULL_PASSWD) != INVALID_PASSWD_OR_CORRUPTED_DB) {
734 MST_LOG("[KvStoreNbCorruptInfo::CorruptCallBackOfExport] Export failed!");
735 pathResult.result = false;
736 }
737 }
738