1 /*
2  * Copyright (c) 2024 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 #include <condition_variable>
17 #include <gtest/gtest.h>
18 #include <thread>
19 
20 #include "cloud_db_sync_utils_test.h"
21 #include "db_constant.h"
22 #include "distributeddb_data_generate_unit_test.h"
23 #include "distributeddb_tools_unit_test.h"
24 #include "kv_store_nb_delegate.h"
25 #include "kv_virtual_device.h"
26 #include "platform_specific.h"
27 #include "relational_store_manager.h"
28 #include "runtime_config.h"
29 #include "virtual_asset_loader.h"
30 #include "virtual_cloud_data_translate.h"
31 
32 using namespace testing::ext;
33 using namespace DistributedDB;
34 using namespace DistributedDBUnitTest;
35 using namespace std;
36 
37 namespace {
38     std::shared_ptr<std::string> g_testDir = nullptr;
39     VirtualCommunicatorAggregator* g_communicatorAggregator = nullptr;
40     const std::string DEVICE_A = "real_device";
41     const std::string DEVICE_B = "deviceB";
42     const std::string KEY_INSTANCE_ID = "INSTANCE_ID";
43     const std::string KEY_SUB_USER = "SUB_USER";
44     KvVirtualDevice *g_deviceB = nullptr;
45     DistributedDBToolsUnitTest g_tool;
46     CloudSyncOption g_CloudSyncoption;
47     std::shared_ptr<VirtualCloudDb> virtualCloudDb_ = nullptr;
48     std::shared_ptr<VirtualCloudDataTranslate> g_virtualCloudDataTranslate;
49     const string ASSETS_TABLE_NAME = "student";
50     const string ASSETS_TABLE_NAME_SHARED = "student_shared";
51     const string COL_ID = "id";
52     const string COL_NAME = "name";
53     const string COL_ASSET = "asset";
54     const string COL_ASSETS = "assets";
55     const int64_t WAIT_TIME = 5;
56     const std::vector<Field> CLOUD_FIELDS = {{COL_ID, TYPE_INDEX<int64_t>, true}, {COL_NAME, TYPE_INDEX<std::string>},
57         {COL_ASSET, TYPE_INDEX<Asset>}, {COL_ASSETS, TYPE_INDEX<Assets>}};
58     const string CREATE_SINGLE_PRIMARY_KEY_TABLE = "CREATE TABLE IF NOT EXISTS " + ASSETS_TABLE_NAME + "(" + COL_ID +
59         " INTEGER PRIMARY KEY," + COL_NAME + " TEXT ," + COL_ASSET + " ASSET," + COL_ASSETS + " ASSETS" + ");";
60     const Asset ASSET_COPY = {.version = 1,
61         .name = "Phone",
62         .assetId = "0",
63         .subpath = "/local/sync",
64         .uri = "/local/sync",
65         .modifyTime = "123456",
66         .createTime = "",
67         .size = "256",
68         .hash = "ASE"};
69     int64_t g_nameId = 0;
70 
OpenDelegate(const std::string & dlpPath,KvStoreNbDelegate * & delegatePtr,KvStoreDelegateManager & mgr,bool syncDualTupleMode=false)71     DBStatus OpenDelegate(const std::string &dlpPath, KvStoreNbDelegate *&delegatePtr,
72         KvStoreDelegateManager &mgr, bool syncDualTupleMode = false)
73     {
74         if (g_testDir == nullptr) {
75             return DB_ERROR;
76         }
77         std::string dbPath = *g_testDir + dlpPath;
78         KvStoreConfig storeConfig;
79         storeConfig.dataDir = dbPath;
80         OS::MakeDBDirectory(dbPath);
81         mgr.SetKvStoreConfig(storeConfig);
82 
83         string dir = dbPath + "/single_ver";
84         DIR* dirTmp = opendir(dir.c_str());
85         if (dirTmp == nullptr) {
86             OS::MakeDBDirectory(dir);
87         } else {
88             closedir(dirTmp);
89         }
90 
91         KvStoreNbDelegate::Option option;
92         option.syncDualTupleMode = syncDualTupleMode;
93         DBStatus res = OK;
94         mgr.GetKvStore(STORE_ID_1, option, [&delegatePtr, &res](DBStatus status, KvStoreNbDelegate *delegate) {
95             delegatePtr = delegate;
96             res = status;
97         });
98         return res;
99     }
100 
GetDataBaseSchema()101     DataBaseSchema GetDataBaseSchema()
102     {
103         DataBaseSchema schema;
104         TableSchema tableSchema;
105         tableSchema.name = CloudDbConstant::CLOUD_KV_TABLE_NAME;
106         Field field;
107         field.colName = CloudDbConstant::CLOUD_KV_FIELD_KEY;
108         field.type = TYPE_INDEX<std::string>;
109         field.primary = true;
110         tableSchema.fields.push_back(field);
111         field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE;
112         field.primary = false;
113         tableSchema.fields.push_back(field);
114         field.colName = CloudDbConstant::CLOUD_KV_FIELD_ORI_DEVICE;
115         tableSchema.fields.push_back(field);
116         field.colName = CloudDbConstant::CLOUD_KV_FIELD_VALUE;
117         tableSchema.fields.push_back(field);
118         field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE_CREATE_TIME;
119         field.type = TYPE_INDEX<int64_t>;
120         tableSchema.fields.push_back(field);
121         schema.tables.push_back(tableSchema);
122         return schema;
123     }
124 
SetCloudDB(KvStoreNbDelegate * & delegatePtr)125     DBStatus SetCloudDB(KvStoreNbDelegate *&delegatePtr)
126     {
127         std::map<std::string, std::shared_ptr<ICloudDb>> cloudDbs;
128         cloudDbs[USER_ID] = virtualCloudDb_;
129         delegatePtr->SetCloudDB(cloudDbs);
130         std::map<std::string, DataBaseSchema> schemas;
131         schemas[USER_ID] = GetDataBaseSchema();
132         return delegatePtr->SetCloudDbSchema(schemas);
133     }
134 
OpenDelegate(const std::string & dlpPath,RelationalStoreDelegate * & rdbDelegatePtr,RelationalStoreManager & mgr,sqlite3 * & db)135     DBStatus OpenDelegate(const std::string &dlpPath, RelationalStoreDelegate *&rdbDelegatePtr,
136         RelationalStoreManager &mgr, sqlite3 *&db)
137     {
138         if (g_testDir == nullptr) {
139             return DB_ERROR;
140         }
141         std::string dbDir = *g_testDir + dlpPath;
142         OS::MakeDBDirectory(dbDir);
143         std::string dbPath = dbDir + "/test.db";
144         db = RelationalTestUtils::CreateDataBase(dbPath);
145         EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
146         EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_SINGLE_PRIMARY_KEY_TABLE), SQLITE_OK);
147         RelationalStoreObserverUnitTest *observer = new (std::nothrow) RelationalStoreObserverUnitTest();
148         RelationalStoreDelegate::Option option = { .observer = observer };
149         return mgr.OpenStore(dbPath, STORE_ID_1, option, rdbDelegatePtr);
150     }
151 
GetCloudDbSchema(DataBaseSchema & dataBaseSchema)152     void GetCloudDbSchema(DataBaseSchema &dataBaseSchema)
153     {
154         TableSchema assetsTableSchema = {.name = ASSETS_TABLE_NAME, .sharedTableName = ASSETS_TABLE_NAME_SHARED,
155             .fields = CLOUD_FIELDS};
156         dataBaseSchema.tables.push_back(assetsTableSchema);
157     }
158 
SetCloudDB(RelationalStoreDelegate * & delegatePtr)159     DBStatus SetCloudDB(RelationalStoreDelegate *&delegatePtr)
160     {
161         EXPECT_EQ(delegatePtr->CreateDistributedTable(ASSETS_TABLE_NAME, CLOUD_COOPERATION), DBStatus::OK);
162         std::shared_ptr<VirtualAssetLoader> virtualAssetLoader = make_shared<VirtualAssetLoader>();
163         EXPECT_EQ(delegatePtr->SetCloudDB(virtualCloudDb_), DBStatus::OK);
164         EXPECT_EQ(delegatePtr->SetIAssetLoader(virtualAssetLoader), DBStatus::OK);
165         DataBaseSchema dataBaseSchema;
166         GetCloudDbSchema(dataBaseSchema);
167         return delegatePtr->SetCloudDbSchema(dataBaseSchema);
168     }
169 
CloseDelegate(KvStoreNbDelegate * & delegatePtr,KvStoreDelegateManager & mgr,std::string storeID)170     void CloseDelegate(KvStoreNbDelegate *&delegatePtr, KvStoreDelegateManager &mgr, std::string storeID)
171     {
172         if (delegatePtr == nullptr) {
173             return;
174         }
175         EXPECT_EQ(mgr.CloseKvStore(delegatePtr), OK);
176         delegatePtr = nullptr;
177         EXPECT_EQ(mgr.DeleteKvStore(storeID), OK);
178     }
179 
CloseDelegate(RelationalStoreDelegate * & delegatePtr,RelationalStoreManager & mgr,sqlite3 * & db)180     void CloseDelegate(RelationalStoreDelegate *&delegatePtr, RelationalStoreManager &mgr, sqlite3 *&db)
181     {
182         EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
183         db = nullptr;
184         if (delegatePtr == nullptr) {
185             return;
186         }
187         EXPECT_EQ(mgr.CloseStore(delegatePtr), OK);
188         delegatePtr = nullptr;
189     }
190 
191 class DistributedDBSingleVerMultiSubUserTest : public testing::Test {
192 public:
193     static void SetUpTestCase(void);
194     static void TearDownTestCase(void);
195     void SetUp();
196     void TearDown();
197 protected:
198     void BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, CloudSyncOption option,
199         int expectSyncResult = OK);
200     void InsertLocalData(int64_t begin, int64_t count, const std::string &tableName, bool isAssetNull, sqlite3 *&db);
201     void GenerateDataRecords(int64_t begin, int64_t count, int64_t gidStart, std::vector<VBucket> &record,
202         std::vector<VBucket> &extend);
203     CloudSyncOption PrepareOption(const Query &query, LockAction action);
204     void CallSync(RelationalStoreDelegate *delegate, const CloudSyncOption &option, DBStatus expectResult = OK);
205     SyncProcess lastProcess_;
206 };
207 
SetUpTestCase(void)208 void DistributedDBSingleVerMultiSubUserTest::SetUpTestCase(void)
209 {
210     /**
211      * @tc.setup: Init datadir and Virtual Communicator.
212      */
213     std::string testDir;
214     DistributedDBToolsUnitTest::TestDirInit(testDir);
215     if (g_testDir == nullptr) {
216         g_testDir = std::make_shared<std::string>(testDir);
217     }
218 
219     g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
220     ASSERT_TRUE(g_communicatorAggregator != nullptr);
221     RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
222 
223     g_CloudSyncoption.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
224     g_CloudSyncoption.users.push_back(USER_ID);
225     g_CloudSyncoption.devices.push_back("cloud");
226     g_virtualCloudDataTranslate = std::make_shared<VirtualCloudDataTranslate>();
227     RuntimeConfig::SetCloudTranslate(g_virtualCloudDataTranslate);
228 }
229 
TearDownTestCase(void)230 void DistributedDBSingleVerMultiSubUserTest::TearDownTestCase(void)
231 {
232     /**
233      * @tc.teardown: Release virtual Communicator and clear data dir.
234      */
235     if (g_testDir != nullptr && DistributedDBToolsUnitTest::RemoveTestDbFiles(*g_testDir) != 0) {
236         LOGE("rm test db files error!");
237     }
238     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
239 }
240 
SetUp(void)241 void DistributedDBSingleVerMultiSubUserTest::SetUp(void)
242 {
243     virtualCloudDb_ = std::make_shared<VirtualCloudDb>();
244     DistributedDBToolsUnitTest::PrintTestCaseInfo();
245     g_deviceB = new (std::nothrow) KvVirtualDevice(DEVICE_B);
246     ASSERT_TRUE(g_deviceB != nullptr);
247     VirtualSingleVerSyncDBInterface *syncInterfaceB = new (std::nothrow) VirtualSingleVerSyncDBInterface();
248     ASSERT_TRUE(syncInterfaceB != nullptr);
249     ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
250 }
251 
TearDown(void)252 void DistributedDBSingleVerMultiSubUserTest::TearDown(void)
253 {
254     virtualCloudDb_ = nullptr;
255     if (g_deviceB != nullptr) {
256         delete g_deviceB;
257         g_deviceB = nullptr;
258     }
259     PermissionCheckCallbackV3 nullCallback = nullptr;
260     RuntimeConfig::SetPermissionCheckCallback(nullCallback);
261     SyncActivationCheckCallbackV2 activeCallBack = nullptr;
262     RuntimeConfig::SetSyncActivationCheckCallback(activeCallBack);
263     RuntimeConfig::SetPermissionConditionCallback(nullptr);
264     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(*g_testDir) != 0) {
265         LOGE("rm test db files error.");
266     }
267 }
268 
BlockSync(KvStoreNbDelegate * delegate,DBStatus expectDBStatus,CloudSyncOption option,int expectSyncResult)269 void DistributedDBSingleVerMultiSubUserTest::BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus,
270     CloudSyncOption option, int expectSyncResult)
271 {
272     if (delegate == nullptr) {
273         return;
274     }
275     std::mutex dataMutex;
276     std::condition_variable cv;
277     bool finish = false;
278     SyncProcess last;
279     auto callback = [expectDBStatus, &last, &cv, &dataMutex, &finish, &option](const std::map<std::string,
280         SyncProcess> &process) {
281         size_t notifyCnt = 0;
282         for (const auto &item: process) {
283             LOGD("user = %s, status = %d", item.first.c_str(), item.second.process);
284             if (item.second.process != DistributedDB::FINISHED) {
285                 continue;
286             }
287             EXPECT_EQ(item.second.errCode, expectDBStatus);
288             {
289                 std::lock_guard<std::mutex> autoLock(dataMutex);
290                 notifyCnt++;
291                 if (notifyCnt == option.users.size()) {
292                     finish = true;
293                     last = item.second;
294                     cv.notify_one();
295                 }
296             }
297         }
298     };
299     EXPECT_EQ(delegate->Sync(option, callback), expectSyncResult);
300     if (expectSyncResult == OK) {
301         std::unique_lock<std::mutex> uniqueLock(dataMutex);
302         cv.wait(uniqueLock, [&finish]() {
303             return finish;
304         });
305     }
306     lastProcess_ = last;
307 }
308 
GenerateDataRecords(int64_t begin,int64_t count,int64_t gidStart,std::vector<VBucket> & record,std::vector<VBucket> & extend)309 void DistributedDBSingleVerMultiSubUserTest::GenerateDataRecords(
310     int64_t begin, int64_t count, int64_t gidStart, std::vector<VBucket> &record, std::vector<VBucket> &extend)
311 {
312     for (int64_t i = begin; i < begin + count; i++) {
313         Assets assets;
314         Asset asset = ASSET_COPY;
315         asset.name = ASSET_COPY.name + std::to_string(i);
316         assets.emplace_back(asset);
317         asset.name = ASSET_COPY.name + std::to_string(i) + "_copy";
318         assets.emplace_back(asset);
319         VBucket data;
320         data.insert_or_assign(COL_ID, i);
321         data.insert_or_assign(COL_NAME, "name" + std::to_string(g_nameId++));
322         data.insert_or_assign(COL_ASSETS, assets);
323         record.push_back(data);
324 
325         VBucket log;
326         Timestamp now = TimeHelper::GetSysCurrentTime();
327         log.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND);
328         log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND);
329         log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false);
330         log.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(i + gidStart));
331         extend.push_back(log);
332     }
333 }
334 
InsertLocalData(int64_t begin,int64_t count,const std::string & tableName,bool isAssetNull,sqlite3 * & db)335 void DistributedDBSingleVerMultiSubUserTest::InsertLocalData(int64_t begin, int64_t count,
336     const std::string &tableName, bool isAssetNull, sqlite3 *&db)
337 {
338     int errCode;
339     std::vector<VBucket> record;
340     std::vector<VBucket> extend;
341     GenerateDataRecords(begin, count, 0, record, extend);
342     const string sql = "insert or replace into " + tableName + " values (?,?,?,?);";
343     for (VBucket vBucket : record) {
344         sqlite3_stmt *stmt = nullptr;
345         ASSERT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
346         ASSERT_EQ(SQLiteUtils::BindInt64ToStatement(stmt, 1, std::get<int64_t>(vBucket[COL_ID])), E_OK); // 1 is id
347         ASSERT_EQ(SQLiteUtils::BindTextToStatement(stmt, 2, std::get<string>(vBucket[COL_NAME])), E_OK); // 2 is name
348         if (isAssetNull) {
349             ASSERT_EQ(sqlite3_bind_null(stmt, 3), SQLITE_OK); // 3 is asset
350         } else {
351             std::vector<uint8_t> assetBlob = g_virtualCloudDataTranslate->AssetToBlob(ASSET_COPY);
352             ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 3, assetBlob, false), E_OK); // 3 is asset
353         }
354         std::vector<uint8_t> assetsBlob = g_virtualCloudDataTranslate->AssetsToBlob(
355             std::get<Assets>(vBucket[COL_ASSETS]));
356         ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 4, assetsBlob, false), E_OK); // 4 is assets
357         EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
358         SQLiteUtils::ResetStatement(stmt, true, errCode);
359     }
360 }
361 
PrepareOption(const Query & query,LockAction action)362 CloudSyncOption DistributedDBSingleVerMultiSubUserTest::PrepareOption(const Query &query, LockAction action)
363 {
364     CloudSyncOption option;
365     option.devices = { "CLOUD" };
366     option.mode = SYNC_MODE_CLOUD_MERGE;
367     option.query = query;
368     option.waitTime = WAIT_TIME;
369     option.priorityTask = false;
370     option.compensatedSyncOnly = false;
371     option.lockAction = action;
372     return option;
373 }
374 
CallSync(RelationalStoreDelegate * delegate,const CloudSyncOption & option,DBStatus expectResult)375 void DistributedDBSingleVerMultiSubUserTest::CallSync(RelationalStoreDelegate *delegate, const CloudSyncOption &option,
376     DBStatus expectResult)
377 {
378     std::mutex dataMutex;
379     std::condition_variable cv;
380     bool finish = false;
381     auto callback = [&cv, &dataMutex, &finish](const std::map<std::string, SyncProcess> &process) {
382         for (const auto &item: process) {
383             if (item.second.process == DistributedDB::FINISHED) {
384                 {
385                     std::lock_guard<std::mutex> autoLock(dataMutex);
386                     finish = true;
387                 }
388                 cv.notify_one();
389             }
390         }
391     };
392     ASSERT_EQ(delegate->Sync(option, callback), expectResult);
393     if (expectResult == OK) {
394         std::unique_lock<std::mutex> uniqueLock(dataMutex);
395         cv.wait(uniqueLock, [&finish]() {
396             return finish;
397         });
398     }
399 }
400 
401 /**
402  * @tc.name: KvDelegateInvalidParamTest001
403  * @tc.desc: Test kv delegate open with invalid subUser.
404  * @tc.type: FUNC
405  * @tc.require:
406  * @tc.author: zhaoliang
407  */
408 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, KvDelegateInvalidParamTest001, TestSize.Level1)
409 {
410     std::string subUser1 = std::string(129, 'a');
411     KvStoreDelegateManager mgr1(APP_ID, USER_ID, subUser1, INSTANCE_ID_1);
412     KvStoreNbDelegate *delegatePtr1 = nullptr;
413     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), INVALID_ARGS);
414     ASSERT_EQ(delegatePtr1, nullptr);
415 
416     std::string subUser2 = "subUser-1";
417     KvStoreDelegateManager mgr2(APP_ID, USER_ID, subUser2, INSTANCE_ID_1);
418     KvStoreNbDelegate *delegatePtr2 = nullptr;
419     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr2, mgr2), INVALID_ARGS);
420     ASSERT_EQ(delegatePtr2, nullptr);
421 
422     std::string subUser3 = std::string(128, 'a');
423     KvStoreDelegateManager mgr3(APP_ID, USER_ID, subUser3, INSTANCE_ID_1);
424     KvStoreNbDelegate *delegatePtr3 = nullptr;
425     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr3, mgr3), OK);
426     ASSERT_NE(delegatePtr3, nullptr);
427 
428     CloseDelegate(delegatePtr3, mgr3, STORE_ID_1);
429 }
430 
431 /**
432  * @tc.name: RDBDelegateInvalidParamTest001
433  * @tc.desc: Test rdb delegate open with invalid subUser.
434  * @tc.type: FUNC
435  * @tc.require:
436  * @tc.author: zhaoliang
437  */
438 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, RDBDelegateInvalidParamTest001, TestSize.Level1)
439 {
440     std::string subUser1 = std::string(129, 'a');
441     RelationalStoreManager mgr1(APP_ID, USER_ID, subUser1, INSTANCE_ID_1);
442     RelationalStoreDelegate *rdbDelegatePtr1 = nullptr;
443     sqlite3 *db1;
444     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, mgr1, db1), INVALID_ARGS);
445     ASSERT_EQ(rdbDelegatePtr1, nullptr);
446 
447     std::string subUser2 = "subUser-1";
448     RelationalStoreManager mgr2(APP_ID, USER_ID, subUser2, INSTANCE_ID_1);
449     RelationalStoreDelegate *rdbDelegatePtr2 = nullptr;
450     sqlite3 *db2;
451     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr2, mgr2, db2), INVALID_ARGS);
452     ASSERT_EQ(rdbDelegatePtr2, nullptr);
453 
454     std::string subUser3 = std::string(128, 'a');
455     RelationalStoreManager mgr3(APP_ID, USER_ID, subUser3, INSTANCE_ID_1);
456     RelationalStoreDelegate *rdbDelegatePtr3 = nullptr;
457     sqlite3 *db3;
458     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr3, mgr3, db3), OK);
459     ASSERT_NE(rdbDelegatePtr3, nullptr);
460 
461     CloseDelegate(rdbDelegatePtr3, mgr3, db3);
462 }
463 
464 /**
465  * @tc.name: SameDelegateTest001
466  * @tc.desc: Test kv delegate open with diff subUser.
467  * @tc.type: FUNC
468  * @tc.require:
469  * @tc.author: zhaoliang
470  */
471 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SameDelegateTest001, TestSize.Level1)
472 {
473     KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
474     KvStoreNbDelegate *delegatePtr1 = nullptr;
475     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK);
476     ASSERT_NE(delegatePtr1, nullptr);
477 
478     KvStoreDelegateManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1);
479     KvStoreNbDelegate *delegatePtr2 = nullptr;
480     EXPECT_EQ(OpenDelegate("/subUser2", delegatePtr2, mgr2), OK);
481     ASSERT_NE(delegatePtr2, nullptr);
482 
483     Key key1 = {'k', '1'};
484     Value value1 = {'v', '1'};
485     delegatePtr1->Put(key1, value1);
486     Key key2 = {'k', '2'};
487     Value value2 = {'v', '2'};
488     delegatePtr2->Put(key2, value2);
489 
490     Value value;
491     EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
492     EXPECT_EQ(value1, value);
493     EXPECT_EQ(delegatePtr2->Get(key2, value), OK);
494     EXPECT_EQ(value2, value);
495 
496     EXPECT_EQ(delegatePtr1->Get(key2, value), NOT_FOUND);
497     EXPECT_EQ(delegatePtr2->Get(key1, value), NOT_FOUND);
498 
499     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
500     CloseDelegate(delegatePtr2, mgr2, STORE_ID_1);
501 }
502 
503 /**
504  * @tc.name: SameDelegateTest002
505  * @tc.desc: Test rdb delegate open with diff subUser.
506  * @tc.type: FUNC
507  * @tc.require:
508  * @tc.author: zhaoliang
509  */
510 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SameDelegateTest002, TestSize.Level1)
511 {
512     RelationalStoreManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
513     RelationalStoreDelegate *rdbDelegatePtr1 = nullptr;
514     sqlite3 *db1;
515     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, mgr1, db1), OK);
516     ASSERT_NE(rdbDelegatePtr1, nullptr);
517 
518     RelationalStoreManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1);
519     RelationalStoreDelegate *rdbDelegatePtr2 = nullptr;
520     sqlite3 *db2;
521     EXPECT_EQ(OpenDelegate("/subUser2", rdbDelegatePtr2, mgr2, db2), OK);
522     ASSERT_NE(rdbDelegatePtr2, nullptr);
523 
524     int localCount = 10;
525     InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1);
526     InsertLocalData(10, localCount, ASSETS_TABLE_NAME, true, db2);
527 
528     std::string sql1 = "select count(*) from " + ASSETS_TABLE_NAME + " where id < 10;";
529     std::string sql2 = "select count(*) from " + ASSETS_TABLE_NAME + " where id >= 10;";
530 
531     EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
532         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
533     EXPECT_EQ(sqlite3_exec(db2, sql2.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
534         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
535 
536     EXPECT_EQ(sqlite3_exec(db1, sql2.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
537         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
538     EXPECT_EQ(sqlite3_exec(db2, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
539         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
540 
541     CloseDelegate(rdbDelegatePtr1, mgr1, db1);
542     CloseDelegate(rdbDelegatePtr2, mgr2, db2);
543 }
544 
545 /**
546  * @tc.name: SubUserDelegateCRUDTest001
547  * @tc.desc: Test subUser rdb delegate crud function.
548  * @tc.type: FUNC
549  * @tc.require:
550  * @tc.author: zhaoliang
551  */
552 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCRUDTest001, TestSize.Level1)
553 {
554     RelationalStoreManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
555     RelationalStoreDelegate *rdbDelegatePtr1 = nullptr;
556     sqlite3 *db1;
557     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, mgr1, db1), OK);
558     ASSERT_NE(rdbDelegatePtr1, nullptr);
559 
560     int localCount = 10;
561     InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1);
562     std::string sql1 = "select count(*) from " + ASSETS_TABLE_NAME + ";";
563     EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
564         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
565 
566     InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1);
567     EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
568         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
569 
570     std::string sql2 = "delete from " + ASSETS_TABLE_NAME + ";";
571     EXPECT_EQ(sqlite3_exec(db1, sql2.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
572         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
573     EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
574         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
575 
576     CloseDelegate(rdbDelegatePtr1, mgr1, db1);
577 }
578 
579 /**
580  * @tc.name: SubUserDelegateCRUDTest002
581  * @tc.desc: Test subUser kv delegate crud function.
582  * @tc.type: FUNC
583  * @tc.require:
584  * @tc.author: zhaoliang
585  */
586 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCRUDTest002, TestSize.Level1)
587 {
588     KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
589     KvStoreNbDelegate *delegatePtr1 = nullptr;
590     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK);
591     ASSERT_NE(delegatePtr1, nullptr);
592 
593     Key key1 = {'k', '1'};
594     Value value1 = {'v', '1'};
595     delegatePtr1->Put(key1, value1);
596 
597     Value value;
598     EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
599     EXPECT_EQ(value1, value);
600 
601     Value value2 = {'v', '2'};
602     delegatePtr1->Put(key1, value2);
603     EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
604     EXPECT_EQ(value2, value);
605 
606     EXPECT_EQ(delegatePtr1->Delete(key1), OK);
607     EXPECT_EQ(delegatePtr1->Get(key1, value), NOT_FOUND);
608 
609     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
610 }
611 
612 /**
613  * @tc.name: SubUserDelegateCloudSyncTest001
614  * @tc.desc: Test subUser kv delegate cloud sync function.
615  * @tc.type: FUNC
616  * @tc.require:
617  * @tc.author: zhaoliang
618  */
619 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCloudSyncTest001, TestSize.Level0)
620 {
621     KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
622     KvStoreNbDelegate *delegatePtr1 = nullptr;
623     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK);
624     ASSERT_NE(delegatePtr1, nullptr);
625     EXPECT_EQ(SetCloudDB(delegatePtr1), OK);
626 
627     KvStoreDelegateManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1);
628     KvStoreNbDelegate *delegatePtr2 = nullptr;
629     EXPECT_EQ(OpenDelegate("/subUser2", delegatePtr2, mgr2), OK);
630     ASSERT_NE(delegatePtr2, nullptr);
631     EXPECT_EQ(SetCloudDB(delegatePtr2), OK);
632 
633     Key key = {'k'};
634     Value expectValue = {'v'};
635     ASSERT_EQ(delegatePtr1->Put(key, expectValue), OK);
636     BlockSync(delegatePtr1, OK, g_CloudSyncoption);
637     for (const auto &table : lastProcess_.tableProcess) {
638         EXPECT_EQ(table.second.upLoadInfo.total, 1u);
639     }
640     BlockSync(delegatePtr2, OK, g_CloudSyncoption);
641     for (const auto &table : lastProcess_.tableProcess) {
642         EXPECT_EQ(table.second.downLoadInfo.total, 1u);
643     }
644     Value actualValue;
645     EXPECT_EQ(delegatePtr2->Get(key, actualValue), OK);
646     EXPECT_EQ(actualValue, expectValue);
647 
648     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
649     CloseDelegate(delegatePtr2, mgr2, STORE_ID_1);
650 }
651 
652 /**
653  * @tc.name: SubUserDelegateCloudSyncTest002
654  * @tc.desc: Test subUser rdb delegate cloud sync function.
655  * @tc.type: FUNC
656  * @tc.require:
657  * @tc.author: zhaoliang
658  */
659 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCloudSyncTest002, TestSize.Level0)
660 {
661     RelationalStoreManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
662     RelationalStoreDelegate *rdbDelegatePtr1 = nullptr;
663     sqlite3 *db1;
664     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, mgr1, db1), OK);
665     ASSERT_NE(rdbDelegatePtr1, nullptr);
666     EXPECT_EQ(SetCloudDB(rdbDelegatePtr1), OK);
667 
668     RelationalStoreManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1);
669     RelationalStoreDelegate *rdbDelegatePtr2 = nullptr;
670     sqlite3 *db2;
671     EXPECT_EQ(OpenDelegate("/subUser2", rdbDelegatePtr2, mgr2, db2), OK);
672     ASSERT_NE(rdbDelegatePtr2, nullptr);
673     EXPECT_EQ(SetCloudDB(rdbDelegatePtr2), OK);
674 
675     int localCount = 10;
676     InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1);
677     CloudSyncOption option = PrepareOption(Query::Select().FromTable({ ASSETS_TABLE_NAME }), LockAction::NONE);
678     CallSync(rdbDelegatePtr1, option);
679     CallSync(rdbDelegatePtr2, option);
680 
681     std::string sql = "select count(*) from " + ASSETS_TABLE_NAME + ";";
682     EXPECT_EQ(sqlite3_exec(db2, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
683         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
684 
685     CloseDelegate(rdbDelegatePtr1, mgr1, db1);
686     CloseDelegate(rdbDelegatePtr2, mgr2, db2);
687 }
688 
689 /**
690  * @tc.name: MultiSubUserDelegateSync001
691  * @tc.desc: Test subUser delegate sync function.
692  * @tc.type: FUNC
693  * @tc.require:
694  * @tc.author: zhaoliang
695  */
696 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, MultiSubUserDelegateSync001, TestSize.Level1)
697 {
698     KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
__anon104506260702(const PermissionCheckParam &param, uint8_t flag) 699     RuntimeConfig::SetPermissionCheckCallback([](const PermissionCheckParam &param, uint8_t flag) {
700         if ((flag & PermissionCheckFlag::CHECK_FLAG_RECEIVE) != 0) {
701             bool res = false;
702             if (param.extraConditions.find(KEY_SUB_USER) != param.extraConditions.end()) {
703                 res = param.extraConditions.at(KEY_SUB_USER) == SUB_USER_1;
704             }
705             return res;
706         }
707         if (param.userId != USER_ID || param.appId != APP_ID || param.storeId != STORE_ID_1 ||
708             (param.instanceId != INSTANCE_ID_1 && param.instanceId != 0)) {
709             return false;
710         }
711         return true;
712     });
__anon104506260802(const PermissionConditionParam &param) 713     RuntimeConfig::SetPermissionConditionCallback([](const PermissionConditionParam &param) {
714         std::map<std::string, std::string> res;
715         res.emplace(KEY_SUB_USER, SUB_USER_1);
716         return res;
717     });
718 
719     KvStoreNbDelegate *delegatePtr1 = nullptr;
720     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK);
721     ASSERT_NE(delegatePtr1, nullptr);
722 
723     Key key1 = {'k', '1'};
724     Value value1 = {'v', '1'};
725     delegatePtr1->Put(key1, value1);
726 
727     std::map<std::string, DBStatus> result;
728     DBStatus status = g_tool.SyncTest(delegatePtr1, { DEVICE_B }, SYNC_MODE_PUSH_ONLY, result);
729     EXPECT_TRUE(status == OK);
730     EXPECT_EQ(result[DEVICE_B], OK);
731 
732     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
733 }
734 
735 /**
736  * @tc.name: MultiSubUserDelegateSync002
737  * @tc.desc: Test subUser delegate sync active if callback return true.
738  * @tc.type: FUNC
739  * @tc.require:
740  * @tc.author: zhaoliang
741  */
742 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, MultiSubUserDelegateSync002, TestSize.Level1)
743 {
744     KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
__anon104506260902(const ActivationCheckParam &param) 745     RuntimeConfig::SetSyncActivationCheckCallback([](const ActivationCheckParam &param) {
746         if (param.userId == USER_ID && param.appId == APP_ID && param.storeId == STORE_ID_1 &&
747             param.instanceId == INSTANCE_ID_1) {
748             return true;
749         }
750         return false;
751     });
752 
753     KvStoreNbDelegate *delegatePtr1 = nullptr;
754     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1, true), OK);
755     ASSERT_NE(delegatePtr1, nullptr);
756 
757     std::map<std::string, DBStatus> result;
758     DBStatus status = g_tool.SyncTest(delegatePtr1, { DEVICE_B }, SYNC_MODE_PUSH_ONLY, result);
759     EXPECT_EQ(status, OK);
760     EXPECT_EQ(result[DEVICE_B], OK);
761 
762     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
763 }
764 
765 } // namespace