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 #ifndef DISTRIBUTEDDB_NB_TEST_TOOLS_H
16 #define DISTRIBUTEDDB_NB_TEST_TOOLS_H
17 
18 #include "kv_store_delegate.h"
19 #include "kv_store_delegate_manager.h"
20 #include "kv_store_nb_delegate.h"
21 #include "kv_store_observer.h"
22 #ifdef RELEASE_MODE_V2
23 #include "query.h"
24 #endif
25 #include "distributeddb_data_generator.h"
26 #include "distributed_test_tools.h"
27 
28 struct DBParameters {
29     std::string storeId;
30     std::string appId;
31     std::string userId;
DBParametersDBParameters32     DBParameters(std::string storeIdStr, std::string appIdStr, std::string userIdStr)
33         : storeId(storeIdStr), appId(appIdStr), userId(userIdStr)
34     {
35     }
36 };
37 
38 struct Option {
39     bool createIfNecessary = true;
40     bool isMemoryDb = false; // true represents using a memory database
41     bool isEncryptedDb = false; // whether need encrypt
42     DistributedDB::CipherType cipher = DistributedDB::CipherType::DEFAULT; // cipher type
43     std::vector<uint8_t> passwd; // cipher password
44 #ifdef RELEASE_MODE_V2
45     std::string schema;
46     bool createDirByStoreIdOnly = false;
47 #endif // endif of RELEASE_MODE_V2
48 #ifdef RELEASE_MODE_V3
49     DistributedDB::SecurityOption secOption;
50     DistributedDB::KvStoreObserver *observer = nullptr;
51     DistributedDB::Key key;
52     unsigned int mode = 0;
53     int conflictType = 0;
54     DistributedDB::KvStoreNbConflictNotifier notifier = nullptr;
55     int conflictResolvePolicy = DistributedDB::LAST_WIN;
56     bool isNeedIntegrityCheck = false;
57     bool isNeedRmCorruptedDb = false;
58     bool isNeedCompressOnSync = false;
59     uint8_t compressionRate = 100; // default compression rate 100%, that means not compressing
60 #endif // end of RELEASE_MODE_V3
OptionOption61     Option(bool createIfNecessary, bool isMemoryDb, bool isEncryptedDb, DistributedDB::CipherType cipher,
62         std::vector<uint8_t> passwd)
63         : createIfNecessary(createIfNecessary), isMemoryDb(isMemoryDb), isEncryptedDb(isEncryptedDb),
64           cipher(cipher), passwd(passwd)
65     {
66     }
67 #ifdef RELEASE_MODE_V3
OptionOption68     Option(bool createIfNecessary, bool isMemoryDb, bool isEncryptedDb, const DistributedDB::CipherType &cipher,
69         const std::vector<uint8_t> &passwd, const DistributedDB::SecurityOption &secOption,
70         DistributedDB::KvStoreObserver *observer, const DistributedDB::KvStoreNbConflictNotifier &notifier)
71         : createIfNecessary(createIfNecessary), isMemoryDb(isMemoryDb), isEncryptedDb(isEncryptedDb),
72           cipher(cipher), passwd(passwd), secOption(secOption), observer(observer), notifier(notifier)
73     {
74     }
75 #endif // endif of RELEASE_MODE_V3
OptionOption76     Option()
77     {}
78 };
79 
80 struct ConflictData {
81     DistributedDB::KvStoreNbConflictType type;
82     DistributedDB::Key key;
83     DistributedDB::Value oldValue;
84     DistributedDB::Value newValue;
85     bool oldIsDeleted = false;
86     bool newIsDeleted = false;
87     bool oldIsNative = false;
88     bool newIsNative = false;
89 };
90 
91 enum EntryType {
92     INSERT_LOCAL = 0,
93     INSERT_NATIVE = 1,
94     DELETE_LOCAL = 2,
95     DELETE_NATIVE = 3,
96     UPDATE_LOCAL = 4,
97     UPDATE_NATIVE = 5
98 };
99 
100 enum class ReadOrWriteTag {
101     READ = 0,
102     WRITE = 1,
103     DELETE = 2,
104     REGISTER = 3
105 };
106 
107 const static DBParameters g_dbParameter1(DistributedDBDataGenerator::STORE_ID_1,
108     DistributedDBDataGenerator::APP_ID_1, DistributedDBDataGenerator::USER_ID_1);
109 const static DBParameters g_dbParameter2(DistributedDBDataGenerator::STORE_ID_2,
110     DistributedDBDataGenerator::APP_ID_2, DistributedDBDataGenerator::USER_ID_2);
111 const static DBParameters g_dbParameter3(DistributedDBDataGenerator::STORE_ID_3,
112     DistributedDBDataGenerator::APP_ID_3, DistributedDBDataGenerator::USER_ID_3);
113 const static DBParameters g_dbParameter4(DistributedDBDataGenerator::STORE_ID_4,
114     DistributedDBDataGenerator::APP_ID_4, DistributedDBDataGenerator::USER_ID_4);
115 const static DBParameters g_dbParameter5(DistributedDBDataGenerator::STORE_ID_5,
116     DistributedDBDataGenerator::APP_ID_5, DistributedDBDataGenerator::USER_ID_5);
117 const static DBParameters g_dbParameter6(DistributedDBDataGenerator::STORE_ID_6,
118     DistributedDBDataGenerator::APP_ID_6, DistributedDBDataGenerator::USER_ID_6);
119 const static DBParameters g_dbParameter2_1(DistributedDBDataGenerator::STORE_ID_2,
120     DistributedDBDataGenerator::APP_ID_1, DistributedDBDataGenerator::USER_ID_1);
121 const static DBParameters DB_PARAMETER_0_1(DistributedDBDataGenerator::STORE_ID,
122     DistributedDBDataGenerator::APP_ID_1, DistributedDBDataGenerator::USER_ID_1);
123 const static DBParameters g_dbParameter1_2_1(DistributedDBDataGenerator::STORE_ID_1,
124     DistributedDBDataGenerator::APP_ID_2, DistributedDBDataGenerator::USER_ID_1);
125 const static DBParameters g_dbParameter2_1_2(DistributedDBDataGenerator::STORE_ID_2,
126     DistributedDBDataGenerator::APP_ID_1, DistributedDBDataGenerator::USER_ID_2);
127 const static DBParameters g_dbParameter3_2_1(DistributedDBDataGenerator::STORE_ID_3,
128     DistributedDBDataGenerator::APP_ID_2, DistributedDBDataGenerator::USER_ID_1);
129 const static DBParameters g_dbParameter4_2_2(DistributedDBDataGenerator::STORE_ID_4,
130     DistributedDBDataGenerator::APP_ID_2, DistributedDBDataGenerator::USER_ID_2);
131 const static Option g_createDiskUnencrypted(true, false, false, DistributedDB::CipherType::DEFAULT,
132     DistributedDBDataGenerator::NULL_PASSWD_VECTOR);
133 const static Option g_createDiskEncrypted(true, false, true, DistributedDB::CipherType::DEFAULT,
134     DistributedDBDataGenerator::PASSWD_VECTOR_1);
135 const static Option g_ncreateDiskUnencrypted(false, false, false, DistributedDB::CipherType::DEFAULT,
136     DistributedDBDataGenerator::NULL_PASSWD_VECTOR);
137 const static Option g_ncreateDiskEncrypted(false, false, true, DistributedDB::CipherType::DEFAULT,
138     DistributedDBDataGenerator::PASSWD_VECTOR_1);
139 const static Option g_createMemUnencrypted(true, true, false, DistributedDB::CipherType::DEFAULT,
140     DistributedDBDataGenerator::NULL_PASSWD_VECTOR);
141 static Option g_option = g_createDiskUnencrypted;
142 const std::vector<Option> g_nbOptions = {g_createDiskUnencrypted, g_createDiskEncrypted, g_createMemUnencrypted};
143 // DelegateMgrNbCallback conclude the Callback implements of function< void(DBStatus, KvStoreDelegate*)>
144 class DelegateMgrNbCallback {
145 public:
DelegateMgrNbCallback()146     DelegateMgrNbCallback() {}
~DelegateMgrNbCallback()147     ~DelegateMgrNbCallback() {}
148 
149     // Delete the copy and assign constructors
150     DelegateMgrNbCallback(const DelegateMgrNbCallback &callback) = delete;
151     DelegateMgrNbCallback& operator=(const DelegateMgrNbCallback &callback) = delete;
152     DelegateMgrNbCallback(DelegateMgrNbCallback &&callback) = delete;
153     DelegateMgrNbCallback& operator=(DelegateMgrNbCallback &&callback) = delete;
154 
155     void Callback(DistributedDB::DBStatus status, DistributedDB::KvStoreNbDelegate *kvStoreNbDelegate);
156     DistributedDB::DBStatus GetStatus();
157     DistributedDB::KvStoreNbDelegate *GetKvStore();
158 
159 private:
160     DistributedDB::DBStatus status_ = DistributedDB::DBStatus::INVALID_ARGS;
161     DistributedDB::KvStoreNbDelegate *kvStoreNbDelegate_ = nullptr;
162 };
163 
164 class ConflictNbCallback {
165 public:
ConflictNbCallback()166     ConflictNbCallback() {}
~ConflictNbCallback()167     ~ConflictNbCallback() {}
168 
169     // Delete the copy and assign constructors
170     ConflictNbCallback(const ConflictNbCallback &callback) = delete;
171     ConflictNbCallback &operator=(const ConflictNbCallback &callback) = delete;
172     ConflictNbCallback(ConflictNbCallback &&callback) = delete;
173     ConflictNbCallback &operator=(ConflictNbCallback &&callback) = delete;
174 
175     void NotifyCallBack(const DistributedDB::KvStoreNbConflictData &data, std::vector<ConflictData> *&conflictData);
176 };
177 
178 class DistributedDBNbTestTools final {
179 public:
DistributedDBNbTestTools()180     DistributedDBNbTestTools() {}
~DistributedDBNbTestTools()181     ~DistributedDBNbTestTools() {}
182 
183     // Delete the copy and assign constructors
184     DistributedDBNbTestTools(const DistributedDBNbTestTools &distributedDBNbTestTools) = delete;
185     DistributedDBNbTestTools& operator=(const DistributedDBNbTestTools &distributedDBNbTestTools) = delete;
186     DistributedDBNbTestTools(DistributedDBNbTestTools &&distributedDBNbTestTools) = delete;
187     DistributedDBNbTestTools& operator=(DistributedDBNbTestTools &&distributedDBNbTestTools) = delete;
188     static DistributedDB::KvStoreNbDelegate* GetNbDelegateStatus(DistributedDB::KvStoreDelegateManager *&outManager,
189         DistributedDB::DBStatus &statusReturn, const DBParameters &param, const Option &optionParam);
190     static DistributedDB::KvStoreNbDelegate* GetNbDelegateSuccess(DistributedDB::KvStoreDelegateManager *&outManager,
191         const DBParameters &param, const Option &optionParam,
192         const std::string &dbPath = DistributedDBDataGenerator::DistributedDBConstant::NB_DIRECTOR);
193     static DistributedDB::DBStatus GetNbDelegateStoresSuccess(DistributedDB::KvStoreDelegateManager *&outManager,
194         std::vector<DistributedDB::KvStoreNbDelegate *> &outDelegateVec, const std::vector<std::string> &storeIds,
195         const std::string &appId, const std::string &userId, const Option &optionParam);
196     static DistributedDB::KvStoreNbDelegate::Option TransferNbOptionType(const Option &optionParam);
197     // this static method is to compare if the two Value has the same data.
198     static bool isValueEquals(const DistributedDB::Value &v1, const DistributedDB::Value &v2);
199 
200     static DistributedDB::DBStatus Get(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
201         const DistributedDB::Key &key, DistributedDB::Value &value);
202 
203     static DistributedDB::DBStatus GetEntries(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
204         const DistributedDB::Key &keyPrefix, std::vector<DistributedDB::Entry> &entries);
205 
206     static DistributedDB::DBStatus Put(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
207         const DistributedDB::Key &key, const DistributedDB::Value &value, bool isNeedRetry = false, int waitTime = 100);
208 
209     static DistributedDB::DBStatus PutBatch(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
210         const std::vector<DistributedDB::Entry> &entries, bool isNeedRetry = false);
211 
212     static DistributedDB::DBStatus Delete(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
213         const DistributedDB::Key &key);
214 
215     static DistributedDB::DBStatus DeleteBatch(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
216         const std::vector<DistributedDB::Key> &keys, bool isNeedRetry = false);
217 
218     static DistributedDB::DBStatus GetLocal(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
219         const DistributedDB::Key &key, DistributedDB::Value &value);
220 
221     static DistributedDB::DBStatus PutLocal(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
222         const DistributedDB::Key &key, const DistributedDB::Value &value, bool isNeedRetry = false, int waitTime = 100);
223 
224     static DistributedDB::DBStatus PutLocalBatch(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
225         const std::vector<DistributedDB::Entry> &entries);
226 
227     static DistributedDB::DBStatus DeleteLocal(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
228         const DistributedDB::Key &key);
229 
230     static DistributedDB::DBStatus DeleteLocalBatch(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
231         const std::vector<DistributedDB::Key> &keys);
232 
233     static DistributedDB::DBStatus RegisterObserver(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
234         const DistributedDB::Key &key, unsigned int mode, DistributedDB::KvStoreObserver *observer);
235 
236     static DistributedDB::DBStatus UnRegisterObserver(DistributedDB::KvStoreNbDelegate &kvStoreNbDelegate,
237         const DistributedDB::KvStoreObserver *observer);
238     static bool CloseNbAndRelease(DistributedDB::KvStoreDelegateManager *&manager,
239         DistributedDB::KvStoreNbDelegate *&delegate);
240     static bool ModifyDatabaseFile(const std::string &fileDir);
241     static std::string GetKvNbStoreDirectory(const DBParameters &param,
242         const std::string &dbFilePath = DistributedDBDataGenerator::DistributedDBConstant::NB_DATABASE_NAME,
243         const std::string &dbDir = DistributedDBDataGenerator::DistributedDBConstant::NB_DIRECTOR);
244     static bool MoveToNextFromBegin(DistributedDB::KvStoreResultSet &resultSet,
245         const std::vector<DistributedDB::Entry> &entries, int recordCnt);
246     static std::string FbfFileToSchemaString(const std::string &fbFileDir, const std::string &fileName);
247     static bool GetCurrentDir(std::string &dir);
248     static std::string GetResourceDir();
249     static bool CheckNbNoRecord(DistributedDB::KvStoreNbDelegate *&delegate, const DistributedDB::Key &key,
250         bool bIsLocalQuery = false);
251     static bool CheckNbRecord(DistributedDB::KvStoreNbDelegate *&delegate,
252         const DistributedDB::Key &key, const DistributedDB::Value &value, bool bIsLocalQuery = false);
253 };
254 
255 struct CallBackParam {
256     const std::string path = "";
257     bool result = true;
258 };
259 
260 class KvStoreNbCorruptInfo {
261 public:
KvStoreNbCorruptInfo()262     KvStoreNbCorruptInfo() {}
~KvStoreNbCorruptInfo()263     ~KvStoreNbCorruptInfo() {}
264 
265     KvStoreNbCorruptInfo(const KvStoreNbCorruptInfo&) = delete;
266     KvStoreNbCorruptInfo& operator=(const KvStoreNbCorruptInfo&) = delete;
267     KvStoreNbCorruptInfo(KvStoreNbCorruptInfo&&) = delete;
268     KvStoreNbCorruptInfo& operator=(KvStoreNbCorruptInfo&&) = delete;
269 
270     // callback function will be called when the db data is changed.
CorruptCallBack(const std::string & appId,const std::string & userId,const std::string & storeId,bool & isCalled)271     void CorruptCallBack(const std::string &appId, const std::string &userId, const std::string &storeId,
272         bool &isCalled)
273     {
274         isCalled = true;
275         MST_LOG("The corrupt Db is %s, %s, %s", appId.c_str(), userId.c_str(), storeId.c_str());
276     }
277     void CorruptNewCallBack(const std::string &appId, const std::string &userId, const std::string &storeId,
278         DistributedDB::KvStoreDelegateManager *&manager, CallBackParam &param);
279     void CorruptCallBackOfImport(const std::string &appId, const std::string &userId, const std::string &storeId,
280         DistributedDB::KvStoreNbDelegate *&delegate, CallBackParam &param);
281     void CorruptCallBackOfExport(const std::string &appId, const std::string &userId, const std::string &storeId,
282         DistributedDB::KvStoreNbDelegate *&delegate, CallBackParam &param);
283 };
284 #ifdef RELEASE_MODE_V2
285 template <typename ParaType>
286 class QueryGenerate {
287 public:
288     static constexpr int FP_COMP_SIZE = 6;
289     static constexpr int FP_LIKE_SIZE = 2;
290     static constexpr int FP_IN_SIZE = 2;
291 
292     typedef DistributedDB::Query&(DistributedDB::Query::*FP_COMP)(const std::string& field, const ParaType& value);
293     typedef DistributedDB::Query&(DistributedDB::Query::*FP_LIKE)(const std::string& field, const std::string& value);
294     typedef DistributedDB::Query&(DistributedDB::Query::*FP_IN)(const std::string& field,
295         const std::vector<ParaType>& value);
296 
Instance()297     static QueryGenerate& Instance()
298     {
299         static QueryGenerate queryGenerateSingleton;
300         return queryGenerateSingleton;
301     }
302 
GenerateQueryComp(std::vector<DistributedDB::Query> & queries,const bool (& funcFilter)[FP_COMP_SIZE],const std::string & field,const ParaType & value)303     void GenerateQueryComp(std::vector<DistributedDB::Query> &queries, const bool (&funcFilter)[FP_COMP_SIZE],
304         const std::string& field, const ParaType& value)
305     {
306         for (int i = 0; i < FP_COMP_SIZE; i++) {
307             if (!funcFilter[i]) {
308                 continue;
309             }
310             queries.push_back((DistributedDB::Query::Select().*(compFunc_[i]))(field, value));
311         }
312     }
313 
GenerateQueryLike(std::vector<DistributedDB::Query> & queries,const bool (& funcFilter)[FP_LIKE_SIZE],const std::string & field,const std::string & value)314     void GenerateQueryLike(std::vector<DistributedDB::Query> &queries, const bool (&funcFilter)[FP_LIKE_SIZE],
315         const std::string& field, const std::string& value)
316     {
317         for (int i = 0; i < FP_LIKE_SIZE; i++) {
318             if (!funcFilter[i]) {
319                 continue;
320             }
321             queries.push_back((DistributedDB::Query::Select().*(likeFunc_[i]))(field, value));
322         }
323     }
GenerateQueryIn(std::vector<DistributedDB::Query> & queries,const bool (& funcFilter)[FP_IN_SIZE],const std::string & field,const std::vector<ParaType> & value)324     void GenerateQueryIn(std::vector<DistributedDB::Query> &queries, const bool (&funcFilter)[FP_IN_SIZE],
325         const std::string& field, const std::vector<ParaType>& value)
326     {
327         for (int i = 0; i < FP_IN_SIZE; i++) {
328             if (!funcFilter[i]) {
329                 continue;
330             }
331             queries.push_back((DistributedDB::Query::Select().*(inFunc_[i]))(field, value));
332         }
333     }
334 private:
335     std::vector<FP_COMP> compFunc_{
336         &DistributedDB::Query::EqualTo,
337         &DistributedDB::Query::NotEqualTo,
338         &DistributedDB::Query::GreaterThan,
339         &DistributedDB::Query::GreaterThanOrEqualTo,
340         &DistributedDB::Query::LessThan,
341         &DistributedDB::Query::LessThanOrEqualTo,
342     };
343     std::vector<FP_LIKE> likeFunc_{
344         &DistributedDB::Query::Like,
345         &DistributedDB::Query::NotLike,
346     };
347     std::vector<FP_IN> inFunc_{
348         &DistributedDB::Query::In,
349         &DistributedDB::Query::NotIn,
350     };
351 };
352 #endif // endif of RELEASE_MODE_V2
353 
354 bool EndCaseDeleteDB(DistributedDB::KvStoreDelegateManager *&manager, DistributedDB::KvStoreNbDelegate *&nbDelegate,
355     const std::string base, bool isMemoryDb);
356 
357 #endif // DISTRIBUTEDDB_NB_TEST_TOOLS_H