• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #ifndef DISTRIBUTEDDB_TOOLS_UNIT_TEST_H
17 #define DISTRIBUTEDDB_TOOLS_UNIT_TEST_H
18 
19 #include <algorithm>
20 #include <condition_variable>
21 #include <dirent.h>
22 #include <mutex>
23 #include <string>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <vector>
28 
29 #include "db_types.h"
30 #include "kv_store_changed_data.h"
31 #include "kv_store_delegate_impl.h"
32 #include "kv_store_delegate_manager.h"
33 #include "kv_store_nb_delegate.h"
34 #include "kv_store_observer.h"
35 #include "kv_store_snapshot_delegate_impl.h"
36 #include "log_print.h"
37 #include "message.h"
38 #include "query.h"
39 #include "relational_store_sqlite_ext.h"
40 #include "store_observer.h"
41 #include "store_changed_data.h"
42 #include "single_ver_kv_entry.h"
43 #include "sqlite_single_ver_natural_store.h"
44 #include "sqlite_utils.h"
45 #include "sync_types.h"
46 #include "store_types.h"
47 #include "types_export.h"
48 namespace DistributedDBUnitTest {
49 struct DatabaseInfo {
50     std::string appId{};
51     std::string userId{};
52     std::string storeId{};
53     std::string dir{};
54     int dbUserVersion = 0;
55 };
56 
57 struct SyncInputArg {
58     uint64_t begin_{};
59     uint64_t end_{};
60     uint32_t blockSize_{};
SyncInputArgSyncInputArg61     SyncInputArg(uint64_t begin, uint64_t end, uint32_t blockSize)
62         : begin_(begin), end_(end), blockSize_(blockSize)
63     {}
64 };
65 
66 struct DataSyncMessageInfo {
67     int messageId_ = DistributedDB::INVALID_MESSAGE_ID;
68     uint16_t messageType_ = DistributedDB::TYPE_INVALID;
69     uint32_t sequenceId_ = 0;
70     uint32_t sessionId_ = 0;
71     int sendCode_ = DistributedDB::E_OK;
72     uint32_t version_ = 0;
73     int32_t mode_ = DistributedDB::PUSH;
74     DistributedDB::WaterMark localMark_ = 0;
75     DistributedDB::WaterMark peerMark_ = 0;
76     DistributedDB::WaterMark deleteMark_ = 0;
77     uint64_t packetId_ = 0;
78 };
79 
80 class DistributedDBToolsUnitTest final {
81 public:
DistributedDBToolsUnitTest()82     DistributedDBToolsUnitTest() {}
~DistributedDBToolsUnitTest()83     ~DistributedDBToolsUnitTest() {}
84 
85     DistributedDBToolsUnitTest(const DistributedDBToolsUnitTest&) = delete;
86     DistributedDBToolsUnitTest& operator=(const DistributedDBToolsUnitTest&) = delete;
87     DistributedDBToolsUnitTest(DistributedDBToolsUnitTest&&) = delete;
88     DistributedDBToolsUnitTest& operator=(DistributedDBToolsUnitTest&&) = delete;
89 
90     // compare whether two vectors are equal.
91     template<typename T>
CompareVector(const std::vector<T> & vec1,const std::vector<T> & vec2)92     static bool CompareVector(const std::vector<T>& vec1, const std::vector<T>& vec2)
93     {
94         if (vec1.size() != vec2.size()) {
95             return false;
96         }
97         for (size_t i = 0; i < vec2.size(); i++) {
98             if (vec1[i] != vec2[i]) {
99                 return false;
100             }
101         }
102         return true;
103     }
104 
105     // compare whether two vectors are equal.
106     template<typename T>
CompareVectorN(const std::vector<T> & vec1,const std::vector<T> & vec2,uint32_t n)107     static bool CompareVectorN(const std::vector<T>& vec1, const std::vector<T>& vec2, uint32_t n)
108     {
109         if (n > std::min(vec1.size(), vec2.size())) {
110             return false;
111         }
112         for (uint32_t i = 0; i < n; i++) {
113             if (vec1[i] != vec2[i]) {
114                 return false;
115             }
116         }
117         return true;
118     }
119     // init the test directory of dir.
120     static void TestDirInit(std::string &dir);
121 
122     // remove the test db files in the test directory of dir.
123     static int RemoveTestDbFiles(const std::string &dir);
124 
125     // callback function for get a KvStoreDelegate pointer.
126     static void KvStoreDelegateCallback(DistributedDB::DBStatus, DistributedDB::KvStoreDelegate*,
127         DistributedDB::DBStatus &, DistributedDB::KvStoreDelegate *&);
128 
129     // callback function for get a KvStoreDelegate pointer.
130     static void KvStoreNbDelegateCallback(DistributedDB::DBStatus, DistributedDB::KvStoreNbDelegate*,
131         DistributedDB::DBStatus &, DistributedDB::KvStoreNbDelegate *&);
132 
133     // callback function for get a KvStoreSnapshotDelegate pointer.
134     static void SnapshotDelegateCallback(DistributedDB::DBStatus, DistributedDB::KvStoreSnapshotDelegate*,
135         DistributedDB::DBStatus &, DistributedDB::KvStoreSnapshotDelegate *&);
136 
137     // callback function for get the value.
138     static void ValueCallback(
139         DistributedDB::DBStatus, const DistributedDB::Value &, DistributedDB::DBStatus &, DistributedDB::Value &);
140 
141     // callback function for get an entry vector.
142     static void EntryVectorCallback(DistributedDB::DBStatus, const std::vector<DistributedDB::Entry> &,
143         DistributedDB::DBStatus &, unsigned long &, std::vector<DistributedDB::Entry> &);
144 
145     // sync test helper
146     DistributedDB::DBStatus SyncTest(DistributedDB::KvStoreNbDelegate* delegate,
147         const std::vector<std::string>& devices, DistributedDB::SyncMode mode,
148         std::map<std::string, DistributedDB::DBStatus>& statuses, bool wait = false);
149 
150     // sync test helper
151     DistributedDB::DBStatus SyncTest(DistributedDB::KvStoreNbDelegate* delegate,
152         const std::vector<std::string>& devices, DistributedDB::SyncMode mode,
153         std::map<std::string, DistributedDB::DBStatus>& statuses, const DistributedDB::Query &query);
154 
155     static void GetRandomKeyValue(std::vector<uint8_t> &value, uint32_t defaultSize = 0);
156 
157     static bool IsValueEqual(const DistributedDB::Value &read, const DistributedDB::Value &origin);
158 
159     static bool IsEntryEqual(const DistributedDB::Entry &entryOrg, const DistributedDB::Entry &entryRet);
160 
161     static bool IsEntriesEqual(const std::vector<DistributedDB::Entry> &entriesOrg,
162         const std::vector<DistributedDB::Entry> &entriesRet, bool needSort = false);
163 
164     static bool CheckObserverResult(const std::vector<DistributedDB::Entry> &orgEntries,
165         const std::list<DistributedDB::Entry> &resultLst);
166 
167     static bool IsItemValueExist(const DistributedDB::DataItem &item,
168         const std::vector<DistributedDB::DataItem> &items);
169 
170     static bool IsEntryExist(const DistributedDB::Entry &entry,
171         const std::vector<DistributedDB::Entry> &entries);
172 
173     static bool IsKvEntryExist(const DistributedDB::Entry &entry,
174         const std::vector<DistributedDB::Entry> &entries);
175 
176     static void CalcHash(const std::vector<uint8_t> &value, std::vector<uint8_t> &hashValue);
177 
178     static int CreateMockSingleDb(DatabaseInfo &dbInfo, DistributedDB::OpenDbProperties &properties);
179 
180     static int CreateMockMultiDb(DatabaseInfo &dbInfo, DistributedDB::OpenDbProperties &properties);
181 
182     static int ModifyDatabaseFile(const std::string &fileDir, uint64_t modifyPos = 0,
183         uint32_t modifyCnt = 256, uint32_t value = 0x1F1F1F1F);
184 
185     static int GetSyncDataTest(const SyncInputArg &syncInputArg, DistributedDB::SQLiteSingleVerNaturalStore *store,
186         std::vector<DistributedDB::DataItem> &dataItems, DistributedDB::ContinueToken &continueStmtToken);
187 
188     static int GetSyncDataNextTest(DistributedDB::SQLiteSingleVerNaturalStore *store, uint32_t blockSize,
189         std::vector<DistributedDB::DataItem> &dataItems, DistributedDB::ContinueToken &continueStmtToken);
190 
191     static int PutSyncDataTest(DistributedDB::SQLiteSingleVerNaturalStore *store,
192         const std::vector<DistributedDB::DataItem> &dataItems, const std::string &deviceName);
193 
194     static int PutSyncDataTest(DistributedDB::SQLiteSingleVerNaturalStore *store,
195         const std::vector<DistributedDB::DataItem> &dataItems, const std::string &deviceName,
196         const DistributedDB::QueryObject &query);
197 
198     static int ConvertItemsToSingleVerEntry(const std::vector<DistributedDB::DataItem> &dataItems,
199         std::vector<DistributedDB::SingleVerKvEntry *> &entries);
200 
201     static void ConvertSingleVerEntryToItems(std::vector<DistributedDB::SingleVerKvEntry *> &entries,
202         std::vector<DistributedDB::DataItem> &dataItems);
203 
204     static void ReleaseSingleVerEntry(std::vector<DistributedDB::SingleVerKvEntry *> &entries);
205 
206     static std::vector<uint8_t> GetRandPrefixKey(const std::vector<uint8_t> &prefixKey, uint32_t size);
207 
208     static int GetCurrentDir(std::string& dir);
209 
210     static int GetResourceDir(std::string& dir);
211 
212     static int GetRandInt(const int randMin, const int randMax);
213     static int64_t GetRandInt64(const int64_t randMin, const int64_t randMax);
214 
215     static void PrintTestCaseInfo();
216 
217     static int BuildMessage(const DataSyncMessageInfo &messageInfo, DistributedDB::Message *&message);
218 
219 private:
220     static int OpenMockMultiDb(DatabaseInfo &dbInfo, DistributedDB::OpenDbProperties &properties);
221 
222     std::mutex syncLock_ {};
223     std::condition_variable syncCondVar_ {};
224 };
225 
226 class KvStoreObserverUnitTest : public DistributedDB::KvStoreObserver {
227 public:
228     KvStoreObserverUnitTest();
~KvStoreObserverUnitTest()229     ~KvStoreObserverUnitTest() {}
230 
231     KvStoreObserverUnitTest(const KvStoreObserverUnitTest&) = delete;
232     KvStoreObserverUnitTest& operator=(const KvStoreObserverUnitTest&) = delete;
233     KvStoreObserverUnitTest(KvStoreObserverUnitTest&&) = delete;
234     KvStoreObserverUnitTest& operator=(KvStoreObserverUnitTest&&) = delete;
235 
236     // callback function will be called when the db data is changed.
237     void OnChange(const DistributedDB::KvStoreChangedData&);
238 
239     // reset the callCount_ to zero.
240     void ResetToZero();
241 
242     // get callback results.
243     unsigned long GetCallCount() const;
244     const std::list<DistributedDB::Entry> &GetEntriesInserted() const;
245     const std::list<DistributedDB::Entry> &GetEntriesUpdated() const;
246     const std::list<DistributedDB::Entry> &GetEntriesDeleted() const;
247     bool IsCleared() const;
248 private:
249     unsigned long callCount_;
250     bool isCleared_;
251     std::list<DistributedDB::Entry> inserted_;
252     std::list<DistributedDB::Entry> updated_;
253     std::list<DistributedDB::Entry> deleted_;
254 };
255 
256 class RelationalStoreObserverUnitTest : public DistributedDB::StoreObserver {
257 public:
258     RelationalStoreObserverUnitTest();
~RelationalStoreObserverUnitTest()259     ~RelationalStoreObserverUnitTest() {}
260 
261     RelationalStoreObserverUnitTest(const RelationalStoreObserverUnitTest&) = delete;
262     RelationalStoreObserverUnitTest& operator=(const RelationalStoreObserverUnitTest&) = delete;
263     RelationalStoreObserverUnitTest(RelationalStoreObserverUnitTest&&) = delete;
264     RelationalStoreObserverUnitTest& operator=(RelationalStoreObserverUnitTest&&) = delete;
265 
266     // callback function will be called when the db data is changed.
267     void OnChange(const DistributedDB::StoreChangedData &data);
268 
269     // reset the callCount_ to zero.
270     void ResetToZero();
271 
272     // get callback results.
273     unsigned long GetCallCount() const;
274     const std::string GetDataChangeDevice() const;
275     DistributedDB::StoreProperty GetStoreProperty() const;
276 private:
277     unsigned long callCount_;
278     std::string changeDevice_;
279     DistributedDB::StoreProperty storeProperty_;
280 };
281 
282 class KvStoreCorruptInfo {
283 public:
KvStoreCorruptInfo()284     KvStoreCorruptInfo() {}
~KvStoreCorruptInfo()285     ~KvStoreCorruptInfo() {}
286 
287     KvStoreCorruptInfo(const KvStoreCorruptInfo&) = delete;
288     KvStoreCorruptInfo& operator=(const KvStoreCorruptInfo&) = delete;
289     KvStoreCorruptInfo(KvStoreCorruptInfo&&) = delete;
290     KvStoreCorruptInfo& operator=(KvStoreCorruptInfo&&) = delete;
291 
292     // callback function will be called when the db data is changed.
293     void CorruptCallBack(const std::string &appId, const std::string &userId, const std::string &storeId);
294     size_t GetDatabaseInfoSize() const;
295     bool IsDataBaseCorrupted(const std::string &appId, const std::string &userId, const std::string &storeId) const;
296     void Reset();
297 private:
298     std::vector<DatabaseInfo> databaseInfoVect_;
299 };
300 
301 class RelationalTestUtils {
302 public:
303     static sqlite3 *CreateDataBase(const std::string &dbUri);
304     static int ExecSql(sqlite3 *db, const std::string &sql);
305     static int ExecSql(sqlite3 *db, const std::string &sql, const std::function<int (sqlite3_stmt *)> &bindCallback,
306         const std::function<int (sqlite3_stmt *)> &resultCallback);
307     static void CreateDeviceTable(sqlite3 *db, const std::string &table, const std::string &device);
308     static int CheckSqlResult(sqlite3 *db, const std::string &sql, bool &result);
309     static int CheckTableRecords(sqlite3 *db, const std::string &table);
310     static int GetMetaData(sqlite3 *db, const DistributedDB::Key &key, DistributedDB::Value &value);
311     static int SetMetaData(sqlite3 *db, const DistributedDB::Key &key, const DistributedDB::Value &value);
312 };
313 } // namespace DistributedDBUnitTest
314 
315 #endif // DISTRIBUTEDDB_TOOLS_UNIT_TEST_H
316