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