1 /*
2 * Copyright (c) 2021 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 #ifdef RELATIONAL_STORE
16 #include <gtest/gtest.h>
17
18 #include "db_common.h"
19 #include "db_constant.h"
20 #include "distributeddb_data_generate_unit_test.h"
21 #include "distributeddb_tools_unit_test.h"
22 #include "isyncer.h"
23 #include "kv_virtual_device.h"
24 #include "mock_sync_task_context.h"
25 #include "platform_specific.h"
26 #include "process_system_api_adapter_impl.h"
27 #include "relational_schema_object.h"
28 #include "relational_store_manager.h"
29 #include "relational_virtual_device.h"
30 #include "runtime_config.h"
31 #include "single_ver_sync_target.h"
32 #include "virtual_relational_ver_sync_db_interface.h"
33
34 using namespace testing::ext;
35 using namespace DistributedDB;
36 using namespace DistributedDBUnitTest;
37 namespace {
38 const std::string DEVICE_A = "real_device";
39 const std::string DEVICE_B = "deviceB";
40 const std::string DEVICE_C = "deviceC";
41 const std::string DEVICE_D = "deviceD";
42 const std::string g_tableName = "TEST_TABLE";
43
44 const int ONE_HUNDERED = 100;
45 const char DEFAULT_CHAR = 'D';
46 const std::string DEFAULT_TEXT = "This is a text";
47 const std::vector<uint8_t> DEFAULT_BLOB(ONE_HUNDERED, DEFAULT_CHAR);
48 const std::string SHA1_ALGO_SQL = "PRAGMA codec_hmac_algo=SHA1";
49 const std::string SHA256_ALGO_SQL = "PRAGMA codec_hmac_algo=SHA256";
50 const std::string SHA256_ALGO_REKEY_SQL = "PRAGMA codec_rekey_hmac_algo=SHA256";
51
52 #ifndef OMIT_ENCRYPT
53 bool g_isAfterRekey = false;
54 const string CORRECT_KEY = "a correct key";
55 CipherPassword g_correctPasswd;
56 const string REKEY_KEY = "a key after rekey";
57 CipherPassword g_rekeyPasswd;
58 const string INCORRECT_KEY = "a incorrect key";
59 CipherPassword g_incorrectPasswd;
60 const int DEFAULT_ITER = 5000;
61 #endif
62 RelationalStoreManager g_mgr(APP_ID, USER_ID);
63 std::string g_testDir;
64 std::string g_dbDir;
65 std::string g_id;
66 std::vector<StorageType> g_storageType = {
67 StorageType::STORAGE_TYPE_INTEGER, StorageType::STORAGE_TYPE_REAL,
68 StorageType::STORAGE_TYPE_TEXT, StorageType::STORAGE_TYPE_BLOB
69 };
70 DistributedDBToolsUnitTest g_tool;
71 RelationalStoreDelegate* g_rdbDelegatePtr = nullptr;
72 VirtualCommunicatorAggregator* g_communicatorAggregator = nullptr;
73 RelationalVirtualDevice *g_deviceB = nullptr;
74 RelationalVirtualDevice *g_deviceC = nullptr;
75 KvVirtualDevice *g_deviceD = nullptr;
76 std::vector<FieldInfo> g_fieldInfoList;
77 RelationalStoreObserverUnitTest *g_observer = nullptr;
GetDeviceTableName(const std::string & tableName)78 std::string GetDeviceTableName(const std::string &tableName)
79 {
80 return "naturalbase_rdb_aux_" +
81 tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(DEVICE_B));
82 }
83
OpenStore()84 void OpenStore()
85 {
86 if (g_observer == nullptr) {
87 g_observer = new (std::nothrow) RelationalStoreObserverUnitTest();
88 }
89 RelationalStoreDelegate::Option option;
90 option.observer = g_observer;
91 #ifndef OMIT_ENCRYPT
92 option.isEncryptedDb = true;
93 option.iterateTimes = DEFAULT_ITER;
94 option.passwd = g_isAfterRekey ? g_rekeyPasswd : g_correctPasswd;
95 option.cipher = CipherType::DEFAULT;
96 #endif
97 g_mgr.OpenStore(g_dbDir, STORE_ID_1, option, g_rdbDelegatePtr);
98 ASSERT_TRUE(g_rdbDelegatePtr != nullptr);
99 }
100
GetDB(sqlite3 * & db,bool isSha256Algo=true)101 int GetDB(sqlite3 *&db, bool isSha256Algo = true)
102 {
103 int flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
104 const auto &dbPath = g_dbDir;
105 int rc = sqlite3_open_v2(dbPath.c_str(), &db, flag, nullptr);
106 if (rc != SQLITE_OK) {
107 return rc;
108 }
109 #ifndef OMIT_ENCRYPT
110 string sql =
111 "PRAGMA key='" + (g_isAfterRekey ? REKEY_KEY : CORRECT_KEY) + "';"
112 "PRAGMA codec_kdf_iter=" + std::to_string(DEFAULT_ITER) + ";";
113 EXPECT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
114 if (isSha256Algo) {
115 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK);
116 } else {
117 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA1_ALGO_SQL), E_OK);
118 }
119 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_REKEY_SQL), E_OK);
120 #endif
121 EXPECT_EQ(SQLiteUtils::RegisterCalcHash(db), E_OK);
122 EXPECT_EQ(SQLiteUtils::RegisterGetSysTime(db), E_OK);
123 EXPECT_EQ(sqlite3_exec(db, "PRAGMA journal_mode=WAL;", nullptr, nullptr, nullptr), SQLITE_OK);
124 return rc;
125 }
126
GetType(StorageType type)127 std::string GetType(StorageType type)
128 {
129 static std::map<StorageType, std::string> typeMap = {
130 {StorageType::STORAGE_TYPE_INTEGER, "INT"},
131 {StorageType::STORAGE_TYPE_REAL, "DOUBLE"},
132 {StorageType::STORAGE_TYPE_TEXT, "TEXT"},
133 {StorageType::STORAGE_TYPE_BLOB, "BLOB"}
134 };
135 if (typeMap.find(type) == typeMap.end()) {
136 type = StorageType::STORAGE_TYPE_INTEGER;
137 }
138 return typeMap[type];
139 }
140
DropTable(sqlite3 * db,const std::string & tableName)141 int DropTable(sqlite3 *db, const std::string &tableName)
142 {
143 std::string sql = "DROP TABLE " + tableName + ";";
144 return sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr);
145 }
146
CreateTable(sqlite3 * db,const std::vector<FieldInfo> & fieldInfoList,const std::string & tableName)147 int CreateTable(sqlite3 *db, const std::vector<FieldInfo> &fieldInfoList, const std::string &tableName)
148 {
149 std::string sql = "CREATE TABLE " + tableName + "(";
150 int index = 0;
151 for (const auto &field : fieldInfoList) {
152 if (index != 0) {
153 sql += ",";
154 }
155 sql += field.GetFieldName() + " ";
156 std::string type = GetType(field.GetStorageType());
157 sql += type + " ";
158 if (index == 0) {
159 sql += "PRIMARY KEY NOT NULL ";
160 }
161 index++;
162 }
163 sql += ");";
164 int rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr);
165 return rc;
166 }
167
PrepareInsert(sqlite3 * db,sqlite3_stmt * & statement,std::vector<FieldInfo> fieldInfoList,const std::string & tableName)168 int PrepareInsert(sqlite3 *db, sqlite3_stmt *&statement,
169 std::vector<FieldInfo> fieldInfoList, const std::string &tableName)
170 {
171 std::string sql = "INSERT OR REPLACE INTO " + tableName + "(";
172 int index = 0;
173 for (const auto &fieldInfo : fieldInfoList) {
174 if (index != 0) {
175 sql += ",";
176 }
177 sql += fieldInfo.GetFieldName();
178 index++;
179 }
180 sql += ") VALUES (";
181 while (index > 0) {
182 sql += "?";
183 if (index != 1) {
184 sql += ", ";
185 }
186 index--;
187 }
188 sql += ");";
189 return sqlite3_prepare_v2(db, sql.c_str(), -1, &statement, nullptr);
190 }
191
SimulateCommitData(sqlite3 * db,sqlite3_stmt * & statement)192 int SimulateCommitData(sqlite3 *db, sqlite3_stmt *&statement)
193 {
194 sqlite3_exec(db, "BEGIN IMMEDIATE TRANSACTION", nullptr, nullptr, nullptr);
195
196 int rc = sqlite3_step(statement);
197
198 sqlite3_exec(db, "COMMIT TRANSACTION", nullptr, nullptr, nullptr);
199 return rc;
200 }
201
BindValue(const DataValue & item,sqlite3_stmt * stmt,int col)202 void BindValue(const DataValue &item, sqlite3_stmt *stmt, int col)
203 {
204 switch (item.GetType()) {
205 case StorageType::STORAGE_TYPE_INTEGER: {
206 int64_t intData = 0;
207 (void)item.GetInt64(intData);
208 EXPECT_EQ(sqlite3_bind_int64(stmt, col, intData), SQLITE_OK);
209 break;
210 }
211
212 case StorageType::STORAGE_TYPE_REAL: {
213 double doubleData = 0;
214 (void)item.GetDouble(doubleData);
215 EXPECT_EQ(sqlite3_bind_double(stmt, col, doubleData), SQLITE_OK);
216 break;
217 }
218
219 case StorageType::STORAGE_TYPE_TEXT: {
220 std::string strData;
221 (void)item.GetText(strData);
222 EXPECT_EQ(SQLiteUtils::BindTextToStatement(stmt, col, strData), E_OK);
223 break;
224 }
225
226 case StorageType::STORAGE_TYPE_BLOB: {
227 Blob blob;
228 (void)item.GetBlob(blob);
229 std::vector<uint8_t> blobData(blob.GetData(), blob.GetData() + blob.GetSize());
230 EXPECT_EQ(SQLiteUtils::BindBlobToStatement(stmt, col, blobData, true), E_OK);
231 break;
232 }
233
234 case StorageType::STORAGE_TYPE_NULL: {
235 EXPECT_EQ(SQLiteUtils::MapSQLiteErrno(sqlite3_bind_null(stmt, col)), E_OK);
236 break;
237 }
238
239 default:
240 break;
241 }
242 }
243
InsertValue(sqlite3 * db,std::map<std::string,DataValue> & dataMap,const std::vector<FieldInfo> & fieldInfoList,const std::string & tableName)244 void InsertValue(sqlite3 *db, std::map<std::string, DataValue> &dataMap,
245 const std::vector<FieldInfo> &fieldInfoList, const std::string &tableName)
246 {
247 sqlite3_stmt *stmt = nullptr;
248 EXPECT_EQ(PrepareInsert(db, stmt, fieldInfoList, tableName), SQLITE_OK);
249 for (int i = 0; i < static_cast<int>(fieldInfoList.size()); ++i) {
250 const auto &fieldName = fieldInfoList[i].GetFieldName();
251 ASSERT_TRUE(dataMap.find(fieldName) != dataMap.end());
252 const auto &item = dataMap[fieldName];
253 const int index = i + 1;
254 BindValue(item, stmt, index);
255 }
256 EXPECT_EQ(SimulateCommitData(db, stmt), SQLITE_DONE);
257 sqlite3_finalize(stmt);
258 }
259
InsertValue(sqlite3 * db,std::map<std::string,DataValue> & dataMap)260 void InsertValue(sqlite3 *db, std::map<std::string, DataValue> &dataMap)
261 {
262 InsertValue(db, dataMap, g_fieldInfoList, g_tableName);
263 }
264
SetNull(DataValue & dataValue)265 void SetNull(DataValue &dataValue)
266 {
267 dataValue.ResetValue();
268 }
269
SetInt64(DataValue & dataValue)270 void SetInt64(DataValue &dataValue)
271 {
272 dataValue = INT64_MAX;
273 }
274
SetDouble(DataValue & dataValue)275 void SetDouble(DataValue &dataValue)
276 {
277 dataValue = 1.0;
278 }
279
SetText(DataValue & dataValue)280 void SetText(DataValue &dataValue)
281 {
282 dataValue.SetText(DEFAULT_TEXT);
283 }
284
SetBlob(DataValue & dataValue)285 void SetBlob(DataValue &dataValue)
286 {
287 Blob blob;
288 blob.WriteBlob(DEFAULT_BLOB.data(), DEFAULT_BLOB.size());
289 dataValue.SetBlob(blob);
290 }
291
GenerateValue(std::map<std::string,DataValue> & dataMap,std::vector<FieldInfo> & fieldInfoList)292 void GenerateValue(std::map<std::string, DataValue> &dataMap, std::vector<FieldInfo> &fieldInfoList)
293 {
294 static std::map<StorageType, void(*)(DataValue&)> typeMapFunction = {
295 {StorageType::STORAGE_TYPE_NULL, &SetNull},
296 {StorageType::STORAGE_TYPE_INTEGER, &SetInt64},
297 {StorageType::STORAGE_TYPE_REAL, &SetDouble},
298 {StorageType::STORAGE_TYPE_TEXT, &SetText},
299 {StorageType::STORAGE_TYPE_BLOB, &SetBlob}
300 };
301 for (auto &fieldInfo : fieldInfoList) {
302 DataValue dataValue;
303 if (typeMapFunction.find(fieldInfo.GetStorageType()) == typeMapFunction.end()) {
304 fieldInfo.SetStorageType(StorageType::STORAGE_TYPE_NULL);
305 }
306 typeMapFunction[fieldInfo.GetStorageType()](dataValue);
307 dataMap[fieldInfo.GetFieldName()] = std::move(dataValue);
308 }
309 }
310
InsertFieldInfo(std::vector<FieldInfo> & fieldInfoList)311 void InsertFieldInfo(std::vector<FieldInfo> &fieldInfoList)
312 {
313 fieldInfoList.clear();
314 FieldInfo columnFirst;
315 columnFirst.SetFieldName("ID");
316 columnFirst.SetStorageType(StorageType::STORAGE_TYPE_INTEGER);
317 columnFirst.SetColumnId(0); // the first column
318 FieldInfo columnSecond;
319 columnSecond.SetFieldName("NAME");
320 columnSecond.SetStorageType(StorageType::STORAGE_TYPE_TEXT);
321 columnSecond.SetColumnId(1); // the 2nd column
322 FieldInfo columnThird;
323 columnThird.SetFieldName("AGE");
324 columnThird.SetStorageType(StorageType::STORAGE_TYPE_INTEGER);
325 columnThird.SetColumnId(2); // the 3rd column(index 2 base 0)
326 fieldInfoList.push_back(columnFirst);
327 fieldInfoList.push_back(columnSecond);
328 fieldInfoList.push_back(columnThird);
329 }
330
BlockSync(const Query & query,SyncMode syncMode,DBStatus exceptStatus,const std::vector<std::string> & devices)331 void BlockSync(const Query &query, SyncMode syncMode, DBStatus exceptStatus,
332 const std::vector<std::string> &devices)
333 {
334 std::map<std::string, std::vector<TableStatus>> statusMap;
335 SyncStatusCallback callBack = [&statusMap](
336 const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
337 statusMap = devicesMap;
338 };
339 DBStatus callStatus = g_rdbDelegatePtr->Sync(devices, syncMode, query, callBack, true);
340 EXPECT_EQ(callStatus, OK);
341 for (const auto &tablesRes : statusMap) {
342 for (const auto &tableStatus : tablesRes.second) {
343 EXPECT_EQ(tableStatus.status, exceptStatus);
344 }
345 }
346 }
347
BlockSync(const std::string & tableName,SyncMode syncMode,DBStatus exceptStatus,const std::vector<std::string> & devices)348 void BlockSync(const std::string &tableName, SyncMode syncMode, DBStatus exceptStatus,
349 const std::vector<std::string> &devices)
350 {
351 Query query = Query::Select(tableName);
352 BlockSync(query, syncMode, exceptStatus, devices);
353 }
354
BlockSync(SyncMode syncMode,DBStatus exceptStatus,const std::vector<std::string> & devices)355 void BlockSync(SyncMode syncMode, DBStatus exceptStatus, const std::vector<std::string> &devices)
356 {
357 BlockSync(g_tableName, syncMode, exceptStatus, devices);
358 }
359
PrepareSelect(sqlite3 * db,sqlite3_stmt * & statement,const std::string & table)360 int PrepareSelect(sqlite3 *db, sqlite3_stmt *&statement, const std::string &table)
361 {
362 const std::string sql = "SELECT * FROM " + table;
363 return sqlite3_prepare_v2(db, sql.c_str(), -1, &statement, nullptr);
364 }
365
GetDataValue(sqlite3_stmt * statement,int col,DataValue & dataValue)366 void GetDataValue(sqlite3_stmt *statement, int col, DataValue &dataValue)
367 {
368 int type = sqlite3_column_type(statement, col);
369 switch (type) {
370 case SQLITE_INTEGER: {
371 dataValue = static_cast<int64_t>(sqlite3_column_int64(statement, col));
372 break;
373 }
374 case SQLITE_FLOAT: {
375 dataValue = sqlite3_column_double(statement, col);
376 break;
377 }
378 case SQLITE_TEXT: {
379 std::string str;
380 SQLiteUtils::GetColumnTextValue(statement, col, str);
381 dataValue.SetText(str);
382 break;
383 }
384 case SQLITE_BLOB: {
385 std::vector<uint8_t> blobValue;
386 (void)SQLiteUtils::GetColumnBlobValue(statement, col, blobValue);
387 Blob blob;
388 blob.WriteBlob(blobValue.data(), static_cast<uint32_t>(blobValue.size()));
389 dataValue.SetBlob(blob);
390 break;
391 }
392 case SQLITE_NULL:
393 break;
394 default:
395 LOGW("unknown type[%d] column[%d] ignore", type, col);
396 }
397 }
398
GetSyncDataStep(std::map<std::string,DataValue> & dataMap,sqlite3_stmt * statement,const std::vector<FieldInfo> & fieldInfoList)399 void GetSyncDataStep(std::map<std::string, DataValue> &dataMap, sqlite3_stmt *statement,
400 const std::vector<FieldInfo> &fieldInfoList)
401 {
402 int columnCount = sqlite3_column_count(statement);
403 ASSERT_EQ(static_cast<size_t>(columnCount), fieldInfoList.size());
404 for (int col = 0; col < columnCount; ++col) {
405 DataValue dataValue;
406 GetDataValue(statement, col, dataValue);
407 dataMap[fieldInfoList.at(col).GetFieldName()] = std::move(dataValue);
408 }
409 }
410
GetSyncData(sqlite3 * db,std::map<std::string,DataValue> & dataMap,const std::string & tableName,const std::vector<FieldInfo> & fieldInfoList)411 void GetSyncData(sqlite3 *db, std::map<std::string, DataValue> &dataMap, const std::string &tableName,
412 const std::vector<FieldInfo> &fieldInfoList)
413 {
414 sqlite3_stmt *statement = nullptr;
415 EXPECT_EQ(PrepareSelect(db, statement, GetDeviceTableName(tableName)), SQLITE_OK);
416 while (true) {
417 int rc = sqlite3_step(statement);
418 if (rc != SQLITE_ROW) {
419 LOGD("GetSyncData Exist by code[%d]", rc);
420 break;
421 }
422 GetSyncDataStep(dataMap, statement, fieldInfoList);
423 }
424 sqlite3_finalize(statement);
425 }
426
InsertValueToDB(std::map<std::string,DataValue> & dataMap)427 void InsertValueToDB(std::map<std::string, DataValue> &dataMap)
428 {
429 sqlite3 *db = nullptr;
430 EXPECT_EQ(GetDB(db), SQLITE_OK);
431 InsertValue(db, dataMap);
432 sqlite3_close(db);
433 }
434
PrepareBasicTable(const std::string & tableName,std::vector<FieldInfo> & fieldInfoList,const std::vector<RelationalVirtualDevice * > & remoteDeviceVec,bool createDistributedTable=true)435 void PrepareBasicTable(const std::string &tableName, std::vector<FieldInfo> &fieldInfoList,
436 const std::vector<RelationalVirtualDevice *> &remoteDeviceVec, bool createDistributedTable = true)
437 {
438 sqlite3 *db = nullptr;
439 EXPECT_EQ(GetDB(db), SQLITE_OK);
440 if (fieldInfoList.empty()) {
441 InsertFieldInfo(fieldInfoList);
442 }
443 for (auto &dev : remoteDeviceVec) {
444 dev->SetLocalFieldInfo(fieldInfoList);
445 }
446 EXPECT_EQ(CreateTable(db, fieldInfoList, tableName), SQLITE_OK);
447 TableInfo tableInfo;
448 SQLiteUtils::AnalysisSchema(db, tableName, tableInfo);
449 for (auto &dev : remoteDeviceVec) {
450 dev->SetTableInfo(tableInfo);
451 }
452 if (createDistributedTable) {
453 EXPECT_EQ(g_rdbDelegatePtr->CreateDistributedTable(tableName), OK);
454 }
455
456 sqlite3_close(db);
457 }
458
PrepareEnvironment(std::map<std::string,DataValue> & dataMap,std::vector<RelationalVirtualDevice * > remoteDeviceVec)459 void PrepareEnvironment(std::map<std::string, DataValue> &dataMap,
460 std::vector<RelationalVirtualDevice *> remoteDeviceVec)
461 {
462 PrepareBasicTable(g_tableName, g_fieldInfoList, remoteDeviceVec);
463 GenerateValue(dataMap, g_fieldInfoList);
464 InsertValueToDB(dataMap);
465 }
466
InsertDataToDeviceB(std::map<std::string,DataValue> & dataMap,const std::string & tableName,std::vector<FieldInfo> & fieldInfoList,Timestamp ts)467 void InsertDataToDeviceB(std::map<std::string, DataValue> &dataMap, const std::string &tableName,
468 std::vector<FieldInfo> &fieldInfoList, Timestamp ts)
469 {
470 GenerateValue(dataMap, fieldInfoList);
471 VirtualRowData virtualRowData;
472 for (const auto &item : dataMap) {
473 virtualRowData.objectData.PutDataValue(item.first, item.second);
474 }
475 virtualRowData.logInfo.timestamp = ts;
476 g_deviceB->PutData(tableName, {virtualRowData});
477 }
478
PrepareVirtualEnvironment(std::map<std::string,DataValue> & dataMap,const std::string & tableName,std::vector<FieldInfo> & fieldInfoList,const std::vector<RelationalVirtualDevice * > remoteDeviceVec,bool createDistributedTable=true)479 void PrepareVirtualEnvironment(std::map<std::string, DataValue> &dataMap, const std::string &tableName,
480 std::vector<FieldInfo> &fieldInfoList, const std::vector<RelationalVirtualDevice *> remoteDeviceVec,
481 bool createDistributedTable = true)
482 {
483 PrepareBasicTable(tableName, fieldInfoList, remoteDeviceVec, createDistributedTable);
484 InsertDataToDeviceB(dataMap, tableName, fieldInfoList, 1);
485 }
486
PrepareVirtualEnvironment(std::map<std::string,DataValue> & dataMap,const std::vector<RelationalVirtualDevice * > remoteDeviceVec,bool createDistributedTable=true)487 void PrepareVirtualEnvironment(std::map<std::string, DataValue> &dataMap,
488 const std::vector<RelationalVirtualDevice *> remoteDeviceVec, bool createDistributedTable = true)
489 {
490 PrepareVirtualEnvironment(dataMap, g_tableName, g_fieldInfoList, remoteDeviceVec, createDistributedTable);
491 }
492
CheckData(const std::map<std::string,DataValue> & targetMap,const std::string & tableName,const std::vector<FieldInfo> & fieldInfoList)493 void CheckData(const std::map<std::string, DataValue> &targetMap, const std::string &tableName,
494 const std::vector<FieldInfo> &fieldInfoList)
495 {
496 std::map<std::string, DataValue> dataMap;
497 sqlite3 *db = nullptr;
498 EXPECT_EQ(GetDB(db), SQLITE_OK);
499 GetSyncData(db, dataMap, tableName, fieldInfoList);
500 sqlite3_close(db);
501
502 for (const auto &[fieldName, dataValue] : targetMap) {
503 ASSERT_TRUE(dataMap.find(fieldName) != dataMap.end());
504 EXPECT_TRUE(dataMap[fieldName] == dataValue);
505 }
506 }
507
CheckData(const std::map<std::string,DataValue> & targetMap)508 void CheckData(const std::map<std::string, DataValue> &targetMap)
509 {
510 CheckData(targetMap, g_tableName, g_fieldInfoList);
511 }
512
CheckVirtualData(const std::string & tableName,std::map<std::string,DataValue> & data)513 void CheckVirtualData(const std::string &tableName, std::map<std::string, DataValue> &data)
514 {
515 std::vector<VirtualRowData> targetData;
516 g_deviceB->GetAllSyncData(tableName, targetData);
517 ASSERT_EQ(targetData.size(), 1u);
518 for (auto &[field, value] : data) {
519 DataValue target;
520 EXPECT_EQ(targetData[0].objectData.GetDataValue(field, target), E_OK);
521 LOGD("field %s actual_val[%s] except_val[%s]", field.c_str(), target.ToString().c_str(),
522 value.ToString().c_str());
523 EXPECT_TRUE(target == value);
524 }
525 }
526
CheckVirtualData(std::map<std::string,DataValue> & data)527 void CheckVirtualData(std::map<std::string, DataValue> &data)
528 {
529 CheckVirtualData(g_tableName, data);
530 }
531
GetFieldInfo(std::vector<FieldInfo> & fieldInfoList,std::vector<StorageType> typeList)532 void GetFieldInfo(std::vector<FieldInfo> &fieldInfoList, std::vector<StorageType> typeList)
533 {
534 fieldInfoList.clear();
535 for (size_t index = 0; index < typeList.size(); index++) {
536 const auto &type = typeList[index];
537 FieldInfo fieldInfo;
538 fieldInfo.SetFieldName("field_" + std::to_string(index));
539 fieldInfo.SetColumnId(index);
540 fieldInfo.SetStorageType(type);
541 fieldInfoList.push_back(fieldInfo);
542 }
543 }
544
InsertValueToDB(std::map<std::string,DataValue> & dataMap,std::vector<FieldInfo> fieldInfoList,const std::string & tableName)545 void InsertValueToDB(std::map<std::string, DataValue> &dataMap,
546 std::vector<FieldInfo> fieldInfoList, const std::string &tableName)
547 {
548 sqlite3 *db = nullptr;
549 EXPECT_EQ(GetDB(db), SQLITE_OK);
550 InsertValue(db, dataMap, fieldInfoList, tableName);
551 sqlite3_close(db);
552 }
553
PrepareEnvironment(std::map<std::string,DataValue> & dataMap,const std::string & tableName,std::vector<FieldInfo> & localFieldInfoList,std::vector<FieldInfo> & remoteFieldInfoList,std::vector<RelationalVirtualDevice * > remoteDeviceVec)554 void PrepareEnvironment(std::map<std::string, DataValue> &dataMap, const std::string &tableName,
555 std::vector<FieldInfo> &localFieldInfoList, std::vector<FieldInfo> &remoteFieldInfoList,
556 std::vector<RelationalVirtualDevice *> remoteDeviceVec)
557 {
558 sqlite3 *db = nullptr;
559 EXPECT_EQ(GetDB(db), SQLITE_OK);
560
561 EXPECT_EQ(CreateTable(db, remoteFieldInfoList, tableName), SQLITE_OK);
562 TableInfo tableInfo;
563 SQLiteUtils::AnalysisSchema(db, tableName, tableInfo);
564 for (auto &dev : remoteDeviceVec) {
565 dev->SetTableInfo(tableInfo);
566 }
567
568 EXPECT_EQ(DropTable(db, tableName), SQLITE_OK);
569 EXPECT_EQ(CreateTable(db, localFieldInfoList, tableName), SQLITE_OK);
570 EXPECT_EQ(g_rdbDelegatePtr->CreateDistributedTable(tableName), OK);
571
572 sqlite3_close(db);
573
574 GenerateValue(dataMap, localFieldInfoList);
575 InsertValueToDB(dataMap, localFieldInfoList, tableName);
576 for (auto &dev : remoteDeviceVec) {
577 dev->SetLocalFieldInfo(remoteFieldInfoList);
578 }
579 }
580
PrepareEnvironment(std::map<std::string,DataValue> & dataMap,std::vector<FieldInfo> & localFieldInfoList,std::vector<FieldInfo> & remoteFieldInfoList,const std::vector<RelationalVirtualDevice * > remoteDeviceVec)581 void PrepareEnvironment(std::map<std::string, DataValue> &dataMap,
582 std::vector<FieldInfo> &localFieldInfoList, std::vector<FieldInfo> &remoteFieldInfoList,
583 const std::vector<RelationalVirtualDevice *> remoteDeviceVec)
584 {
585 PrepareEnvironment(dataMap, g_tableName, localFieldInfoList, remoteFieldInfoList, remoteDeviceVec);
586 }
587
CheckIdentify(RelationalStoreObserverUnitTest * observer)588 void CheckIdentify(RelationalStoreObserverUnitTest *observer)
589 {
590 ASSERT_NE(observer, nullptr);
591 StoreProperty property = observer->GetStoreProperty();
592 EXPECT_EQ(property.appId, APP_ID);
593 EXPECT_EQ(property.storeId, STORE_ID_1);
594 EXPECT_EQ(property.userId, USER_ID);
595 }
596
CheckSearchData(std::shared_ptr<ResultSet> result,std::map<std::string,DataValue> & dataMap)597 void CheckSearchData(std::shared_ptr<ResultSet> result, std::map<std::string, DataValue> &dataMap)
598 {
599 ASSERT_NE(result, nullptr);
600 EXPECT_EQ(result->GetCount(), 1);
601 ASSERT_TRUE(result->MoveToFirst());
602 std::vector<string> columnNames;
603 result->GetColumnNames(columnNames);
604 ASSERT_EQ(columnNames.size(), dataMap.size());
605 int index = 0;
606 for (auto &column : columnNames) {
607 ASSERT_TRUE(dataMap.find(column) != dataMap.end());
608 LOGD("now check %s", column.c_str());
609 if (dataMap[column].GetType() == StorageType::STORAGE_TYPE_INTEGER) {
610 int64_t expectVal = 0;
611 dataMap[column].GetInt64(expectVal);
612 int64_t actualVal = 0;
613 ASSERT_EQ(result->Get(index, actualVal), OK);
614 EXPECT_EQ(expectVal, actualVal);
615 } else if (dataMap[column].GetType() == StorageType::STORAGE_TYPE_TEXT) {
616 std::string expectVal = "";
617 dataMap[column].GetText(expectVal);
618 std::string actualVal = "";
619 ASSERT_EQ(result->Get(index, actualVal), OK);
620 EXPECT_EQ(expectVal, actualVal);
621 } else if (dataMap[column].GetType() == StorageType::STORAGE_TYPE_REAL) {
622 double expectVal = 0;
623 dataMap[column].GetDouble(expectVal);
624 double actualVal = 0;
625 ASSERT_EQ(result->Get(index, actualVal), OK);
626 EXPECT_EQ(expectVal, actualVal);
627 }
628 index++;
629 }
630 }
631
GetCount(sqlite3 * db,const string & sql,size_t & count)632 int GetCount(sqlite3 *db, const string &sql, size_t &count)
633 {
634 sqlite3_stmt *stmt = nullptr;
635 int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
636 if (errCode != E_OK) {
637 return errCode;
638 }
639 errCode = SQLiteUtils::StepWithRetry(stmt, false);
640 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
641 count = static_cast<size_t>(sqlite3_column_int64(stmt, 0));
642 errCode = E_OK;
643 }
644 SQLiteUtils::ResetStatement(stmt, true, errCode);
645 return errCode;
646 }
647
GenerateSecurityData(std::vector<SecurityLabel> & labelList,std::vector<SecurityFlag> & flagList)648 void GenerateSecurityData(std::vector<SecurityLabel> &labelList, std::vector<SecurityFlag> &flagList)
649 {
650 labelList = {
651 SecurityLabel::NOT_SET,
652 SecurityLabel::S1, SecurityLabel::S2,
653 SecurityLabel::S3, SecurityLabel::S4
654 };
655 flagList = {
656 SecurityFlag::ECE, SecurityFlag::SECE
657 };
658 }
659
SelectSecurityOption(int & labelIndex,int & flagIndex,const std::vector<SecurityLabel> & labelList,const std::vector<SecurityFlag> & flagList)660 SecurityOption SelectSecurityOption(int &labelIndex, int &flagIndex,
661 const std::vector<SecurityLabel> &labelList, const std::vector<SecurityFlag> &flagList)
662 {
663 SecurityOption option;
664 if (labelIndex >= static_cast<int>(labelList.size()) || flagIndex >= static_cast<int>(flagList.size())) {
665 return option;
666 }
667 option.securityLabel = labelList[labelIndex];
668 option.securityFlag = flagList[flagIndex];
669 labelIndex++;
670 if (labelIndex >= static_cast<int>(labelList.size())) {
671 labelIndex = 0;
672 flagIndex++;
673 }
674 return option;
675 }
676
SelectSecurityEnd(int flagIndex,const std::vector<SecurityFlag> & flagList)677 bool SelectSecurityEnd(int flagIndex, const std::vector<SecurityFlag> &flagList)
678 {
679 return flagIndex >= static_cast<int>(flagList.size());
680 }
681
GetSecurityRes(const SecurityOption & localOption,const SecurityOption & remoteOption,bool checkDeviceResult)682 DBStatus GetSecurityRes(const SecurityOption &localOption, const SecurityOption &remoteOption,
683 bool checkDeviceResult)
684 {
685 if (!checkDeviceResult) {
686 return SECURITY_OPTION_CHECK_ERROR;
687 }
688 if (localOption.securityLabel == static_cast<int>(SecurityLabel::NOT_SET) ||
689 remoteOption.securityLabel == static_cast<int>(SecurityLabel::NOT_SET)) {
690 return SECURITY_OPTION_CHECK_ERROR;
691 }
692 if (localOption.securityLabel != remoteOption.securityLabel) {
693 return SECURITY_OPTION_CHECK_ERROR;
694 }
695 return OK;
696 }
697
SyncWithSecurityCheck(const SecurityOption & localOption,const SecurityOption & remoteOption,bool remoteQuery,bool checkDeviceResult)698 void SyncWithSecurityCheck(const SecurityOption &localOption, const SecurityOption &remoteOption,
699 bool remoteQuery, bool checkDeviceResult)
700 {
701 std::shared_ptr<ProcessSystemApiAdapterImpl> adapter = std::make_shared<ProcessSystemApiAdapterImpl>();
702 adapter->ForkCheckDeviceSecurityAbility(
703 [&localOption, &remoteOption, checkDeviceResult, remoteQuery](const std::string &devId,
704 const SecurityOption &option) {
705 if (remoteQuery) {
706 EXPECT_TRUE(remoteOption == option);
707 EXPECT_EQ(devId, DEVICE_A);
708 } else {
709 EXPECT_TRUE(localOption == option);
710 }
711 return checkDeviceResult;
712 });
713 adapter->ForkGetSecurityOption(
714 [&localOption, &remoteOption](const std::string &filePath, SecurityOption &option) {
715 if (filePath.empty()) {
716 option = remoteOption;
717 } else {
718 option = localOption;
719 }
720 return OK;
721 });
722 RuntimeConfig::SetProcessSystemAPIAdapter(adapter);
723 DBStatus resStatus = GetSecurityRes(localOption, remoteOption, checkDeviceResult);
724 if (remoteQuery) {
725 RemoteCondition condition;
726 condition.sql = "SELECT * FROM " + g_tableName;
727 std::shared_ptr<ResultSet> result = nullptr;
728 ASSERT_NE(g_rdbDelegatePtr, nullptr);
729 LOGW("local:label %d, flag %d, remote:label %d, flag %d, expect %d", localOption.securityLabel,
730 localOption.securityFlag, remoteOption.securityLabel, remoteOption.securityFlag,
731 static_cast<int>(resStatus));
732 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_B, condition, DBConstant::MIN_TIMEOUT, result), resStatus);
733 } else {
734 BlockSync(SYNC_MODE_PUSH_ONLY, resStatus, {DEVICE_B});
735 }
736 RuntimeConfig::SetProcessSystemAPIAdapter(nullptr);
737 LOGD("CloseStore Start");
738 EXPECT_EQ(g_rdbDelegatePtr->RemoveDeviceData(), OK);
739 ASSERT_EQ(g_mgr.CloseStore(g_rdbDelegatePtr), OK);
740 g_rdbDelegatePtr = nullptr;
741 OpenStore();
742 }
743
TestWithSecurityCheck(bool remoteQuery)744 void TestWithSecurityCheck(bool remoteQuery)
745 {
746 /**
747 * @tc.steps: step1. create table and open store
748 * @tc.expected: step1. open store ok
749 */
750 std::map<std::string, DataValue> dataMap;
751 if (remoteQuery) {
752 PrepareEnvironment(dataMap, {g_deviceB});
753 } else {
754 PrepareVirtualEnvironment(dataMap, {g_deviceB});
755 }
756 ASSERT_NE(g_rdbDelegatePtr, nullptr);
757
758 /**
759 * @tc.steps: step2. generate test data
760 */
761 std::vector<SecurityLabel> labelList;
762 std::vector<SecurityFlag> flagList;
763 int localLabelIndex = 0;
764 int localFlagIndex = 0;
765 GenerateSecurityData(labelList, flagList);
766
767 // loop local
768 while (!SelectSecurityEnd(localFlagIndex, flagList)) {
769 SecurityOption localOption = SelectSecurityOption(localLabelIndex, localFlagIndex, labelList, flagList);
770 // loop remote
771 int remoteLabelIndex = 0;
772 int remoteFlagIndex = 0;
773 while (!SelectSecurityEnd(remoteFlagIndex, flagList)) {
774 SecurityOption remoteOption = SelectSecurityOption(remoteLabelIndex, remoteFlagIndex,
775 labelList, flagList);
776 /**
777 * @tc.steps: step3. call sync
778 * @tc.expected: step3. sync result is based on security option
779 */
780 SyncWithSecurityCheck(localOption, remoteOption, remoteQuery, true);
781 SyncWithSecurityCheck(localOption, remoteOption, remoteQuery, false);
782 }
783 }
784 }
785
ReleaseForObserver007(RelationalStoreDelegate * rdb1,RelationalStoreObserverUnitTest * observer1,RelationalStoreObserverUnitTest * observer)786 static void ReleaseForObserver007(RelationalStoreDelegate *rdb1, RelationalStoreObserverUnitTest *observer1,
787 RelationalStoreObserverUnitTest *observer)
788 {
789 ASSERT_EQ(g_mgr.CloseStore(rdb1), OK);
790 rdb1 = nullptr;
791 delete observer1;
792 observer1 = nullptr;
793 std::this_thread::sleep_for(std::chrono::seconds(2)); // sleep 2 second to wait sync finish
794 RuntimeConfig::ReleaseAutoLaunch(USER_ID, APP_ID, STORE_ID_1, DBType::DB_RELATION);
795 RuntimeContext::GetInstance()->StopTaskPool();
796 delete observer;
797 observer = nullptr;
798 }
799
SetOption(StoreObserver * observer,RelationalStoreDelegate::Option & option)800 void SetOption(StoreObserver *observer, RelationalStoreDelegate::Option &option)
801 {
802 option.observer = observer;
803 #ifndef OMIT_ENCRYPT
804 option.isEncryptedDb = true;
805 option.iterateTimes = DEFAULT_ITER;
806 option.passwd = g_isAfterRekey ? g_rekeyPasswd : g_correctPasswd;
807 option.cipher = CipherType::DEFAULT;
808 #endif
809 }
810
811 class DistributedDBRelationalVerP2PSyncTest : public testing::Test {
812 public:
813 static void SetUpTestCase();
814 static void TearDownTestCase();
815 void SetUp();
816 void TearDown();
817 };
818
SetUpTestCase()819 void DistributedDBRelationalVerP2PSyncTest::SetUpTestCase()
820 {
821 /**
822 * @tc.setup: Init datadir and Virtual Communicator.
823 */
824 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
825 g_dbDir = g_testDir + "/test.db";
826 sqlite3 *db = nullptr;
827 ASSERT_EQ(GetDB(db), SQLITE_OK);
828 sqlite3_close(db);
829
830 g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
831 ASSERT_TRUE(g_communicatorAggregator != nullptr);
832 RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
833
834 g_id = g_mgr.GetRelationalStoreIdentifier(USER_ID, APP_ID, STORE_ID_1);
835
836 #ifndef OMIT_ENCRYPT
837 g_correctPasswd.SetValue(reinterpret_cast<const uint8_t *>(CORRECT_KEY.data()), CORRECT_KEY.size());
838 g_rekeyPasswd.SetValue(reinterpret_cast<const uint8_t *>(REKEY_KEY.data()), REKEY_KEY.size());
839 g_incorrectPasswd.SetValue(reinterpret_cast<const uint8_t *>(INCORRECT_KEY.data()), INCORRECT_KEY.size());
840 #endif
841 }
842
TearDownTestCase()843 void DistributedDBRelationalVerP2PSyncTest::TearDownTestCase()
844 {
845 /**
846 * @tc.teardown: Release virtual Communicator and clear data dir.
847 */
848 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
849 LOGE("rm test db files error!");
850 }
851 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
852 LOGD("TearDownTestCase FINISH");
853 }
854
SetUp(void)855 void DistributedDBRelationalVerP2PSyncTest::SetUp(void)
856 {
857 DistributedDBToolsUnitTest::PrintTestCaseInfo();
858 g_fieldInfoList.clear();
859 /**
860 * @tc.setup: create virtual device B, and get a KvStoreNbDelegate as deviceA
861 */
862 sqlite3 *db = nullptr;
863 ASSERT_EQ(GetDB(db), SQLITE_OK);
864 sqlite3_close(db);
865 OpenStore();
866 g_deviceB = new (std::nothrow) RelationalVirtualDevice(DEVICE_B);
867 ASSERT_TRUE(g_deviceB != nullptr);
868 g_deviceC = new (std::nothrow) RelationalVirtualDevice(DEVICE_C);
869 ASSERT_TRUE(g_deviceC != nullptr);
870 g_deviceD = new (std::nothrow) KvVirtualDevice(DEVICE_D);
871 ASSERT_TRUE(g_deviceD != nullptr);
872 auto *syncInterfaceB = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
873 auto *syncInterfaceC = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
874 auto *syncInterfaceD = new (std::nothrow) VirtualSingleVerSyncDBInterface();
875 ASSERT_TRUE(syncInterfaceB != nullptr);
876 ASSERT_TRUE(syncInterfaceC != nullptr);
877 ASSERT_TRUE(syncInterfaceD != nullptr);
878 ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
879 ASSERT_EQ(g_deviceC->Initialize(g_communicatorAggregator, syncInterfaceC), E_OK);
880 ASSERT_EQ(g_deviceD->Initialize(g_communicatorAggregator, syncInterfaceD), E_OK);
881
882 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
883 const std::string &deviceId, uint8_t flag) -> bool {
884 return true;
885 };
886 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
887 }
888
TearDown(void)889 void DistributedDBRelationalVerP2PSyncTest::TearDown(void)
890 {
891 /**
892 * @tc.teardown: Release device A, B, C
893 */
894 if (g_rdbDelegatePtr != nullptr) {
895 LOGD("CloseStore Start");
896 ASSERT_EQ(g_mgr.CloseStore(g_rdbDelegatePtr), OK);
897 g_rdbDelegatePtr = nullptr;
898 }
899 if (g_deviceB != nullptr) {
900 delete g_deviceB;
901 g_deviceB = nullptr;
902 }
903 if (g_deviceC != nullptr) {
904 delete g_deviceC;
905 g_deviceC = nullptr;
906 }
907 if (g_deviceD != nullptr) {
908 delete g_deviceD;
909 g_deviceD = nullptr;
910 }
911 if (g_observer != nullptr) {
912 delete g_observer;
913 g_observer = nullptr;
914 }
915 PermissionCheckCallbackV2 nullCallback;
916 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(nullCallback), OK);
917 EXPECT_EQ(DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir), E_OK);
918 if (g_communicatorAggregator != nullptr) {
919 g_communicatorAggregator->RegOnDispatch(nullptr);
920 }
921 g_isAfterRekey = false;
922 LOGD("TearDown FINISH");
923 }
924
925 /**
926 * @tc.name: Normal Sync 001
927 * @tc.desc: Test normal push sync for add data.
928 * @tc.type: FUNC
929 * @tc.require: AR000GK58N
930 * @tc.author: zhangqiquan
931 */
932 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync001, TestSize.Level0)
933 {
934 std::map<std::string, DataValue> dataMap;
935 PrepareEnvironment(dataMap, {g_deviceB});
936 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
937
938 CheckVirtualData(dataMap);
939 DistributedDBToolsUnitTest::Dump();
940 }
941
942 /**
943 * @tc.name: Normal Sync 002
944 * @tc.desc: Test normal pull sync for add data.
945 * @tc.type: FUNC
946 * @tc.require: AR000GK58N
947 * @tc.author: zhangqiquan
948 */
949 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync002, TestSize.Level0)
950 {
951 std::map<std::string, DataValue> dataMap;
952 PrepareEnvironment(dataMap, {g_deviceB});
953
954 Query query = Query::Select(g_tableName);
955 g_deviceB->GenericVirtualDevice::Sync(DistributedDB::SYNC_MODE_PULL_ONLY, query, true);
956
957 CheckVirtualData(dataMap);
958 }
959
960 /**
961 * @tc.name: Normal Sync 003
962 * @tc.desc: Test normal push sync for update data.
963 * @tc.type: FUNC
964 * @tc.require: AR000GK58N
965 * @tc.author: zhangqiquan
966 */
967 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync003, TestSize.Level1)
968 {
969 std::map<std::string, DataValue> dataMap;
970 PrepareEnvironment(dataMap, {g_deviceB});
971
972 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
973
974 CheckVirtualData(dataMap);
975
976 GenerateValue(dataMap, g_fieldInfoList);
977 dataMap["AGE"] = static_cast<int64_t>(1);
978 InsertValueToDB(dataMap);
979 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
980
981 CheckVirtualData(dataMap);
982 }
983
984 /**
985 * @tc.name: Normal Sync 004
986 * @tc.desc: Test normal push sync for delete data.
987 * @tc.type: FUNC
988 * @tc.require: AR000GK58N
989 * @tc.author: zhangqiquan
990 */
991 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync004, TestSize.Level1)
992 {
993 std::map<std::string, DataValue> dataMap;
994 PrepareEnvironment(dataMap, {g_deviceB});
995
996 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
997
998 CheckVirtualData(dataMap);
999
1000 sqlite3 *db = nullptr;
1001 EXPECT_EQ(GetDB(db), SQLITE_OK);
1002 std::string sql = "DELETE FROM TEST_TABLE WHERE 1 = 1";
1003 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
1004 sqlite3_close(db);
1005
1006 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1007
1008 std::vector<VirtualRowData> dataList;
1009 EXPECT_EQ(g_deviceB->GetAllSyncData(g_tableName, dataList), E_OK);
1010 EXPECT_EQ(static_cast<int>(dataList.size()), 0);
1011 }
1012
1013 /**
1014 * @tc.name: Normal Sync 005
1015 * @tc.desc: Test normal push sync for add data.
1016 * @tc.type: FUNC
1017 * @tc.require: AR000GK58N
1018 * @tc.author: zhangqiquan
1019 */
1020 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync005, TestSize.Level0)
1021 {
1022 std::map<std::string, DataValue> dataMap;
1023 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1024
1025 Query query = Query::Select(g_tableName);
1026 g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true);
1027
1028 CheckData(dataMap);
1029
1030 g_rdbDelegatePtr->RemoveDeviceData(DEVICE_B);
1031
1032 g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true);
1033
1034 CheckData(dataMap);
1035 }
1036
1037 /**
1038 * @tc.name: Normal Sync 006
1039 * @tc.desc: Test normal pull sync for add data.
1040 * @tc.type: FUNC
1041 * @tc.require: AR000GK58N
1042 * @tc.author: zhangqiquan
1043 */
1044 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync006, TestSize.Level1)
1045 {
1046 std::map<std::string, DataValue> dataMap;
1047 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1048
1049 BlockSync(SYNC_MODE_PULL_ONLY, OK, {DEVICE_B});
1050
1051 CheckData(dataMap);
1052 }
1053
1054 /**
1055 * @tc.name: Normal Sync 007
1056 * @tc.desc: Test normal sync for miss query data.
1057 * @tc.type: FUNC
1058 * @tc.require: AR000GK58N
1059 * @tc.author: zhangqiquan
1060 */
1061 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync007, TestSize.Level1)
1062 {
1063 std::map<std::string, DataValue> dataMap;
1064 PrepareEnvironment(dataMap, {g_deviceB});
1065
1066 Query query = Query::Select(g_tableName).EqualTo("NAME", DEFAULT_TEXT);
1067 BlockSync(query, SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1068
1069 CheckVirtualData(dataMap);
1070
1071 sqlite3 *db = nullptr;
1072 EXPECT_EQ(GetDB(db), SQLITE_OK);
1073 std::string sql = "UPDATE TEST_TABLE SET NAME = '' WHERE 1 = 1";
1074 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
1075 sqlite3_close(db);
1076
1077 BlockSync(query, SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1078
1079 std::vector<VirtualRowData> dataList;
1080 EXPECT_EQ(g_deviceB->GetAllSyncData(g_tableName, dataList), E_OK);
1081 EXPECT_EQ(static_cast<int>(dataList.size()), 1);
1082 for (const auto &item : dataList) {
1083 EXPECT_EQ(item.logInfo.flag, DataItem::REMOTE_DEVICE_DATA_MISS_QUERY);
1084 }
1085 }
1086
1087 /**
1088 * @tc.name: Normal Sync 008
1089 * @tc.desc: Test encry db sync for delete table;
1090 * @tc.type: FUNC
1091 * @tc.require: AR000GK58N
1092 * @tc.author: zhuwentao
1093 */
1094 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync008, TestSize.Level0)
1095 {
1096 /**
1097 * @tc.steps: step1. open rdb store, create distribute table, insert data and sync to deviceB
1098 */
1099 std::map<std::string, DataValue> dataMap;
1100 PrepareEnvironment(dataMap, {g_deviceB});
1101 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1102 CheckVirtualData(dataMap);
1103 /**
1104 * @tc.steps: step2.drop table operation and sync again
1105 */
1106 sqlite3 *db = nullptr;
1107 EXPECT_EQ(GetDB(db), SQLITE_OK);
1108 std::string dropTableSql = "drop table TEST_TABLE;";
1109 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, dropTableSql), E_OK);
1110 std::vector<RelationalVirtualDevice *> remoteDeviceVec = {g_deviceB};
1111 PrepareBasicTable(g_tableName, g_fieldInfoList, remoteDeviceVec, true);
1112 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1113 /**
1114 * @tc.steps: step3.check data in deviceB
1115 */
1116 std::vector<VirtualRowData> targetData;
1117 g_deviceB->GetAllSyncData(g_tableName, targetData);
1118 ASSERT_EQ(targetData.size(), 0u);
1119 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1120 }
1121
1122 /**
1123 * @tc.name: Normal Sync 009
1124 * @tc.desc: Test normal push sync for while create distribute table
1125 * @tc.type: FUNC
1126 * @tc.require: AR000GK58N
1127 * @tc.author: zhuwentao
1128 */
1129 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync009, TestSize.Level0)
1130 {
1131 std::map<std::string, DataValue> dataMap;
1132 PrepareEnvironment(dataMap, {g_deviceB});
1133
1134 sqlite3 *db = nullptr;
1135 EXPECT_EQ(GetDB(db), SQLITE_OK);
1136 std::string sql = "alter table TEST_TABLE add column addr Text;";
1137 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
1138 sqlite3_close(db);
1139
1140 std::mutex syncMutex;
1141 std::condition_variable syncCv;
1142 std::mutex syncCallMutex;
1143 std::condition_variable syncCallCv;
1144 std::map<std::string, std::vector<TableStatus>> statusMap;
1145 SyncStatusCallback callBack = [&statusMap, &syncMutex, &syncCv](
__anon342485330602( const std::map<std::string, std::vector<TableStatus>> &devicesMap) 1146 const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1147 statusMap = devicesMap;
1148 std::unique_lock<std::mutex> lock(syncMutex);
1149 syncCv.notify_one();
1150 };
__anon342485330702null1151 std::thread t1([] {
1152 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1153 g_rdbDelegatePtr->CreateDistributedTable(g_tableName);
1154 });
1155 DBStatus callStatus = OK;
__anon342485330802null1156 std::thread t2([&syncCallCv, &callBack, &callStatus] {
1157 Query query = Query::Select(g_tableName);
1158 callStatus = g_rdbDelegatePtr->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callBack, false);
1159 syncCallCv.notify_one();
1160 });
1161 {
1162 std::unique_lock<std::mutex> callLock(syncCallMutex);
1163 syncCallCv.wait(callLock);
1164 }
1165 if (callStatus == OK) {
1166 std::unique_lock<std::mutex> lock(syncMutex);
1167 syncCv.wait(lock);
1168 }
1169 t1.join();
1170 t2.join();
1171 }
1172
1173 /**
1174 * @tc.name: AutoLaunchSync 001
1175 * @tc.desc: Test rdb autoLaunch success when callback return true.
1176 * @tc.type: FUNC
1177 * @tc.require: AR000GK58N
1178 * @tc.author: zhangqiquan
1179 */
1180 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSync001, TestSize.Level3)
1181 {
1182 /**
1183 * @tc.steps: step1. open rdb store, create distribute table and insert data
1184 */
1185 std::map<std::string, DataValue> dataMap;
1186 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1187
1188 /**
1189 * @tc.steps: step2. set auto launch callBack
1190 */
1191 int currentStatus = 0;
1192 const AutoLaunchNotifier notifier = [¤tStatus](const std::string &userId,
__anon342485330902(const std::string &userId, const std::string &appId, const std::string &storeId, AutoLaunchStatus status) 1193 const std::string &appId, const std::string &storeId, AutoLaunchStatus status) {
1194 currentStatus = static_cast<int>(status);
1195 };
__anon342485330a02(const std::string &identifier, AutoLaunchParam ¶m) 1196 const AutoLaunchRequestCallback callback = [¬ifier](const std::string &identifier, AutoLaunchParam ¶m) {
1197 if (g_id != identifier) {
1198 return false;
1199 }
1200 param.path = g_dbDir;
1201 param.appId = APP_ID;
1202 param.userId = USER_ID;
1203 param.storeId = STORE_ID_1;
1204 param.notifier = notifier;
1205 #ifndef OMIT_ENCRYPT
1206 param.option.isEncryptedDb = true;
1207 param.option.cipher = CipherType::DEFAULT;
1208 param.option.passwd = g_correctPasswd;
1209 param.option.iterateTimes = DEFAULT_ITER;
1210 #endif
1211 return true;
1212 };
1213 g_mgr.SetAutoLaunchRequestCallback(callback);
1214 /**
1215 * @tc.steps: step3. close store ensure communicator has closed
1216 */
1217 g_mgr.CloseStore(g_rdbDelegatePtr);
1218 g_rdbDelegatePtr = nullptr;
1219 /**
1220 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
1221 */
1222 LabelType labelType(g_id.begin(), g_id.end());
1223 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1224 std::this_thread::sleep_for(std::chrono::seconds(1));
1225 EXPECT_EQ(currentStatus, 0);
1226 /**
1227 * @tc.steps: step5. Call sync expect sync successful
1228 */
1229 Query query = Query::Select(g_tableName);
1230 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1231 /**
1232 * @tc.steps: step6. check sync data ensure sync successful
1233 */
1234 CheckData(dataMap);
1235
1236 OpenStore();
1237 RuntimeConfig::ReleaseAutoLaunch(USER_ID, APP_ID, STORE_ID_1, DBType::DB_RELATION);
1238 }
1239
1240 /**
1241 * @tc.name: AutoLaunchSync 002
1242 * @tc.desc: Test rdb autoLaunch failed when callback return false.
1243 * @tc.type: FUNC
1244 * @tc.require: AR000GK58N
1245 * @tc.author: zhangqiquan
1246 */
1247 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSync002, TestSize.Level3)
1248 {
1249 /**
1250 * @tc.steps: step1. open rdb store, create distribute table and insert data
1251 */
1252 std::map<std::string, DataValue> dataMap;
1253 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1254
1255 /**
1256 * @tc.steps: step2. set auto launch callBack
1257 */
__anon342485330b02(const std::string &identifier, AutoLaunchParam ¶m) 1258 const AutoLaunchRequestCallback callback = [](const std::string &identifier, AutoLaunchParam ¶m) {
1259 return false;
1260 };
1261 g_mgr.SetAutoLaunchRequestCallback(callback);
1262 /**
1263 * @tc.steps: step2. close store ensure communicator has closed
1264 */
1265 g_mgr.CloseStore(g_rdbDelegatePtr);
1266 g_rdbDelegatePtr = nullptr;
1267 /**
1268 * @tc.steps: step3. store can't autoLaunch because callback return false
1269 */
1270 LabelType labelType(g_id.begin(), g_id.end());
1271 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1272 std::this_thread::sleep_for(std::chrono::seconds(1));
1273 /**
1274 * @tc.steps: step4. Call sync expect sync fail
1275 */
1276 Query query = Query::Select(g_tableName);
__anon342485330c02(const std::map<std::string, int> &statusMap) 1277 SyncOperation::UserCallback callBack = [](const std::map<std::string, int> &statusMap) {
1278 for (const auto &entry : statusMap) {
1279 EXPECT_EQ(entry.second, -E_NOT_FOUND);
1280 }
1281 };
1282 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, callBack, true), E_OK);
1283
1284 OpenStore();
1285 std::this_thread::sleep_for(std::chrono::minutes(1));
1286 }
1287
1288 /**
1289 * @tc.name: AutoLaunchSync 003
1290 * @tc.desc: Test rdb autoLaunch failed when callback is nullptr.
1291 * @tc.type: FUNC
1292 * @tc.require: AR000GK58N
1293 * @tc.author: zhangqiquan
1294 */
1295 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSync003, TestSize.Level3)
1296 {
1297 /**
1298 * @tc.steps: step1. open rdb store, create distribute table and insert data
1299 */
1300 std::map<std::string, DataValue> dataMap;
1301 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1302
1303 g_mgr.SetAutoLaunchRequestCallback(nullptr);
1304 /**
1305 * @tc.steps: step2. close store ensure communicator has closed
1306 */
1307 g_mgr.CloseStore(g_rdbDelegatePtr);
1308 g_rdbDelegatePtr = nullptr;
1309 /**
1310 * @tc.steps: step3. store can't autoLaunch because callback is nullptr
1311 */
1312 LabelType labelType(g_id.begin(), g_id.end());
1313 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1314 std::this_thread::sleep_for(std::chrono::seconds(1));
1315 /**
1316 * @tc.steps: step4. Call sync expect sync fail
1317 */
1318 Query query = Query::Select(g_tableName);
__anon342485330d02(const std::map<std::string, int> &statusMap) 1319 SyncOperation::UserCallback callBack = [](const std::map<std::string, int> &statusMap) {
1320 for (const auto &entry : statusMap) {
1321 EXPECT_EQ(entry.second, -E_NOT_FOUND);
1322 }
1323 };
1324 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, callBack, true), E_OK);
1325
1326 OpenStore();
1327 std::this_thread::sleep_for(std::chrono::minutes(1));
1328 }
1329
1330
1331 /**
1332 * @tc.name: AutoLaunchSync 004
1333 * @tc.desc: Test invalid db type for autoLaunch.
1334 * @tc.type: FUNC
1335 * @tc.require:
1336 * @tc.author: zhangshijie
1337 */
1338 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSync004, TestSize.Level3)
1339 {
1340 /**
1341 * @tc.steps: step1. open rdb store, create distribute table and insert data
1342 */
1343 std::map<std::string, DataValue> dataMap;
1344 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1345
1346 /**
1347 * @tc.steps: step2. set auto launch callBack
1348 */
1349 int currentStatus = 0;
1350 const AutoLaunchNotifier notifier = [¤tStatus](const std::string &userId,
__anon342485330e02(const std::string &userId, const std::string &appId, const std::string &storeId, AutoLaunchStatus status) 1351 const std::string &appId, const std::string &storeId, AutoLaunchStatus status) {
1352 printf("SET STATUS = %d\n", static_cast<int>(status));
1353 currentStatus = static_cast<int>(status);
1354 };
__anon342485330f02(const std::string &identifier, AutoLaunchParam ¶m) 1355 const AutoLaunchRequestCallback callback = [¬ifier](const std::string &identifier, AutoLaunchParam ¶m) {
1356 if (g_id != identifier) {
1357 return false;
1358 }
1359 param.path = g_dbDir;
1360 param.appId = APP_ID;
1361 param.userId = USER_ID;
1362 param.storeId = STORE_ID_1;
1363 param.notifier = notifier;
1364 #ifndef OMIT_ENCRYPT
1365 param.option.isEncryptedDb = true;
1366 param.option.cipher = CipherType::DEFAULT;
1367 param.option.passwd = g_correctPasswd;
1368 param.option.iterateTimes = DEFAULT_ITER;
1369 #endif
1370 return true;
1371 };
1372 RuntimeConfig::SetAutoLaunchRequestCallback(callback, static_cast<DBType>(3)); // 3 is invalid db type
1373
1374 /**
1375 * @tc.steps: step3. close store ensure communicator has closed
1376 */
1377 g_mgr.CloseStore(g_rdbDelegatePtr);
1378 g_rdbDelegatePtr = nullptr;
1379 /**
1380 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
1381 */
1382 LabelType labelType(g_id.begin(), g_id.end());
1383 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1384 std::this_thread::sleep_for(std::chrono::seconds(1));
1385 EXPECT_EQ(currentStatus, AutoLaunchStatus::INVALID_PARAM);
1386 }
1387
1388 /**
1389 * @tc.name: Ability Sync 001
1390 * @tc.desc: Test ability sync success when has same schema.
1391 * @tc.type: FUNC
1392 * @tc.require: AR000GK58N
1393 * @tc.author: zhangqiquan
1394 */
1395 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AbilitySync001, TestSize.Level1)
1396 {
1397 std::map<std::string, DataValue> dataMap;
1398 std::vector<FieldInfo> localFieldInfo;
1399 GetFieldInfo(localFieldInfo, g_storageType);
1400
1401 PrepareEnvironment(dataMap, localFieldInfo, localFieldInfo, {g_deviceB});
1402 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1403
1404 CheckVirtualData(dataMap);
1405 }
1406
1407 /**
1408 * @tc.name: Ability Sync 002
1409 * @tc.desc: Test ability sync failed when has different schema.
1410 * @tc.type: FUNC
1411 * @tc.require: AR000GK58N
1412 * @tc.author: zhangqiquan
1413 */
1414 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AbilitySync002, TestSize.Level1)
1415 {
1416 /**
1417 * @tc.steps: step1. set local schema is (BOOL, INTEGER, REAL, TEXT, BLOB, INTEGER)
1418 */
1419 std::map<std::string, DataValue> dataMap;
1420 std::vector<FieldInfo> localFieldInfo;
1421 std::vector<StorageType> localStorageType = g_storageType;
1422 localStorageType.push_back(StorageType::STORAGE_TYPE_INTEGER);
1423 GetFieldInfo(localFieldInfo, localStorageType);
1424
1425 /**
1426 * @tc.steps: step2. set remote schema is (BOOL, INTEGER, REAL, TEXT, BLOB, TEXT)
1427 */
1428 std::vector<FieldInfo> remoteFieldInfo;
1429 std::vector<StorageType> remoteStorageType = g_storageType;
1430 remoteStorageType.push_back(StorageType::STORAGE_TYPE_TEXT);
1431 GetFieldInfo(remoteFieldInfo, remoteStorageType);
1432
1433 /**
1434 * @tc.steps: step3. call sync
1435 * @tc.expected: sync fail when abilitySync
1436 */
1437 PrepareEnvironment(dataMap, localFieldInfo, remoteFieldInfo, {g_deviceB});
1438 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, SCHEMA_MISMATCH, {DEVICE_B});
1439 }
1440
1441 /**
1442 * @tc.name: Ability Sync 003
1443 * @tc.desc: Test ability sync failed when has different schema.
1444 * @tc.type: FUNC
1445 * @tc.require: AR000GK58N
1446 * @tc.author: zhangqiquan
1447 */
1448 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AbilitySync003, TestSize.Level1)
1449 {
1450 /**
1451 * @tc.steps: step1. set local and remote schema is (BOOL, INTEGER, REAL, TEXT, BLOB)
1452 */
1453 std::map<std::string, DataValue> dataMap;
1454 std::vector<FieldInfo> schema;
1455 std::vector<StorageType> localStorageType = g_storageType;
1456 GetFieldInfo(schema, localStorageType);
1457
1458 /**
1459 * @tc.steps: step2. create table and insert data
1460 */
1461 PrepareEnvironment(dataMap, schema, schema, {g_deviceB});
1462
1463 /**
1464 * @tc.steps: step3. change local table to (BOOL, INTEGER, REAL, TEXT, BLOB)
1465 * @tc.expected: sync fail
1466 */
1467 bool alter = false;
__anon342485331002(const std::string &target, Message *inMsg) 1468 g_communicatorAggregator->RegOnDispatch([&alter](const std::string &target, Message *inMsg) {
1469 if (target != "real_device") {
1470 return;
1471 }
1472 if (inMsg->GetMessageType() != TYPE_NOTIFY || inMsg->GetMessageId() != ABILITY_SYNC_MESSAGE) {
1473 return;
1474 }
1475 if (alter) {
1476 return;
1477 }
1478 alter = true;
1479 sqlite3 *db = nullptr;
1480 EXPECT_EQ(GetDB(db), SQLITE_OK);
1481 ASSERT_NE(db, nullptr);
1482 std::string alterSql = "ALTER TABLE " + g_tableName + " ADD COLUMN NEW_COLUMN TEXT DEFAULT 'DEFAULT_TEXT'";
1483 EXPECT_EQ(sqlite3_exec(db, alterSql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1484 EXPECT_EQ(sqlite3_close(db), SQLITE_OK);
1485 EXPECT_EQ(g_rdbDelegatePtr->CreateDistributedTable(g_tableName), OK);
1486 });
1487
1488 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1489
1490 g_communicatorAggregator->RegOnDispatch(nullptr);
1491 }
1492
1493 /**
1494 * @tc.name: Ability Sync 004
1495 * @tc.desc: Test ability sync failed when one device hasn't distributed table.
1496 * @tc.type: FUNC
1497 * @tc.require: AR000GK58N
1498 * @tc.author: zhangqiquan
1499 */
1500 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AbilitySync004, TestSize.Level1)
1501 {
1502 std::map<std::string, DataValue> dataMap;
1503 PrepareVirtualEnvironment(dataMap, {g_deviceB}, false);
1504
1505 Query query = Query::Select(g_tableName);
1506 int res = DB_ERROR;
__anon342485331102(std::map<std::string, int> resMap) 1507 auto callBack = [&res](std::map<std::string, int> resMap) {
1508 if (resMap.find("real_device") != resMap.end()) {
1509 res = resMap["real_device"];
1510 }
1511 };
1512 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(DistributedDB::SYNC_MODE_PULL_ONLY, query, callBack, true), E_OK);
1513 EXPECT_EQ(res, static_cast<int>(SyncOperation::Status::OP_SCHEMA_INCOMPATIBLE));
1514 }
1515
1516 /**
1517 * @tc.name: Ability Sync 005
1518 * @tc.desc: Test ability sync fail when SendMessage err.
1519 * @tc.type: FUNC
1520 * @tc.require:
1521 * @tc.author: suyue
1522 */
1523 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AbilitySync005, TestSize.Level1)
1524 {
1525 std::map<std::string, DataValue> dataMap;
1526 std::vector<FieldInfo> localFieldInfo;
1527 GetFieldInfo(localFieldInfo, g_storageType);
1528 g_communicatorAggregator->DisableCommunicator();
1529 PrepareEnvironment(dataMap, localFieldInfo, localFieldInfo, {g_deviceB});
1530 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, DB_ERROR, {DEVICE_B});
1531 }
1532
1533 /**
1534 * @tc.name: WaterMark 001
1535 * @tc.desc: Test sync success after erase waterMark.
1536 * @tc.type: FUNC
1537 * @tc.require: AR000GK58N
1538 * @tc.author: zhangqiquan
1539 */
1540 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, WaterMark001, TestSize.Level1)
1541 {
1542 std::map<std::string, DataValue> dataMap;
1543 PrepareEnvironment(dataMap, {g_deviceB});
1544 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1545
1546 CheckVirtualData(dataMap);
1547
1548 EXPECT_EQ(g_rdbDelegatePtr->RemoveDeviceData(g_deviceB->GetDeviceId(), g_tableName), OK);
1549 g_deviceB->EraseSyncData(g_tableName);
1550
1551 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1552
1553 CheckVirtualData(dataMap);
1554 }
1555
1556 /*
1557 * @tc.name: pressure sync 001
1558 * @tc.desc: Test rdb sync different table at same time
1559 * @tc.type: FUNC
1560 * @tc.require: AR000GK58N
1561 * @tc.author: zhangqiquan
1562 */
1563 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, PressureSync001, TestSize.Level1)
1564 {
1565 /**
1566 * @tc.steps: step1. create table A and device A push data to device B
1567 * @tc.expected: step1. all is ok
1568 */
1569 std::map<std::string, DataValue> tableADataMap;
1570 std::vector<FieldInfo> tableAFieldInfo;
1571 std::vector<StorageType> localStorageType = g_storageType;
1572 localStorageType.push_back(StorageType::STORAGE_TYPE_INTEGER);
1573 GetFieldInfo(tableAFieldInfo, localStorageType);
1574 const std::string tableNameA = "TABLE_A";
1575 PrepareEnvironment(tableADataMap, tableNameA, tableAFieldInfo, tableAFieldInfo, {g_deviceB});
1576
1577 /**
1578 * @tc.steps: step2. create table B and device B push data to device A
1579 * @tc.expected: step2. all is ok
1580 */
1581 std::map<std::string, DataValue> tableBDataMap;
1582 std::vector<FieldInfo> tableBFieldInfo;
1583 localStorageType = g_storageType;
1584 localStorageType.push_back(StorageType::STORAGE_TYPE_REAL);
1585 GetFieldInfo(tableBFieldInfo, localStorageType);
1586 const std::string tableNameB = "TABLE_B";
1587 PrepareVirtualEnvironment(tableBDataMap, tableNameB, tableBFieldInfo, {g_deviceB});
1588
1589 std::condition_variable cv;
1590 bool subFinish = false;
__anon342485331202() 1591 std::thread subThread = std::thread([&subFinish, &cv, &tableNameA, &tableADataMap]() {
1592 BlockSync(tableNameA, SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1593
1594 CheckVirtualData(tableNameA, tableADataMap);
1595 subFinish = true;
1596 cv.notify_all();
1597 });
1598 subThread.detach();
1599
1600 Query query = Query::Select(tableNameB);
1601 g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true);
1602 CheckData(tableBDataMap, tableNameB, tableBFieldInfo);
1603
1604 std::mutex mutex;
1605 std::unique_lock<std::mutex> lock(mutex);
__anon342485331302null1606 cv.wait(lock, [&subFinish] { return subFinish; });
1607 }
1608
1609 /*
1610 * @tc.name: relation observer 001
1611 * @tc.desc: Test relation observer while normal pull sync
1612 * @tc.type: FUNC
1613 * @tc.require:
1614 * @tc.author: zhuwentao
1615 */
1616 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer001, TestSize.Level0)
1617 {
1618 /**
1619 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1620 * @tc.expected: step1. create and insert ok
1621 */
1622 g_observer->ResetToZero();
1623 std::map<std::string, DataValue> dataMap;
1624 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1625 /**
1626 * @tc.steps: step2. device A pull sync mode
1627 * @tc.expected: step2. sync ok
1628 */
1629 BlockSync(SyncMode::SYNC_MODE_PULL_ONLY, OK, {DEVICE_B, DEVICE_C});
1630 /**
1631 * @tc.steps: step3. device A check observer
1632 * @tc.expected: step2. data change device is deviceB
1633 */
1634 EXPECT_EQ(g_observer->GetCallCount(), 1u);
1635 EXPECT_EQ(g_observer->GetDataChangeDevice(), DEVICE_B);
1636 CheckIdentify(g_observer);
1637 }
1638
1639 /**
1640 * @tc.name: relation observer 002
1641 * @tc.desc: Test rdb observer ok in autolauchCallback scene
1642 * @tc.type: FUNC
1643 * @tc.require: AR000GK58N
1644 * @tc.author: zhuwentao
1645 */
1646 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer002, TestSize.Level3)
1647 {
1648 /**
1649 * @tc.steps: step1. open rdb store, create distribute table and insert data
1650 */
1651 g_observer->ResetToZero();
1652 std::map<std::string, DataValue> dataMap;
1653 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1654
1655 /**
1656 * @tc.steps: step2. set auto launch callBack
1657 */
1658 RelationalStoreObserverUnitTest *observer = new (std::nothrow) RelationalStoreObserverUnitTest();
__anon342485331402(const std::string &identifier, AutoLaunchParam ¶m) 1659 const AutoLaunchRequestCallback callback = [observer](const std::string &identifier, AutoLaunchParam ¶m) {
1660 if (g_id != identifier) {
1661 return false;
1662 }
1663 param.path = g_dbDir;
1664 param.appId = APP_ID;
1665 param.userId = USER_ID;
1666 param.storeId = STORE_ID_1;
1667 param.option.storeObserver = observer;
1668 #ifndef OMIT_ENCRYPT
1669 param.option.isEncryptedDb = true;
1670 param.option.cipher = CipherType::DEFAULT;
1671 param.option.passwd = g_correctPasswd;
1672 param.option.iterateTimes = DEFAULT_ITER;
1673 #endif
1674 return true;
1675 };
1676 g_mgr.SetAutoLaunchRequestCallback(callback);
1677 /**
1678 * @tc.steps: step3. close store ensure communicator has closed
1679 */
1680 g_mgr.CloseStore(g_rdbDelegatePtr);
1681 g_rdbDelegatePtr = nullptr;
1682 /**
1683 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
1684 */
1685 LabelType labelType(g_id.begin(), g_id.end());
1686 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1687 std::this_thread::sleep_for(std::chrono::seconds(1));
1688 /**
1689 * @tc.steps: step5. Call sync expect sync successful and device A check observer
1690 */
1691 Query query = Query::Select(g_tableName);
1692 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1693 EXPECT_EQ(observer->GetCallCount(), 1u);
1694 EXPECT_EQ(observer->GetDataChangeDevice(), DEVICE_B);
1695 CheckIdentify(observer);
1696 std::this_thread::sleep_for(std::chrono::minutes(1));
1697 delete observer;
1698 }
1699
1700 /*
1701 * @tc.name: relation observer 003
1702 * @tc.desc: Test relation observer without manager
1703 * @tc.type: FUNC
1704 * @tc.require:
1705 * @tc.author: zhangqiquan
1706 */
1707 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer003, TestSize.Level0)
1708 {
1709 /**
1710 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1711 * @tc.expected: step1. create and insert ok
1712 */
1713 g_observer->ResetToZero();
1714 std::map<std::string, DataValue> dataMap;
1715 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1716 std::shared_ptr<RelationalStoreManager> mgr = std::make_shared<RelationalStoreManager>(APP_ID, USER_ID);
1717 ASSERT_NE(mgr, nullptr);
1718 RelationalStoreDelegate::Option option;
1719 option.observer = g_observer;
1720 #ifndef OMIT_ENCRYPT
1721 option.isEncryptedDb = true;
1722 option.iterateTimes = DEFAULT_ITER;
1723 option.passwd = g_isAfterRekey ? g_rekeyPasswd : g_correctPasswd;
1724 option.cipher = CipherType::DEFAULT;
1725 #endif
1726 RelationalStoreDelegate *rdbDelegatePtr = nullptr;
1727 mgr->OpenStore(g_dbDir, STORE_ID_1, option, rdbDelegatePtr);
1728 mgr = nullptr;
1729 /**
1730 * @tc.steps: step2. device A pull sync mode
1731 * @tc.expected: step2. sync ok
1732 */
1733 Query query = Query::Select(g_tableName);
1734 DBStatus callStatus = rdbDelegatePtr->Sync({DEVICE_B, DEVICE_C}, SyncMode::SYNC_MODE_PULL_ONLY, query,
1735 nullptr, true);
1736 EXPECT_EQ(callStatus, OK);
1737 /**
1738 * @tc.steps: step3. device A check observer
1739 * @tc.expected: step2. data change device is deviceB
1740 */
1741 EXPECT_EQ(g_observer->GetCallCount(), 2u); // 2 is observer triggered times
1742 EXPECT_EQ(g_observer->GetDataChangeDevice(), DEVICE_B);
1743 CheckIdentify(g_observer);
1744 mgr = std::make_shared<RelationalStoreManager>(APP_ID, USER_ID);
1745 ASSERT_NE(mgr, nullptr);
1746 mgr->CloseStore(rdbDelegatePtr);
1747 mgr = nullptr;
1748 }
1749
1750 /*
1751 * @tc.name: relation observer 004
1752 * @tc.desc: Test relation register observer
1753 * @tc.type: FUNC
1754 * @tc.require:
1755 * @tc.author: zhangqiquan
1756 */
1757 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer004, TestSize.Level0)
1758 {
1759 /**
1760 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1761 * @tc.expected: step1. create and insert ok
1762 */
1763 ASSERT_NE(g_rdbDelegatePtr, nullptr);
1764 g_observer->ResetToZero();
1765 auto observer = new (std::nothrow) RelationalStoreObserverUnitTest();
1766 std::map<std::string, DataValue> dataMap;
1767 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1768 g_rdbDelegatePtr->RegisterObserver(observer);
1769 /**
1770 * @tc.steps: step2. device A pull sync mode
1771 * @tc.expected: step2. sync ok
1772 */
1773 BlockSync(SyncMode::SYNC_MODE_PULL_ONLY, OK, {DEVICE_B, DEVICE_C});
1774 /**
1775 * @tc.steps: step3. device A check observer
1776 * @tc.expected: step2. data change device is deviceB
1777 */
1778 EXPECT_EQ(observer->GetCallCount(), 1u);
1779 EXPECT_EQ(g_observer->GetCallCount(), 1u); // support multi observer for one delegate
1780 EXPECT_EQ(observer->GetDataChangeDevice(), DEVICE_B);
1781 CheckIdentify(observer);
1782 delete observer;
1783 }
1784
1785 /*
1786 * @tc.name: relation observer 005
1787 * @tc.desc: Test relation unregister observer
1788 * @tc.type: FUNC
1789 * @tc.require:
1790 * @tc.author: zhangqiquan
1791 */
1792 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer005, TestSize.Level0)
1793 {
1794 /**
1795 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1796 * @tc.expected: step1. create and insert ok
1797 */
1798 ASSERT_NE(g_rdbDelegatePtr, nullptr);
1799 g_observer->ResetToZero();
1800 std::map<std::string, DataValue> dataMap;
1801 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1802 g_rdbDelegatePtr->UnRegisterObserver();
1803 /**
1804 * @tc.steps: step2. device A pull sync mode
1805 * @tc.expected: step2. sync ok
1806 */
1807 BlockSync(SyncMode::SYNC_MODE_PULL_ONLY, OK, {DEVICE_B, DEVICE_C});
1808 /**
1809 * @tc.steps: step3. device A check observer
1810 * @tc.expected: step2. data change device is deviceB
1811 */
1812 EXPECT_EQ(g_observer->GetCallCount(), 0u);
1813 }
1814
1815
1816 /*
1817 * @tc.name: relation observer 006
1818 * @tc.desc: Test observer is destructed when sync finish
1819 * @tc.type: FUNC
1820 * @tc.require:
1821 * @tc.author: zhangshijie
1822 */
1823 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer006, TestSize.Level3)
1824 {
1825 /**
1826 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1827 * @tc.expected: step1. create and insert ok
1828 */
1829 g_observer->ResetToZero();
1830 std::map<std::string, DataValue> dataMap;
1831 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1832
1833 /**
1834 * @tc.steps: step2. device A pull sync mode
1835 * @tc.expected: step2. sync ok
1836 */
1837 int count = 0;
1838 PermissionCheckCallbackV2 callback = [&count](const std::string &userId, const std::string &appId,
__anon342485331502(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 1839 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
1840 if ((flag == CHECK_FLAG_RECEIVE) && (count == 0)) {
1841 for (int i = 0; i < 10; i++) { // 10 is capacity of thread pool
1842 RuntimeContext::GetInstance()->ScheduleTask([] () {
1843 std::this_thread::sleep_for(std::chrono::seconds(6)); // sleep 6 seconds
1844 });
1845 }
1846 count++;
1847 }
1848 return true;
1849 };
1850 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(callback), OK);
1851
1852 /**
1853 * @tc.steps: step3. device A check observer
1854 * @tc.expected: step2. data change device is deviceB
1855 */
1856 Query query = Query::Select(g_tableName);
1857 g_rdbDelegatePtr->Sync({DEVICE_B}, SyncMode::SYNC_MODE_PULL_ONLY, query, nullptr, false);
1858 std::this_thread::sleep_for(std::chrono::seconds(1));
1859 ASSERT_EQ(g_mgr.CloseStore(g_rdbDelegatePtr), OK);
1860 g_rdbDelegatePtr = nullptr;
1861 delete g_observer;
1862 g_observer = nullptr;
1863 std::this_thread::sleep_for(std::chrono::seconds(10)); // sleep 10 second to wait sync finish
1864 RuntimeContext::GetInstance()->StopTaskPool();
1865 }
1866
1867 /*
1868 * @tc.name: relation observer 007
1869 * @tc.desc: Test open store observer will not overwrite autolaunch observer
1870 * @tc.type: FUNC
1871 * @tc.require:
1872 * @tc.author: zhangshijie
1873 */
1874 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer007, TestSize.Level3)
1875 {
1876 /**
1877 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1878 * @tc.expected: step1. create and insert ok
1879 */
1880 g_observer->ResetToZero();
1881 std::map<std::string, DataValue> dataMap;
1882 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1883
1884 /**
1885 * @tc.steps: step2. device A pull sync mode
1886 * @tc.expected: step2. sync ok
1887 */
1888 RelationalStoreObserverUnitTest *observer = new (std::nothrow) RelationalStoreObserverUnitTest();
1889 ASSERT_NE(observer, nullptr);
__anon342485331702(const std::string &identifier, AutoLaunchParam ¶m) 1890 const AutoLaunchRequestCallback callback = [observer](const std::string &identifier, AutoLaunchParam ¶m) {
1891 if (g_id != identifier) {
1892 return false;
1893 }
1894 param.path = g_dbDir;
1895 param.appId = APP_ID;
1896 param.userId = USER_ID;
1897 param.storeId = STORE_ID_1;
1898 param.option.storeObserver = observer;
1899 #ifndef OMIT_ENCRYPT
1900 param.option.isEncryptedDb = true;
1901 param.option.cipher = CipherType::DEFAULT;
1902 param.option.passwd = g_correctPasswd;
1903 param.option.iterateTimes = DEFAULT_ITER;
1904 #endif
1905 return true;
1906 };
1907
1908 /**
1909 * @tc.steps: step2. SetAutoLaunchRequestCallback
1910 * @tc.expected: step2. success.
1911 */
1912 g_mgr.SetAutoLaunchRequestCallback(callback);
1913
1914 /**
1915 * @tc.steps: step3. RunCommunicatorLackCallback
1916 * @tc.expected: step3. success.
1917 */
1918 LabelType labelType(g_id.begin(), g_id.end());
1919 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1920
1921 /**
1922 * @tc.steps: step4. start sync
1923 * @tc.expected: step4. success
1924 */
1925 Query query = Query::Select(g_tableName);
1926 g_rdbDelegatePtr->Sync({DEVICE_B}, SyncMode::SYNC_MODE_PULL_ONLY, query, nullptr, false);
1927
1928 /**
1929 * @tc.steps: step5. open store with observer1
1930 * @tc.expected: step5. success.
1931 */
1932 auto observer1 = new (std::nothrow) RelationalStoreObserverUnitTest();
1933 ASSERT_NE(observer1, nullptr);
1934 RelationalStoreDelegate::Option option;
1935 option.observer = observer1;
1936 #ifndef OMIT_ENCRYPT
1937 option.isEncryptedDb = true;
1938 option.iterateTimes = DEFAULT_ITER;
1939 option.passwd = g_isAfterRekey ? g_rekeyPasswd : g_correctPasswd;
1940 option.cipher = CipherType::DEFAULT;
1941 #endif
1942 RelationalStoreDelegate *rdb1 = nullptr;
1943 g_mgr.OpenStore(g_dbDir, STORE_ID_1, option, rdb1);
1944 ASSERT_TRUE(rdb1 != nullptr);
1945
1946 /**
1947 * @tc.steps: step6. close store and delete observer1
1948 * @tc.expected: step6. success.
1949 */
1950 ReleaseForObserver007(rdb1, observer1, observer);
1951 }
1952
RegisterNewObserver(RelationalStoreDelegate * rdb1,RelationalStoreObserverUnitTest * observer1,RelationalStoreObserverUnitTest * autoLaunchObserver)1953 void RegisterNewObserver(RelationalStoreDelegate *rdb1, RelationalStoreObserverUnitTest *observer1,
1954 RelationalStoreObserverUnitTest *autoLaunchObserver)
1955 {
1956 /**
1957 * @tc.steps: step1. register another observer
1958 */
1959 auto observer2 = new (std::nothrow) RelationalStoreObserverUnitTest();
1960 ASSERT_NE(observer2, nullptr);
1961 EXPECT_EQ(rdb1->RegisterObserver(observer2), OK);
1962 observer1->ResetToZero();
1963 std::map<std::string, DataValue> dataMap;
1964 InsertDataToDeviceB(dataMap, g_tableName, g_fieldInfoList, 2); // 2 is watermark
1965 Query query = Query::Select(g_tableName);
1966 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1967 EXPECT_EQ(observer1->GetCallCount(), 1u); // one delegate can register 8 observer
1968 EXPECT_EQ(autoLaunchObserver->GetCallCount(), 2u); // 2 is auto_launch observer triggered times
1969 EXPECT_EQ(observer2->GetCallCount(), 1u);
1970
1971 EXPECT_EQ(rdb1->UnRegisterObserver(), OK);
1972 observer2->ResetToZero();
1973 observer1->ResetToZero();
1974 InsertDataToDeviceB(dataMap, g_tableName, g_fieldInfoList, 3); // 3 is watermark
1975 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1976 EXPECT_EQ(observer1->GetCallCount(), 0u);
1977 EXPECT_EQ(autoLaunchObserver->GetCallCount(), 3u); // 3 is auto_launch observer triggered times
1978 EXPECT_EQ(observer2->GetCallCount(), 0u);
1979
1980 RuntimeConfig::ReleaseAutoLaunch(USER_ID, APP_ID, STORE_ID_1, DBType::DB_RELATION);
1981 delete autoLaunchObserver;
1982 delete observer1;
1983 delete observer2;
1984 ASSERT_EQ(g_mgr.CloseStore(rdb1), OK);
1985 rdb1 = nullptr;
1986 }
1987
1988 /**
1989 * @tc.name: relation observer 008
1990 * @tc.desc: Test multi rdb observer
1991 * @tc.type: FUNC
1992 * @tc.require:
1993 * @tc.author: zhangshijie
1994 */
1995 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer008, TestSize.Level3)
1996 {
1997 /**
1998 * @tc.steps: step1. open rdb store, create distribute table and insert data
1999 */
2000 g_observer->ResetToZero();
2001 std::map<std::string, DataValue> dataMap;
2002 PrepareVirtualEnvironment(dataMap, {g_deviceB});
2003
2004 /**
2005 * @tc.steps: step2. set auto launch callBack
2006 */
2007 RelationalStoreObserverUnitTest *autoObserver = new (std::nothrow) RelationalStoreObserverUnitTest();
__anon342485331802(const std::string &identifier, AutoLaunchParam ¶m) 2008 const AutoLaunchRequestCallback callback = [autoObserver](const std::string &identifier, AutoLaunchParam ¶m) {
2009 if (g_id != identifier) {
2010 return false;
2011 }
2012 param.path = g_dbDir;
2013 param.appId = APP_ID;
2014 param.userId = USER_ID;
2015 param.storeId = STORE_ID_1;
2016 param.option.storeObserver = autoObserver;
2017 #ifndef OMIT_ENCRYPT
2018 param.option.isEncryptedDb = true;
2019 param.option.cipher = CipherType::DEFAULT;
2020 param.option.passwd = g_correctPasswd;
2021 param.option.iterateTimes = DEFAULT_ITER;
2022 #endif
2023 return true;
2024 };
2025 g_mgr.SetAutoLaunchRequestCallback(callback);
2026 /**
2027 * @tc.steps: step3. close store ensure communicator has closed
2028 */
2029 g_mgr.CloseStore(g_rdbDelegatePtr);
2030 g_rdbDelegatePtr = nullptr;
2031
2032 /**
2033 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
2034 * @tc.expected: step4. success.
2035 */
2036 LabelType labelType(g_id.begin(), g_id.end());
2037 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
2038 std::this_thread::sleep_for(std::chrono::seconds(1));
2039
2040 auto observer1 = new (std::nothrow) RelationalStoreObserverUnitTest();
2041 ASSERT_NE(observer1, nullptr);
2042 RelationalStoreDelegate::Option option;
2043 SetOption(observer1, option);
2044 RelationalStoreDelegate *rdb1 = nullptr;
2045 g_mgr.OpenStore(g_dbDir, STORE_ID_1, option, rdb1);
2046 ASSERT_TRUE(rdb1 != nullptr);
2047 /**
2048 * @tc.steps: step5. Call sync expect sync successful and device A check observer
2049 */
2050 Query query = Query::Select(g_tableName);
2051 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
2052
2053 /**
2054 * @tc.steps: step6. Call sync expect sync successful and device A check observer
2055 */
2056 EXPECT_EQ(autoObserver->GetCallCount(), 1u);
2057 int reTry = 5;
2058 while (observer1->GetCallCount() != 1u && reTry > 0) {
2059 reTry--;
2060 std::this_thread::sleep_for(std::chrono::seconds(1));
2061 }
2062 EXPECT_EQ(observer1->GetCallCount(), 1u);
2063 EXPECT_EQ(autoObserver->GetDataChangeDevice(), DEVICE_B);
2064 CheckIdentify(autoObserver);
2065 RegisterNewObserver(rdb1, observer1, autoObserver);
2066 }
2067
2068 /**
2069 * @tc.name: remote query 001
2070 * @tc.desc: Test rdb remote query
2071 * @tc.type: FUNC
2072 * @tc.require: AR000GK58G
2073 * @tc.author: zhangqiquan
2074 */
2075 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery001, TestSize.Level1)
2076 {
2077 std::map<std::string, DataValue> dataMap;
2078 PrepareEnvironment(dataMap, {g_deviceB});
2079 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2080 RemoteCondition condition;
2081 condition.sql = "SELECT * FROM " + g_tableName;
2082 std::shared_ptr<ResultSet> result = nullptr;
2083 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_B, condition, DBConstant::MIN_TIMEOUT, result), OK);
2084
2085 EXPECT_NE(result, nullptr);
2086 }
2087
2088 /**
2089 * @tc.name: remote query 002
2090 * @tc.desc: Test rdb remote query
2091 * @tc.type: FUNC
2092 * @tc.require: AR000GK58G
2093 * @tc.author: zhangqiquan
2094 */
2095 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery002, TestSize.Level1)
2096 {
2097 std::map<std::string, DataValue> dataMap;
2098 PrepareEnvironment(dataMap, {g_deviceB});
2099 ASSERT_NE(g_deviceB, nullptr);
2100 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2101 RemoteCondition condition;
2102 condition.sql = "SELECT * FROM " + g_tableName;
2103 std::shared_ptr<ResultSet> result = nullptr;
2104 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result), OK);
2105 CheckSearchData(result, dataMap);
2106 }
2107
2108 /**
2109 * @tc.name: remote query 003
2110 * @tc.desc: Test rdb remote query but query not data
2111 * @tc.type: FUNC
2112 * @tc.require: AR000GK58G
2113 * @tc.author: zhangqiquan
2114 */
2115 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery003, TestSize.Level1)
2116 {
2117 std::map<std::string, DataValue> dataMap;
2118 PrepareEnvironment(dataMap, {g_deviceB});
2119 ASSERT_NE(g_deviceB, nullptr);
2120 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2121 RemoteCondition condition;
2122 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2123 std::shared_ptr<ResultSet> result = nullptr;
2124 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result), OK);
2125 ASSERT_NE(result, nullptr);
2126 EXPECT_EQ(result->GetCount(), 0);
2127 }
2128
2129 /**
2130 * @tc.name: remote query 004
2131 * @tc.desc: Test rdb queue size
2132 * @tc.type: FUNC
2133 * @tc.require: AR000GK58G
2134 * @tc.author: zhangqiquan
2135 */
2136 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery004, TestSize.Level3)
2137 {
2138 std::map<std::string, DataValue> dataMap;
2139 PrepareEnvironment(dataMap, {g_deviceB});
2140 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2141 RemoteCondition condition;
2142 condition.sql = "SELECT * FROM " + g_tableName;
2143 std::vector<std::string> deviceMap = {DEVICE_B, DEVICE_C};
__anon342485331902(const std::string &device, Message *inMsg) 2144 g_communicatorAggregator->RegOnDispatch([](const std::string &device, Message *inMsg) {
2145 ASSERT_NE(inMsg, nullptr);
2146 inMsg->SetMessageId(INVALID_MESSAGE_ID);
2147 });
2148 const size_t MAX_SIZE = 7;
2149 std::vector<std::thread *> threadList;
2150 for (size_t j = 0; j < deviceMap.size(); j++) {
2151 for (size_t i = 0; i < MAX_SIZE; i++) {
2152 std::string device = deviceMap[j];
__anon342485331a02() 2153 threadList.push_back(new std::thread([&, device]() {
2154 std::shared_ptr<ResultSet> result = nullptr;
2155 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(device, condition,
2156 DBConstant::MIN_TIMEOUT, result), TIME_OUT);
2157 EXPECT_EQ(result, nullptr);
2158 }));
2159 }
2160 }
2161 for (size_t i = 0; i < threadList.size(); i++) {
2162 threadList[i]->join();
2163 delete threadList[i];
2164 threadList[i] = nullptr;
2165 }
2166 }
2167
2168 /**
2169 * @tc.name: remote query 005
2170 * @tc.desc: Test rdb remote query timeout by invalid message
2171 * @tc.type: FUNC
2172 * @tc.require: AR000GK58G
2173 * @tc.author: zhangqiquan
2174 */
2175 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery005, TestSize.Level1)
2176 {
2177 std::map<std::string, DataValue> dataMap;
2178 PrepareEnvironment(dataMap, {g_deviceB});
2179 ASSERT_NE(g_deviceB, nullptr);
2180 ASSERT_NE(g_rdbDelegatePtr, nullptr);
__anon342485331b02(const std::string &device, Message *inMsg) 2181 g_communicatorAggregator->RegOnDispatch([](const std::string &device, Message *inMsg) {
2182 ASSERT_NE(inMsg, nullptr);
2183 inMsg->SetMessageId(INVALID_MESSAGE_ID);
2184 });
2185 RemoteCondition condition;
2186 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2187 std::shared_ptr<ResultSet> result = nullptr;
2188 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_B, condition, DBConstant::MIN_TIMEOUT, result), TIME_OUT);
2189 ASSERT_EQ(result, nullptr);
2190 }
2191
2192 /**
2193 * @tc.name: remote query 006
2194 * @tc.desc: Test rdb remote query commfailure by offline
2195 * @tc.type: FUNC
2196 * @tc.require: AR000GK58G
2197 * @tc.author: zhangqiquan
2198 */
2199 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery006, TestSize.Level1)
2200 {
2201 std::map<std::string, DataValue> dataMap;
2202 PrepareEnvironment(dataMap, {g_deviceB});
2203 ASSERT_NE(g_deviceB, nullptr);
2204 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2205 std::thread offlineThread;
2206 std::atomic<bool> offline = false;
__anon342485331c02(const std::string &device, Message *inMsg) 2207 g_communicatorAggregator->RegOnDispatch([&offlineThread, &offline](const std::string &device, Message *inMsg) {
2208 ASSERT_NE(inMsg, nullptr);
2209 inMsg->SetMessageId(INVALID_MESSAGE_ID);
2210 if (offline) {
2211 return;
2212 }
2213 offline = true;
2214 std::thread t([]() {
2215 g_deviceB->Offline();
2216 });
2217 offlineThread = std::move(t);
2218 });
2219 RemoteCondition condition;
2220 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2221 std::shared_ptr<ResultSet> result = nullptr;
2222 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_B, condition, DBConstant::MIN_TIMEOUT, result), COMM_FAILURE);
2223 ASSERT_EQ(result, nullptr);
2224 if (offline) {
2225 offlineThread.join();
2226 }
2227 }
2228
2229 /**
2230 * @tc.name: remote query 007
2231 * @tc.desc: Test rdb remote query failed by permission check
2232 * @tc.type: FUNC
2233 * @tc.require: AR000GK58G
2234 * @tc.author: zhangqiquan
2235 */
2236 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery007, TestSize.Level1)
2237 {
2238 std::map<std::string, DataValue> dataMap;
2239 PrepareEnvironment(dataMap, {g_deviceB});
2240 ASSERT_NE(g_deviceB, nullptr);
2241 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2242 PermissionCheckCallbackV2 callback = [](const std::string &userId, const std::string &appId,
__anon342485331e02(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 2243 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
2244 return false;
2245 };
2246 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(callback), OK);
2247 RemoteCondition condition;
2248 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2249 std::shared_ptr<ResultSet> result = nullptr;
2250 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result),
2251 PERMISSION_CHECK_FORBID_SYNC);
2252 ASSERT_EQ(result, nullptr);
2253 callback = nullptr;
2254 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(callback), OK);
2255 }
2256
2257 /**
2258 * @tc.name: remote query 008
2259 * @tc.desc: Test rdb remote query timeout but not effected by invalid message
2260 * @tc.type: FUNC
2261 * @tc.require: AR000GK58G
2262 * @tc.author: zhangqiquan
2263 */
2264 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery008, TestSize.Level1)
2265 {
2266 std::map<std::string, DataValue> dataMap;
2267 PrepareEnvironment(dataMap, {g_deviceB});
2268 ASSERT_NE(g_deviceB, nullptr);
2269 ASSERT_NE(g_rdbDelegatePtr, nullptr);
__anon342485331f02(const std::string &device, Message *inMsg) 2270 g_communicatorAggregator->RegOnDispatch([](const std::string &device, Message *inMsg) {
2271 ASSERT_NE(inMsg, nullptr);
2272 if (device != DEVICE_B) {
2273 return;
2274 }
2275 inMsg->SetMessageId(INVALID_MESSAGE_ID);
2276 std::thread t([]() {
2277 auto *msg = new (std::nothrow) Message(REMOTE_EXECUTE_MESSAGE);
2278 ASSERT_NE(msg, nullptr);
2279 auto *packet = new (std::nothrow) RemoteExecutorAckPacket();
2280 if (packet != nullptr) {
2281 packet->SetAckCode(-E_FEEDBACK_COMMUNICATOR_NOT_FOUND);
2282 }
2283 if (msg->SetExternalObject(packet) != E_OK) {
2284 delete packet;
2285 packet = nullptr;
2286 }
2287 msg->SetMessageType(TYPE_RESPONSE);
2288 msg->SetErrorNo(E_FEEDBACK_COMMUNICATOR_NOT_FOUND);
2289 msg->SetSessionId(0u);
2290 msg->SetSequenceId(1u);
2291 g_communicatorAggregator->DispatchMessage(DEVICE_B, DEVICE_A, msg, nullptr);
2292 LOGD("DispatchMessage Finish");
2293 });
2294 t.detach();
2295 });
2296 RemoteCondition condition;
2297 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2298 std::shared_ptr<ResultSet> result = nullptr;
2299 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_B, condition, DBConstant::MIN_TIMEOUT, result), TIME_OUT);
2300 ASSERT_EQ(result, nullptr);
2301 }
2302
2303 /**
2304 * @tc.name: remote query 009
2305 * @tc.desc: Test rdb remote query busy before timeout
2306 * @tc.type: FUNC
2307 * @tc.require: AR000GK58G
2308 * @tc.author: zhangqiquan
2309 */
2310 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery009, TestSize.Level1)
2311 {
2312 std::map<std::string, DataValue> dataMap;
2313 PrepareEnvironment(dataMap, {g_deviceB});
2314 ASSERT_NE(g_deviceB, nullptr);
2315 ASSERT_NE(g_rdbDelegatePtr, nullptr);
__anon342485332102(const std::string &device, Message *inMsg) 2316 g_communicatorAggregator->RegOnDispatch([](const std::string &device, Message *inMsg) {
2317 ASSERT_NE(inMsg, nullptr);
2318 inMsg->SetMessageId(INVALID_MESSAGE_ID);
2319 });
2320 RemoteCondition condition;
2321 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2322 std::shared_ptr<ResultSet> result = nullptr;
__anon342485332202() 2323 std::thread t([]() {
2324 std::this_thread::sleep_for(std::chrono::seconds(1));
2325 if (g_rdbDelegatePtr != nullptr) {
2326 LOGD("CloseStore Start");
2327 ASSERT_EQ(g_mgr.CloseStore(g_rdbDelegatePtr), OK);
2328 g_rdbDelegatePtr = nullptr;
2329 }
2330 });
2331 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_B, condition, DBConstant::MIN_TIMEOUT, result), BUSY);
2332 ASSERT_EQ(result, nullptr);
2333 t.join();
2334 }
2335
2336 /**
2337 * @tc.name: remote query 010
2338 * @tc.desc: Test rdb remote query with kv db
2339 * @tc.type: FUNC
2340 * @tc.require: AR000GK58G
2341 * @tc.author: zhangqiquan
2342 */
2343 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery010, TestSize.Level1)
2344 {
2345 std::map<std::string, DataValue> dataMap;
2346 PrepareEnvironment(dataMap, {g_deviceB});
2347 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2348 RemoteCondition condition;
2349 condition.sql = "SELECT * FROM " + g_tableName;
2350 std::shared_ptr<ResultSet> result = nullptr;
2351 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_D, condition, DBConstant::MIN_TIMEOUT, result), NOT_SUPPORT);
2352
2353 EXPECT_EQ(result, nullptr);
2354 }
2355
2356 /**
2357 * @tc.name: remote query 010
2358 * @tc.desc: Test rdb remote query with error sql
2359 * @tc.type: FUNC
2360 * @tc.require: AR000GK58G
2361 * @tc.author: zhangqiquan
2362 */
2363 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery011, TestSize.Level1)
2364 {
2365 std::map<std::string, DataValue> dataMap;
2366 PrepareEnvironment(dataMap, {g_deviceB});
2367 ASSERT_NE(g_deviceB, nullptr);
2368 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2369 RemoteCondition condition;
2370 condition.sql = "This is error sql";
2371 std::shared_ptr<ResultSet> result = nullptr;
2372 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result), DB_ERROR);
2373 EXPECT_EQ(result, nullptr);
2374 }
2375
2376 /**
2377 * @tc.name: remote query 012
2378 * @tc.desc: Test rdb remote query with invalid dev
2379 * @tc.type: FUNC
2380 * @tc.require: AR000GK58G
2381 * @tc.author: zhangqiquan
2382 */
2383 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery012, TestSize.Level1)
2384 {
2385 std::map<std::string, DataValue> dataMap;
2386 std::string invalidDev = std::string(DBConstant::MAX_DEV_LENGTH + 1, '0');
2387 PrepareEnvironment(dataMap, {g_deviceB});
2388 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2389 RemoteCondition condition;
2390 condition.sql = "SELECT * FROM " + g_tableName;
2391 std::shared_ptr<ResultSet> result = nullptr;
2392 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(invalidDev, condition, DBConstant::MIN_TIMEOUT, result), INVALID_ARGS);
2393 EXPECT_EQ(result, nullptr);
2394 }
2395
2396 /**
2397 * @tc.name: remote query 013
2398 * @tc.desc: Test rdb remote query deny fts3_tokenizer
2399 * @tc.type: FUNC
2400 * @tc.require:
2401 * @tc.author: zhangqiquan
2402 */
2403 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery013, TestSize.Level0)
2404 {
2405 std::map<std::string, DataValue> dataMap;
2406 PrepareEnvironment(dataMap, {g_deviceB});
2407 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2408 RemoteCondition condition;
2409 condition.sql = "SELECT hex(fts3_tokenizer('simple'))";
2410 std::shared_ptr<ResultSet> result = nullptr;
2411 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result), DB_ERROR);
2412 EXPECT_EQ(result, nullptr);
2413 }
2414
2415 /**
2416 * @tc.name: RelationalPemissionTest001
2417 * @tc.desc: deviceB PermissionCheck not pass test, SYNC_MODE_PUSH_ONLY
2418 * @tc.type: FUNC
2419 * @tc.require: AR000GK58N
2420 * @tc.author: zhangshijie
2421 */
2422 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RelationalPemissionTest001, TestSize.Level0)
2423 {
2424 /**
2425 * @tc.steps: step1. SetPermissionCheckCallback
2426 * @tc.expected: step1. return OK.
2427 */
2428 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId,
__anon342485332302(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 2429 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
2430 LOGE("u: %s, a: %s, s: %s", userId.c_str(), appId.c_str(), storeId.c_str());
2431 bool empty = userId.empty() || appId.empty() || storeId.empty();
2432 EXPECT_TRUE(empty == false);
2433 if (flag & (CHECK_FLAG_SEND)) {
2434 LOGD("in RunPermissionCheck callback, check not pass, flag:%d", flag);
2435 return false;
2436 } else {
2437 LOGD("in RunPermissionCheck callback, check pass, flag:%d", flag);
2438 return true;
2439 }
2440 };
2441 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
2442
2443 /**
2444 * @tc.steps: step2. sync with deviceB
2445 */
2446 std::map<std::string, DataValue> dataMap;
2447 PrepareEnvironment(dataMap, { g_deviceB });
2448 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, PERMISSION_CHECK_FORBID_SYNC, { DEVICE_B });
2449
2450 /**
2451 * @tc.steps: step3. check data in deviceB
2452 * @tc.expected: step3. deviceB has no data
2453 */
2454 std::vector<VirtualRowData> targetData;
2455 g_deviceB->GetAllSyncData(g_tableName, targetData);
2456
2457 ASSERT_EQ(targetData.size(), 0u);
2458 }
2459
2460 /**
2461 * @tc.name: RelationalPemissionTest002
2462 * @tc.desc: deviceB PermissionCheck not pass test, SYNC_MODE_PULL_ONLY
2463 * @tc.type: FUNC
2464 * @tc.require: AR000GK58N
2465 * @tc.author: zhangshijie
2466 */
2467 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RelationalPemissionTest002, TestSize.Level0)
2468 {
2469 /**
2470 * @tc.steps: step1. SetPermissionCheckCallback
2471 * @tc.expected: step1. return OK.
2472 */
2473 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId,
__anon342485332402(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 2474 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
2475 LOGE("u: %s, a: %s, s: %s", userId.c_str(), appId.c_str(), storeId.c_str());
2476 bool empty = userId.empty() || appId.empty() || storeId.empty();
2477 EXPECT_TRUE(empty == false);
2478 if (flag & (CHECK_FLAG_RECEIVE)) {
2479 LOGD("in RunPermissionCheck callback, check not pass, flag:%d", flag);
2480 return false;
2481 } else {
2482 LOGD("in RunPermissionCheck callback, check pass, flag:%d", flag);
2483 return true;
2484 }
2485 };
2486 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
2487
2488 /**
2489 * @tc.steps: step2. sync with deviceB
2490 */
2491 std::map<std::string, DataValue> dataMap;
2492 PrepareEnvironment(dataMap, { g_deviceB });
2493 BlockSync(SyncMode::SYNC_MODE_PULL_ONLY, PERMISSION_CHECK_FORBID_SYNC, { DEVICE_B });
2494
2495 /**
2496 * @tc.steps: step3. check data in deviceB
2497 * @tc.expected: step3. deviceB has no data
2498 */
2499 std::vector<VirtualRowData> targetData;
2500 g_deviceB->GetAllSyncData(g_tableName, targetData);
2501
2502 ASSERT_EQ(targetData.size(), 0u);
2503 }
2504
2505 /**
2506 * @tc.name: RelationalPemissionTest003
2507 * @tc.desc: deviceB PermissionCheck not pass test, flag CHECK_FLAG_SPONSOR
2508 * @tc.type: FUNC
2509 * @tc.require: AR000GK58N
2510 * @tc.author: zhangshijie
2511 */
2512 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RelationalPemissionTest003, TestSize.Level0)
2513 {
2514 /**
2515 * @tc.steps: step1. SetPermissionCheckCallback
2516 * @tc.expected: step1. return OK.
2517 */
2518 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId,
__anon342485332502(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 2519 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
2520 LOGE("u: %s, a: %s, s: %s", userId.c_str(), appId.c_str(), storeId.c_str());
2521 bool empty = userId.empty() || appId.empty() || storeId.empty();
2522 EXPECT_TRUE(empty == false);
2523 if (flag & CHECK_FLAG_SPONSOR) {
2524 LOGD("in RunPermissionCheck callback, check not pass, flag:%d", flag);
2525 return false;
2526 } else {
2527 LOGD("in RunPermissionCheck callback, check pass, flag:%d", flag);
2528 return true;
2529 }
2530 };
2531 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
2532
2533 /**
2534 * @tc.steps: step2. sync with deviceB
2535 */
2536 std::map<std::string, DataValue> dataMap;
2537 PrepareEnvironment(dataMap, { g_deviceB });
2538 BlockSync(SyncMode::SYNC_MODE_PULL_ONLY, PERMISSION_CHECK_FORBID_SYNC, { DEVICE_B });
2539
2540 /**
2541 * @tc.steps: step3. check data in deviceB
2542 * @tc.expected: step3. deviceB has no data
2543 */
2544 std::vector<VirtualRowData> targetData;
2545 g_deviceB->GetAllSyncData(g_tableName, targetData);
2546
2547 ASSERT_EQ(targetData.size(), 0u);
2548 }
2549
2550 /**
2551 * @tc.name: RelationalPemissionTest004
2552 * @tc.desc: deviceB PermissionCheck pass test. deviceC not pass, SYNC_MODE_PUSH_ONLY
2553 * @tc.type: FUNC
2554 * @tc.require: AR000GK58N
2555 * @tc.author: zhangshijie
2556 */
2557 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RelationalPemissionTest004, TestSize.Level0)
2558 {
2559 /**
2560 * @tc.steps: step1. SetPermissionCheckCallback
2561 * @tc.expected: step1. return OK.
2562 */
2563 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId,
__anon342485332602(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 2564 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
2565 LOGE("u: %s, a: %s, s: %s", userId.c_str(), appId.c_str(), storeId.c_str());
2566 if (deviceId == g_deviceC->GetDeviceId()) {
2567 LOGE("in RunPermissionCheck callback, check pass, device:%s", deviceId.c_str());
2568 return false;
2569 } else {
2570 LOGE("in RunPermissionCheck callback, check not pass, device:%s", deviceId.c_str());
2571 return true;
2572 }
2573 };
2574 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
2575
2576 std::map<std::string, DataValue> dataMap;
2577 PrepareEnvironment(dataMap, { g_deviceB, g_deviceC });
2578
2579 /**
2580 * @tc.steps: step2. sync with deviceB
2581 */
2582 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, { DEVICE_B });
2583
2584 /**
2585 * @tc.steps: step3. check data in deviceB
2586 * @tc.expected: step3. deviceB has data
2587 */
2588 std::vector<VirtualRowData> targetData;
2589 g_deviceB->GetAllSyncData(g_tableName, targetData);
2590 ASSERT_EQ(targetData.size(), 1u);
2591
2592 /**
2593 * @tc.steps: step4. sync with deviceC
2594 */
2595 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, PERMISSION_CHECK_FORBID_SYNC, { DEVICE_C });
2596
2597 /**
2598 * @tc.steps: step5. check data in deviceC
2599 * @tc.expected: step5. deviceC has no data
2600 */
2601 targetData.clear();
2602 g_deviceC->GetAllSyncData(g_tableName, targetData);
2603 ASSERT_EQ(targetData.size(), 0u);
2604 }
2605
2606 /**
2607 * @tc.name: SecurityOptionCheck001
2608 * @tc.desc: Test sync failed when getSecurityOption return error
2609 * @tc.type: FUNC
2610 * @tc.require: AR000GK58N
2611 * @tc.author: zhangqiquan
2612 */
2613 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, SecurityOptionCheck001, TestSize.Level1)
2614 {
2615 std::vector<std::string> devices;
2616 devices.push_back(g_deviceB->GetDeviceId());
2617
2618 /**
2619 * @tc.steps: step1. make getSecurityOption return -1
2620 */
2621 std::shared_ptr<ProcessSystemApiAdapterImpl> adapter = std::make_shared<ProcessSystemApiAdapterImpl>();
2622 adapter->ForkGetSecurityOption(
__anon342485332702(const std::string &filePath, SecurityOption &option) 2623 [](const std::string &filePath, SecurityOption &option) {
2624 (void)filePath;
2625 (void)option;
2626 return DB_ERROR;
2627 });
2628 RuntimeConfig::SetProcessSystemAPIAdapter(adapter);
2629
2630 std::map<std::string, DataValue> dataMap;
2631 PrepareEnvironment(dataMap, { g_deviceB });
2632
2633 /**
2634 * @tc.steps: step2. sync with deviceB
2635 */
2636 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, SECURITY_OPTION_CHECK_ERROR, { DEVICE_B });
2637 RuntimeConfig::SetProcessSystemAPIAdapter(nullptr);
2638 }
2639
2640 /**
2641 * @tc.name: SecurityOptionCheck002
2642 * @tc.desc: Test remote query failed when getSecurityOption return error
2643 * @tc.type: FUNC
2644 * @tc.require: AR000GK58G
2645 * @tc.author: zhangqiquan
2646 */
2647 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, SecurityOptionCheck002, TestSize.Level1)
2648 {
2649 /**
2650 * @tc.steps: step1. make getSecurityOption return -1
2651 */
2652 std::shared_ptr<ProcessSystemApiAdapterImpl> adapter = std::make_shared<ProcessSystemApiAdapterImpl>();
2653 adapter->ForkGetSecurityOption(
__anon342485332802(const std::string &filePath, SecurityOption &option) 2654 [](const std::string &filePath, SecurityOption &option) {
2655 (void)filePath;
2656 (void)option;
2657 return DB_ERROR;
2658 });
2659 RuntimeConfig::SetProcessSystemAPIAdapter(adapter);
2660
2661 /**
2662 * @tc.steps: step2. remote query with deviceB
2663 */
2664 std::map<std::string, DataValue> dataMap;
2665 PrepareEnvironment(dataMap, {g_deviceB});
2666 ASSERT_NE(g_deviceB, nullptr);
2667 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2668 RemoteCondition condition;
2669 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2670 std::shared_ptr<ResultSet> result = nullptr;
2671 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result),
2672 SECURITY_OPTION_CHECK_ERROR);
2673 EXPECT_EQ(result, nullptr);
2674 RuntimeConfig::SetProcessSystemAPIAdapter(nullptr);
2675 }
2676
2677 /**
2678 * @tc.name: OrderbyWriteTimeSync001
2679 * @tc.desc: sync query with order by writeTime
2680 * @tc.type: FUNC
2681 * @tc.require: AR000H5VLO
2682 * @tc.author: zhuwentao
2683 */
2684 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, OrderbyWriteTimeSync001, TestSize.Level0)
2685 {
2686 std::map<std::string, DataValue> dataMap;
2687 PrepareEnvironment(dataMap, {g_deviceB});
2688 Query query = Query::Select(g_tableName).OrderByWriteTime(true);;
2689 EXPECT_EQ(g_rdbDelegatePtr->Sync({DEVICE_B}, DistributedDB::SYNC_MODE_PUSH_ONLY, query, nullptr, false),
2690 NOT_SUPPORT);
2691 }
2692
2693 /**
2694 * @tc.name: RDBSecurityOptionCheck001
2695 * @tc.desc: Test sync with security option.
2696 * @tc.type: FUNC
2697 * @tc.require: AR000GK58N
2698 * @tc.author: zhangqiquan
2699 */
2700 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RDBSecurityOptionCheck001, TestSize.Level3)
2701 {
2702 TestWithSecurityCheck(false);
2703 }
2704
2705 /**
2706 * @tc.name: RDBSecurityOptionCheck002
2707 * @tc.desc: Test remote query with security option.
2708 * @tc.type: FUNC
2709 * @tc.require: AR000GK58N
2710 * @tc.author: zhangqiquan
2711 */
2712 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RDBSecurityOptionCheck002, TestSize.Level1)
2713 {
2714 TestWithSecurityCheck(true);
2715 }
2716
2717 /**
2718 * @tc.name: EncryptedAlgoUpgrade001
2719 * @tc.desc: Test upgrade encrypted db can sync normally
2720 * @tc.type: FUNC
2721 * @tc.require: AR000HI2JS
2722 * @tc.author: zhuwentao
2723 */
2724 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, EncryptedAlgoUpgrade001, TestSize.Level0)
2725 {
2726 if (g_rdbDelegatePtr != nullptr) {
2727 LOGD("CloseStore Start");
2728 ASSERT_EQ(g_mgr.CloseStore(g_rdbDelegatePtr), OK);
2729 g_rdbDelegatePtr = nullptr;
2730 }
2731 EXPECT_EQ(OS::RemoveFile(g_dbDir), E_OK);
2732 /**
2733 * @tc.steps: step1. open old db use sha1 algo and insert some data
2734 * @tc.expected: step1. interface return ok
2735 */
2736 sqlite3 *db = nullptr;
2737 EXPECT_EQ(GetDB(db, false), SQLITE_OK);
2738 const std::string user_version_sql = "PRAGMA user_version=101;";
2739 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, user_version_sql), E_OK);
2740 sqlite3_close(db);
2741
2742 /**
2743 * @tc.steps: step2. open db by OpenStore
2744 * @tc.expected: step2. interface return ok
2745 */
2746 OpenStore();
2747 /**
2748 * @tc.steps: step3. sync with push
2749 * @tc.expected: step3. interface return ok
2750 */
2751 std::map<std::string, DataValue> dataMap;
2752 PrepareEnvironment(dataMap, {g_deviceB});
2753 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
2754 CheckVirtualData(dataMap);
2755 dataMap.clear();
2756
2757 /**
2758 * @tc.steps: step4. sync with pull
2759 * @tc.expected: step4. interface return ok
2760 */
2761
2762 Query query = Query::Select(g_tableName);
2763 g_deviceB->GenericVirtualDevice::Sync(DistributedDB::SYNC_MODE_PULL_ONLY, query, true);
2764 CheckVirtualData(dataMap);
2765 }
2766
2767 #ifndef OMIT_ENCRYPT
2768 /**
2769 * @tc.name: AutoLaunchSyncAfterRekey_001
2770 * @tc.desc: Test auto launch sync ok after rekey.
2771 * @tc.type: FUNC
2772 * @tc.require: AR000H68LL
2773 * @tc.author: lidongwei
2774 */
2775 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSyncAfterRekey_001, TestSize.Level3)
2776 {
2777 /**
2778 * @tc.steps: step1. open rdb store, create distribute table and insert data
2779 */
2780 std::map<std::string, DataValue> dataMap;
2781 PrepareVirtualEnvironment(dataMap, {g_deviceB});
2782
2783 /**
2784 * @tc.steps: step2. set auto launch callBack
2785 */
2786 AutoLaunchParam encryptedParam { USER_ID, APP_ID, STORE_ID_1, AutoLaunchOption {}, nullptr, g_dbDir };
2787 encryptedParam.option.isEncryptedDb = true;
2788 encryptedParam.option.cipher = CipherType::DEFAULT;
2789 encryptedParam.option.passwd = g_correctPasswd;
2790 encryptedParam.option.iterateTimes = DEFAULT_ITER;
__anon342485332902(const std::string &identifier, AutoLaunchParam ¶m) 2791 AutoLaunchRequestCallback callback = [&encryptedParam](const std::string &identifier, AutoLaunchParam ¶m) {
2792 if (g_id != identifier) {
2793 return false;
2794 }
2795 param = encryptedParam;
2796 return true;
2797 };
2798 g_mgr.SetAutoLaunchRequestCallback(callback);
2799 /**
2800 * @tc.steps: step3. close store ensure communicator has closed
2801 */
2802 g_mgr.CloseStore(g_rdbDelegatePtr);
2803 g_rdbDelegatePtr = nullptr;
2804 /**
2805 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
2806 */
2807 LabelType labelType(g_id.begin(), g_id.end());
2808 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
2809 std::this_thread::sleep_for(std::chrono::seconds(1));
2810
2811 /**
2812 * @tc.steps: step5. Rekey
2813 */
2814 sqlite3 *db = nullptr;
2815 EXPECT_EQ(GetDB(db), SQLITE_OK);
__anon342485332a02null2816 std::thread t1([&db] {
2817 std::string sql = "PARGMA rekey=" + REKEY_KEY;
2818 EXPECT_EQ(sqlite3_rekey(db, REKEY_KEY.data(), REKEY_KEY.size()), SQLITE_OK);
2819 });
2820 t1.join();
2821 g_isAfterRekey = true;
2822
2823 /**
2824 * @tc.steps: step6. Call sync expect sync failed
2825 */
2826 Query query = Query::Select(g_tableName);
2827 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
2828 size_t count = 0;
2829 GetCount(db, "SELECT count(*) FROM sqlite_master WHERE name='" + GetDeviceTableName(g_tableName) + "';", count);
2830 EXPECT_EQ(count, 0u);
2831
2832 /**
2833 * @tc.steps: step7. Set callback.
2834 */
2835 encryptedParam.option.passwd = g_rekeyPasswd;
2836 g_mgr.SetAutoLaunchRequestCallback(callback);
2837 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
2838 std::this_thread::sleep_for(std::chrono::seconds(2));
2839
2840 /**
2841 * @tc.steps: step8. Call sync expect sync success
2842 */
2843 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
2844 GetCount(db, "SELECT count(*) FROM sqlite_master WHERE name='" + GetDeviceTableName(g_tableName) + "';", count);
2845 EXPECT_EQ(count, 1u);
2846 GetSyncData(db, dataMap, g_tableName, g_fieldInfoList);
2847 EXPECT_EQ(dataMap.size(), 3u);
2848 OpenStore();
2849 std::this_thread::sleep_for(std::chrono::minutes(1));
2850 sqlite3_close(db);
2851 db = nullptr;
2852 }
2853
2854 /**
2855 * @tc.name: AutoLaunchSyncAfterRekey_002
2856 * @tc.desc: Test auto launch close check after rekey.
2857 * @tc.type: FUNC
2858 * @tc.require: AR000H68LL
2859 * @tc.author: zhangqiquan
2860 */
2861 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSyncAfterRekey_002, TestSize.Level3)
2862 {
2863 /**
2864 * @tc.steps: step1. open rdb store, create distribute table and insert data
2865 */
2866 std::map<std::string, DataValue> dataMap;
2867 PrepareVirtualEnvironment(dataMap, {g_deviceB});
2868 /**
2869 * @tc.steps: step2. set auto launch callBack
2870 */
2871 AutoLaunchParam encryptedParam { USER_ID, APP_ID, STORE_ID_1, AutoLaunchOption {}, nullptr, g_dbDir };
2872 encryptedParam.option.isEncryptedDb = true;
2873 encryptedParam.option.cipher = CipherType::DEFAULT;
2874 encryptedParam.option.passwd = g_correctPasswd;
2875 encryptedParam.option.iterateTimes = DEFAULT_ITER;
__anon342485332b02(const std::string &identifier, AutoLaunchParam ¶m) 2876 AutoLaunchRequestCallback callback = [&encryptedParam](const std::string &identifier, AutoLaunchParam ¶m) {
2877 param = encryptedParam;
2878 return true;
2879 };
2880 RelationalStoreManager::SetAutoLaunchRequestCallback(callback);
2881 /**
2882 * @tc.steps: step3. close store ensure communicator has closed
2883 */
2884 g_mgr.CloseStore(g_rdbDelegatePtr);
2885 g_rdbDelegatePtr = nullptr;
2886 /**
2887 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
2888 */
2889 LabelType labelType(g_id.begin(), g_id.end());
2890 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
2891 std::this_thread::sleep_for(std::chrono::seconds(2)); // wait 2s for auto launch
2892 /**
2893 * @tc.steps: step5. Rekey
2894 */
2895 sqlite3 *db = nullptr;
2896 EXPECT_EQ(GetDB(db), SQLITE_OK);
2897 std::string sql = "PARGMA rekey=" + REKEY_KEY;
2898 EXPECT_EQ(sqlite3_rekey(db, REKEY_KEY.data(), REKEY_KEY.size()), SQLITE_OK);
2899 g_isAfterRekey = true;
2900
2901 RelationalDBProperties properties;
2902 properties.SetStringProp(DBProperties::USER_ID, USER_ID);
2903 properties.SetStringProp(DBProperties::APP_ID, APP_ID);
2904 properties.SetStringProp(DBProperties::STORE_ID, STORE_ID_1);
2905 properties.SetIntProp(DBProperties::AUTO_LAUNCH_ID, 7); // 7: invalid AUTO LAUNCH ID
2906 const string &id = RelationalStoreManager::GetRelationalStoreIdentifier(USER_ID, APP_ID, STORE_ID_1);
2907 properties.SetStringProp(DBProperties::IDENTIFIER_DATA, id);
2908 RuntimeContext::GetInstance()->CloseAutoLaunchConnection(DBTypeInner::DB_RELATION, properties);
2909
2910 encryptedParam.option.passwd = g_rekeyPasswd;
2911 RelationalStoreManager::SetAutoLaunchRequestCallback(callback);
2912 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
2913 std::this_thread::sleep_for(std::chrono::seconds(2)); // wait 2s for auto launch
2914
2915 Query query = Query::Select(g_tableName);
2916 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
2917 size_t count = 0;
2918 GetCount(db, "SELECT count(*) FROM sqlite_master WHERE name='" + GetDeviceTableName(g_tableName) + "';", count);
2919 EXPECT_EQ(count, 0u);
2920
2921 OpenStore();
2922 std::this_thread::sleep_for(std::chrono::minutes(1));
2923 sqlite3_close(db);
2924 db = nullptr;
2925 }
2926
2927 /**
2928 * @tc.name: AutoLaunchSyncAfterRekey_002
2929 * @tc.desc: Test AddSyncTarget will not cause heap_use_after_free
2930 * @tc.type: FUNC
2931 * @tc.require:
2932 * @tc.author: zhangshijie
2933 */
2934 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, SyncTargetTest001, TestSize.Level1) {
2935 MockSyncTaskContext syncTaskContext;
2936 SyncOperation *operation = new SyncOperation(1, {}, 0, nullptr, false);
2937 EXPECT_NE(operation, nullptr);
__anon342485332c02() 2938 std::thread addTarget([&syncTaskContext, &operation]() {
2939 auto *newTarget = new (std::nothrow) SingleVerSyncTarget;
2940 EXPECT_NE(newTarget, nullptr);
2941 newTarget->SetTaskType(ISyncTarget::REQUEST);
2942 EXPECT_EQ(syncTaskContext.AddSyncTarget(newTarget), E_OK);
2943 newTarget->SetSyncOperation(operation);
2944 });
2945
__anon342485332d02() 2946 std::thread removeTarget([&syncTaskContext]() {
2947 syncTaskContext.ClearAllSyncTask();
2948 });
2949 addTarget.join();
2950 removeTarget.join();
2951 syncTaskContext.ClearAllSyncTask();
2952 RefObject::KillAndDecObjRef(operation);
2953 }
2954 }
2955 #endif
2956 #endif