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(), E_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
800 class DistributedDBRelationalVerP2PSyncTest : public testing::Test {
801 public:
802 static void SetUpTestCase();
803 static void TearDownTestCase();
804 void SetUp();
805 void TearDown();
806 };
807
SetUpTestCase()808 void DistributedDBRelationalVerP2PSyncTest::SetUpTestCase()
809 {
810 /**
811 * @tc.setup: Init datadir and Virtual Communicator.
812 */
813 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
814 g_dbDir = g_testDir + "/test.db";
815 sqlite3 *db = nullptr;
816 ASSERT_EQ(GetDB(db), SQLITE_OK);
817 sqlite3_close(db);
818
819 g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
820 ASSERT_TRUE(g_communicatorAggregator != nullptr);
821 RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
822
823 g_id = g_mgr.GetRelationalStoreIdentifier(USER_ID, APP_ID, STORE_ID_1);
824
825 #ifndef OMIT_ENCRYPT
826 g_correctPasswd.SetValue(reinterpret_cast<const uint8_t *>(CORRECT_KEY.data()), CORRECT_KEY.size());
827 g_rekeyPasswd.SetValue(reinterpret_cast<const uint8_t *>(REKEY_KEY.data()), REKEY_KEY.size());
828 g_incorrectPasswd.SetValue(reinterpret_cast<const uint8_t *>(INCORRECT_KEY.data()), INCORRECT_KEY.size());
829 #endif
830 }
831
TearDownTestCase()832 void DistributedDBRelationalVerP2PSyncTest::TearDownTestCase()
833 {
834 /**
835 * @tc.teardown: Release virtual Communicator and clear data dir.
836 */
837 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
838 LOGE("rm test db files error!");
839 }
840 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
841 LOGD("TearDownTestCase FINISH");
842 }
843
SetUp(void)844 void DistributedDBRelationalVerP2PSyncTest::SetUp(void)
845 {
846 DistributedDBToolsUnitTest::PrintTestCaseInfo();
847 g_fieldInfoList.clear();
848 /**
849 * @tc.setup: create virtual device B, and get a KvStoreNbDelegate as deviceA
850 */
851 sqlite3 *db = nullptr;
852 ASSERT_EQ(GetDB(db), SQLITE_OK);
853 sqlite3_close(db);
854 OpenStore();
855 g_deviceB = new (std::nothrow) RelationalVirtualDevice(DEVICE_B);
856 ASSERT_TRUE(g_deviceB != nullptr);
857 g_deviceC = new (std::nothrow) RelationalVirtualDevice(DEVICE_C);
858 ASSERT_TRUE(g_deviceC != nullptr);
859 g_deviceD = new (std::nothrow) KvVirtualDevice(DEVICE_D);
860 ASSERT_TRUE(g_deviceD != nullptr);
861 auto *syncInterfaceB = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
862 auto *syncInterfaceC = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
863 auto *syncInterfaceD = new (std::nothrow) VirtualSingleVerSyncDBInterface();
864 ASSERT_TRUE(syncInterfaceB != nullptr);
865 ASSERT_TRUE(syncInterfaceC != nullptr);
866 ASSERT_TRUE(syncInterfaceD != nullptr);
867 ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
868 ASSERT_EQ(g_deviceC->Initialize(g_communicatorAggregator, syncInterfaceC), E_OK);
869 ASSERT_EQ(g_deviceD->Initialize(g_communicatorAggregator, syncInterfaceD), E_OK);
870
871 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
872 const std::string &deviceId, uint8_t flag) -> bool {
873 return true;
874 };
875 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
876 }
877
TearDown(void)878 void DistributedDBRelationalVerP2PSyncTest::TearDown(void)
879 {
880 /**
881 * @tc.teardown: Release device A, B, C
882 */
883 if (g_rdbDelegatePtr != nullptr) {
884 LOGD("CloseStore Start");
885 ASSERT_EQ(g_mgr.CloseStore(g_rdbDelegatePtr), OK);
886 g_rdbDelegatePtr = nullptr;
887 }
888 if (g_deviceB != nullptr) {
889 delete g_deviceB;
890 g_deviceB = nullptr;
891 }
892 if (g_deviceC != nullptr) {
893 delete g_deviceC;
894 g_deviceC = nullptr;
895 }
896 if (g_deviceD != nullptr) {
897 delete g_deviceD;
898 g_deviceD = nullptr;
899 }
900 if (g_observer != nullptr) {
901 delete g_observer;
902 g_observer = nullptr;
903 }
904 PermissionCheckCallbackV2 nullCallback;
905 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(nullCallback), OK);
906 EXPECT_EQ(DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir), E_OK);
907 if (g_communicatorAggregator != nullptr) {
908 g_communicatorAggregator->RegOnDispatch(nullptr);
909 }
910 g_isAfterRekey = false;
911 LOGD("TearDown FINISH");
912 }
913
WaitCallCount(RelationalStoreObserverUnitTest * observer1)914 void WaitCallCount(RelationalStoreObserverUnitTest *observer1)
915 {
916 int reTry = 5;
917 while (observer1->GetCallCount() != 1u && reTry > 0) {
918 std::this_thread::sleep_for(std::chrono::seconds(1));
919 reTry--;
920 }
921 }
922
923 /**
924 * @tc.name: Normal Sync 001
925 * @tc.desc: Test normal push sync for add data.
926 * @tc.type: FUNC
927 * @tc.require: AR000GK58N
928 * @tc.author: zhangqiquan
929 */
930 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync001, TestSize.Level0)
931 {
932 std::map<std::string, DataValue> dataMap;
933 PrepareEnvironment(dataMap, {g_deviceB});
934 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
935
936 CheckVirtualData(dataMap);
937 DistributedDBToolsUnitTest::Dump();
938 }
939
940 /**
941 * @tc.name: Normal Sync 002
942 * @tc.desc: Test normal pull sync for add data.
943 * @tc.type: FUNC
944 * @tc.require: AR000GK58N
945 * @tc.author: zhangqiquan
946 */
947 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync002, TestSize.Level0)
948 {
949 std::map<std::string, DataValue> dataMap;
950 PrepareEnvironment(dataMap, {g_deviceB});
951
952 Query query = Query::Select(g_tableName);
953 g_deviceB->GenericVirtualDevice::Sync(DistributedDB::SYNC_MODE_PULL_ONLY, query, true);
954
955 CheckVirtualData(dataMap);
956 }
957
958 /**
959 * @tc.name: Normal Sync 003
960 * @tc.desc: Test normal push sync for update data.
961 * @tc.type: FUNC
962 * @tc.require: AR000GK58N
963 * @tc.author: zhangqiquan
964 */
965 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync003, TestSize.Level1)
966 {
967 std::map<std::string, DataValue> dataMap;
968 PrepareEnvironment(dataMap, {g_deviceB});
969
970 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
971
972 CheckVirtualData(dataMap);
973
974 GenerateValue(dataMap, g_fieldInfoList);
975 dataMap["AGE"] = static_cast<int64_t>(1);
976 InsertValueToDB(dataMap);
977 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
978
979 CheckVirtualData(dataMap);
980 }
981
982 /**
983 * @tc.name: Normal Sync 004
984 * @tc.desc: Test normal push sync for delete data.
985 * @tc.type: FUNC
986 * @tc.require: AR000GK58N
987 * @tc.author: zhangqiquan
988 */
989 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync004, TestSize.Level1)
990 {
991 std::map<std::string, DataValue> dataMap;
992 PrepareEnvironment(dataMap, {g_deviceB});
993
994 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
995
996 CheckVirtualData(dataMap);
997
998 sqlite3 *db = nullptr;
999 EXPECT_EQ(GetDB(db), SQLITE_OK);
1000 std::string sql = "DELETE FROM TEST_TABLE WHERE 1 = 1";
1001 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
1002 sqlite3_close(db);
1003
1004 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1005
1006 std::vector<VirtualRowData> dataList;
1007 EXPECT_EQ(g_deviceB->GetAllSyncData(g_tableName, dataList), E_OK);
1008 EXPECT_EQ(static_cast<int>(dataList.size()), 0);
1009 }
1010
1011 /**
1012 * @tc.name: Normal Sync 005
1013 * @tc.desc: Test normal push sync for add data.
1014 * @tc.type: FUNC
1015 * @tc.require: AR000GK58N
1016 * @tc.author: zhangqiquan
1017 */
1018 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync005, TestSize.Level0)
1019 {
1020 std::map<std::string, DataValue> dataMap;
1021 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1022
1023 Query query = Query::Select(g_tableName);
1024 g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true);
1025
1026 CheckData(dataMap);
1027
1028 g_rdbDelegatePtr->RemoveDeviceData(DEVICE_B);
1029
1030 g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true);
1031
1032 CheckData(dataMap);
1033 }
1034
1035 /**
1036 * @tc.name: Normal Sync 006
1037 * @tc.desc: Test normal pull sync for add data.
1038 * @tc.type: FUNC
1039 * @tc.require: AR000GK58N
1040 * @tc.author: zhangqiquan
1041 */
1042 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync006, TestSize.Level1)
1043 {
1044 std::map<std::string, DataValue> dataMap;
1045 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1046
1047 BlockSync(SYNC_MODE_PULL_ONLY, OK, {DEVICE_B});
1048
1049 CheckData(dataMap);
1050 }
1051
1052 /**
1053 * @tc.name: Normal Sync 007
1054 * @tc.desc: Test normal sync for miss query data.
1055 * @tc.type: FUNC
1056 * @tc.require: AR000GK58N
1057 * @tc.author: zhangqiquan
1058 */
1059 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync007, TestSize.Level1)
1060 {
1061 std::map<std::string, DataValue> dataMap;
1062 PrepareEnvironment(dataMap, {g_deviceB});
1063
1064 Query query = Query::Select(g_tableName).EqualTo("NAME", DEFAULT_TEXT);
1065 BlockSync(query, SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1066
1067 CheckVirtualData(dataMap);
1068
1069 sqlite3 *db = nullptr;
1070 EXPECT_EQ(GetDB(db), SQLITE_OK);
1071 std::string sql = "UPDATE TEST_TABLE SET NAME = '' WHERE 1 = 1";
1072 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
1073 sqlite3_close(db);
1074
1075 BlockSync(query, SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1076
1077 std::vector<VirtualRowData> dataList;
1078 EXPECT_EQ(g_deviceB->GetAllSyncData(g_tableName, dataList), E_OK);
1079 EXPECT_EQ(static_cast<int>(dataList.size()), 1);
1080 for (const auto &item : dataList) {
1081 EXPECT_EQ(item.logInfo.flag, DataItem::REMOTE_DEVICE_DATA_MISS_QUERY);
1082 }
1083 }
1084
1085 /**
1086 * @tc.name: Normal Sync 008
1087 * @tc.desc: Test encry db sync for delete table;
1088 * @tc.type: FUNC
1089 * @tc.require: AR000GK58N
1090 * @tc.author: zhuwentao
1091 */
1092 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync008, TestSize.Level0)
1093 {
1094 /**
1095 * @tc.steps: step1. open rdb store, create distribute table, insert data and sync to deviceB
1096 */
1097 std::map<std::string, DataValue> dataMap;
1098 PrepareEnvironment(dataMap, {g_deviceB});
1099 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1100 CheckVirtualData(dataMap);
1101 /**
1102 * @tc.steps: step2.drop table operation and sync again
1103 */
1104 sqlite3 *db = nullptr;
1105 EXPECT_EQ(GetDB(db), SQLITE_OK);
1106 std::string dropTableSql = "drop table TEST_TABLE;";
1107 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, dropTableSql), E_OK);
1108 std::vector<RelationalVirtualDevice *> remoteDeviceVec = {g_deviceB};
1109 PrepareBasicTable(g_tableName, g_fieldInfoList, remoteDeviceVec, true);
1110 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1111 /**
1112 * @tc.steps: step3.check data in deviceB
1113 */
1114 std::vector<VirtualRowData> targetData;
1115 g_deviceB->GetAllSyncData(g_tableName, targetData);
1116 ASSERT_EQ(targetData.size(), 0u);
1117 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1118 }
1119
1120 /**
1121 * @tc.name: Normal Sync 009
1122 * @tc.desc: Test normal push sync for while create distribute table
1123 * @tc.type: FUNC
1124 * @tc.require: AR000GK58N
1125 * @tc.author: zhuwentao
1126 */
1127 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync009, TestSize.Level0)
1128 {
1129 std::map<std::string, DataValue> dataMap;
1130 PrepareEnvironment(dataMap, {g_deviceB});
1131
1132 sqlite3 *db = nullptr;
1133 EXPECT_EQ(GetDB(db), SQLITE_OK);
1134 std::string sql = "alter table TEST_TABLE add column addr Text;";
1135 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
1136 sqlite3_close(db);
1137
1138 std::mutex syncMutex;
1139 std::condition_variable syncCv;
1140 std::mutex syncCallMutex;
1141 std::condition_variable syncCallCv;
1142 std::map<std::string, std::vector<TableStatus>> statusMap;
1143 SyncStatusCallback callBack = [&statusMap, &syncMutex, &syncCv](
__anond45d0a2b0602( const std::map<std::string, std::vector<TableStatus>> &devicesMap) 1144 const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1145 statusMap = devicesMap;
1146 std::unique_lock<std::mutex> lock(syncMutex);
1147 syncCv.notify_one();
1148 };
__anond45d0a2b0702null1149 std::thread t1([] {
1150 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1151 g_rdbDelegatePtr->CreateDistributedTable(g_tableName);
1152 });
1153 DBStatus callStatus = OK;
__anond45d0a2b0802null1154 std::thread t2([&syncCallCv, &callBack, &callStatus] {
1155 Query query = Query::Select(g_tableName);
1156 callStatus = g_rdbDelegatePtr->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callBack, false);
1157 syncCallCv.notify_one();
1158 });
1159 {
1160 std::unique_lock<std::mutex> callLock(syncCallMutex);
1161 syncCallCv.wait(callLock);
1162 }
1163 if (callStatus == OK) {
1164 std::unique_lock<std::mutex> lock(syncMutex);
1165 syncCv.wait(lock);
1166 }
1167 t1.join();
1168 t2.join();
1169 }
1170
1171 /**
1172 * @tc.name: AutoLaunchSync 001
1173 * @tc.desc: Test rdb autoLaunch success when callback return true.
1174 * @tc.type: FUNC
1175 * @tc.require: AR000GK58N
1176 * @tc.author: zhangqiquan
1177 */
1178 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSync001, TestSize.Level3)
1179 {
1180 /**
1181 * @tc.steps: step1. open rdb store, create distribute table and insert data
1182 */
1183 std::map<std::string, DataValue> dataMap;
1184 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1185
1186 /**
1187 * @tc.steps: step2. set auto launch callBack
1188 */
1189 int currentStatus = 0;
1190 const AutoLaunchNotifier notifier = [¤tStatus](const std::string &userId,
__anond45d0a2b0902(const std::string &userId, const std::string &appId, const std::string &storeId, AutoLaunchStatus status) 1191 const std::string &appId, const std::string &storeId, AutoLaunchStatus status) {
1192 currentStatus = static_cast<int>(status);
1193 };
__anond45d0a2b0a02(const std::string &identifier, AutoLaunchParam ¶m) 1194 const AutoLaunchRequestCallback callback = [¬ifier](const std::string &identifier, AutoLaunchParam ¶m) {
1195 if (g_id != identifier) {
1196 return false;
1197 }
1198 param.path = g_dbDir;
1199 param.appId = APP_ID;
1200 param.userId = USER_ID;
1201 param.storeId = STORE_ID_1;
1202 param.notifier = notifier;
1203 #ifndef OMIT_ENCRYPT
1204 param.option.isEncryptedDb = true;
1205 param.option.cipher = CipherType::DEFAULT;
1206 param.option.passwd = g_correctPasswd;
1207 param.option.iterateTimes = DEFAULT_ITER;
1208 #endif
1209 return true;
1210 };
1211 g_mgr.SetAutoLaunchRequestCallback(callback);
1212 /**
1213 * @tc.steps: step3. close store ensure communicator has closed
1214 */
1215 g_mgr.CloseStore(g_rdbDelegatePtr);
1216 g_rdbDelegatePtr = nullptr;
1217 /**
1218 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
1219 */
1220 LabelType labelType(g_id.begin(), g_id.end());
1221 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1222 std::this_thread::sleep_for(std::chrono::seconds(1));
1223 EXPECT_EQ(currentStatus, 0);
1224 /**
1225 * @tc.steps: step5. Call sync expect sync successful
1226 */
1227 Query query = Query::Select(g_tableName);
1228 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1229 /**
1230 * @tc.steps: step6. check sync data ensure sync successful
1231 */
1232 CheckData(dataMap);
1233
1234 OpenStore();
1235 RuntimeConfig::ReleaseAutoLaunch(USER_ID, APP_ID, STORE_ID_1, DBType::DB_RELATION);
1236 }
1237
1238 /**
1239 * @tc.name: AutoLaunchSync 002
1240 * @tc.desc: Test rdb autoLaunch failed when callback return false.
1241 * @tc.type: FUNC
1242 * @tc.require: AR000GK58N
1243 * @tc.author: zhangqiquan
1244 */
1245 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSync002, TestSize.Level3)
1246 {
1247 /**
1248 * @tc.steps: step1. open rdb store, create distribute table and insert data
1249 */
1250 std::map<std::string, DataValue> dataMap;
1251 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1252
1253 /**
1254 * @tc.steps: step2. set auto launch callBack
1255 */
__anond45d0a2b0b02(const std::string &identifier, AutoLaunchParam ¶m) 1256 const AutoLaunchRequestCallback callback = [](const std::string &identifier, AutoLaunchParam ¶m) {
1257 return false;
1258 };
1259 g_mgr.SetAutoLaunchRequestCallback(callback);
1260 /**
1261 * @tc.steps: step2. close store ensure communicator has closed
1262 */
1263 g_mgr.CloseStore(g_rdbDelegatePtr);
1264 g_rdbDelegatePtr = nullptr;
1265 /**
1266 * @tc.steps: step3. store can't autoLaunch because callback return false
1267 */
1268 LabelType labelType(g_id.begin(), g_id.end());
1269 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1270 std::this_thread::sleep_for(std::chrono::seconds(1));
1271 /**
1272 * @tc.steps: step4. Call sync expect sync fail
1273 */
1274 Query query = Query::Select(g_tableName);
__anond45d0a2b0c02(const std::map<std::string, int> &statusMap) 1275 SyncOperation::UserCallback callBack = [](const std::map<std::string, int> &statusMap) {
1276 for (const auto &entry : statusMap) {
1277 EXPECT_EQ(entry.second, -E_NOT_FOUND);
1278 }
1279 };
1280 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, callBack, true), E_OK);
1281
1282 OpenStore();
1283 std::this_thread::sleep_for(std::chrono::minutes(1));
1284 }
1285
1286 /**
1287 * @tc.name: AutoLaunchSync 003
1288 * @tc.desc: Test rdb autoLaunch failed when callback is nullptr.
1289 * @tc.type: FUNC
1290 * @tc.require: AR000GK58N
1291 * @tc.author: zhangqiquan
1292 */
1293 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSync003, TestSize.Level3)
1294 {
1295 /**
1296 * @tc.steps: step1. open rdb store, create distribute table and insert data
1297 */
1298 std::map<std::string, DataValue> dataMap;
1299 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1300
1301 g_mgr.SetAutoLaunchRequestCallback(nullptr);
1302 /**
1303 * @tc.steps: step2. close store ensure communicator has closed
1304 */
1305 g_mgr.CloseStore(g_rdbDelegatePtr);
1306 g_rdbDelegatePtr = nullptr;
1307 /**
1308 * @tc.steps: step3. store can't autoLaunch because callback is nullptr
1309 */
1310 LabelType labelType(g_id.begin(), g_id.end());
1311 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1312 std::this_thread::sleep_for(std::chrono::seconds(1));
1313 /**
1314 * @tc.steps: step4. Call sync expect sync fail
1315 */
1316 Query query = Query::Select(g_tableName);
__anond45d0a2b0d02(const std::map<std::string, int> &statusMap) 1317 SyncOperation::UserCallback callBack = [](const std::map<std::string, int> &statusMap) {
1318 for (const auto &entry : statusMap) {
1319 EXPECT_EQ(entry.second, -E_NOT_FOUND);
1320 }
1321 };
1322 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, callBack, true), E_OK);
1323
1324 OpenStore();
1325 std::this_thread::sleep_for(std::chrono::minutes(1));
1326 }
1327
1328
1329 /**
1330 * @tc.name: AutoLaunchSync 004
1331 * @tc.desc: Test invalid db type for autoLaunch.
1332 * @tc.type: FUNC
1333 * @tc.require:
1334 * @tc.author: zhangshijie
1335 */
1336 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSync004, TestSize.Level3)
1337 {
1338 /**
1339 * @tc.steps: step1. open rdb store, create distribute table and insert data
1340 */
1341 std::map<std::string, DataValue> dataMap;
1342 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1343
1344 /**
1345 * @tc.steps: step2. set auto launch callBack
1346 */
1347 int currentStatus = 0;
1348 const AutoLaunchNotifier notifier = [¤tStatus](const std::string &userId,
__anond45d0a2b0e02(const std::string &userId, const std::string &appId, const std::string &storeId, AutoLaunchStatus status) 1349 const std::string &appId, const std::string &storeId, AutoLaunchStatus status) {
1350 printf("SET STATUS = %d\n", static_cast<int>(status));
1351 currentStatus = static_cast<int>(status);
1352 };
__anond45d0a2b0f02(const std::string &identifier, AutoLaunchParam ¶m) 1353 const AutoLaunchRequestCallback callback = [¬ifier](const std::string &identifier, AutoLaunchParam ¶m) {
1354 if (g_id != identifier) {
1355 return false;
1356 }
1357 param.path = g_dbDir;
1358 param.appId = APP_ID;
1359 param.userId = USER_ID;
1360 param.storeId = STORE_ID_1;
1361 param.notifier = notifier;
1362 #ifndef OMIT_ENCRYPT
1363 param.option.isEncryptedDb = true;
1364 param.option.cipher = CipherType::DEFAULT;
1365 param.option.passwd = g_correctPasswd;
1366 param.option.iterateTimes = DEFAULT_ITER;
1367 #endif
1368 return true;
1369 };
1370 RuntimeConfig::SetAutoLaunchRequestCallback(callback, static_cast<DBType>(3)); // 3 is invalid db type
1371
1372 /**
1373 * @tc.steps: step3. close store ensure communicator has closed
1374 */
1375 g_mgr.CloseStore(g_rdbDelegatePtr);
1376 g_rdbDelegatePtr = nullptr;
1377 /**
1378 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
1379 */
1380 LabelType labelType(g_id.begin(), g_id.end());
1381 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1382 std::this_thread::sleep_for(std::chrono::seconds(1));
1383 EXPECT_EQ(currentStatus, AutoLaunchStatus::INVALID_PARAM);
1384 }
1385
1386 /**
1387 * @tc.name: Ability Sync 001
1388 * @tc.desc: Test ability sync success when has same schema.
1389 * @tc.type: FUNC
1390 * @tc.require: AR000GK58N
1391 * @tc.author: zhangqiquan
1392 */
1393 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AbilitySync001, TestSize.Level1)
1394 {
1395 std::map<std::string, DataValue> dataMap;
1396 std::vector<FieldInfo> localFieldInfo;
1397 GetFieldInfo(localFieldInfo, g_storageType);
1398
1399 PrepareEnvironment(dataMap, localFieldInfo, localFieldInfo, {g_deviceB});
1400 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1401
1402 CheckVirtualData(dataMap);
1403 }
1404
1405 /**
1406 * @tc.name: Ability Sync 002
1407 * @tc.desc: Test ability sync failed when has different schema.
1408 * @tc.type: FUNC
1409 * @tc.require: AR000GK58N
1410 * @tc.author: zhangqiquan
1411 */
1412 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AbilitySync002, TestSize.Level1)
1413 {
1414 /**
1415 * @tc.steps: step1. set local schema is (BOOL, INTEGER, REAL, TEXT, BLOB, INTEGER)
1416 */
1417 std::map<std::string, DataValue> dataMap;
1418 std::vector<FieldInfo> localFieldInfo;
1419 std::vector<StorageType> localStorageType = g_storageType;
1420 localStorageType.push_back(StorageType::STORAGE_TYPE_INTEGER);
1421 GetFieldInfo(localFieldInfo, localStorageType);
1422
1423 /**
1424 * @tc.steps: step2. set remote schema is (BOOL, INTEGER, REAL, TEXT, BLOB, TEXT)
1425 */
1426 std::vector<FieldInfo> remoteFieldInfo;
1427 std::vector<StorageType> remoteStorageType = g_storageType;
1428 remoteStorageType.push_back(StorageType::STORAGE_TYPE_TEXT);
1429 GetFieldInfo(remoteFieldInfo, remoteStorageType);
1430
1431 /**
1432 * @tc.steps: step3. call sync
1433 * @tc.expected: sync fail when abilitySync
1434 */
1435 PrepareEnvironment(dataMap, localFieldInfo, remoteFieldInfo, {g_deviceB});
1436 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, SCHEMA_MISMATCH, {DEVICE_B});
1437 }
1438
1439 /**
1440 * @tc.name: Ability Sync 003
1441 * @tc.desc: Test ability sync failed when has different schema.
1442 * @tc.type: FUNC
1443 * @tc.require: AR000GK58N
1444 * @tc.author: zhangqiquan
1445 */
1446 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AbilitySync003, TestSize.Level1)
1447 {
1448 /**
1449 * @tc.steps: step1. set local and remote schema is (BOOL, INTEGER, REAL, TEXT, BLOB)
1450 */
1451 std::map<std::string, DataValue> dataMap;
1452 std::vector<FieldInfo> schema;
1453 std::vector<StorageType> localStorageType = g_storageType;
1454 GetFieldInfo(schema, localStorageType);
1455
1456 /**
1457 * @tc.steps: step2. create table and insert data
1458 */
1459 PrepareEnvironment(dataMap, schema, schema, {g_deviceB});
1460
1461 /**
1462 * @tc.steps: step3. change local table to (BOOL, INTEGER, REAL, TEXT, BLOB)
1463 * @tc.expected: sync fail
1464 */
1465 bool alter = false;
__anond45d0a2b1002(const std::string &target, Message *inMsg) 1466 g_communicatorAggregator->RegOnDispatch([&alter](const std::string &target, Message *inMsg) {
1467 if (target != "real_device") {
1468 return;
1469 }
1470 if (inMsg->GetMessageType() != TYPE_NOTIFY || inMsg->GetMessageId() != ABILITY_SYNC_MESSAGE) {
1471 return;
1472 }
1473 if (alter) {
1474 return;
1475 }
1476 alter = true;
1477 sqlite3 *db = nullptr;
1478 EXPECT_EQ(GetDB(db), SQLITE_OK);
1479 ASSERT_NE(db, nullptr);
1480 std::string alterSql = "ALTER TABLE " + g_tableName + " ADD COLUMN NEW_COLUMN TEXT DEFAULT 'DEFAULT_TEXT'";
1481 EXPECT_EQ(sqlite3_exec(db, alterSql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1482 EXPECT_EQ(sqlite3_close(db), SQLITE_OK);
1483 EXPECT_EQ(g_rdbDelegatePtr->CreateDistributedTable(g_tableName), OK);
1484 });
1485
1486 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1487
1488 g_communicatorAggregator->RegOnDispatch(nullptr);
1489 }
1490
1491 /**
1492 * @tc.name: Ability Sync 004
1493 * @tc.desc: Test ability sync failed when one device hasn't distributed table.
1494 * @tc.type: FUNC
1495 * @tc.require: AR000GK58N
1496 * @tc.author: zhangqiquan
1497 */
1498 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AbilitySync004, TestSize.Level1)
1499 {
1500 std::map<std::string, DataValue> dataMap;
1501 PrepareVirtualEnvironment(dataMap, {g_deviceB}, false);
1502
1503 Query query = Query::Select(g_tableName);
1504 int res = DB_ERROR;
__anond45d0a2b1102(std::map<std::string, int> resMap) 1505 auto callBack = [&res](std::map<std::string, int> resMap) {
1506 if (resMap.find("real_device") != resMap.end()) {
1507 res = resMap["real_device"];
1508 }
1509 };
1510 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(DistributedDB::SYNC_MODE_PULL_ONLY, query, callBack, true), E_OK);
1511 EXPECT_EQ(res, static_cast<int>(SyncOperation::Status::OP_SCHEMA_INCOMPATIBLE));
1512 }
1513
1514 /**
1515 * @tc.name: WaterMark 001
1516 * @tc.desc: Test sync success after erase waterMark.
1517 * @tc.type: FUNC
1518 * @tc.require: AR000GK58N
1519 * @tc.author: zhangqiquan
1520 */
1521 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, WaterMark001, TestSize.Level1)
1522 {
1523 std::map<std::string, DataValue> dataMap;
1524 PrepareEnvironment(dataMap, {g_deviceB});
1525 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1526
1527 CheckVirtualData(dataMap);
1528
1529 EXPECT_EQ(g_rdbDelegatePtr->RemoveDeviceData(g_deviceB->GetDeviceId(), g_tableName), OK);
1530 g_deviceB->EraseSyncData(g_tableName);
1531
1532 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1533
1534 CheckVirtualData(dataMap);
1535 }
1536
1537 /*
1538 * @tc.name: pressure sync 001
1539 * @tc.desc: Test rdb sync different table at same time
1540 * @tc.type: FUNC
1541 * @tc.require: AR000GK58N
1542 * @tc.author: zhangqiquan
1543 */
1544 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, PressureSync001, TestSize.Level1)
1545 {
1546 /**
1547 * @tc.steps: step1. create table A and device A push data to device B
1548 * @tc.expected: step1. all is ok
1549 */
1550 std::map<std::string, DataValue> tableADataMap;
1551 std::vector<FieldInfo> tableAFieldInfo;
1552 std::vector<StorageType> localStorageType = g_storageType;
1553 localStorageType.push_back(StorageType::STORAGE_TYPE_INTEGER);
1554 GetFieldInfo(tableAFieldInfo, localStorageType);
1555 const std::string tableNameA = "TABLE_A";
1556 PrepareEnvironment(tableADataMap, tableNameA, tableAFieldInfo, tableAFieldInfo, {g_deviceB});
1557
1558 /**
1559 * @tc.steps: step2. create table B and device B push data to device A
1560 * @tc.expected: step2. all is ok
1561 */
1562 std::map<std::string, DataValue> tableBDataMap;
1563 std::vector<FieldInfo> tableBFieldInfo;
1564 localStorageType = g_storageType;
1565 localStorageType.push_back(StorageType::STORAGE_TYPE_REAL);
1566 GetFieldInfo(tableBFieldInfo, localStorageType);
1567 const std::string tableNameB = "TABLE_B";
1568 PrepareVirtualEnvironment(tableBDataMap, tableNameB, tableBFieldInfo, {g_deviceB});
1569
1570 std::condition_variable cv;
1571 bool subFinish = false;
__anond45d0a2b1202() 1572 std::thread subThread = std::thread([&subFinish, &cv, &tableNameA, &tableADataMap]() {
1573 BlockSync(tableNameA, SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
1574
1575 CheckVirtualData(tableNameA, tableADataMap);
1576 subFinish = true;
1577 cv.notify_all();
1578 });
1579 subThread.detach();
1580
1581 Query query = Query::Select(tableNameB);
1582 g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true);
1583 CheckData(tableBDataMap, tableNameB, tableBFieldInfo);
1584
1585 std::mutex mutex;
1586 std::unique_lock<std::mutex> lock(mutex);
__anond45d0a2b1302null1587 cv.wait(lock, [&subFinish] { return subFinish; });
1588 }
1589
1590 /*
1591 * @tc.name: relation observer 001
1592 * @tc.desc: Test relation observer while normal pull sync
1593 * @tc.type: FUNC
1594 * @tc.require:
1595 * @tc.author: zhuwentao
1596 */
1597 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer001, TestSize.Level0)
1598 {
1599 /**
1600 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1601 * @tc.expected: step1. create and insert ok
1602 */
1603 g_observer->ResetToZero();
1604 std::map<std::string, DataValue> dataMap;
1605 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1606 /**
1607 * @tc.steps: step2. device A pull sync mode
1608 * @tc.expected: step2. sync ok
1609 */
1610 BlockSync(SyncMode::SYNC_MODE_PULL_ONLY, OK, {DEVICE_B, DEVICE_C});
1611 /**
1612 * @tc.steps: step3. device A check observer
1613 * @tc.expected: step2. data change device is deviceB
1614 */
1615 EXPECT_EQ(g_observer->GetCallCount(), 1u);
1616 EXPECT_EQ(g_observer->GetDataChangeDevice(), DEVICE_B);
1617 CheckIdentify(g_observer);
1618 }
1619
1620 /**
1621 * @tc.name: relation observer 002
1622 * @tc.desc: Test rdb observer ok in autolauchCallback scene
1623 * @tc.type: FUNC
1624 * @tc.require: AR000GK58N
1625 * @tc.author: zhuwentao
1626 */
1627 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer002, TestSize.Level3)
1628 {
1629 /**
1630 * @tc.steps: step1. open rdb store, create distribute table and insert data
1631 */
1632 g_observer->ResetToZero();
1633 std::map<std::string, DataValue> dataMap;
1634 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1635
1636 /**
1637 * @tc.steps: step2. set auto launch callBack
1638 */
1639 RelationalStoreObserverUnitTest *observer = new (std::nothrow) RelationalStoreObserverUnitTest();
__anond45d0a2b1402(const std::string &identifier, AutoLaunchParam ¶m) 1640 const AutoLaunchRequestCallback callback = [observer](const std::string &identifier, AutoLaunchParam ¶m) {
1641 if (g_id != identifier) {
1642 return false;
1643 }
1644 param.path = g_dbDir;
1645 param.appId = APP_ID;
1646 param.userId = USER_ID;
1647 param.storeId = STORE_ID_1;
1648 param.option.storeObserver = observer;
1649 #ifndef OMIT_ENCRYPT
1650 param.option.isEncryptedDb = true;
1651 param.option.cipher = CipherType::DEFAULT;
1652 param.option.passwd = g_correctPasswd;
1653 param.option.iterateTimes = DEFAULT_ITER;
1654 #endif
1655 return true;
1656 };
1657 g_mgr.SetAutoLaunchRequestCallback(callback);
1658 /**
1659 * @tc.steps: step3. close store ensure communicator has closed
1660 */
1661 g_mgr.CloseStore(g_rdbDelegatePtr);
1662 g_rdbDelegatePtr = nullptr;
1663 /**
1664 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
1665 */
1666 LabelType labelType(g_id.begin(), g_id.end());
1667 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1668 std::this_thread::sleep_for(std::chrono::seconds(1));
1669 /**
1670 * @tc.steps: step5. Call sync expect sync successful and device A check observer
1671 */
1672 Query query = Query::Select(g_tableName);
1673 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1674 EXPECT_EQ(observer->GetCallCount(), 1u);
1675 EXPECT_EQ(observer->GetDataChangeDevice(), DEVICE_B);
1676 CheckIdentify(observer);
1677 std::this_thread::sleep_for(std::chrono::minutes(1));
1678 delete observer;
1679 }
1680
1681 /*
1682 * @tc.name: relation observer 003
1683 * @tc.desc: Test relation observer without manager
1684 * @tc.type: FUNC
1685 * @tc.require:
1686 * @tc.author: zhangqiquan
1687 */
1688 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer003, TestSize.Level0)
1689 {
1690 /**
1691 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1692 * @tc.expected: step1. create and insert ok
1693 */
1694 g_observer->ResetToZero();
1695 std::map<std::string, DataValue> dataMap;
1696 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1697 std::shared_ptr<RelationalStoreManager> mgr = std::make_shared<RelationalStoreManager>(APP_ID, USER_ID);
1698 ASSERT_NE(mgr, nullptr);
1699 RelationalStoreDelegate::Option option;
1700 option.observer = g_observer;
1701 #ifndef OMIT_ENCRYPT
1702 option.isEncryptedDb = true;
1703 option.iterateTimes = DEFAULT_ITER;
1704 option.passwd = g_isAfterRekey ? g_rekeyPasswd : g_correctPasswd;
1705 option.cipher = CipherType::DEFAULT;
1706 #endif
1707 RelationalStoreDelegate *rdbDelegatePtr = nullptr;
1708 mgr->OpenStore(g_dbDir, STORE_ID_1, option, rdbDelegatePtr);
1709 mgr = nullptr;
1710 /**
1711 * @tc.steps: step2. device A pull sync mode
1712 * @tc.expected: step2. sync ok
1713 */
1714 Query query = Query::Select(g_tableName);
1715 DBStatus callStatus = rdbDelegatePtr->Sync({DEVICE_B, DEVICE_C}, SyncMode::SYNC_MODE_PULL_ONLY, query,
1716 nullptr, true);
1717 EXPECT_EQ(callStatus, OK);
1718 /**
1719 * @tc.steps: step3. device A check observer
1720 * @tc.expected: step2. data change device is deviceB
1721 */
1722 EXPECT_EQ(g_observer->GetCallCount(), 2u); // 2 is observer triggered times
1723 EXPECT_EQ(g_observer->GetDataChangeDevice(), DEVICE_B);
1724 CheckIdentify(g_observer);
1725 mgr = std::make_shared<RelationalStoreManager>(APP_ID, USER_ID);
1726 ASSERT_NE(mgr, nullptr);
1727 mgr->CloseStore(rdbDelegatePtr);
1728 mgr = nullptr;
1729 }
1730
1731 /*
1732 * @tc.name: relation observer 004
1733 * @tc.desc: Test relation register observer
1734 * @tc.type: FUNC
1735 * @tc.require:
1736 * @tc.author: zhangqiquan
1737 */
1738 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer004, TestSize.Level0)
1739 {
1740 /**
1741 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1742 * @tc.expected: step1. create and insert ok
1743 */
1744 ASSERT_NE(g_rdbDelegatePtr, nullptr);
1745 g_observer->ResetToZero();
1746 auto observer = new (std::nothrow) RelationalStoreObserverUnitTest();
1747 std::map<std::string, DataValue> dataMap;
1748 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1749 g_rdbDelegatePtr->RegisterObserver(observer);
1750 /**
1751 * @tc.steps: step2. device A pull sync mode
1752 * @tc.expected: step2. sync ok
1753 */
1754 BlockSync(SyncMode::SYNC_MODE_PULL_ONLY, OK, {DEVICE_B, DEVICE_C});
1755 /**
1756 * @tc.steps: step3. device A check observer
1757 * @tc.expected: step2. data change device is deviceB
1758 */
1759 EXPECT_EQ(observer->GetCallCount(), 1u);
1760 EXPECT_EQ(g_observer->GetCallCount(), 1u); // support multi observer for one delegate
1761 EXPECT_EQ(observer->GetDataChangeDevice(), DEVICE_B);
1762 CheckIdentify(observer);
1763 delete observer;
1764 }
1765
1766 /*
1767 * @tc.name: relation observer 005
1768 * @tc.desc: Test relation unregister observer
1769 * @tc.type: FUNC
1770 * @tc.require:
1771 * @tc.author: zhangqiquan
1772 */
1773 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer005, TestSize.Level0)
1774 {
1775 /**
1776 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1777 * @tc.expected: step1. create and insert ok
1778 */
1779 ASSERT_NE(g_rdbDelegatePtr, nullptr);
1780 g_observer->ResetToZero();
1781 std::map<std::string, DataValue> dataMap;
1782 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1783 g_rdbDelegatePtr->UnRegisterObserver();
1784 /**
1785 * @tc.steps: step2. device A pull sync mode
1786 * @tc.expected: step2. sync ok
1787 */
1788 BlockSync(SyncMode::SYNC_MODE_PULL_ONLY, OK, {DEVICE_B, DEVICE_C});
1789 /**
1790 * @tc.steps: step3. device A check observer
1791 * @tc.expected: step2. data change device is deviceB
1792 */
1793 EXPECT_EQ(g_observer->GetCallCount(), 0u);
1794 }
1795
1796
1797 /*
1798 * @tc.name: relation observer 006
1799 * @tc.desc: Test observer is destructed when sync finish
1800 * @tc.type: FUNC
1801 * @tc.require:
1802 * @tc.author: zhangshijie
1803 */
1804 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer006, TestSize.Level3)
1805 {
1806 /**
1807 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1808 * @tc.expected: step1. create and insert ok
1809 */
1810 g_observer->ResetToZero();
1811 std::map<std::string, DataValue> dataMap;
1812 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1813
1814 /**
1815 * @tc.steps: step2. device A pull sync mode
1816 * @tc.expected: step2. sync ok
1817 */
1818 int count = 0;
1819 PermissionCheckCallbackV2 callback = [&count](const std::string &userId, const std::string &appId,
__anond45d0a2b1502(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 1820 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
1821 if ((flag == CHECK_FLAG_RECEIVE) && (count == 0)) {
1822 for (int i = 0; i < 10; i++) { // 10 is capacity of thread pool
1823 RuntimeContext::GetInstance()->ScheduleTask([] () {
1824 std::this_thread::sleep_for(std::chrono::seconds(6)); // sleep 6 seconds
1825 });
1826 }
1827 count++;
1828 }
1829 return true;
1830 };
1831 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(callback), E_OK);
1832
1833 /**
1834 * @tc.steps: step3. device A check observer
1835 * @tc.expected: step2. data change device is deviceB
1836 */
1837 Query query = Query::Select(g_tableName);
1838 g_rdbDelegatePtr->Sync({DEVICE_B}, SyncMode::SYNC_MODE_PULL_ONLY, query, nullptr, false);
1839 std::this_thread::sleep_for(std::chrono::seconds(1));
1840 ASSERT_EQ(g_mgr.CloseStore(g_rdbDelegatePtr), OK);
1841 g_rdbDelegatePtr = nullptr;
1842 delete g_observer;
1843 g_observer = nullptr;
1844 std::this_thread::sleep_for(std::chrono::seconds(10)); // sleep 10 second to wait sync finish
1845 RuntimeContext::GetInstance()->StopTaskPool();
1846 }
1847
1848 /*
1849 * @tc.name: relation observer 007
1850 * @tc.desc: Test open store observer will not overwrite autolaunch observer
1851 * @tc.type: FUNC
1852 * @tc.require:
1853 * @tc.author: zhangshijie
1854 */
1855 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer007, TestSize.Level3)
1856 {
1857 /**
1858 * @tc.steps: step1. device A create table and device B insert data and device C don't insert data
1859 * @tc.expected: step1. create and insert ok
1860 */
1861 g_observer->ResetToZero();
1862 std::map<std::string, DataValue> dataMap;
1863 PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC});
1864
1865 /**
1866 * @tc.steps: step2. device A pull sync mode
1867 * @tc.expected: step2. sync ok
1868 */
1869 RelationalStoreObserverUnitTest *observer = new (std::nothrow) RelationalStoreObserverUnitTest();
1870 ASSERT_NE(observer, nullptr);
__anond45d0a2b1702(const std::string &identifier, AutoLaunchParam ¶m) 1871 const AutoLaunchRequestCallback callback = [observer](const std::string &identifier, AutoLaunchParam ¶m) {
1872 if (g_id != identifier) {
1873 return false;
1874 }
1875 param.path = g_dbDir;
1876 param.appId = APP_ID;
1877 param.userId = USER_ID;
1878 param.storeId = STORE_ID_1;
1879 param.option.storeObserver = observer;
1880 #ifndef OMIT_ENCRYPT
1881 param.option.isEncryptedDb = true;
1882 param.option.cipher = CipherType::DEFAULT;
1883 param.option.passwd = g_correctPasswd;
1884 param.option.iterateTimes = DEFAULT_ITER;
1885 #endif
1886 return true;
1887 };
1888
1889 /**
1890 * @tc.steps: step2. SetAutoLaunchRequestCallback
1891 * @tc.expected: step2. success.
1892 */
1893 g_mgr.SetAutoLaunchRequestCallback(callback);
1894
1895 /**
1896 * @tc.steps: step3. RunCommunicatorLackCallback
1897 * @tc.expected: step3. success.
1898 */
1899 LabelType labelType(g_id.begin(), g_id.end());
1900 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
1901
1902 /**
1903 * @tc.steps: step4. start sync
1904 * @tc.expected: step4. success
1905 */
1906 Query query = Query::Select(g_tableName);
1907 g_rdbDelegatePtr->Sync({DEVICE_B}, SyncMode::SYNC_MODE_PULL_ONLY, query, nullptr, false);
1908
1909 /**
1910 * @tc.steps: step5. open store with observer1
1911 * @tc.expected: step5. success.
1912 */
1913 auto observer1 = new (std::nothrow) RelationalStoreObserverUnitTest();
1914 ASSERT_NE(observer1, nullptr);
1915 RelationalStoreDelegate::Option option;
1916 option.observer = observer1;
1917 #ifndef OMIT_ENCRYPT
1918 option.isEncryptedDb = true;
1919 option.iterateTimes = DEFAULT_ITER;
1920 option.passwd = g_isAfterRekey ? g_rekeyPasswd : g_correctPasswd;
1921 option.cipher = CipherType::DEFAULT;
1922 #endif
1923 RelationalStoreDelegate *rdb1 = nullptr;
1924 g_mgr.OpenStore(g_dbDir, STORE_ID_1, option, rdb1);
1925 ASSERT_TRUE(rdb1 != nullptr);
1926
1927 /**
1928 * @tc.steps: step6. close store and delete observer1
1929 * @tc.expected: step6. success.
1930 */
1931 ReleaseForObserver007(rdb1, observer1, observer);
1932 }
1933
RegisterNewObserver(RelationalStoreDelegate * rdb1,RelationalStoreObserverUnitTest * observer1,RelationalStoreObserverUnitTest * autoLaunchObserver)1934 void RegisterNewObserver(RelationalStoreDelegate *rdb1, RelationalStoreObserverUnitTest *observer1,
1935 RelationalStoreObserverUnitTest *autoLaunchObserver)
1936 {
1937 /**
1938 * @tc.steps: step1. register another observer
1939 */
1940 auto observer2 = new (std::nothrow) RelationalStoreObserverUnitTest();
1941 ASSERT_NE(observer2, nullptr);
1942 EXPECT_EQ(rdb1->RegisterObserver(observer2), OK);
1943 observer1->ResetToZero();
1944 std::map<std::string, DataValue> dataMap;
1945 InsertDataToDeviceB(dataMap, g_tableName, g_fieldInfoList, 2); // 2 is watermark
1946 Query query = Query::Select(g_tableName);
1947 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1948 EXPECT_EQ(observer1->GetCallCount(), 1u); // one delegate can register 8 observer
1949 EXPECT_EQ(autoLaunchObserver->GetCallCount(), 2u); // 2 is auto_launch observer triggered times
1950 EXPECT_EQ(observer2->GetCallCount(), 1u);
1951
1952 EXPECT_EQ(rdb1->UnRegisterObserver(), OK);
1953 observer2->ResetToZero();
1954 observer1->ResetToZero();
1955 InsertDataToDeviceB(dataMap, g_tableName, g_fieldInfoList, 3); // 3 is watermark
1956 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1957 EXPECT_EQ(observer1->GetCallCount(), 0u);
1958 EXPECT_EQ(autoLaunchObserver->GetCallCount(), 3u); // 3 is auto_launch observer triggered times
1959 EXPECT_EQ(observer2->GetCallCount(), 0u);
1960
1961 RuntimeConfig::ReleaseAutoLaunch(USER_ID, APP_ID, STORE_ID_1, DBType::DB_RELATION);
1962 delete autoLaunchObserver;
1963 delete observer1;
1964 delete observer2;
1965 ASSERT_EQ(g_mgr.CloseStore(rdb1), OK);
1966 rdb1 = nullptr;
1967 }
1968
1969 /**
1970 * @tc.name: relation observer 008
1971 * @tc.desc: Test multi rdb observer
1972 * @tc.type: FUNC
1973 * @tc.require:
1974 * @tc.author: zhangshijie
1975 */
1976 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer008, TestSize.Level3)
1977 {
1978 /**
1979 * @tc.steps: step1. open rdb store, create distribute table and insert data
1980 */
1981 g_observer->ResetToZero();
1982 std::map<std::string, DataValue> dataMap;
1983 PrepareVirtualEnvironment(dataMap, {g_deviceB});
1984
1985 /**
1986 * @tc.steps: step2. set auto launch callBack
1987 */
1988 RelationalStoreObserverUnitTest *autoObserver = new (std::nothrow) RelationalStoreObserverUnitTest();
__anond45d0a2b1802(const std::string &identifier, AutoLaunchParam ¶m) 1989 const AutoLaunchRequestCallback callback = [autoObserver](const std::string &identifier, AutoLaunchParam ¶m) {
1990 if (g_id != identifier) {
1991 return false;
1992 }
1993 param.path = g_dbDir;
1994 param.appId = APP_ID;
1995 param.userId = USER_ID;
1996 param.storeId = STORE_ID_1;
1997 param.option.storeObserver = autoObserver;
1998 #ifndef OMIT_ENCRYPT
1999 param.option.isEncryptedDb = true;
2000 param.option.cipher = CipherType::DEFAULT;
2001 param.option.passwd = g_correctPasswd;
2002 param.option.iterateTimes = DEFAULT_ITER;
2003 #endif
2004 return true;
2005 };
2006 g_mgr.SetAutoLaunchRequestCallback(callback);
2007 /**
2008 * @tc.steps: step3. close store ensure communicator has closed
2009 */
2010 g_mgr.CloseStore(g_rdbDelegatePtr);
2011 g_rdbDelegatePtr = nullptr;
2012
2013 /**
2014 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
2015 * @tc.expected: step4. success.
2016 */
2017 LabelType labelType(g_id.begin(), g_id.end());
2018 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
2019 std::this_thread::sleep_for(std::chrono::seconds(1));
2020
2021 auto observer1 = new (std::nothrow) RelationalStoreObserverUnitTest();
2022 ASSERT_NE(observer1, nullptr);
2023 RelationalStoreDelegate::Option option;
2024 option.observer = observer1;
2025 #ifndef OMIT_ENCRYPT
2026 option.isEncryptedDb = true;
2027 option.iterateTimes = DEFAULT_ITER;
2028 option.passwd = g_isAfterRekey ? g_rekeyPasswd : g_correctPasswd;
2029 option.cipher = CipherType::DEFAULT;
2030 #endif
2031 RelationalStoreDelegate *rdb1 = nullptr;
2032 g_mgr.OpenStore(g_dbDir, STORE_ID_1, option, rdb1);
2033 ASSERT_TRUE(rdb1 != nullptr);
2034 /**
2035 * @tc.steps: step5. Call sync expect sync successful and device A check observer
2036 */
2037 Query query = Query::Select(g_tableName);
2038 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
2039
2040 /**
2041 * @tc.steps: step6. Call sync expect sync successful and device A check observer
2042 */
2043 EXPECT_EQ(autoObserver->GetCallCount(), 1u);
2044 WaitCallCount(observer1);
2045 EXPECT_EQ(observer1->GetCallCount(), 1u);
2046 EXPECT_EQ(autoObserver->GetDataChangeDevice(), DEVICE_B);
2047 CheckIdentify(autoObserver);
2048 RegisterNewObserver(rdb1, observer1, autoObserver);
2049 }
2050
2051 /**
2052 * @tc.name: remote query 001
2053 * @tc.desc: Test rdb remote query
2054 * @tc.type: FUNC
2055 * @tc.require: AR000GK58G
2056 * @tc.author: zhangqiquan
2057 */
2058 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery001, TestSize.Level1)
2059 {
2060 std::map<std::string, DataValue> dataMap;
2061 PrepareEnvironment(dataMap, {g_deviceB});
2062 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2063 RemoteCondition condition;
2064 condition.sql = "SELECT * FROM " + g_tableName;
2065 std::shared_ptr<ResultSet> result = nullptr;
2066 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_B, condition, DBConstant::MIN_TIMEOUT, result), OK);
2067
2068 EXPECT_NE(result, nullptr);
2069 }
2070
2071 /**
2072 * @tc.name: remote query 002
2073 * @tc.desc: Test rdb remote query
2074 * @tc.type: FUNC
2075 * @tc.require: AR000GK58G
2076 * @tc.author: zhangqiquan
2077 */
2078 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery002, TestSize.Level1)
2079 {
2080 std::map<std::string, DataValue> dataMap;
2081 PrepareEnvironment(dataMap, {g_deviceB});
2082 ASSERT_NE(g_deviceB, nullptr);
2083 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2084 RemoteCondition condition;
2085 condition.sql = "SELECT * FROM " + g_tableName;
2086 std::shared_ptr<ResultSet> result = nullptr;
2087 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result), OK);
2088 CheckSearchData(result, dataMap);
2089 }
2090
2091 /**
2092 * @tc.name: remote query 003
2093 * @tc.desc: Test rdb remote query but query not data
2094 * @tc.type: FUNC
2095 * @tc.require: AR000GK58G
2096 * @tc.author: zhangqiquan
2097 */
2098 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery003, TestSize.Level1)
2099 {
2100 std::map<std::string, DataValue> dataMap;
2101 PrepareEnvironment(dataMap, {g_deviceB});
2102 ASSERT_NE(g_deviceB, nullptr);
2103 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2104 RemoteCondition condition;
2105 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2106 std::shared_ptr<ResultSet> result = nullptr;
2107 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result), OK);
2108 ASSERT_NE(result, nullptr);
2109 EXPECT_EQ(result->GetCount(), 0);
2110 }
2111
2112 /**
2113 * @tc.name: remote query 004
2114 * @tc.desc: Test rdb queue size
2115 * @tc.type: FUNC
2116 * @tc.require: AR000GK58G
2117 * @tc.author: zhangqiquan
2118 */
2119 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery004, TestSize.Level3)
2120 {
2121 std::map<std::string, DataValue> dataMap;
2122 PrepareEnvironment(dataMap, {g_deviceB});
2123 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2124 RemoteCondition condition;
2125 condition.sql = "SELECT * FROM " + g_tableName;
2126 std::vector<std::string> deviceMap = {DEVICE_B, DEVICE_C};
__anond45d0a2b1902(const std::string &device, Message *inMsg) 2127 g_communicatorAggregator->RegOnDispatch([](const std::string &device, Message *inMsg) {
2128 ASSERT_NE(inMsg, nullptr);
2129 inMsg->SetMessageId(INVALID_MESSAGE_ID);
2130 });
2131 const size_t MAX_SIZE = 7;
2132 std::vector<std::thread *> threadList;
2133 for (size_t j = 0; j < deviceMap.size(); j++) {
2134 for (size_t i = 0; i < MAX_SIZE; i++) {
2135 std::string device = deviceMap[j];
__anond45d0a2b1a02() 2136 threadList.push_back(new std::thread([&, device]() {
2137 std::shared_ptr<ResultSet> result = nullptr;
2138 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(device, condition,
2139 DBConstant::MIN_TIMEOUT, result), TIME_OUT);
2140 EXPECT_EQ(result, nullptr);
2141 }));
2142 }
2143 }
2144 for (size_t i = 0; i < threadList.size(); i++) {
2145 threadList[i]->join();
2146 delete threadList[i];
2147 threadList[i] = nullptr;
2148 }
2149 }
2150
2151 /**
2152 * @tc.name: remote query 005
2153 * @tc.desc: Test rdb remote query timeout by invalid message
2154 * @tc.type: FUNC
2155 * @tc.require: AR000GK58G
2156 * @tc.author: zhangqiquan
2157 */
2158 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery005, TestSize.Level1)
2159 {
2160 std::map<std::string, DataValue> dataMap;
2161 PrepareEnvironment(dataMap, {g_deviceB});
2162 ASSERT_NE(g_deviceB, nullptr);
2163 ASSERT_NE(g_rdbDelegatePtr, nullptr);
__anond45d0a2b1b02(const std::string &device, Message *inMsg) 2164 g_communicatorAggregator->RegOnDispatch([](const std::string &device, Message *inMsg) {
2165 ASSERT_NE(inMsg, nullptr);
2166 inMsg->SetMessageId(INVALID_MESSAGE_ID);
2167 });
2168 RemoteCondition condition;
2169 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2170 std::shared_ptr<ResultSet> result = nullptr;
2171 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_B, condition, DBConstant::MIN_TIMEOUT, result), TIME_OUT);
2172 ASSERT_EQ(result, nullptr);
2173 }
2174
2175 /**
2176 * @tc.name: remote query 006
2177 * @tc.desc: Test rdb remote query commfailure by offline
2178 * @tc.type: FUNC
2179 * @tc.require: AR000GK58G
2180 * @tc.author: zhangqiquan
2181 */
2182 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery006, TestSize.Level1)
2183 {
2184 std::map<std::string, DataValue> dataMap;
2185 PrepareEnvironment(dataMap, {g_deviceB});
2186 ASSERT_NE(g_deviceB, nullptr);
2187 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2188 std::thread offlineThread;
2189 std::atomic<bool> offline = false;
__anond45d0a2b1c02(const std::string &device, Message *inMsg) 2190 g_communicatorAggregator->RegOnDispatch([&offlineThread, &offline](const std::string &device, Message *inMsg) {
2191 ASSERT_NE(inMsg, nullptr);
2192 inMsg->SetMessageId(INVALID_MESSAGE_ID);
2193 if (offline) {
2194 return;
2195 }
2196 offline = true;
2197 std::thread t([]() {
2198 g_deviceB->Offline();
2199 });
2200 offlineThread = std::move(t);
2201 });
2202 RemoteCondition condition;
2203 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2204 std::shared_ptr<ResultSet> result = nullptr;
2205 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_B, condition, DBConstant::MIN_TIMEOUT, result), COMM_FAILURE);
2206 ASSERT_EQ(result, nullptr);
2207 if (offline) {
2208 offlineThread.join();
2209 }
2210 }
2211
2212 /**
2213 * @tc.name: remote query 007
2214 * @tc.desc: Test rdb remote query failed by permission check
2215 * @tc.type: FUNC
2216 * @tc.require: AR000GK58G
2217 * @tc.author: zhangqiquan
2218 */
2219 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery007, TestSize.Level1)
2220 {
2221 std::map<std::string, DataValue> dataMap;
2222 PrepareEnvironment(dataMap, {g_deviceB});
2223 ASSERT_NE(g_deviceB, nullptr);
2224 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2225 PermissionCheckCallbackV2 callback = [](const std::string &userId, const std::string &appId,
__anond45d0a2b1e02(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 2226 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
2227 return false;
2228 };
2229 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(callback), OK);
2230 RemoteCondition condition;
2231 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2232 std::shared_ptr<ResultSet> result = nullptr;
2233 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result),
2234 PERMISSION_CHECK_FORBID_SYNC);
2235 ASSERT_EQ(result, nullptr);
2236 callback = nullptr;
2237 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(callback), OK);
2238 }
2239
2240 /**
2241 * @tc.name: remote query 008
2242 * @tc.desc: Test rdb remote query timeout but not effected by invalid message
2243 * @tc.type: FUNC
2244 * @tc.require: AR000GK58G
2245 * @tc.author: zhangqiquan
2246 */
2247 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery008, TestSize.Level1)
2248 {
2249 std::map<std::string, DataValue> dataMap;
2250 PrepareEnvironment(dataMap, {g_deviceB});
2251 ASSERT_NE(g_deviceB, nullptr);
2252 ASSERT_NE(g_rdbDelegatePtr, nullptr);
__anond45d0a2b1f02(const std::string &device, Message *inMsg) 2253 g_communicatorAggregator->RegOnDispatch([](const std::string &device, Message *inMsg) {
2254 ASSERT_NE(inMsg, nullptr);
2255 if (device != DEVICE_B) {
2256 return;
2257 }
2258 inMsg->SetMessageId(INVALID_MESSAGE_ID);
2259 std::thread t([]() {
2260 auto *msg = new (std::nothrow) Message(REMOTE_EXECUTE_MESSAGE);
2261 ASSERT_NE(msg, nullptr);
2262 auto *packet = new (std::nothrow) RemoteExecutorAckPacket();
2263 if (packet != nullptr) {
2264 packet->SetAckCode(-E_FEEDBACK_COMMUNICATOR_NOT_FOUND);
2265 }
2266 if (msg->SetExternalObject(packet) != E_OK) {
2267 delete packet;
2268 packet = nullptr;
2269 }
2270 msg->SetMessageType(TYPE_RESPONSE);
2271 msg->SetErrorNo(E_FEEDBACK_COMMUNICATOR_NOT_FOUND);
2272 msg->SetSessionId(0u);
2273 msg->SetSequenceId(1u);
2274 g_communicatorAggregator->DispatchMessage(DEVICE_B, DEVICE_A, msg, nullptr);
2275 LOGD("DispatchMessage Finish");
2276 });
2277 t.detach();
2278 });
2279 RemoteCondition condition;
2280 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2281 std::shared_ptr<ResultSet> result = nullptr;
2282 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_B, condition, DBConstant::MIN_TIMEOUT, result), TIME_OUT);
2283 ASSERT_EQ(result, nullptr);
2284 }
2285
2286 /**
2287 * @tc.name: remote query 009
2288 * @tc.desc: Test rdb remote query busy before timeout
2289 * @tc.type: FUNC
2290 * @tc.require: AR000GK58G
2291 * @tc.author: zhangqiquan
2292 */
2293 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery009, TestSize.Level1)
2294 {
2295 std::map<std::string, DataValue> dataMap;
2296 PrepareEnvironment(dataMap, {g_deviceB});
2297 ASSERT_NE(g_deviceB, nullptr);
2298 ASSERT_NE(g_rdbDelegatePtr, nullptr);
__anond45d0a2b2102(const std::string &device, Message *inMsg) 2299 g_communicatorAggregator->RegOnDispatch([](const std::string &device, Message *inMsg) {
2300 ASSERT_NE(inMsg, nullptr);
2301 inMsg->SetMessageId(INVALID_MESSAGE_ID);
2302 });
2303 RemoteCondition condition;
2304 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2305 std::shared_ptr<ResultSet> result = nullptr;
__anond45d0a2b2202() 2306 std::thread t([]() {
2307 std::this_thread::sleep_for(std::chrono::seconds(1));
2308 if (g_rdbDelegatePtr != nullptr) {
2309 LOGD("CloseStore Start");
2310 ASSERT_EQ(g_mgr.CloseStore(g_rdbDelegatePtr), OK);
2311 g_rdbDelegatePtr = nullptr;
2312 }
2313 });
2314 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_B, condition, DBConstant::MIN_TIMEOUT, result), BUSY);
2315 ASSERT_EQ(result, nullptr);
2316 t.join();
2317 }
2318
2319 /**
2320 * @tc.name: remote query 010
2321 * @tc.desc: Test rdb remote query with kv db
2322 * @tc.type: FUNC
2323 * @tc.require: AR000GK58G
2324 * @tc.author: zhangqiquan
2325 */
2326 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery010, TestSize.Level1)
2327 {
2328 std::map<std::string, DataValue> dataMap;
2329 PrepareEnvironment(dataMap, {g_deviceB});
2330 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2331 RemoteCondition condition;
2332 condition.sql = "SELECT * FROM " + g_tableName;
2333 std::shared_ptr<ResultSet> result = nullptr;
2334 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(DEVICE_D, condition, DBConstant::MIN_TIMEOUT, result), NOT_SUPPORT);
2335
2336 EXPECT_EQ(result, nullptr);
2337 }
2338
2339 /**
2340 * @tc.name: remote query 010
2341 * @tc.desc: Test rdb remote query with error sql
2342 * @tc.type: FUNC
2343 * @tc.require: AR000GK58G
2344 * @tc.author: zhangqiquan
2345 */
2346 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery011, TestSize.Level1)
2347 {
2348 std::map<std::string, DataValue> dataMap;
2349 PrepareEnvironment(dataMap, {g_deviceB});
2350 ASSERT_NE(g_deviceB, nullptr);
2351 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2352 RemoteCondition condition;
2353 condition.sql = "This is error sql";
2354 std::shared_ptr<ResultSet> result = nullptr;
2355 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result), DB_ERROR);
2356 EXPECT_EQ(result, nullptr);
2357 }
2358
2359 /**
2360 * @tc.name: remote query 012
2361 * @tc.desc: Test rdb remote query with invalid dev
2362 * @tc.type: FUNC
2363 * @tc.require: AR000GK58G
2364 * @tc.author: zhangqiquan
2365 */
2366 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery012, TestSize.Level1)
2367 {
2368 std::map<std::string, DataValue> dataMap;
2369 std::string invalidDev = std::string(DBConstant::MAX_DEV_LENGTH + 1, '0');
2370 PrepareEnvironment(dataMap, {g_deviceB});
2371 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2372 RemoteCondition condition;
2373 condition.sql = "SELECT * FROM " + g_tableName;
2374 std::shared_ptr<ResultSet> result = nullptr;
2375 EXPECT_EQ(g_rdbDelegatePtr->RemoteQuery(invalidDev, condition, DBConstant::MIN_TIMEOUT, result), INVALID_ARGS);
2376 EXPECT_EQ(result, nullptr);
2377 }
2378
2379 /**
2380 * @tc.name: remote query 013
2381 * @tc.desc: Test rdb remote query deny fts3_tokenizer
2382 * @tc.type: FUNC
2383 * @tc.require:
2384 * @tc.author: zhangqiquan
2385 */
2386 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RemoteQuery013, TestSize.Level0)
2387 {
2388 std::map<std::string, DataValue> dataMap;
2389 PrepareEnvironment(dataMap, {g_deviceB});
2390 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2391 RemoteCondition condition;
2392 condition.sql = "SELECT hex(fts3_tokenizer('simple'))";
2393 std::shared_ptr<ResultSet> result = nullptr;
2394 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result), DB_ERROR);
2395 EXPECT_EQ(result, nullptr);
2396 }
2397
2398 /**
2399 * @tc.name: RelationalPemissionTest001
2400 * @tc.desc: deviceB PermissionCheck not pass test, SYNC_MODE_PUSH_ONLY
2401 * @tc.type: FUNC
2402 * @tc.require: AR000GK58N
2403 * @tc.author: zhangshijie
2404 */
2405 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RelationalPemissionTest001, TestSize.Level0)
2406 {
2407 /**
2408 * @tc.steps: step1. SetPermissionCheckCallback
2409 * @tc.expected: step1. return OK.
2410 */
2411 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId,
__anond45d0a2b2302(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 2412 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
2413 LOGE("u: %s, a: %s, s: %s", userId.c_str(), appId.c_str(), storeId.c_str());
2414 bool empty = userId.empty() || appId.empty() || storeId.empty();
2415 EXPECT_TRUE(empty == false);
2416 if (flag & (CHECK_FLAG_SEND)) {
2417 LOGD("in RunPermissionCheck callback, check not pass, flag:%d", flag);
2418 return false;
2419 } else {
2420 LOGD("in RunPermissionCheck callback, check pass, flag:%d", flag);
2421 return true;
2422 }
2423 };
2424 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
2425
2426 /**
2427 * @tc.steps: step2. sync with deviceB
2428 */
2429 std::map<std::string, DataValue> dataMap;
2430 PrepareEnvironment(dataMap, { g_deviceB });
2431 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, PERMISSION_CHECK_FORBID_SYNC, { DEVICE_B });
2432
2433 /**
2434 * @tc.steps: step3. check data in deviceB
2435 * @tc.expected: step3. deviceB has no data
2436 */
2437 std::vector<VirtualRowData> targetData;
2438 g_deviceB->GetAllSyncData(g_tableName, targetData);
2439
2440 ASSERT_EQ(targetData.size(), 0u);
2441 }
2442
2443 /**
2444 * @tc.name: RelationalPemissionTest002
2445 * @tc.desc: deviceB PermissionCheck not pass test, SYNC_MODE_PULL_ONLY
2446 * @tc.type: FUNC
2447 * @tc.require: AR000GK58N
2448 * @tc.author: zhangshijie
2449 */
2450 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RelationalPemissionTest002, TestSize.Level0)
2451 {
2452 /**
2453 * @tc.steps: step1. SetPermissionCheckCallback
2454 * @tc.expected: step1. return OK.
2455 */
2456 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId,
__anond45d0a2b2402(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 2457 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
2458 LOGE("u: %s, a: %s, s: %s", userId.c_str(), appId.c_str(), storeId.c_str());
2459 bool empty = userId.empty() || appId.empty() || storeId.empty();
2460 EXPECT_TRUE(empty == false);
2461 if (flag & (CHECK_FLAG_RECEIVE)) {
2462 LOGD("in RunPermissionCheck callback, check not pass, flag:%d", flag);
2463 return false;
2464 } else {
2465 LOGD("in RunPermissionCheck callback, check pass, flag:%d", flag);
2466 return true;
2467 }
2468 };
2469 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
2470
2471 /**
2472 * @tc.steps: step2. sync with deviceB
2473 */
2474 std::map<std::string, DataValue> dataMap;
2475 PrepareEnvironment(dataMap, { g_deviceB });
2476 BlockSync(SyncMode::SYNC_MODE_PULL_ONLY, PERMISSION_CHECK_FORBID_SYNC, { DEVICE_B });
2477
2478 /**
2479 * @tc.steps: step3. check data in deviceB
2480 * @tc.expected: step3. deviceB has no data
2481 */
2482 std::vector<VirtualRowData> targetData;
2483 g_deviceB->GetAllSyncData(g_tableName, targetData);
2484
2485 ASSERT_EQ(targetData.size(), 0u);
2486 }
2487
2488 /**
2489 * @tc.name: RelationalPemissionTest003
2490 * @tc.desc: deviceB PermissionCheck not pass test, flag CHECK_FLAG_SPONSOR
2491 * @tc.type: FUNC
2492 * @tc.require: AR000GK58N
2493 * @tc.author: zhangshijie
2494 */
2495 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RelationalPemissionTest003, TestSize.Level0)
2496 {
2497 /**
2498 * @tc.steps: step1. SetPermissionCheckCallback
2499 * @tc.expected: step1. return OK.
2500 */
2501 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId,
__anond45d0a2b2502(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 2502 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
2503 LOGE("u: %s, a: %s, s: %s", userId.c_str(), appId.c_str(), storeId.c_str());
2504 bool empty = userId.empty() || appId.empty() || storeId.empty();
2505 EXPECT_TRUE(empty == false);
2506 if (flag & CHECK_FLAG_SPONSOR) {
2507 LOGD("in RunPermissionCheck callback, check not pass, flag:%d", flag);
2508 return false;
2509 } else {
2510 LOGD("in RunPermissionCheck callback, check pass, flag:%d", flag);
2511 return true;
2512 }
2513 };
2514 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
2515
2516 /**
2517 * @tc.steps: step2. sync with deviceB
2518 */
2519 std::map<std::string, DataValue> dataMap;
2520 PrepareEnvironment(dataMap, { g_deviceB });
2521 BlockSync(SyncMode::SYNC_MODE_PULL_ONLY, PERMISSION_CHECK_FORBID_SYNC, { DEVICE_B });
2522
2523 /**
2524 * @tc.steps: step3. check data in deviceB
2525 * @tc.expected: step3. deviceB has no data
2526 */
2527 std::vector<VirtualRowData> targetData;
2528 g_deviceB->GetAllSyncData(g_tableName, targetData);
2529
2530 ASSERT_EQ(targetData.size(), 0u);
2531 }
2532
2533 /**
2534 * @tc.name: RelationalPemissionTest004
2535 * @tc.desc: deviceB PermissionCheck pass test. deviceC not pass, SYNC_MODE_PUSH_ONLY
2536 * @tc.type: FUNC
2537 * @tc.require: AR000GK58N
2538 * @tc.author: zhangshijie
2539 */
2540 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RelationalPemissionTest004, TestSize.Level0)
2541 {
2542 /**
2543 * @tc.steps: step1. SetPermissionCheckCallback
2544 * @tc.expected: step1. return OK.
2545 */
2546 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId,
__anond45d0a2b2602(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 2547 const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
2548 LOGE("u: %s, a: %s, s: %s", userId.c_str(), appId.c_str(), storeId.c_str());
2549 if (deviceId == g_deviceC->GetDeviceId()) {
2550 LOGE("in RunPermissionCheck callback, check pass, device:%s", deviceId.c_str());
2551 return false;
2552 } else {
2553 LOGE("in RunPermissionCheck callback, check not pass, device:%s", deviceId.c_str());
2554 return true;
2555 }
2556 };
2557 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
2558
2559 std::map<std::string, DataValue> dataMap;
2560 PrepareEnvironment(dataMap, { g_deviceB, g_deviceC });
2561
2562 /**
2563 * @tc.steps: step2. sync with deviceB
2564 */
2565 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, { DEVICE_B });
2566
2567 /**
2568 * @tc.steps: step3. check data in deviceB
2569 * @tc.expected: step3. deviceB has data
2570 */
2571 std::vector<VirtualRowData> targetData;
2572 g_deviceB->GetAllSyncData(g_tableName, targetData);
2573 ASSERT_EQ(targetData.size(), 1u);
2574
2575 /**
2576 * @tc.steps: step4. sync with deviceC
2577 */
2578 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, PERMISSION_CHECK_FORBID_SYNC, { DEVICE_C });
2579
2580 /**
2581 * @tc.steps: step5. check data in deviceC
2582 * @tc.expected: step5. deviceC has no data
2583 */
2584 targetData.clear();
2585 g_deviceC->GetAllSyncData(g_tableName, targetData);
2586 ASSERT_EQ(targetData.size(), 0u);
2587 }
2588
2589 /**
2590 * @tc.name: SecurityOptionCheck001
2591 * @tc.desc: Test sync failed when getSecurityOption return error
2592 * @tc.type: FUNC
2593 * @tc.require: AR000GK58N
2594 * @tc.author: zhangqiquan
2595 */
2596 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, SecurityOptionCheck001, TestSize.Level1)
2597 {
2598 std::vector<std::string> devices;
2599 devices.push_back(g_deviceB->GetDeviceId());
2600
2601 /**
2602 * @tc.steps: step1. make getSecurityOption return -1
2603 */
2604 std::shared_ptr<ProcessSystemApiAdapterImpl> adapter = std::make_shared<ProcessSystemApiAdapterImpl>();
2605 adapter->ForkGetSecurityOption(
__anond45d0a2b2702(const std::string &filePath, SecurityOption &option) 2606 [](const std::string &filePath, SecurityOption &option) {
2607 (void)filePath;
2608 (void)option;
2609 return DB_ERROR;
2610 });
2611 RuntimeConfig::SetProcessSystemAPIAdapter(adapter);
2612
2613 std::map<std::string, DataValue> dataMap;
2614 PrepareEnvironment(dataMap, { g_deviceB });
2615
2616 /**
2617 * @tc.steps: step2. sync with deviceB
2618 */
2619 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, SECURITY_OPTION_CHECK_ERROR, { DEVICE_B });
2620 RuntimeConfig::SetProcessSystemAPIAdapter(nullptr);
2621 }
2622
2623 /**
2624 * @tc.name: SecurityOptionCheck002
2625 * @tc.desc: Test remote query failed when getSecurityOption return error
2626 * @tc.type: FUNC
2627 * @tc.require: AR000GK58G
2628 * @tc.author: zhangqiquan
2629 */
2630 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, SecurityOptionCheck002, TestSize.Level1)
2631 {
2632 /**
2633 * @tc.steps: step1. make getSecurityOption return -1
2634 */
2635 std::shared_ptr<ProcessSystemApiAdapterImpl> adapter = std::make_shared<ProcessSystemApiAdapterImpl>();
2636 adapter->ForkGetSecurityOption(
__anond45d0a2b2802(const std::string &filePath, SecurityOption &option) 2637 [](const std::string &filePath, SecurityOption &option) {
2638 (void)filePath;
2639 (void)option;
2640 return DB_ERROR;
2641 });
2642 RuntimeConfig::SetProcessSystemAPIAdapter(adapter);
2643
2644 /**
2645 * @tc.steps: step2. remote query with deviceB
2646 */
2647 std::map<std::string, DataValue> dataMap;
2648 PrepareEnvironment(dataMap, {g_deviceB});
2649 ASSERT_NE(g_deviceB, nullptr);
2650 ASSERT_NE(g_rdbDelegatePtr, nullptr);
2651 RemoteCondition condition;
2652 condition.sql = "SELECT * FROM " + g_tableName + " WHERE 1=0";
2653 std::shared_ptr<ResultSet> result = nullptr;
2654 EXPECT_EQ(g_deviceB->RemoteQuery(DEVICE_A, condition, DBConstant::MIN_TIMEOUT, result),
2655 SECURITY_OPTION_CHECK_ERROR);
2656 EXPECT_EQ(result, nullptr);
2657 RuntimeConfig::SetProcessSystemAPIAdapter(nullptr);
2658 }
2659
2660 /**
2661 * @tc.name: OrderbyWriteTimeSync001
2662 * @tc.desc: sync query with order by writeTime
2663 * @tc.type: FUNC
2664 * @tc.require: AR000H5VLO
2665 * @tc.author: zhuwentao
2666 */
2667 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, OrderbyWriteTimeSync001, TestSize.Level0)
2668 {
2669 std::map<std::string, DataValue> dataMap;
2670 PrepareEnvironment(dataMap, {g_deviceB});
2671 Query query = Query::Select(g_tableName).OrderByWriteTime(true);;
2672 EXPECT_EQ(g_rdbDelegatePtr->Sync({DEVICE_B}, DistributedDB::SYNC_MODE_PUSH_ONLY, query, nullptr, false),
2673 NOT_SUPPORT);
2674 }
2675
2676 /**
2677 * @tc.name: RDBSecurityOptionCheck001
2678 * @tc.desc: Test sync with security option.
2679 * @tc.type: FUNC
2680 * @tc.require: AR000GK58N
2681 * @tc.author: zhangqiquan
2682 */
2683 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RDBSecurityOptionCheck001, TestSize.Level3)
2684 {
2685 TestWithSecurityCheck(false);
2686 }
2687
2688 /**
2689 * @tc.name: RDBSecurityOptionCheck002
2690 * @tc.desc: Test remote query with security option.
2691 * @tc.type: FUNC
2692 * @tc.require: AR000GK58N
2693 * @tc.author: zhangqiquan
2694 */
2695 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, RDBSecurityOptionCheck002, TestSize.Level1)
2696 {
2697 TestWithSecurityCheck(true);
2698 }
2699
2700 /**
2701 * @tc.name: EncryptedAlgoUpgrade001
2702 * @tc.desc: Test upgrade encrypted db can sync normally
2703 * @tc.type: FUNC
2704 * @tc.require: AR000HI2JS
2705 * @tc.author: zhuwentao
2706 */
2707 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, EncryptedAlgoUpgrade001, TestSize.Level0)
2708 {
2709 if (g_rdbDelegatePtr != nullptr) {
2710 LOGD("CloseStore Start");
2711 ASSERT_EQ(g_mgr.CloseStore(g_rdbDelegatePtr), OK);
2712 g_rdbDelegatePtr = nullptr;
2713 }
2714 EXPECT_EQ(OS::RemoveFile(g_dbDir), E_OK);
2715 /**
2716 * @tc.steps: step1. open old db use sha1 algo and insert some data
2717 * @tc.expected: step1. interface return ok
2718 */
2719 sqlite3 *db = nullptr;
2720 EXPECT_EQ(GetDB(db, false), SQLITE_OK);
2721 const std::string user_version_sql = "PRAGMA user_version=101;";
2722 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, user_version_sql), E_OK);
2723 sqlite3_close(db);
2724
2725 /**
2726 * @tc.steps: step2. open db by OpenStore
2727 * @tc.expected: step2. interface return ok
2728 */
2729 OpenStore();
2730 /**
2731 * @tc.steps: step3. sync with push
2732 * @tc.expected: step3. interface return ok
2733 */
2734 std::map<std::string, DataValue> dataMap;
2735 PrepareEnvironment(dataMap, {g_deviceB});
2736 BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B});
2737 CheckVirtualData(dataMap);
2738 dataMap.clear();
2739
2740 /**
2741 * @tc.steps: step4. sync with pull
2742 * @tc.expected: step4. interface return ok
2743 */
2744
2745 Query query = Query::Select(g_tableName);
2746 g_deviceB->GenericVirtualDevice::Sync(DistributedDB::SYNC_MODE_PULL_ONLY, query, true);
2747 CheckVirtualData(dataMap);
2748 }
2749
2750 /**
2751 * @tc.name: QueryParamCheck001
2752 * @tc.desc: Test sync query param
2753 * @tc.type: FUNC
2754 * @tc.require:
2755 * @tc.author: zhangqiquan
2756 */
2757 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, QueryParamCheck001, TestSize.Level0)
2758 {
2759 std::map<std::string, DataValue> dataMap;
2760 PrepareEnvironment(dataMap, {g_deviceB});
2761 Query query = Query::Select().FromTable({ g_tableName });
2762 EXPECT_EQ(g_rdbDelegatePtr->Sync({DEVICE_B}, DistributedDB::SYNC_MODE_PUSH_ONLY, query, nullptr, false),
2763 NOT_SUPPORT);
2764 }
2765
2766 #ifndef OMIT_ENCRYPT
2767 /**
2768 * @tc.name: AutoLaunchSyncAfterRekey_001
2769 * @tc.desc: Test auto launch sync ok after rekey.
2770 * @tc.type: FUNC
2771 * @tc.require: AR000H68LL
2772 * @tc.author: lidongwei
2773 */
2774 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSyncAfterRekey_001, TestSize.Level3)
2775 {
2776 /**
2777 * @tc.steps: step1. open rdb store, create distribute table and insert data
2778 */
2779 std::map<std::string, DataValue> dataMap;
2780 PrepareVirtualEnvironment(dataMap, {g_deviceB});
2781
2782 /**
2783 * @tc.steps: step2. set auto launch callBack
2784 */
2785 AutoLaunchParam encryptedParam { USER_ID, APP_ID, STORE_ID_1, AutoLaunchOption {}, nullptr, g_dbDir };
2786 encryptedParam.option.isEncryptedDb = true;
2787 encryptedParam.option.cipher = CipherType::DEFAULT;
2788 encryptedParam.option.passwd = g_correctPasswd;
2789 encryptedParam.option.iterateTimes = DEFAULT_ITER;
__anond45d0a2b2902(const std::string &identifier, AutoLaunchParam ¶m) 2790 AutoLaunchRequestCallback callback = [&encryptedParam](const std::string &identifier, AutoLaunchParam ¶m) {
2791 if (g_id != identifier) {
2792 return false;
2793 }
2794 param = encryptedParam;
2795 return true;
2796 };
2797 g_mgr.SetAutoLaunchRequestCallback(callback);
2798 /**
2799 * @tc.steps: step3. close store ensure communicator has closed
2800 */
2801 g_mgr.CloseStore(g_rdbDelegatePtr);
2802 g_rdbDelegatePtr = nullptr;
2803 /**
2804 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
2805 */
2806 LabelType labelType(g_id.begin(), g_id.end());
2807 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
2808 std::this_thread::sleep_for(std::chrono::seconds(1));
2809
2810 /**
2811 * @tc.steps: step5. Rekey
2812 */
2813 sqlite3 *db = nullptr;
2814 EXPECT_EQ(GetDB(db), SQLITE_OK);
__anond45d0a2b2a02null2815 std::thread t1([&db] {
2816 std::string sql = "PARGMA rekey=" + REKEY_KEY;
2817 EXPECT_EQ(sqlite3_rekey(db, REKEY_KEY.data(), REKEY_KEY.size()), SQLITE_OK);
2818 });
2819 t1.join();
2820 g_isAfterRekey = true;
2821
2822 /**
2823 * @tc.steps: step6. Call sync expect sync failed
2824 */
2825 Query query = Query::Select(g_tableName);
2826 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
2827 size_t count = 0;
2828 GetCount(db, "SELECT count(*) FROM sqlite_master WHERE name='" + GetDeviceTableName(g_tableName) + "';", count);
2829 EXPECT_EQ(count, 0u);
2830
2831 /**
2832 * @tc.steps: step7. Set callback.
2833 */
2834 encryptedParam.option.passwd = g_rekeyPasswd;
2835 g_mgr.SetAutoLaunchRequestCallback(callback);
2836 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
2837 std::this_thread::sleep_for(std::chrono::seconds(2));
2838
2839 /**
2840 * @tc.steps: step8. Call sync expect sync success
2841 */
2842 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
2843 GetCount(db, "SELECT count(*) FROM sqlite_master WHERE name='" + GetDeviceTableName(g_tableName) + "';", count);
2844 EXPECT_EQ(count, 1u);
2845 GetSyncData(db, dataMap, g_tableName, g_fieldInfoList);
2846 EXPECT_EQ(dataMap.size(), 3u);
2847 OpenStore();
2848 std::this_thread::sleep_for(std::chrono::minutes(1));
2849 sqlite3_close(db);
2850 db = nullptr;
2851 }
2852
2853 /**
2854 * @tc.name: AutoLaunchSyncAfterRekey_002
2855 * @tc.desc: Test auto launch close check after rekey.
2856 * @tc.type: FUNC
2857 * @tc.require: AR000H68LL
2858 * @tc.author: zhangqiquan
2859 */
2860 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSyncAfterRekey_002, TestSize.Level3)
2861 {
2862 /**
2863 * @tc.steps: step1. open rdb store, create distribute table and insert data
2864 */
2865 std::map<std::string, DataValue> dataMap;
2866 PrepareVirtualEnvironment(dataMap, {g_deviceB});
2867 /**
2868 * @tc.steps: step2. set auto launch callBack
2869 */
2870 AutoLaunchParam encryptedParam { USER_ID, APP_ID, STORE_ID_1, AutoLaunchOption {}, nullptr, g_dbDir };
2871 encryptedParam.option.isEncryptedDb = true;
2872 encryptedParam.option.cipher = CipherType::DEFAULT;
2873 encryptedParam.option.passwd = g_correctPasswd;
2874 encryptedParam.option.iterateTimes = DEFAULT_ITER;
__anond45d0a2b2b02(const std::string &identifier, AutoLaunchParam ¶m) 2875 AutoLaunchRequestCallback callback = [&encryptedParam](const std::string &identifier, AutoLaunchParam ¶m) {
2876 param = encryptedParam;
2877 return true;
2878 };
2879 RelationalStoreManager::SetAutoLaunchRequestCallback(callback);
2880 /**
2881 * @tc.steps: step3. close store ensure communicator has closed
2882 */
2883 g_mgr.CloseStore(g_rdbDelegatePtr);
2884 g_rdbDelegatePtr = nullptr;
2885 /**
2886 * @tc.steps: step4. RunCommunicatorLackCallback to autolaunch store
2887 */
2888 LabelType labelType(g_id.begin(), g_id.end());
2889 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
2890 std::this_thread::sleep_for(std::chrono::seconds(2)); // wait 2s for auto launch
2891 /**
2892 * @tc.steps: step5. Rekey
2893 */
2894 sqlite3 *db = nullptr;
2895 EXPECT_EQ(GetDB(db), SQLITE_OK);
2896 std::string sql = "PARGMA rekey=" + REKEY_KEY;
2897 EXPECT_EQ(sqlite3_rekey(db, REKEY_KEY.data(), REKEY_KEY.size()), SQLITE_OK);
2898 g_isAfterRekey = true;
2899
2900 RelationalDBProperties properties;
2901 properties.SetStringProp(DBProperties::USER_ID, USER_ID);
2902 properties.SetStringProp(DBProperties::APP_ID, APP_ID);
2903 properties.SetStringProp(DBProperties::STORE_ID, STORE_ID_1);
2904 properties.SetIntProp(DBProperties::AUTO_LAUNCH_ID, 7); // 7: invalid AUTO LAUNCH ID
2905 const string &id = RelationalStoreManager::GetRelationalStoreIdentifier(USER_ID, APP_ID, STORE_ID_1);
2906 properties.SetStringProp(DBProperties::IDENTIFIER_DATA, id);
2907 RuntimeContext::GetInstance()->CloseAutoLaunchConnection(DBTypeInner::DB_RELATION, properties);
2908
2909 encryptedParam.option.passwd = g_rekeyPasswd;
2910 RelationalStoreManager::SetAutoLaunchRequestCallback(callback);
2911 g_communicatorAggregator->RunCommunicatorLackCallback(labelType);
2912 std::this_thread::sleep_for(std::chrono::seconds(2)); // wait 2s for auto launch
2913
2914 Query query = Query::Select(g_tableName);
2915 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
2916 size_t count = 0;
2917 GetCount(db, "SELECT count(*) FROM sqlite_master WHERE name='" + GetDeviceTableName(g_tableName) + "';", count);
2918 EXPECT_EQ(count, 0u);
2919
2920 OpenStore();
2921 std::this_thread::sleep_for(std::chrono::minutes(1));
2922 sqlite3_close(db);
2923 db = nullptr;
2924 }
2925
2926 /**
2927 * @tc.name: AutoLaunchSyncAfterRekey_002
2928 * @tc.desc: Test AddSyncTarget will not cause heap_use_after_free
2929 * @tc.type: FUNC
2930 * @tc.require:
2931 * @tc.author: zhangshijie
2932 */
2933 HWTEST_F(DistributedDBRelationalVerP2PSyncTest, SyncTargetTest001, TestSize.Level1) {
2934 MockSyncTaskContext syncTaskContext;
2935 SyncOperation *operation = new SyncOperation(1, {}, 0, nullptr, false);
2936 EXPECT_NE(operation, nullptr);
__anond45d0a2b2c02() 2937 std::thread addTarget([&syncTaskContext, &operation]() {
2938 auto *newTarget = new (std::nothrow) SingleVerSyncTarget;
2939 EXPECT_NE(newTarget, nullptr);
2940 newTarget->SetTaskType(ISyncTarget::REQUEST);
2941 EXPECT_EQ(syncTaskContext.AddSyncTarget(newTarget), E_OK);
2942 newTarget->SetSyncOperation(operation);
2943 });
2944
__anond45d0a2b2d02() 2945 std::thread removeTarget([&syncTaskContext]() {
2946 syncTaskContext.ClearAllSyncTask();
2947 });
2948 addTarget.join();
2949 removeTarget.join();
2950 syncTaskContext.ClearAllSyncTask();
2951 RefObject::KillAndDecObjRef(operation);
2952 }
2953 }
2954 #endif
2955 #endif