• 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 "cloud/virtual_cloud_db.h"
31 #include "db_info_handle.h"
32 #include "db_types.h"
33 #include "kv_store_changed_data.h"
34 #include "kv_store_delegate_impl.h"
35 #include "kv_store_delegate_manager.h"
36 #include "kv_store_nb_delegate.h"
37 #include "kv_store_observer.h"
38 #include "kv_store_snapshot_delegate_impl.h"
39 #include "log_print.h"
40 #include "message.h"
41 #include "query.h"
42 #include "relational_store_delegate.h"
43 #include "relational_store_sqlite_ext.h"
44 #include "store_observer.h"
45 #include "store_changed_data.h"
46 #include "single_ver_kv_entry.h"
47 #include "sqlite_single_ver_natural_store.h"
48 #include "sqlite_utils.h"
49 #include "sync_types.h"
50 #include "store_types.h"
51 #include "types_export.h"
52 
53 namespace DistributedDBUnitTest {
54 struct DatabaseInfo {
55     std::string appId{};
56     std::string userId{};
57     std::string storeId{};
58     std::string dir{};
59     int dbUserVersion = 0;
60 };
61 
62 struct SyncInputArg {
63     uint64_t begin_{};
64     uint64_t end_{};
65     uint32_t blockSize_{};
SyncInputArgSyncInputArg66     SyncInputArg(uint64_t begin, uint64_t end, uint32_t blockSize)
67         : begin_(begin), end_(end), blockSize_(blockSize)
68     {}
69 };
70 
71 struct DataSyncMessageInfo {
72     int messageId_ = DistributedDB::INVALID_MESSAGE_ID;
73     uint16_t messageType_ = DistributedDB::TYPE_INVALID;
74     uint32_t sequenceId_ = 0;
75     uint32_t sessionId_ = 0;
76     int sendCode_ = DistributedDB::E_OK;
77     uint32_t version_ = 0;
78     int32_t mode_ = DistributedDB::PUSH;
79     DistributedDB::WaterMark localMark_ = 0;
80     DistributedDB::WaterMark peerMark_ = 0;
81     DistributedDB::WaterMark deleteMark_ = 0;
82     uint64_t packetId_ = 0;
83 };
84 
85 class DistributedDBToolsUnitTest final {
86 public:
DistributedDBToolsUnitTest()87     DistributedDBToolsUnitTest() {}
~DistributedDBToolsUnitTest()88     ~DistributedDBToolsUnitTest() {}
89 
90     DistributedDBToolsUnitTest(const DistributedDBToolsUnitTest&) = delete;
91     DistributedDBToolsUnitTest& operator=(const DistributedDBToolsUnitTest&) = delete;
92     DistributedDBToolsUnitTest(DistributedDBToolsUnitTest&&) = delete;
93     DistributedDBToolsUnitTest& operator=(DistributedDBToolsUnitTest&&) = delete;
94 
95     // compare whether two vectors are equal.
96     template<typename T>
CompareVector(const std::vector<T> & vec1,const std::vector<T> & vec2)97     static bool CompareVector(const std::vector<T>& vec1, const std::vector<T>& vec2)
98     {
99         if (vec1.size() != vec2.size()) {
100             return false;
101         }
102         for (size_t i = 0; i < vec2.size(); i++) {
103             if (vec1[i] != vec2[i]) {
104                 return false;
105             }
106         }
107         return true;
108     }
109 
110     // compare whether two vectors are equal.
111     template<typename T>
CompareVectorN(const std::vector<T> & vec1,const std::vector<T> & vec2,uint32_t n)112     static bool CompareVectorN(const std::vector<T>& vec1, const std::vector<T>& vec2, uint32_t n)
113     {
114         if (n > std::min(vec1.size(), vec2.size())) {
115             return false;
116         }
117         for (uint32_t i = 0; i < n; i++) {
118             if (vec1[i] != vec2[i]) {
119                 return false;
120             }
121         }
122         return true;
123     }
124     // init the test directory of dir.
125     static void TestDirInit(std::string &dir);
126 
127     // remove the test db files in the test directory of dir.
128     static int RemoveTestDbFiles(const std::string &dir);
129 
130 #ifndef OMIT_MULTI_VER
131     // callback function for get a KvStoreDelegate pointer.
132     static void KvStoreDelegateCallback(DistributedDB::DBStatus, DistributedDB::KvStoreDelegate*,
133         DistributedDB::DBStatus &, DistributedDB::KvStoreDelegate *&);
134 
135     // callback function for get a KvStoreSnapshotDelegate pointer.
136     static void SnapshotDelegateCallback(DistributedDB::DBStatus, DistributedDB::KvStoreSnapshotDelegate*,
137         DistributedDB::DBStatus &, DistributedDB::KvStoreSnapshotDelegate *&);
138 #endif
139 
140     // callback function for get a KvStoreDelegate pointer.
141     static void KvStoreNbDelegateCallback(DistributedDB::DBStatus, DistributedDB::KvStoreNbDelegate*,
142         DistributedDB::DBStatus &, DistributedDB::KvStoreNbDelegate *&);
143 
144     // callback function for get the value.
145     static void ValueCallback(
146         DistributedDB::DBStatus, const DistributedDB::Value &, DistributedDB::DBStatus &, DistributedDB::Value &);
147 
148     // callback function for get an entry vector.
149     static void EntryVectorCallback(DistributedDB::DBStatus, const std::vector<DistributedDB::Entry> &,
150         DistributedDB::DBStatus &, unsigned long &, std::vector<DistributedDB::Entry> &);
151 
152     // sync test helper
153     DistributedDB::DBStatus SyncTest(DistributedDB::KvStoreNbDelegate* delegate,
154         const std::vector<std::string>& devices, DistributedDB::SyncMode mode,
155         std::map<std::string, DistributedDB::DBStatus>& statuses, bool wait = false);
156 
157     // sync test helper
158     DistributedDB::DBStatus SyncTest(DistributedDB::KvStoreNbDelegate* delegate,
159         const std::vector<std::string>& devices, DistributedDB::SyncMode mode,
160         std::map<std::string, DistributedDB::DBStatus>& statuses, const DistributedDB::Query &query);
161 
162     DistributedDB::DBStatus SyncTest(DistributedDB::KvStoreNbDelegate* delegate,
163         DistributedDB::DeviceSyncOption option,
164         std::map<std::string, DistributedDB::DeviceSyncProcess> &syncProcessMap);
165 
166     static void GetRandomKeyValue(std::vector<uint8_t> &value, uint32_t defaultSize = 0);
167 
168     static bool IsValueEqual(const DistributedDB::Value &read, const DistributedDB::Value &origin);
169 
170     static bool IsEntryEqual(const DistributedDB::Entry &entryOrg, const DistributedDB::Entry &entryRet);
171 
172     static bool IsEntriesEqual(const std::vector<DistributedDB::Entry> &entriesOrg,
173         const std::vector<DistributedDB::Entry> &entriesRet, bool needSort = false);
174 
175     static bool CheckObserverResult(const std::vector<DistributedDB::Entry> &orgEntries,
176         const std::list<DistributedDB::Entry> &resultLst);
177 
178     static bool IsItemValueExist(const DistributedDB::DataItem &item,
179         const std::vector<DistributedDB::DataItem> &items);
180 
181     static bool IsEntryExist(const DistributedDB::Entry &entry,
182         const std::vector<DistributedDB::Entry> &entries);
183 
184     static bool IsKvEntryExist(const DistributedDB::Entry &entry,
185         const std::vector<DistributedDB::Entry> &entries);
186 
187     static void CalcHash(const std::vector<uint8_t> &value, std::vector<uint8_t> &hashValue);
188 
189     static int CreateMockSingleDb(DatabaseInfo &dbInfo, DistributedDB::OpenDbProperties &properties);
190 
191     static int CreateMockMultiDb(DatabaseInfo &dbInfo, DistributedDB::OpenDbProperties &properties);
192 
193     static int ModifyDatabaseFile(const std::string &fileDir, uint64_t modifyPos = 0,
194         uint32_t modifyCnt = 256, uint32_t value = 0x1F1F1F1F);
195 
196     static int GetSyncDataTest(const SyncInputArg &syncInputArg, DistributedDB::SQLiteSingleVerNaturalStore *store,
197         std::vector<DistributedDB::DataItem> &dataItems, DistributedDB::ContinueToken &continueStmtToken);
198 
199     static int GetSyncDataNextTest(DistributedDB::SQLiteSingleVerNaturalStore *store, uint32_t blockSize,
200         std::vector<DistributedDB::DataItem> &dataItems, DistributedDB::ContinueToken &continueStmtToken);
201 
202     static int PutSyncDataTest(DistributedDB::SQLiteSingleVerNaturalStore *store,
203         const std::vector<DistributedDB::DataItem> &dataItems, const std::string &deviceName);
204 
205     static int PutSyncDataTest(DistributedDB::SQLiteSingleVerNaturalStore *store,
206         const std::vector<DistributedDB::DataItem> &dataItems, const std::string &deviceName,
207         const DistributedDB::QueryObject &query);
208 
209     static int ConvertItemsToSingleVerEntry(const std::vector<DistributedDB::DataItem> &dataItems,
210         std::vector<DistributedDB::SingleVerKvEntry *> &entries);
211 
212     static void ConvertSingleVerEntryToItems(std::vector<DistributedDB::SingleVerKvEntry *> &entries,
213         std::vector<DistributedDB::DataItem> &dataItems);
214 
215     static void ReleaseSingleVerEntry(std::vector<DistributedDB::SingleVerKvEntry *> &entries);
216 
217     static std::vector<uint8_t> GetRandPrefixKey(const std::vector<uint8_t> &prefixKey, uint32_t size);
218 
219     static int GetCurrentDir(std::string& dir);
220 
221     static int GetResourceDir(std::string& dir);
222 
223     static int GetRandInt(const int randMin, const int randMax);
224     static int64_t GetRandInt64(const int64_t randMin, const int64_t randMax);
225 
226     static void PrintTestCaseInfo();
227 
228     static int BuildMessage(const DataSyncMessageInfo &messageInfo, DistributedDB::Message *&message);
229 
230     static void Dump();
231 
232     static std::string GetKvNbStoreDirectory(const std::string &identifier, const std::string &dbFilePath,
233         const std::string &dbDir);
234 
235     static void BlockSync(DistributedDB::RelationalStoreDelegate &delegate, const DistributedDB::Query &query,
236         DistributedDB::SyncMode syncMode, DistributedDB::DBStatus exceptStatus,
237         const std::vector<std::string> &devices);
238 private:
239     static int OpenMockMultiDb(DatabaseInfo &dbInfo, DistributedDB::OpenDbProperties &properties);
240 
241     std::mutex syncLock_ {};
242     std::condition_variable syncCondVar_ {};
243 };
244 
245 class KvStoreObserverUnitTest : public DistributedDB::KvStoreObserver {
246 public:
247     KvStoreObserverUnitTest();
248     ~KvStoreObserverUnitTest() override = default;
249 
250     KvStoreObserverUnitTest(const KvStoreObserverUnitTest&) = delete;
251     KvStoreObserverUnitTest& operator=(const KvStoreObserverUnitTest&) = delete;
252     KvStoreObserverUnitTest(KvStoreObserverUnitTest&&) = delete;
253     KvStoreObserverUnitTest& operator=(KvStoreObserverUnitTest&&) = delete;
254 
255     // callback function will be called when the db data is changed.
256     void OnChange(const DistributedDB::KvStoreChangedData&) override;
257 
258     void OnChange(const DistributedDB::StoreChangedData &data) override;
259 
260     void OnChange(DistributedDB::Origin origin, const std::string &originalId,
261         DistributedDB::ChangedData &&data) override;
262 
263     void OnChange(StoreChangedInfo &&data) override;
264 
265     // reset the callCount_ to zero.
266     void ResetToZero();
267 
268     // get callback results.
269     unsigned long GetCallCount() const;
270     const std::list<DistributedDB::Entry> &GetEntriesInserted() const;
271     const std::list<DistributedDB::Entry> &GetEntriesUpdated() const;
272     const std::list<DistributedDB::Entry> &GetEntriesDeleted() const;
273     bool IsCleared() const;
274 private:
275     unsigned long callCount_;
276     bool isCleared_;
277     std::list<DistributedDB::Entry> inserted_;
278     std::list<DistributedDB::Entry> updated_;
279     std::list<DistributedDB::Entry> deleted_;
280 };
281 
282 class RelationalStoreObserverUnitTest : public DistributedDB::StoreObserver {
283 public:
284     RelationalStoreObserverUnitTest();
~RelationalStoreObserverUnitTest()285     ~RelationalStoreObserverUnitTest() {}
286 
287     RelationalStoreObserverUnitTest(const RelationalStoreObserverUnitTest&) = delete;
288     RelationalStoreObserverUnitTest& operator=(const RelationalStoreObserverUnitTest&) = delete;
289     RelationalStoreObserverUnitTest(RelationalStoreObserverUnitTest&&) = delete;
290     RelationalStoreObserverUnitTest& operator=(RelationalStoreObserverUnitTest&&) = delete;
291 
292     // callback function will be called when the db data is changed.
293     void OnChange(const DistributedDB::StoreChangedData &data);
294 
295     void OnChange(DistributedDB::Origin origin, const std::string &originalId, DistributedDB::ChangedData &&data);
296 
297     uint32_t GetCallbackDetailsType() const;
298     void SetCallbackDetailsType(uint32_t type);
299 
300     void SetExpectedResult(const DistributedDB::ChangedData &changedData);
301 
302     bool IsAllChangedDataEq();
303 
304     void ClearChangedData();
305 
306     // reset the callCount_ to zero.
307     void ResetToZero();
308     void ResetCloudSyncToZero();
309 
310     // get callback results.
311     unsigned long GetCallCount() const;
312     unsigned long GetCloudCallCount() const;
313     const std::string GetDataChangeDevice() const;
314     DistributedDB::StoreProperty GetStoreProperty() const;
315     std::unordered_map<std::string, DistributedDB::ChangedData> GetSavedChangedData() const;
316 
317     bool IsAssetChange(const std::string &table) const;
318 
319     DistributedDB::Origin GetLastOrigin() const;
320 private:
321     unsigned long callCount_;
322     unsigned long cloudCallCount_ = 0;
323     std::string changeDevice_;
324     DistributedDB::StoreProperty storeProperty_;
325     std::unordered_map<std::string, DistributedDB::ChangedData> expectedChangedData_;
326     std::unordered_map<std::string, DistributedDB::ChangedData> savedChangedData_;
327     uint32_t detailsType_ = static_cast<uint32_t>(DistributedDB::CallbackDetailsType::DEFAULT);
328     DistributedDB::Origin lastOrigin_ = DistributedDB::ORIGIN_REMOTE;
329 };
330 
331 class KvStoreCorruptInfo {
332 public:
KvStoreCorruptInfo()333     KvStoreCorruptInfo() {}
~KvStoreCorruptInfo()334     ~KvStoreCorruptInfo() {}
335 
336     KvStoreCorruptInfo(const KvStoreCorruptInfo&) = delete;
337     KvStoreCorruptInfo& operator=(const KvStoreCorruptInfo&) = delete;
338     KvStoreCorruptInfo(KvStoreCorruptInfo&&) = delete;
339     KvStoreCorruptInfo& operator=(KvStoreCorruptInfo&&) = delete;
340 
341     // callback function will be called when the db data is changed.
342     void CorruptCallBack(const std::string &appId, const std::string &userId, const std::string &storeId);
343     size_t GetDatabaseInfoSize() const;
344     bool IsDataBaseCorrupted(const std::string &appId, const std::string &userId, const std::string &storeId) const;
345     void Reset();
346 private:
347     std::vector<DatabaseInfo> databaseInfoVect_;
348 };
349 
350 class RelationalTestUtils {
351 public:
352     static sqlite3 *CreateDataBase(const std::string &dbUri);
353     static int ExecSql(sqlite3 *db, const std::string &sql);
354     static int ExecSql(sqlite3 *db, const std::string &sql, const std::function<int (sqlite3_stmt *)> &bindCallback,
355         const std::function<int (sqlite3_stmt *)> &resultCallback);
356     static void CreateDeviceTable(sqlite3 *db, const std::string &table, const std::string &device);
357     static int CheckSqlResult(sqlite3 *db, const std::string &sql, bool &result);
358     static int CheckTableRecords(sqlite3 *db, const std::string &table);
359     static int GetMetaData(sqlite3 *db, const DistributedDB::Key &key, DistributedDB::Value &value);
360     static int SetMetaData(sqlite3 *db, const DistributedDB::Key &key, const DistributedDB::Value &value);
361     static void CloudBlockSync(const DistributedDB::Query &query, DistributedDB::RelationalStoreDelegate *delegate,
362         DistributedDB::DBStatus expect = DistributedDB::DBStatus::OK,
363         DistributedDB::DBStatus callbackExpect = DistributedDB::DBStatus::OK);
364     static int SelectData(sqlite3 *db, const DistributedDB::TableSchema &schema,
365         std::vector<DistributedDB::VBucket> &data);
366     static DistributedDB::Assets GetAssets(const DistributedDB::Type &value,
367         const std::shared_ptr<DistributedDB::ICloudDataTranslate> &translate, bool isAsset = false);
368     static DistributedDB::DBStatus InsertCloudRecord(int64_t begin, int64_t count, const std::string &tableName,
369         const std::shared_ptr<DistributedDB::VirtualCloudDb> &cloudDbPtr, int32_t assetCount = 1);
370     static std::vector<DistributedDB::Assets> GetAllAssets(sqlite3 *db, const DistributedDB::TableSchema &schema,
371         const std::shared_ptr<DistributedDB::ICloudDataTranslate> &translate);
372     static int GetRecordLog(sqlite3 *db, const std::string &tableName, std::vector<DistributedDB::VBucket> &records);
373     static int DeleteRecord(sqlite3 *db, const std::string &tableName,
374         const std::vector<std::map<std::string, std::string>> &conditions);
375     static void CloudBlockSync(const DistributedDB::CloudSyncOption &option,
376         DistributedDB::RelationalStoreDelegate *delegate,
377         DistributedDB::DBStatus expect = DistributedDB::DBStatus::OK,
378         DistributedDB::DBStatus callbackExpect = DistributedDB::DBStatus::OK);
379     static bool IsExistEmptyHashAsset(sqlite3 *db, const DistributedDB::TableSchema &schema);
380     static bool IsExistEmptyHashAsset(const DistributedDB::Assets &assets);
381     static DistributedDB::ICloudSyncStorageHook *GetRDBStorageHook(const std::string &userId,
382         const std::string &appId, const std::string &storeId, const std::string &dbPath);
383 };
384 
385 class DBInfoHandleTest : public DistributedDB::DBInfoHandle {
386 public:
387     ~DBInfoHandleTest() override = default;
388 
389     bool IsSupport() override;
390 
391     bool IsNeedAutoSync(const std::string &userId, const std::string &appId, const std::string &storeId,
392         const DistributedDB::DeviceInfos &devInfo) override;
393 
394     void SetLocalIsSupport(bool isSupport);
395 
396     void SetNeedAutoSync(bool needAutoSync);
397 private:
398     std::mutex supportMutex_;
399     bool localIsSupport_ = true;
400     std::mutex autoSyncMutex_;
401     bool isNeedAutoSync_ = true;
402 };
403 } // namespace DistributedDBUnitTest
404 
405 #endif // DISTRIBUTEDDB_TOOLS_UNIT_TEST_H
406