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 ¶m, uint8_t flag) 451 auto permissionCheckCallback = [] (const PermissionCheckParamV4 ¶m, 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 ¶m, uint8_t flag) 781 RuntimeConfig::SetPermissionCheckCallback([](const PermissionCheckParam ¶m, 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 ¶m) 795 RuntimeConfig::SetPermissionConditionCallback([](const PermissionConditionParam ¶m) {
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 ¶m) 827 RuntimeConfig::SetSyncActivationCheckCallback([](const ActivationCheckParam ¶m) {
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