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