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