• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,RelationalStoreObserverUnitTest * & observer,RelationalStoreManager & mgr,sqlite3 * & db)135     DBStatus OpenDelegate(const std::string &dlpPath, RelationalStoreDelegate *&rdbDelegatePtr,
136         RelationalStoreObserverUnitTest *&observer, 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         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,RelationalStoreObserverUnitTest * & observer,RelationalStoreManager & mgr,sqlite3 * & db)180     void CloseDelegate(RelationalStoreDelegate *&delegatePtr, RelationalStoreObserverUnitTest *&observer,
181         RelationalStoreManager &mgr, sqlite3 *&db)
182     {
183         EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
184         db = nullptr;
185         if (delegatePtr != nullptr) {
186             EXPECT_EQ(mgr.CloseStore(delegatePtr), OK);
187             delegatePtr = nullptr;
188         }
189         if (observer == nullptr) {
190             return;
191         }
192         delete observer;
193         observer = nullptr;
194     }
195 
196 class DistributedDBSingleVerMultiSubUserTest : public testing::Test {
197 public:
198     static void SetUpTestCase(void);
199     static void TearDownTestCase(void);
200     void SetUp();
201     void TearDown();
202 protected:
203     void BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, CloudSyncOption option,
204         int expectSyncResult = OK);
205     void InsertLocalData(int64_t begin, int64_t count, const std::string &tableName, bool isAssetNull, sqlite3 *&db);
206     void GenerateDataRecords(int64_t begin, int64_t count, int64_t gidStart, std::vector<VBucket> &record,
207         std::vector<VBucket> &extend);
208     CloudSyncOption PrepareOption(const Query &query, LockAction action);
209     void CallSync(RelationalStoreDelegate *delegate, const CloudSyncOption &option, DBStatus expectResult = OK);
210     SyncProcess lastProcess_;
211 };
212 
SetUpTestCase(void)213 void DistributedDBSingleVerMultiSubUserTest::SetUpTestCase(void)
214 {
215     /**
216      * @tc.setup: Init datadir and Virtual Communicator.
217      */
218     std::string testDir;
219     DistributedDBToolsUnitTest::TestDirInit(testDir);
220     if (g_testDir == nullptr) {
221         g_testDir = std::make_shared<std::string>(testDir);
222     }
223 
224     g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
225     ASSERT_TRUE(g_communicatorAggregator != nullptr);
226     RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
227 
228     g_CloudSyncoption.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
229     g_CloudSyncoption.users.push_back(USER_ID);
230     g_CloudSyncoption.devices.push_back("cloud");
231     g_virtualCloudDataTranslate = std::make_shared<VirtualCloudDataTranslate>();
232     RuntimeConfig::SetCloudTranslate(g_virtualCloudDataTranslate);
233 }
234 
TearDownTestCase(void)235 void DistributedDBSingleVerMultiSubUserTest::TearDownTestCase(void)
236 {
237     /**
238      * @tc.teardown: Release virtual Communicator and clear data dir.
239      */
240     if (g_testDir != nullptr && DistributedDBToolsUnitTest::RemoveTestDbFiles(*g_testDir) != 0) {
241         LOGE("rm test db files error!");
242     }
243     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
244 }
245 
SetUp(void)246 void DistributedDBSingleVerMultiSubUserTest::SetUp(void)
247 {
248     virtualCloudDb_ = std::make_shared<VirtualCloudDb>();
249     DistributedDBToolsUnitTest::PrintTestCaseInfo();
250     g_deviceB = new (std::nothrow) KvVirtualDevice(DEVICE_B);
251     ASSERT_TRUE(g_deviceB != nullptr);
252     VirtualSingleVerSyncDBInterface *syncInterfaceB = new (std::nothrow) VirtualSingleVerSyncDBInterface();
253     ASSERT_TRUE(syncInterfaceB != nullptr);
254     ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
255 }
256 
TearDown(void)257 void DistributedDBSingleVerMultiSubUserTest::TearDown(void)
258 {
259     virtualCloudDb_ = nullptr;
260     if (g_deviceB != nullptr) {
261         delete g_deviceB;
262         g_deviceB = nullptr;
263     }
264     PermissionCheckCallbackV3 nullCallback = nullptr;
265     RuntimeConfig::SetPermissionCheckCallback(nullCallback);
266     SyncActivationCheckCallbackV2 activeCallBack = nullptr;
267     RuntimeConfig::SetSyncActivationCheckCallback(activeCallBack);
268     RuntimeConfig::SetPermissionConditionCallback(nullptr);
269     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(*g_testDir) != 0) {
270         LOGE("rm test db files error.");
271     }
272 }
273 
BlockSync(KvStoreNbDelegate * delegate,DBStatus expectDBStatus,CloudSyncOption option,int expectSyncResult)274 void DistributedDBSingleVerMultiSubUserTest::BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus,
275     CloudSyncOption option, int expectSyncResult)
276 {
277     if (delegate == nullptr) {
278         return;
279     }
280     std::mutex dataMutex;
281     std::condition_variable cv;
282     bool finish = false;
283     SyncProcess last;
284     auto callback = [expectDBStatus, &last, &cv, &dataMutex, &finish, &option](const std::map<std::string,
285         SyncProcess> &process) {
286         size_t notifyCnt = 0;
287         for (const auto &item: process) {
288             LOGD("user = %s, status = %d", item.first.c_str(), item.second.process);
289             if (item.second.process != DistributedDB::FINISHED) {
290                 continue;
291             }
292             EXPECT_EQ(item.second.errCode, expectDBStatus);
293             {
294                 std::lock_guard<std::mutex> autoLock(dataMutex);
295                 notifyCnt++;
296                 if (notifyCnt == option.users.size()) {
297                     finish = true;
298                     last = item.second;
299                     cv.notify_one();
300                 }
301             }
302         }
303     };
304     EXPECT_EQ(delegate->Sync(option, callback), expectSyncResult);
305     if (expectSyncResult == OK) {
306         std::unique_lock<std::mutex> uniqueLock(dataMutex);
307         cv.wait(uniqueLock, [&finish]() {
308             return finish;
309         });
310     }
311     lastProcess_ = last;
312 }
313 
GenerateDataRecords(int64_t begin,int64_t count,int64_t gidStart,std::vector<VBucket> & record,std::vector<VBucket> & extend)314 void DistributedDBSingleVerMultiSubUserTest::GenerateDataRecords(
315     int64_t begin, int64_t count, int64_t gidStart, std::vector<VBucket> &record, std::vector<VBucket> &extend)
316 {
317     for (int64_t i = begin; i < begin + count; i++) {
318         Assets assets;
319         Asset asset = ASSET_COPY;
320         asset.name = ASSET_COPY.name + std::to_string(i);
321         assets.emplace_back(asset);
322         asset.name = ASSET_COPY.name + std::to_string(i) + "_copy";
323         assets.emplace_back(asset);
324         VBucket data;
325         data.insert_or_assign(COL_ID, i);
326         data.insert_or_assign(COL_NAME, "name" + std::to_string(g_nameId++));
327         data.insert_or_assign(COL_ASSETS, assets);
328         record.push_back(data);
329 
330         VBucket log;
331         Timestamp now = TimeHelper::GetSysCurrentTime();
332         log.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND);
333         log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND);
334         log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false);
335         log.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(i + gidStart));
336         extend.push_back(log);
337     }
338 }
339 
InsertLocalData(int64_t begin,int64_t count,const std::string & tableName,bool isAssetNull,sqlite3 * & db)340 void DistributedDBSingleVerMultiSubUserTest::InsertLocalData(int64_t begin, int64_t count,
341     const std::string &tableName, bool isAssetNull, sqlite3 *&db)
342 {
343     int errCode;
344     std::vector<VBucket> record;
345     std::vector<VBucket> extend;
346     GenerateDataRecords(begin, count, 0, record, extend);
347     const string sql = "insert or replace into " + tableName + " values (?,?,?,?);";
348     for (VBucket vBucket : record) {
349         sqlite3_stmt *stmt = nullptr;
350         ASSERT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
351         ASSERT_EQ(SQLiteUtils::BindInt64ToStatement(stmt, 1, std::get<int64_t>(vBucket[COL_ID])), E_OK); // 1 is id
352         ASSERT_EQ(SQLiteUtils::BindTextToStatement(stmt, 2, std::get<string>(vBucket[COL_NAME])), E_OK); // 2 is name
353         if (isAssetNull) {
354             ASSERT_EQ(sqlite3_bind_null(stmt, 3), SQLITE_OK); // 3 is asset
355         } else {
356             std::vector<uint8_t> assetBlob = g_virtualCloudDataTranslate->AssetToBlob(ASSET_COPY);
357             ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 3, assetBlob, false), E_OK); // 3 is asset
358         }
359         std::vector<uint8_t> assetsBlob = g_virtualCloudDataTranslate->AssetsToBlob(
360             std::get<Assets>(vBucket[COL_ASSETS]));
361         ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 4, assetsBlob, false), E_OK); // 4 is assets
362         EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
363         SQLiteUtils::ResetStatement(stmt, true, errCode);
364     }
365 }
366 
PrepareOption(const Query & query,LockAction action)367 CloudSyncOption DistributedDBSingleVerMultiSubUserTest::PrepareOption(const Query &query, LockAction action)
368 {
369     CloudSyncOption option;
370     option.devices = { "CLOUD" };
371     option.mode = SYNC_MODE_CLOUD_MERGE;
372     option.query = query;
373     option.waitTime = WAIT_TIME;
374     option.priorityTask = false;
375     option.compensatedSyncOnly = false;
376     option.lockAction = action;
377     return option;
378 }
379 
CallSync(RelationalStoreDelegate * delegate,const CloudSyncOption & option,DBStatus expectResult)380 void DistributedDBSingleVerMultiSubUserTest::CallSync(RelationalStoreDelegate *delegate, const CloudSyncOption &option,
381     DBStatus expectResult)
382 {
383     std::mutex dataMutex;
384     std::condition_variable cv;
385     bool finish = false;
386     auto callback = [&cv, &dataMutex, &finish](const std::map<std::string, SyncProcess> &process) {
387         for (const auto &item: process) {
388             if (item.second.process == DistributedDB::FINISHED) {
389                 {
390                     std::lock_guard<std::mutex> autoLock(dataMutex);
391                     finish = true;
392                 }
393                 cv.notify_one();
394             }
395         }
396     };
397     ASSERT_EQ(delegate->Sync(option, callback), expectResult);
398     if (expectResult == OK) {
399         std::unique_lock<std::mutex> uniqueLock(dataMutex);
400         cv.wait(uniqueLock, [&finish]() {
401             return finish;
402         });
403     }
404 }
405 
406 /**
407  * @tc.name: KvDelegateInvalidParamTest001
408  * @tc.desc: Test kv delegate open with invalid subUser.
409  * @tc.type: FUNC
410  * @tc.require:
411  * @tc.author: zhaoliang
412  */
413 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, KvDelegateInvalidParamTest001, TestSize.Level1)
414 {
415     std::string subUser1 = std::string(129, 'a');
416     KvStoreDelegateManager mgr1(APP_ID, USER_ID, subUser1, INSTANCE_ID_1);
417     KvStoreNbDelegate *delegatePtr1 = nullptr;
418     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), INVALID_ARGS);
419     ASSERT_EQ(delegatePtr1, nullptr);
420 
421     std::string subUser2 = "subUser-1";
422     KvStoreDelegateManager mgr2(APP_ID, USER_ID, subUser2, INSTANCE_ID_1);
423     KvStoreNbDelegate *delegatePtr2 = nullptr;
424     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr2, mgr2), INVALID_ARGS);
425     ASSERT_EQ(delegatePtr2, nullptr);
426 
427     std::string subUser3 = std::string(128, 'a');
428     KvStoreDelegateManager mgr3(APP_ID, USER_ID, subUser3, INSTANCE_ID_1);
429     KvStoreNbDelegate *delegatePtr3 = nullptr;
430     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr3, mgr3), OK);
431     ASSERT_NE(delegatePtr3, nullptr);
432 
433     CloseDelegate(delegatePtr3, mgr3, STORE_ID_1);
434 }
435 
436 /**
437  * @tc.name: SubUserPermissionCheck
438  * @tc.desc: permission check subuser
439  * @tc.type: FUNC
440  * @tc.require:
441  * @tc.author: luoguo
442  */
443 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserPermissionCheck, TestSize.Level1)
444 {
445     /**
446      * @tc.steps: step1. set permission check callback
447      * @tc.expected: step1. set OK.
448      */
449     std::string subUser1 = std::string(128, 'a');
450     KvStoreDelegateManager mgr1(APP_ID, USER_ID, subUser1, INSTANCE_ID_1);
__anonaaa884500702(const PermissionCheckParamV4 &param, uint8_t flag) 451     auto permissionCheckCallback = [] (const PermissionCheckParamV4 &param, uint8_t flag) -> bool {
452         if (param.deviceId == g_deviceB->GetDeviceId() && (flag && CHECK_FLAG_SPONSOR)) {
453             LOGD("in RunPermissionCheck callback func, check not pass, flag:%d", flag);
454             return false;
455         } else {
456             LOGD("in RunPermissionCheck callback func, check pass, flag:%d", flag);
457             return true;
458         }
459     };
460     EXPECT_EQ(mgr1.SetPermissionCheckCallback(permissionCheckCallback), OK);
461 
462     /**
463      * @tc.steps: step2. deviceB put {1,1}
464      * @tc.expected: step2. put success
465      */
466     KvStoreNbDelegate *delegatePtr1 = nullptr;
467     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK);
468     ASSERT_NE(delegatePtr1, nullptr);
469 
470     std::vector<std::string> devices;
471     devices.push_back(g_deviceB->GetDeviceId());
472 
473     Key key = {'1'};
474     Value value = {'1'};
475     g_deviceB->PutData(key, value, 0, 0);
476 
477     /**
478      * @tc.steps: step3. deviceB push data
479      * @tc.expected: step3. return PERMISSION_CHECK_FORBID_SYNC.
480      */
481     std::map<std::string, DBStatus> result;
482     DBStatus status = g_tool.SyncTest(delegatePtr1, devices, SYNC_MODE_PUSH_ONLY, result);
483     ASSERT_TRUE(status == OK);
484     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
485 
486     ASSERT_TRUE(result.size() == devices.size());
487     for (const auto &pair : result) {
488         LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
489         if (g_deviceB->GetDeviceId() == pair.first) {
490             EXPECT_TRUE(pair.second == PERMISSION_CHECK_FORBID_SYNC);
491         } else {
492             EXPECT_TRUE(pair.second == OK);
493         }
494     }
495 
496     PermissionCheckCallbackV4 nullCallback = nullptr;
497     EXPECT_EQ(mgr1.SetPermissionCheckCallback(nullCallback), OK);
498     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
499 }
500 
501 /**
502  * @tc.name: RDBDelegateInvalidParamTest001
503  * @tc.desc: Test rdb delegate open with invalid subUser.
504  * @tc.type: FUNC
505  * @tc.require:
506  * @tc.author: zhaoliang
507  */
508 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, RDBDelegateInvalidParamTest001, TestSize.Level1)
509 {
510     std::string subUser1 = std::string(129, 'a');
511     RelationalStoreManager mgr1(APP_ID, USER_ID, subUser1, INSTANCE_ID_1);
512     RelationalStoreDelegate *rdbDelegatePtr1 = nullptr;
513     sqlite3 *db1;
514     RelationalStoreObserverUnitTest *observer1 = nullptr;
515     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, observer1, mgr1, db1), INVALID_ARGS);
516     ASSERT_EQ(rdbDelegatePtr1, nullptr);
517     CloseDelegate(rdbDelegatePtr1, observer1, mgr1, db1);
518 
519     std::string subUser2 = "subUser-1";
520     RelationalStoreManager mgr2(APP_ID, USER_ID, subUser2, INSTANCE_ID_1);
521     RelationalStoreDelegate *rdbDelegatePtr2 = nullptr;
522     sqlite3 *db2;
523     RelationalStoreObserverUnitTest *observer2 = nullptr;
524     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr2, observer2, mgr2, db2), INVALID_ARGS);
525     ASSERT_EQ(rdbDelegatePtr2, nullptr);
526     CloseDelegate(rdbDelegatePtr2, observer2, mgr2, db2);
527 
528     std::string subUser3 = std::string(128, 'a');
529     RelationalStoreManager mgr3(APP_ID, USER_ID, subUser3, INSTANCE_ID_1);
530     RelationalStoreDelegate *rdbDelegatePtr3 = nullptr;
531     sqlite3 *db3;
532     RelationalStoreObserverUnitTest *observer3 = nullptr;
533     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr3, observer3, mgr3, db3), OK);
534     ASSERT_NE(rdbDelegatePtr3, nullptr);
535 
536     CloseDelegate(rdbDelegatePtr3, observer3, mgr3, db3);
537 }
538 
539 /**
540  * @tc.name: SameDelegateTest001
541  * @tc.desc: Test kv delegate open with diff subUser.
542  * @tc.type: FUNC
543  * @tc.require:
544  * @tc.author: zhaoliang
545  */
546 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SameDelegateTest001, TestSize.Level1)
547 {
548     KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
549     KvStoreNbDelegate *delegatePtr1 = nullptr;
550     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK);
551     ASSERT_NE(delegatePtr1, nullptr);
552 
553     KvStoreDelegateManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1);
554     KvStoreNbDelegate *delegatePtr2 = nullptr;
555     EXPECT_EQ(OpenDelegate("/subUser2", delegatePtr2, mgr2), OK);
556     ASSERT_NE(delegatePtr2, nullptr);
557 
558     Key key1 = {'k', '1'};
559     Value value1 = {'v', '1'};
560     delegatePtr1->Put(key1, value1);
561     Key key2 = {'k', '2'};
562     Value value2 = {'v', '2'};
563     delegatePtr2->Put(key2, value2);
564 
565     Value value;
566     EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
567     EXPECT_EQ(value1, value);
568     EXPECT_EQ(delegatePtr2->Get(key2, value), OK);
569     EXPECT_EQ(value2, value);
570 
571     EXPECT_EQ(delegatePtr1->Get(key2, value), NOT_FOUND);
572     EXPECT_EQ(delegatePtr2->Get(key1, value), NOT_FOUND);
573 
574     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
575     CloseDelegate(delegatePtr2, mgr2, STORE_ID_1);
576 }
577 
578 /**
579  * @tc.name: SameDelegateTest002
580  * @tc.desc: Test rdb delegate open with diff subUser.
581  * @tc.type: FUNC
582  * @tc.require:
583  * @tc.author: zhaoliang
584  */
585 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SameDelegateTest002, TestSize.Level1)
586 {
587     RelationalStoreManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
588     RelationalStoreDelegate *rdbDelegatePtr1 = nullptr;
589     sqlite3 *db1;
590     RelationalStoreObserverUnitTest *observer1 = nullptr;
591     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, observer1, mgr1, db1), OK);
592     ASSERT_NE(rdbDelegatePtr1, nullptr);
593 
594     RelationalStoreManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1);
595     RelationalStoreDelegate *rdbDelegatePtr2 = nullptr;
596     sqlite3 *db2;
597     RelationalStoreObserverUnitTest *observer2 = nullptr;
598     EXPECT_EQ(OpenDelegate("/subUser2", rdbDelegatePtr2, observer2, mgr2, db2), OK);
599     ASSERT_NE(rdbDelegatePtr2, nullptr);
600 
601     int localCount = 10;
602     InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1);
603     InsertLocalData(10, localCount, ASSETS_TABLE_NAME, true, db2);
604 
605     std::string sql1 = "select count(*) from " + ASSETS_TABLE_NAME + " where id < 10;";
606     std::string sql2 = "select count(*) from " + ASSETS_TABLE_NAME + " where id >= 10;";
607 
608     EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
609         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
610     EXPECT_EQ(sqlite3_exec(db2, sql2.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
611         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
612 
613     EXPECT_EQ(sqlite3_exec(db1, sql2.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
614         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
615     EXPECT_EQ(sqlite3_exec(db2, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
616         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
617 
618     CloseDelegate(rdbDelegatePtr1, observer1, mgr1, db1);
619     CloseDelegate(rdbDelegatePtr2, observer2, mgr2, db2);
620 }
621 
622 /**
623  * @tc.name: SubUserDelegateCRUDTest001
624  * @tc.desc: Test subUser rdb delegate crud function.
625  * @tc.type: FUNC
626  * @tc.require:
627  * @tc.author: zhaoliang
628  */
629 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCRUDTest001, TestSize.Level1)
630 {
631     RelationalStoreManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
632     RelationalStoreDelegate *rdbDelegatePtr1 = nullptr;
633     sqlite3 *db1;
634     RelationalStoreObserverUnitTest *observer1 = nullptr;
635     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, observer1, mgr1, db1), OK);
636     ASSERT_NE(rdbDelegatePtr1, nullptr);
637 
638     int localCount = 10;
639     InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1);
640     std::string sql1 = "select count(*) from " + ASSETS_TABLE_NAME + ";";
641     EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
642         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
643 
644     InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1);
645     EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
646         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
647 
648     std::string sql2 = "delete from " + ASSETS_TABLE_NAME + ";";
649     EXPECT_EQ(sqlite3_exec(db1, sql2.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
650         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
651     EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
652         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
653 
654     CloseDelegate(rdbDelegatePtr1, observer1, mgr1, db1);
655 }
656 
657 /**
658  * @tc.name: SubUserDelegateCRUDTest002
659  * @tc.desc: Test subUser kv delegate crud function.
660  * @tc.type: FUNC
661  * @tc.require:
662  * @tc.author: zhaoliang
663  */
664 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCRUDTest002, TestSize.Level1)
665 {
666     KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
667     KvStoreNbDelegate *delegatePtr1 = nullptr;
668     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK);
669     ASSERT_NE(delegatePtr1, nullptr);
670 
671     Key key1 = {'k', '1'};
672     Value value1 = {'v', '1'};
673     delegatePtr1->Put(key1, value1);
674 
675     Value value;
676     EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
677     EXPECT_EQ(value1, value);
678 
679     Value value2 = {'v', '2'};
680     delegatePtr1->Put(key1, value2);
681     EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
682     EXPECT_EQ(value2, value);
683 
684     EXPECT_EQ(delegatePtr1->Delete(key1), OK);
685     EXPECT_EQ(delegatePtr1->Get(key1, value), NOT_FOUND);
686 
687     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
688 }
689 
690 #ifdef USE_DISTRIBUTEDDB_CLOUD
691 /**
692  * @tc.name: SubUserDelegateCloudSyncTest001
693  * @tc.desc: Test subUser kv delegate cloud sync function.
694  * @tc.type: FUNC
695  * @tc.require:
696  * @tc.author: zhaoliang
697  */
698 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCloudSyncTest001, TestSize.Level1)
699 {
700     KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
701     KvStoreNbDelegate *delegatePtr1 = nullptr;
702     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK);
703     ASSERT_NE(delegatePtr1, nullptr);
704     EXPECT_EQ(SetCloudDB(delegatePtr1), OK);
705 
706     KvStoreDelegateManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1);
707     KvStoreNbDelegate *delegatePtr2 = nullptr;
708     EXPECT_EQ(OpenDelegate("/subUser2", delegatePtr2, mgr2), OK);
709     ASSERT_NE(delegatePtr2, nullptr);
710     EXPECT_EQ(SetCloudDB(delegatePtr2), OK);
711 
712     Key key = {'k'};
713     Value expectValue = {'v'};
714     ASSERT_EQ(delegatePtr1->Put(key, expectValue), OK);
715     BlockSync(delegatePtr1, OK, g_CloudSyncoption);
716     for (const auto &table : lastProcess_.tableProcess) {
717         EXPECT_EQ(table.second.upLoadInfo.total, 1u);
718     }
719     BlockSync(delegatePtr2, OK, g_CloudSyncoption);
720     for (const auto &table : lastProcess_.tableProcess) {
721         EXPECT_EQ(table.second.downLoadInfo.total, 1u);
722     }
723     Value actualValue;
724     EXPECT_EQ(delegatePtr2->Get(key, actualValue), OK);
725     EXPECT_EQ(actualValue, expectValue);
726 
727     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
728     CloseDelegate(delegatePtr2, mgr2, STORE_ID_1);
729 }
730 
731 /**
732  * @tc.name: SubUserDelegateCloudSyncTest002
733  * @tc.desc: Test subUser rdb delegate cloud sync function.
734  * @tc.type: FUNC
735  * @tc.require:
736  * @tc.author: zhaoliang
737  */
738 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCloudSyncTest002, TestSize.Level1)
739 {
740     RelationalStoreManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
741     RelationalStoreDelegate *rdbDelegatePtr1 = nullptr;
742     sqlite3 *db1;
743     RelationalStoreObserverUnitTest *observer1 = nullptr;
744     EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, observer1, mgr1, db1), OK);
745     ASSERT_NE(rdbDelegatePtr1, nullptr);
746     EXPECT_EQ(SetCloudDB(rdbDelegatePtr1), OK);
747 
748     RelationalStoreManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1);
749     RelationalStoreDelegate *rdbDelegatePtr2 = nullptr;
750     sqlite3 *db2;
751     RelationalStoreObserverUnitTest *observer2 = nullptr;
752     EXPECT_EQ(OpenDelegate("/subUser2", rdbDelegatePtr2, observer2, mgr2, db2), OK);
753     ASSERT_NE(rdbDelegatePtr2, nullptr);
754     EXPECT_EQ(SetCloudDB(rdbDelegatePtr2), OK);
755 
756     int localCount = 10;
757     InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1);
758     CloudSyncOption option = PrepareOption(Query::Select().FromTable({ ASSETS_TABLE_NAME }), LockAction::NONE);
759     CallSync(rdbDelegatePtr1, option);
760     CallSync(rdbDelegatePtr2, option);
761 
762     std::string sql = "select count(*) from " + ASSETS_TABLE_NAME + ";";
763     EXPECT_EQ(sqlite3_exec(db2, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
764         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
765 
766     CloseDelegate(rdbDelegatePtr1, observer1, mgr1, db1);
767     CloseDelegate(rdbDelegatePtr2, observer2, mgr2, db2);
768 }
769 #endif
770 
771 /**
772  * @tc.name: MultiSubUserDelegateSync001
773  * @tc.desc: Test subUser delegate sync function.
774  * @tc.type: FUNC
775  * @tc.require:
776  * @tc.author: zhaoliang
777  */
778 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, MultiSubUserDelegateSync001, TestSize.Level1)
779 {
780     KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
__anonaaa884500802(const PermissionCheckParam &param, uint8_t flag) 781     RuntimeConfig::SetPermissionCheckCallback([](const PermissionCheckParam &param, uint8_t flag) {
782         if ((flag & PermissionCheckFlag::CHECK_FLAG_RECEIVE) != 0) {
783             bool res = false;
784             if (param.extraConditions.find(KEY_SUB_USER) != param.extraConditions.end()) {
785                 res = param.extraConditions.at(KEY_SUB_USER) == SUB_USER_1;
786             }
787             return res;
788         }
789         if (param.userId != USER_ID || param.appId != APP_ID || param.storeId != STORE_ID_1 ||
790             (param.instanceId != INSTANCE_ID_1 && param.instanceId != 0)) {
791             return false;
792         }
793         return true;
794     });
__anonaaa884500902(const PermissionConditionParam &param) 795     RuntimeConfig::SetPermissionConditionCallback([](const PermissionConditionParam &param) {
796         std::map<std::string, std::string> res;
797         res.emplace(KEY_SUB_USER, SUB_USER_1);
798         return res;
799     });
800 
801     KvStoreNbDelegate *delegatePtr1 = nullptr;
802     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK);
803     ASSERT_NE(delegatePtr1, nullptr);
804 
805     Key key1 = {'k', '1'};
806     Value value1 = {'v', '1'};
807     delegatePtr1->Put(key1, value1);
808 
809     std::map<std::string, DBStatus> result;
810     DBStatus status = g_tool.SyncTest(delegatePtr1, { DEVICE_B }, SYNC_MODE_PUSH_ONLY, result);
811     EXPECT_TRUE(status == OK);
812     EXPECT_EQ(result[DEVICE_B], OK);
813 
814     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
815 }
816 
817 /**
818  * @tc.name: MultiSubUserDelegateSync002
819  * @tc.desc: Test subUser delegate sync active if callback return true.
820  * @tc.type: FUNC
821  * @tc.require:
822  * @tc.author: zhaoliang
823  */
824 HWTEST_F(DistributedDBSingleVerMultiSubUserTest, MultiSubUserDelegateSync002, TestSize.Level1)
825 {
826     KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1);
__anonaaa884500a02(const ActivationCheckParam &param) 827     RuntimeConfig::SetSyncActivationCheckCallback([](const ActivationCheckParam &param) {
828         if (param.userId == USER_ID && param.appId == APP_ID && param.storeId == STORE_ID_1 &&
829             param.instanceId == INSTANCE_ID_1) {
830             return true;
831         }
832         return false;
833     });
834 
835     KvStoreNbDelegate *delegatePtr1 = nullptr;
836     EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1, true), OK);
837     ASSERT_NE(delegatePtr1, nullptr);
838 
839     std::map<std::string, DBStatus> result;
840     DBStatus status = g_tool.SyncTest(delegatePtr1, { DEVICE_B }, SYNC_MODE_PUSH_ONLY, result);
841     EXPECT_EQ(status, OK);
842     EXPECT_EQ(result[DEVICE_B], OK);
843 
844     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
845 }
846 
847 } // namespace