1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <gtest/gtest.h>
16 #include <variant>
17
18 #include "cloud_db_sync_utils_test.h"
19 #include "distributeddb_data_generate_unit_test.h"
20 #include "distributeddb_tools_unit_test.h"
21 #include "rdb_data_generator.h"
22 #include "relational_store_client.h"
23 #include "relational_store_manager.h"
24 #include "relational_virtual_device.h"
25 #include "virtual_communicator_aggregator.h"
26
27 using namespace testing::ext;
28 using namespace DistributedDB;
29 using namespace DistributedDBUnitTest;
30 using namespace std;
31
32 namespace {
33 string g_testDir;
34
35 class DistributedDBRDBCollaborationTest : public testing::Test {
36 public:
37 static void SetUpTestCase();
38 static void TearDownTestCase();
39 void SetUp() override;
40 void TearDown() override;
41 protected:
42 static DataBaseSchema GetSchema();
43 static TableSchema GetTableSchema(bool upgrade = false, bool pkInStr = false);
44 void InitStore();
45 void InitDelegate(DistributedTableMode mode = DistributedTableMode::COLLABORATION);
46 void CloseDb();
47 std::string storePath_;
48 sqlite3 *db_ = nullptr;
49 RelationalStoreDelegate *delegate_ = nullptr;
50 VirtualCommunicatorAggregator *communicatorAggregator_ = nullptr;
51 RelationalVirtualDevice *deviceB_ = nullptr;
52 RelationalStoreObserverUnitTest *delegateObserver_ = nullptr;
53
54 static constexpr const char *DEVICE_SYNC_TABLE = "DEVICE_SYNC_TABLE";
55 static constexpr const char *DEVICE_SYNC_TABLE_UPGRADE = "DEVICE_SYNC_TABLE_UPGRADE";
56 static constexpr const char *DEVICE_SYNC_TABLE_AUTOINCREMENT = "DEVICE_SYNC_TABLE_AUTOINCREMENT";
57 static constexpr const char *CLOUD_SYNC_TABLE = "CLOUD_SYNC_TABLE";
58 static constexpr const char *BIG_COLUMNS_TABLE = "BIG_COLUMNS_TABLE";
59 static constexpr const char *INVALID_TABLE = "INVALID_TABLE";
60 };
61
SetUpTestCase()62 void DistributedDBRDBCollaborationTest::SetUpTestCase()
63 {
64 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
65 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
66 LOGE("rm test db files error!");
67 }
68 }
69
TearDownTestCase()70 void DistributedDBRDBCollaborationTest::TearDownTestCase()
71 {
72 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
73 LOGE("rm test db files error!");
74 }
75 }
76
SetUp()77 void DistributedDBRDBCollaborationTest::SetUp()
78 {
79 DistributedDBToolsUnitTest::PrintTestCaseInfo();
80 InitStore();
81 communicatorAggregator_ = new (std::nothrow) VirtualCommunicatorAggregator();
82 ASSERT_TRUE(communicatorAggregator_ != nullptr);
83 RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicatorAggregator_);
84
85 deviceB_ = new (std::nothrow) RelationalVirtualDevice(UnitTestCommonConstant::DEVICE_B);
86 ASSERT_NE(deviceB_, nullptr);
87 auto syncInterfaceB = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
88 ASSERT_NE(syncInterfaceB, nullptr);
89 ASSERT_EQ(deviceB_->Initialize(communicatorAggregator_, syncInterfaceB), E_OK);
90 }
91
TearDown()92 void DistributedDBRDBCollaborationTest::TearDown()
93 {
94 CloseDb();
95 if (deviceB_ != nullptr) {
96 delete deviceB_;
97 deviceB_ = nullptr;
98 }
99 if (delegateObserver_ != nullptr) {
100 delete delegateObserver_;
101 delegateObserver_ = nullptr;
102 }
103 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
104 LOGE("rm test db files error.");
105 }
106 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
107 communicatorAggregator_ = nullptr;
108 }
109
GetSchema()110 DataBaseSchema DistributedDBRDBCollaborationTest::GetSchema()
111 {
112 DataBaseSchema schema;
113 auto table = GetTableSchema();
114 schema.tables.push_back(table);
115 table.name = CLOUD_SYNC_TABLE;
116 schema.tables.push_back(table);
117 schema.tables.push_back(GetTableSchema(true));
118 return schema;
119 }
120
GetTableSchema(bool upgrade,bool pkInStr)121 TableSchema DistributedDBRDBCollaborationTest::GetTableSchema(bool upgrade, bool pkInStr)
122 {
123 TableSchema tableSchema;
124 tableSchema.name = upgrade ? DEVICE_SYNC_TABLE_UPGRADE : DEVICE_SYNC_TABLE;
125 Field field;
126 if (!pkInStr) {
127 field.primary = true;
128 }
129 field.type = TYPE_INDEX<int64_t>;
130 field.colName = "pk";
131 tableSchema.fields.push_back(field);
132 field.primary = false;
133 field.colName = "int_field1";
134 tableSchema.fields.push_back(field);
135 field.colName = "int_field2";
136 tableSchema.fields.push_back(field);
137 field.colName = "123";
138 field.type = TYPE_INDEX<std::string>;
139 if (pkInStr) {
140 field.primary = true;
141 }
142 tableSchema.fields.push_back(field);
143 if (upgrade) {
144 field.primary = false;
145 field.colName = "int_field_upgrade";
146 field.type = TYPE_INDEX<int64_t>;
147 tableSchema.fields.push_back(field);
148 }
149 return tableSchema;
150 }
151
InitStore()152 void DistributedDBRDBCollaborationTest::InitStore()
153 {
154 if (storePath_.empty()) {
155 storePath_ = g_testDir + "/" + STORE_ID_1 + ".db";
156 }
157 db_ = RelationalTestUtils::CreateDataBase(storePath_);
158 ASSERT_NE(db_, nullptr);
159 auto schema = GetSchema();
160 EXPECT_EQ(RDBDataGenerator::InitDatabase(schema, *db_), SQLITE_OK);
161 }
162
InitDelegate(DistributedTableMode mode)163 void DistributedDBRDBCollaborationTest::InitDelegate(DistributedTableMode mode)
164 {
165 if (delegateObserver_ == nullptr) {
166 delegateObserver_ = new (std::nothrow) RelationalStoreObserverUnitTest();
167 ASSERT_NE(delegateObserver_, nullptr);
168 delegateObserver_->SetCallbackDetailsType(static_cast<uint32_t>(CallbackDetailsType::DETAILED));
169 }
170 RelationalStoreManager mgr(APP_ID, USER_ID);
171 RelationalStoreDelegate::Option option;
172 option.tableMode = mode;
173 option.observer = delegateObserver_;
174 ASSERT_EQ(mgr.OpenStore(storePath_, STORE_ID_1, option, delegate_), OK);
175 ASSERT_NE(delegate_, nullptr);
176 }
177
CloseDb()178 void DistributedDBRDBCollaborationTest::CloseDb()
179 {
180 if (db_ != nullptr) {
181 sqlite3_close_v2(db_);
182 db_ = nullptr;
183 }
184 if (delegate_ != nullptr) {
185 RelationalStoreManager mgr(APP_ID, USER_ID);
186 EXPECT_EQ(mgr.CloseStore(delegate_), OK);
187 delegate_ = nullptr;
188 }
189 }
190
191 /**
192 * @tc.name: SetSchema001
193 * @tc.desc: Test set distributed schema.
194 * @tc.type: FUNC
195 * @tc.require:
196 * @tc.author: zqq
197 */
198 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema001, TestSize.Level1)
199 {
200 /**
201 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
202 * @tc.expected: step1.ok
203 */
204 ASSERT_NO_FATAL_FAILURE(InitDelegate());
205 auto schema = GetSchema();
206 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
207 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
208 EXPECT_EQ(delegate_->CreateDistributedTable(CLOUD_SYNC_TABLE, TableSyncType::CLOUD_COOPERATION), OK);
209 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", CLOUD_SYNC_TABLE);
210 auto distributedSchema = RDBDataGenerator::ParseSchema(schema);
211 for (auto &table : distributedSchema.tables) {
212 for (auto &field : table.fields) {
213 field.isSpecified = false;
214 }
215 }
216 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
217 /**
218 * @tc.steps: step2. Insert update delete local
219 * @tc.expected: step2.ok
220 */
221 EXPECT_EQ(RDBDataGenerator::InsertLocalDBData(0, 1, db_, GetTableSchema()), E_OK);
__anond430f6f20202(ClientChangedData &changedData) 222 EXPECT_EQ(RegisterClientObserver(db_, [](ClientChangedData &changedData) {
223 for (const auto &table : changedData.tableData) {
224 EXPECT_FALSE(table.second.isTrackedDataChange);
225 EXPECT_TRUE(table.second.isP2pSyncDataChange);
226 EXPECT_FALSE(table.second.isCloudSyncDataChange);
227 }
228 }), OK);
229 EXPECT_EQ(RDBDataGenerator::UpdateLocalDBData(0, 1, db_, GetTableSchema()), E_OK);
230 UnRegisterClientObserver(db_);
231 }
232
233 /**
234 * @tc.name: SetSchema002
235 * @tc.desc: Test upgrade table mode.
236 * @tc.type: FUNC
237 * @tc.require:
238 * @tc.author: zqq
239 */
240 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema002, TestSize.Level1)
241 {
242 /**
243 * @tc.steps: step1. Create cloud table in SPLIT_BY_DEVICE
244 * @tc.expected: step1.ok
245 */
246 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::SPLIT_BY_DEVICE));
247 EXPECT_EQ(delegate_->CreateDistributedTable(CLOUD_SYNC_TABLE, TableSyncType::CLOUD_COOPERATION), OK);
248 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", CLOUD_SYNC_TABLE);
249 CloseDb();
250 /**
251 * @tc.steps: step2. Create device table in COLLABORATION
252 * @tc.expected: step2.ok
253 */
254 ASSERT_NO_FATAL_FAILURE(InitDelegate());
255 auto schema = GetSchema();
256 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
257 EXPECT_EQ(delegate_->SetDistributedSchema(RDBDataGenerator::ParseSchema(schema)), OK);
258 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
259 CloseDb();
260 }
261
262 /**
263 * @tc.name: SetSchema003
264 * @tc.desc: Test set distributed schema.
265 * @tc.type: FUNC
266 * @tc.require:
267 * @tc.author: zqq
268 */
269 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema003, TestSize.Level1)
270 {
271 /**
272 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
273 * @tc.expected: step1.ok
274 */
275 ASSERT_NO_FATAL_FAILURE(InitDelegate());
276 auto schema = GetSchema();
277 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
278 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
279 EXPECT_EQ(delegate_->SetDistributedSchema(RDBDataGenerator::ParseSchema(schema, true)), OK);
280 /**
281 * @tc.steps: step2. Insert update delete local
282 * @tc.expected: step2.ok
283 */
284 EXPECT_EQ(RDBDataGenerator::InsertLocalDBData(0, 1, db_, GetTableSchema()), E_OK);
__anond430f6f20302(ClientChangedData &changedData) 285 EXPECT_EQ(RegisterClientObserver(db_, [](ClientChangedData &changedData) {
286 for (const auto &table : changedData.tableData) {
287 EXPECT_FALSE(table.second.isTrackedDataChange);
288 EXPECT_FALSE(table.second.isP2pSyncDataChange);
289 EXPECT_FALSE(table.second.isCloudSyncDataChange);
290 }
291 }), OK);
292 EXPECT_EQ(RDBDataGenerator::UpdateLocalDBData(0, 1, db_, GetTableSchema()), E_OK);
293 UnRegisterClientObserver(db_);
294 }
295
296 /**
297 * @tc.name: SetSchema004
298 * @tc.desc: Test create distributed table without schema.
299 * @tc.type: FUNC
300 * @tc.require:
301 * @tc.author: zqq
302 */
303 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema004, TestSize.Level0)
304 {
305 /**
306 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
307 * @tc.expected: step1.ok
308 */
309 ASSERT_NO_FATAL_FAILURE(InitDelegate());
310 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
311 }
312
GetDistributedSchema(const std::string & tableName,const std::vector<std::string> & fields)313 DistributedSchema GetDistributedSchema(const std::string &tableName, const std::vector<std::string> &fields)
314 {
315 DistributedTable table;
316 table.tableName = tableName;
317 for (const auto &fieldName : fields) {
318 DistributedField field;
319 field.isP2pSync = true;
320 field.colName = fieldName;
321 table.fields.push_back(field);
322 }
323 DistributedSchema schema;
324 schema.tables.push_back(table);
325 return schema;
326 }
327
328 /**
329 * @tc.name: SetSchema005
330 * @tc.desc: Test set distributed schema with invalid schema
331 * @tc.type: FUNC
332 * @tc.require:
333 * @tc.author: liaoyonghuang
334 */
335 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema005, TestSize.Level0)
336 {
337 /**
338 * @tc.steps: step1. Prepare db
339 * @tc.expected: step1.ok
340 */
341 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
342 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
343 /**
344 * @tc.steps: step2. Test set distributed schema with invalid table name
345 * @tc.expected: step2. return SCHEMA_MISMATCH
346 */
347 DistributedSchema schema1 = GetDistributedSchema("", {});
348 EXPECT_EQ(delegate_->SetDistributedSchema(schema1), SCHEMA_MISMATCH);
349 DistributedSchema schema2 = GetDistributedSchema("xxx", {});
350 EXPECT_EQ(delegate_->SetDistributedSchema(schema2), SCHEMA_MISMATCH);
351 /**
352 * @tc.steps: step3. Test set distributed schema with invalid fields
353 * @tc.expected: step3. return SCHEMA_MISMATCH OR DISTRIBUTED_FIELD_DECREASE
354 */
355 DistributedSchema schema3 = GetDistributedSchema(DEVICE_SYNC_TABLE, {});
356 EXPECT_EQ(delegate_->SetDistributedSchema(schema3), SCHEMA_MISMATCH);
357 DistributedSchema schema4 = GetDistributedSchema(DEVICE_SYNC_TABLE, {"xxx"});
358 EXPECT_EQ(delegate_->SetDistributedSchema(schema4), SCHEMA_MISMATCH);
359 DistributedSchema schema5 = GetDistributedSchema(DEVICE_SYNC_TABLE, {"pk", "int_field1"});
360 EXPECT_EQ(delegate_->SetDistributedSchema(schema5), OK);
361 DistributedSchema schema6 = GetDistributedSchema(DEVICE_SYNC_TABLE, {"pk"});
362 EXPECT_EQ(delegate_->SetDistributedSchema(schema6), DISTRIBUTED_FIELD_DECREASE);
363
364 /**
365 * @tc.steps: step4. Test set distributed schema with int_field1 but isP2pSync is false
366 * @tc.expected: step4. return DISTRIBUTED_FIELD_DECREASE
367 */
368 DistributedSchema distributedSchema1 = {0, {{DEVICE_SYNC_TABLE, {{"int_field1", false}}}}};
369 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema1), DISTRIBUTED_FIELD_DECREASE);
370 }
371
372 /**
373 * @tc.name: SetSchema006
374 * @tc.desc: Test register client observer
375 * @tc.type: FUNC
376 * @tc.require:
377 * @tc.author: liaoyonghuang
378 */
379 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema006, TestSize.Level1)
380 {
381 /**
382 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
383 * @tc.expected: step1.ok
384 */
385 ASSERT_NO_FATAL_FAILURE(InitDelegate());
386 DistributedSchema distributedSchema = GetDistributedSchema(DEVICE_SYNC_TABLE, {"pk", "int_field1"});
387 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
388 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
389 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
390 TrackerSchema trackerSchema = {
391 .tableName = DEVICE_SYNC_TABLE, .extendColNames = {"int_field1"}, .trackerColNames = {"int_field1"}
392 };
393 EXPECT_EQ(delegate_->SetTrackerTable(trackerSchema), OK);
394 /**
395 * @tc.steps: step2. Insert update local
396 * @tc.expected: step2.ok
397 */
__anond430f6f20402(ClientChangedData &changedData) 398 EXPECT_EQ(RegisterClientObserver(db_, [](ClientChangedData &changedData) {
399 for (const auto &table : changedData.tableData) {
400 EXPECT_TRUE(table.second.isTrackedDataChange);
401 EXPECT_TRUE(table.second.isP2pSyncDataChange);
402 EXPECT_FALSE(table.second.isCloudSyncDataChange);
403 }
404 }), OK);
405 EXPECT_EQ(RDBDataGenerator::InsertLocalDBData(0, 1, db_, GetTableSchema()), E_OK);
406 std::string sql = "update " + std::string(DEVICE_SYNC_TABLE) + " set int_field1 = int_field1 + 1 where pk = 0";
407 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
408
409 /**
410 * @tc.steps: step3. Insert data that pk = 0 and sync to real device
411 * @tc.expected: step3.ok
412 */
413 auto schema = GetSchema();
414 deviceB_->SetDistributedSchema(distributedSchema);
415 auto tableSchema = GetTableSchema();
416 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_, tableSchema), E_OK);
417 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
418 Query query = Query::Select(tableSchema.name);
419 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
420
421 /**
422 * @tc.steps: step4. Check extend_field
423 * @tc.expected: step4.ok
424 */
425 sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + std::string(DEVICE_SYNC_TABLE) + "_log"
426 " where json_extract(extend_field, '$.int_field1')=0";
427 EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
428 reinterpret_cast<void *>(1u), nullptr), SQLITE_OK);
429 UnRegisterClientObserver(db_);
430 }
431
GetTriggerSql(const std::string & tableName,const std::string & triggerTypeName,sqlite3 * db)432 std::string GetTriggerSql(const std::string &tableName, const std::string &triggerTypeName, sqlite3 *db) {
433 if (db == nullptr) {
434 return "";
435 }
436 std::string sql = "select sql from sqlite_master where type = 'trigger' and tbl_name = '" + tableName +
437 "' and name = 'naturalbase_rdb_" + tableName + "_ON_" + triggerTypeName + "';";
438 sqlite3_stmt *stmt = nullptr;
439 int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
440 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_OK)) {
441 LOGE("[GetTriggerSql] prepare statement failed(%d), sys(%d), errmsg(%s)", errCode, errno, sqlite3_errmsg(db));
442 return "";
443 }
444 errCode = SQLiteUtils::StepWithRetry(stmt);
445 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
446 LOGE("[GetTriggerSql] execute statement failed(%d), sys(%d), errmsg(%s)", errCode, errno, sqlite3_errmsg(db));
447 return "";
448 }
449 const std::string triggerSql = std::string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)));
450 int ret = E_OK;
451 SQLiteUtils::ResetStatement(stmt, true, ret);
452 return triggerSql;
453 }
454
455 /**
456 * @tc.name: SetSchema007
457 * @tc.desc: Test whether setting the schema multiple times will refresh the trigger
458 * @tc.type: FUNC
459 * @tc.require:
460 * @tc.author: liaoyonghuang
461 */
462 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema007, TestSize.Level1)
463 {
464 /**
465 * @tc.steps: step1. Prepare db
466 * @tc.expected: step1.ok
467 */
468 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
469 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
470 DistributedSchema schema1 = GetDistributedSchema(DEVICE_SYNC_TABLE, {"pk"});
471 EXPECT_EQ(delegate_->SetDistributedSchema(schema1), OK);
472 /**
473 * @tc.steps:step2. delete triggers
474 * @tc.expected: step2. Return OK.
475 */
476 std::string oldInsertTriggerSql = GetTriggerSql(DEVICE_SYNC_TABLE, "INSERT", db_);
477 std::string oldUpdateTriggerSql = GetTriggerSql(DEVICE_SYNC_TABLE, "UPDATE", db_);
478 std::string oldDeleteTriggerSql = GetTriggerSql(DEVICE_SYNC_TABLE, "DELETE", db_);
479 EXPECT_FALSE(oldInsertTriggerSql.empty() || oldUpdateTriggerSql.empty() || oldDeleteTriggerSql.empty());
480 std::vector<std::string> triggerTypes = {"INSERT", "UPDATE", "DELETE"};
481 for (const auto &triggerType : triggerTypes) {
482 std::string sql = "DROP TRIGGER IF EXISTS naturalbase_rdb_" + std::string(DEVICE_SYNC_TABLE) + "_ON_" +
483 triggerType;
484 SQLiteUtils::ExecuteRawSQL(db_, sql);
485 }
486 /**
487 * @tc.steps:step3. Set distributed schema and check if the trigger exists
488 * @tc.expected: step3. Check OK.
489 */
490 DistributedSchema schema2 = GetDistributedSchema(DEVICE_SYNC_TABLE, {"pk", "int_field1"});
491 EXPECT_EQ(delegate_->SetDistributedSchema(schema2), OK);
492 for (const auto &triggerType : triggerTypes) {
493 std::string sql = "select count(*) from sqlite_master where type = 'trigger' and tbl_name = '" +
494 std::string(DEVICE_SYNC_TABLE) + "' and name = 'naturalbase_rdb_" + std::string(DEVICE_SYNC_TABLE) +
495 "_ON_" + triggerType + "';";
496 int count = 0;
497 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, sql, count), E_OK);
498 EXPECT_EQ(count, 1);
499 }
500 std::string newInsertTriggerSql = GetTriggerSql(DEVICE_SYNC_TABLE, "INSERT", db_);
501 std::string newUpdateTriggerSql = GetTriggerSql(DEVICE_SYNC_TABLE, "UPDATE", db_);
502 std::string newDeleteTriggerSql = GetTriggerSql(DEVICE_SYNC_TABLE, "DELETE", db_);
503 EXPECT_FALSE(newInsertTriggerSql.empty() || newUpdateTriggerSql.empty() || newDeleteTriggerSql.empty());
504 EXPECT_TRUE(oldInsertTriggerSql == newInsertTriggerSql);
505 EXPECT_TRUE(oldUpdateTriggerSql != newUpdateTriggerSql);
506 EXPECT_TRUE(oldDeleteTriggerSql == newDeleteTriggerSql);
507 }
508
509 /**
510 * @tc.name: SetSchema008
511 * @tc.desc: Test set distributed schema with pk but pk isP2pSync is false
512 * @tc.type: FUNC
513 * @tc.require:
514 * @tc.author: tankaisheng
515 */
516 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema008, TestSize.Level1)
517 {
518 /**
519 * @tc.steps: step1. Prepare db
520 * @tc.expected: step1.ok
521 */
522 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
523 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
524 /**
525 * @tc.steps: step2. Test set distributed schema without pk
526 * @tc.expected: step2. return OK
527 */
528 DistributedSchema distributedSchema = {0, {{DEVICE_SYNC_TABLE, {{"int_field1", true}}}}};
529 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
530 /**
531 * @tc.steps: step3. Test set distributed schema with pk but pk isP2pSync is false
532 * @tc.expected: step3. return SCHEMA_MISMATCH
533 */
534 DistributedSchema distributedSchema1 = {0, {{DEVICE_SYNC_TABLE, {{"pk", false}}}}};
535 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema1), SCHEMA_MISMATCH);
536 /**
537 * @tc.steps: step4. Test set same distributed schema
538 * @tc.expected: step4. return OK
539 */
540 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
541 }
542
543 /**
544 * @tc.name: SetSchema009
545 * @tc.desc: Test tableMode is SPLIT_BY_DEVICE then SetDistributedSchema.
546 * @tc.type: FUNC
547 * @tc.require:
548 * @tc.author: tankaisheng
549 */
550 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema009, TestSize.Level0)
551 {
552 /**
553 * @tc.steps: step1. Prepare db, tableMode is SPLIT_BY_DEVICE
554 * @tc.expected: step1.ok
555 */
556 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::SPLIT_BY_DEVICE));
557 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
558 /**
559 * @tc.steps: step2. Test set distributed schema without pk
560 * @tc.expected: step2. return NOT_SUPPORT
561 */
562 DistributedSchema distributedSchema = {0, {{DEVICE_SYNC_TABLE, {{"int_field1", true}}}}};
563 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), NOT_SUPPORT);
564 }
565
566 /**
567 * @tc.name: SetSchema010
568 * @tc.desc: Test create distributed table without communicator.
569 * @tc.type: FUNC
570 * @tc.require:
571 * @tc.author: zqq
572 */
573 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema010, TestSize.Level0)
574 {
575 if (deviceB_ != nullptr) {
576 delete deviceB_;
577 deviceB_ = nullptr;
578 }
579 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
580 ASSERT_NO_FATAL_FAILURE(InitDelegate());
581 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
582 }
583
584 /**
585 * @tc.name: SetSchema011
586 * @tc.desc: Test set schema with not null field but isP2pSync is false
587 * @tc.type: FUNC
588 * @tc.require:
589 * @tc.author: liaoyonghuang
590 */
591 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema011, TestSize.Level0)
592 {
593 /**
594 * @tc.steps: step1. Prepare db
595 * @tc.expected: step1.ok
596 */
597 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
598 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
599 /**
600 * @tc.steps: step2. Test set distributed schema
601 * @tc.expected: step2. return SCHEMA_MISMATCH
602 */
603 DistributedSchema schema1 = GetDistributedSchema(DEVICE_SYNC_TABLE, {"pk"});
604 DistributedField &field1 = schema1.tables.front().fields.front();
605 field1.isP2pSync = false;
606 EXPECT_EQ(delegate_->SetDistributedSchema(schema1), SCHEMA_MISMATCH);
607 }
608
609 /**
610 * @tc.name: SetSchema012
611 * @tc.desc: Test call SetDistributedSchema with empty tables
612 * @tc.type: FUNC
613 * @tc.require:
614 * @tc.author: liuhongyang
615 */
616 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema012, TestSize.Level0)
617 {
618 /**
619 * @tc.steps: step1. Prepare db, tableMode is SPLIT_BY_DEVICE
620 * @tc.expected: step1.ok
621 */
622 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::SPLIT_BY_DEVICE));
623 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
624 /**
625 * @tc.steps: step2. Test set schema with empty tables vector
626 * @tc.expected: step2. return SCHEMA_MISMATCH
627 */
628 DistributedSchema distributedSchema = {0, {}};
629 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), SCHEMA_MISMATCH);
630 /**
631 * @tc.steps: step3. Test set schema with a list of empty tables
632 * @tc.expected: step3. return SCHEMA_MISMATCH
633 */
634 distributedSchema = {0, {{}, {}, {}}};
635 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), SCHEMA_MISMATCH);
636 /**
637 * @tc.steps: step4. Test set schema with a mix of empty and non-empty tables
638 * @tc.expected: step4. return SCHEMA_MISMATCH
639 */
640 distributedSchema = {0, {{DEVICE_SYNC_TABLE, {{"int_field1", true}}}, {}}};
641 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), SCHEMA_MISMATCH);
642 }
643
644 /**
645 * @tc.name: SetSchema013
646 * @tc.desc: Test set tracker table for device table and check if timestamp has changed
647 * @tc.type: FUNC
648 * @tc.require:
649 * @tc.author: bty
650 */
651 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema013, TestSize.Level1)
652 {
653 /**
654 * @tc.steps: step1. Create device table
655 * @tc.expected: step1.ok
656 */
657 ASSERT_NO_FATAL_FAILURE(InitDelegate());
658 DistributedSchema distributedSchema = GetDistributedSchema(DEVICE_SYNC_TABLE, {"pk", "int_field1"});
659 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
660 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
661 TrackerSchema trackerSchema = {
662 .tableName = DEVICE_SYNC_TABLE, .extendColNames = {"int_field1"}, .trackerColNames = {"int_field1"}
663 };
664 /**
665 * @tc.steps: step2. Insert one data and query timestamp
666 * @tc.expected: step2.ok
667 */
668 EXPECT_EQ(RDBDataGenerator::InsertLocalDBData(0, 1, db_, GetTableSchema()), E_OK);
669 sqlite3_stmt *stmt = nullptr;
670 std::string sql = "select timestamp from " + DBCommon::GetLogTableName(DEVICE_SYNC_TABLE) +
671 " where data_key=0";
672 EXPECT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
673 EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_ROW));
674 int64_t timestamp1 = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
675 int ret = E_OK;
676 SQLiteUtils::ResetStatement(stmt, true, ret);
677 /**
678 * @tc.steps: step3. Set tracker table and query timestamp
679 * @tc.expected: step3.Equal
680 */
681 EXPECT_EQ(delegate_->SetTrackerTable(trackerSchema), WITH_INVENTORY_DATA);
682 EXPECT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
683 EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_ROW));
684 int64_t timestamp2 = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
685 SQLiteUtils::ResetStatement(stmt, true, ret);
686 EXPECT_EQ(timestamp1, timestamp2);
687 }
688
689 /**
690 * @tc.name: SetSchema014
691 * @tc.desc: Test set tracker table for device table and check if timestamp has changed
692 * @tc.type: FUNC
693 * @tc.require:
694 * @tc.author: zqq
695 */
696 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema014, TestSize.Level1)
697 {
698 /**
699 * @tc.steps: step1. Create auto increment table and specified pk, distributed schema without not null field
700 * @tc.expected: step1. create distributed table ok but set schema failed
701 */
702 auto tableSchema = GetTableSchema();
703 tableSchema.name = DEVICE_SYNC_TABLE_AUTOINCREMENT;
704 ASSERT_EQ(RDBDataGenerator::InitTable(tableSchema, true, true, *db_), E_OK);
705 ASSERT_NO_FATAL_FAILURE(InitDelegate());
706 DistributedSchema distributedSchema;
707 DistributedTable distributedTable;
708 distributedTable.tableName = tableSchema.name;
709 DistributedField distributedField;
710 distributedField.colName = "pk";
711 distributedField.isSpecified = true;
712 distributedField.isP2pSync = true;
713 distributedTable.fields.push_back(distributedField);
714 distributedSchema.tables.push_back(distributedTable);
715 EXPECT_EQ(delegate_->CreateDistributedTable(tableSchema.name, TableSyncType::DEVICE_COOPERATION), OK);
716 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), SCHEMA_MISMATCH);
717 /**
718 * @tc.steps: step2. Distributed schema with not null field
719 * @tc.expected: step2. ok
720 */
721 distributedSchema.tables.clear();
722 distributedField.colName = "123";
723 distributedField.isSpecified = false;
724 distributedTable.fields.push_back(distributedField);
725 distributedSchema.tables.push_back(distributedTable);
726 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
727 /**
728 * @tc.steps: step3. Distributed schema with error specified
729 * @tc.expected: step3. SCHEMA_MISMATCH
730 */
731 distributedSchema.tables.clear();
732 distributedField.colName = "123";
733 distributedField.isSpecified = true;
734 distributedTable.fields.push_back(distributedField);
735 distributedField.colName = "pk";
736 distributedField.isP2pSync = false;
737 distributedTable.fields.push_back(distributedField);
738 distributedSchema.tables.push_back(distributedTable);
739 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), SCHEMA_MISMATCH);
740 }
741
742 /**
743 * @tc.name: SetSchema015
744 * @tc.desc: Test call SetDistributedSchema with mark more than one unique col isSpecified true
745 * @tc.type: FUNC
746 * @tc.require:
747 * @tc.author: tankaisheng
748 */
749 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema015, TestSize.Level1)
750 {
751 /**
752 * @tc.steps: step1. Prepare db, tableMode is COLLABORATION
753 * @tc.expected: step1.ok
754 */
755 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
756 std::string createSql = "CREATE TABLE IF NOT EXISTS table_pk_int(integer_field INTEGER PRIMARY KEY AUTOINCREMENT,"
757 "int_field INT, char_field CHARACTER(20) UNIQUE, clob_field CLOB UNIQUE, UNIQUE(char_field, clob_field));";
758 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, createSql), E_OK);
759 EXPECT_EQ(delegate_->CreateDistributedTable("table_pk_int", TableSyncType::DEVICE_COOPERATION), OK);
760
761 /**
762 * @tc.steps: step2. Test mark more than one unique col isSpecified true
763 * @tc.expected: step2. return SCHEMA_MISMATCH
764 */
765 DistributedSchema distributedSchema = {0, {{"table_pk_int", {
766 {"integer_field", false, false},
767 {"int_field", true, false},
768 {"char_field", true, true},
769 {"clob_field", true, true}}}}};
770 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), SCHEMA_MISMATCH);
771 }
772
773 /**
774 * @tc.name: SetSchema016
775 * @tc.desc: Test set isSpecified to false after isSpecified was set to true
776 * @tc.type: FUNC
777 * @tc.require:
778 * @tc.author: liaoyonghuang
779 */
780 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema016, TestSize.Level0)
781 {
782 /**
783 * @tc.steps: step1. Prepare db
784 * @tc.expected: step1.ok
785 */
786 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
787 std::string tableName = "multiPriKeyTable";
788 std::string sql = "CREATE TABLE IF NOT EXISTS " + tableName +
789 "(pk1 INTEGER, pk2 INT, PRIMARY KEY (pk1, pk2));";
790 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
791 EXPECT_EQ(delegate_->CreateDistributedTable(tableName, TableSyncType::DEVICE_COOPERATION), OK);
792 /**
793 * @tc.steps: step2. Test set distributed schema
794 * @tc.expected: step2. return OK
795 */
796 DistributedSchema schema1 = GetDistributedSchema(tableName, {"pk1", "pk2"});
797 EXPECT_EQ(delegate_->SetDistributedSchema(schema1), OK);
798 /**
799 * @tc.steps: step3. Test set distributed schema
800 * @tc.expected: step3. return SCHEMA_MISMATCH
801 */
802 DistributedSchema schema2 = GetDistributedSchema(tableName, {"pk1", "pk2"});
803 DistributedField &field2 = schema2.tables.front().fields.front();
804 field2.isSpecified = true;
805 EXPECT_EQ(delegate_->SetDistributedSchema(schema2), SCHEMA_MISMATCH);
806 }
807
GetHashKey(sqlite3 * db,const std::string & tableName,std::vector<std::string> & hashKeys)808 int GetHashKey(sqlite3 *db, const std::string &tableName, std::vector<std::string> &hashKeys) {
809 if (db == nullptr) {
810 return -E_INVALID_DB;
811 }
812
813 std::string sql = "select cast(hash_key as text) from " + DBCommon::GetLogTableName(tableName) +
814 " order by timestamp;";
815 sqlite3_stmt *stmt = nullptr;
816 int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
817 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_OK)) {
818 LOGE("prepare statement failed(%d), sys(%d), msg(%s)", errCode, errno, sqlite3_errmsg(db));
819 return errCode;
820 }
821
822 do {
823 errCode = SQLiteUtils::StepWithRetry(stmt);
824 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
825 errCode = E_OK;
826 } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
827 LOGE("[SQLiteUtils][ExecuteSQL] execute statement failed(%d), sys(%d), msg(%s)",
828 errCode, errno, sqlite3_errmsg(db));
829 } else {
830 const unsigned char *result = sqlite3_column_text(stmt, 0);
831 hashKeys.push_back(reinterpret_cast<const std::string::value_type *>(result));
832 }
833 } while (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW));
834
835 int ret = E_OK;
836 SQLiteUtils::ResetStatement(stmt, true, ret);
837 return errCode;
838 }
839
840 /**
841 * @tc.name: SetSchema017
842 * @tc.desc: Test whether to update hash_key after setting up distributed schema
843 * @tc.type: FUNC
844 * @tc.require:
845 * @tc.author: liaoyonghuang
846 */
847 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema017, TestSize.Level1)
848 {
849 /**
850 * @tc.steps: step1. Prepare db
851 * @tc.expected: step1.ok
852 */
853 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
854 std::string tableName = "multiPriKeyTable";
855 std::string sql = "CREATE TABLE IF NOT EXISTS " + tableName +
856 "(pk1 INTEGER PRIMARY KEY AUTOINCREMENT, pk2 INT UNIQUE);";
857 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
858 EXPECT_EQ(delegate_->CreateDistributedTable(tableName, TableSyncType::DEVICE_COOPERATION), OK);
859 /**
860 * @tc.steps: step2. Insert a record and get hash_key
861 * @tc.expected: step2.ok
862 */
863 int dataCount = 10;
864 for (int i = 0; i < dataCount; i++) {
865 sql = "insert into " + tableName + " values (" + std::to_string(i) + ", " + std::to_string(i + 1) + ");";
866 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
867 }
868 std::vector<std::string> oldHashKeys;
869 EXPECT_EQ(GetHashKey(db_, tableName, oldHashKeys), E_OK);
870 ASSERT_EQ(oldHashKeys.size(), static_cast<size_t>(dataCount));
871 /**
872 * @tc.steps: step3. Set distributed schema and get old hash_key
873 * @tc.expected: step3.ok
874 */
875 DistributedSchema schema1 = GetDistributedSchema(tableName, {"pk1", "pk2"});
876 EXPECT_EQ(delegate_->SetDistributedSchema(schema1), OK);
877 std::vector<std::string> newHashKeys1;
878 EXPECT_EQ(GetHashKey(db_, tableName, newHashKeys1), E_OK);
879 ASSERT_EQ(newHashKeys1.size(), static_cast<size_t>(dataCount));
880 for (int i = 0; i < dataCount; i++) {
881 EXPECT_EQ(oldHashKeys[i], newHashKeys1[i]);
882 }
883 /**
884 * @tc.steps: step4. Set another distributed schema and get old hash_key
885 * @tc.expected: step4.ok
886 */
887 DistributedSchema schema2 = {0, {{"multiPriKeyTable", {
888 {"pk1", false, false},
889 {"pk2", true, true}}}}};
890 EXPECT_EQ(delegate_->SetDistributedSchema(schema2, true), OK);
891 std::vector<std::string> newHashKeys2;
892 EXPECT_EQ(GetHashKey(db_, tableName, newHashKeys2), E_OK);
893 ASSERT_EQ(newHashKeys2.size(), static_cast<size_t>(dataCount));
894 for (int i = 0; i < dataCount; i++) {
895 EXPECT_NE(newHashKeys1[i], newHashKeys2[i]);
896 }
897 EXPECT_NE(newHashKeys2, oldHashKeys);
898 }
899
900 /**
901 * @tc.name: SetSchema018
902 * @tc.desc: Test no primary key table setting isSpecified
903 * @tc.type: FUNC
904 * @tc.require:
905 * @tc.author: liaoyonghuang
906 */
907 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema018, TestSize.Level0)
908 {
909 /**
910 * @tc.steps: step1. Prepare db
911 * @tc.expected: step1.ok
912 */
913 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
914 std::string tableName = "noPriKeyTable";
915 std::string sql = "CREATE TABLE IF NOT EXISTS " + tableName +
916 "(field_int1 INTEGER, field_int2 INT);";
917 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
918 EXPECT_EQ(delegate_->CreateDistributedTable(tableName, TableSyncType::DEVICE_COOPERATION), OK);
919 /**
920 * @tc.steps: step2. Test set distributed schema
921 * @tc.expected: step2. return SCHEMA_MISMATCH
922 */
923 DistributedSchema schema = GetDistributedSchema(tableName, {"field_int1"});
924 DistributedField &field = schema.tables.front().fields.front();
925 field.isSpecified = true;
926 EXPECT_EQ(delegate_->SetDistributedSchema(schema), SCHEMA_MISMATCH);
927 }
928
929 /**
930 * @tc.name: SetSchema019
931 * @tc.desc: Test call SetDistributedSchema when unique col not set isP2pSync
932 * @tc.type: FUNC
933 * @tc.require:
934 * @tc.author: tankaisheng
935 */
936 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema019, TestSize.Level0)
937 {
938 /**
939 * @tc.steps: step1. Prepare db, tableMode is COLLABORATION
940 * @tc.expected: step1.ok
941 */
942 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
943 std::string createSql = "CREATE TABLE IF NOT EXISTS table_pk_integer(integer_field INTEGER UNIQUE,"
944 "int_field INT, char_field CHARACTER(20), clob_field CLOB);";
945 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, createSql), E_OK);
946 EXPECT_EQ(delegate_->CreateDistributedTable("table_pk_integer", TableSyncType::DEVICE_COOPERATION), OK);
947
948 /**
949 * @tc.steps: step2. Test mark unique col isP2pSync true
950 * @tc.expected: step2. return SCHEMA_MISMATCH
951 */
952 DistributedSchema distributedSchema = {1, {{"table_pk_integer", {
953 {"int_field", true},
954 {"char_field", true},
955 {"clob_field", true}}}}};
956 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), SCHEMA_MISMATCH);
957 }
958
959 /**
960 * @tc.name: SetSchema020
961 * @tc.desc: Test call SetDistributedSchema when unique col and pk isP2pSync
962 * @tc.type: FUNC
963 * @tc.require:
964 * @tc.author: zqq
965 */
966 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema020, TestSize.Level0)
967 {
968
969 /**
970 * @tc.steps: step1. Prepare db, tableMode is COLLABORATION
971 * @tc.expected: step1.ok
972 */
973 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
974 std::string createSql = "CREATE TABLE IF NOT EXISTS table_pk_int(integer_field INTEGER PRIMARY KEY AUTOINCREMENT,"
975 "int_field INT UNIQUE, char_field CHARACTER(20), clob_field CLOB);";
976 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, createSql), E_OK);
977 EXPECT_EQ(delegate_->CreateDistributedTable("table_pk_int", TableSyncType::DEVICE_COOPERATION), OK);
978
979 /**
980 * @tc.steps: step2. Test mark unique col and pk isP2pSync true, specified unique col
981 * @tc.expected: step2. return NOT_SUPPORT
982 */
983 DistributedSchema distributedSchema = {1, {
984 {"table_pk_int", {
985 {"integer_field", true},
986 {"int_field", true, true},
987 {"char_field", true},
988 {"clob_field", true}
989 }}}
990 };
991 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), NOT_SUPPORT);
992 }
993
994 /**
995 * @tc.name: SetSchema021
996 * @tc.desc: Test call SetDistributedSchema when table contains 1000 columns
997 * @tc.type: FUNC
998 * @tc.require:
999 * @tc.author: suyue
1000 */
1001 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema021, TestSize.Level1)
1002 {
1003 /**
1004 * @tc.steps: step1. create table which contains 1000 columns
1005 * @tc.expected: step1. create table ok
1006 */
1007 TableSchema tableSchema;
1008 tableSchema.name = BIG_COLUMNS_TABLE;
1009 Field field;
1010 field.primary = true;
1011 field.type = TYPE_INDEX<int64_t>;
1012 field.colName = "pk";
1013 tableSchema.fields.push_back(field);
1014 field.primary = false;
1015 field.colName = "123";
1016 field.type = TYPE_INDEX<std::string>;
1017 tableSchema.fields.push_back(field);
1018 const uint16_t fieldNum = 1000;
1019 for (int i = 0; i < fieldNum; i++) {
1020 field.colName = "field" + to_string(i);
1021 tableSchema.fields.push_back(field);
1022 }
1023 ASSERT_EQ(RDBDataGenerator::InitTable(tableSchema, true, true, *db_), E_OK);
1024 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1025 EXPECT_EQ(delegate_->CreateDistributedTable(tableSchema.name, TableSyncType::DEVICE_COOPERATION), OK);
1026
1027 /**
1028 * @tc.steps: step2. set schema
1029 * @tc.expected: step2. ok
1030 */
1031 DistributedSchema distributedSchema;
1032 DistributedTable distributedTable;
1033 distributedTable.tableName = tableSchema.name;
1034 DistributedField distributedField;
1035 distributedField.isP2pSync = true;
1036 distributedField.colName = "123";
1037 distributedField.isSpecified = false;
1038 distributedTable.fields.push_back(distributedField);
1039 for (int i = 0; i < fieldNum; i++) {
1040 distributedField.colName = "field" + to_string(i);
1041 distributedTable.fields.push_back(distributedField);
1042 }
1043 distributedSchema.tables.push_back(distributedTable);
1044 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1045 }
1046
1047 /**
1048 * @tc.name: SetSchema022
1049 * @tc.desc: Test setting the distributed schema with table names named keywords.
1050 * @tc.type: FUNC
1051 * @tc.require:
1052 * @tc.author: liaoyonghuang
1053 */
1054 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema022, TestSize.Level1)
1055 {
1056 /**
1057 * @tc.steps: step1. Create device table named keywords.
1058 * @tc.expected: step1.ok
1059 */
1060 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1061 std::string tableName = "except";
1062 std::string sql = "CREATE TABLE IF NOT EXISTS '" + tableName + "'(field1 INTEGER, field2 INT);";
1063 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
1064 /**
1065 * @tc.steps: step2. Create distributed table and set distributed schema
1066 * @tc.expected: step2.ok
1067 */
1068 auto distributedSchema = GetDistributedSchema(tableName, {"field1", "field2"});
1069 deviceB_->SetDistributedSchema(distributedSchema);
1070 EXPECT_EQ(delegate_->CreateDistributedTable(tableName, TableSyncType::DEVICE_COOPERATION), OK);
1071 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1072 }
1073
1074 /**
1075 * @tc.name: SetSchema023
1076 * @tc.desc: Test SetDistributedSchema interface when tables decrease.
1077 * @tc.type: FUNC
1078 * @tc.require:
1079 * @tc.author: suyue
1080 */
1081 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema023, TestSize.Level0)
1082 {
1083 /**
1084 * @tc.steps: step1. set distributed schema for the first time
1085 * @tc.expected: step1. return OK
1086 */
1087 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1088 DistributedSchema distributedSchema = {1, {{DEVICE_SYNC_TABLE, {{"pk", true}, {"int_field1", true}}},
1089 {CLOUD_SYNC_TABLE, {{"pk", true}, {"int_field2", false}}}}};
1090 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1091
1092 /**
1093 * @tc.steps: step2. decrease tables of input parameter to set distributed schema
1094 * @tc.expected: step2. return OK
1095 */
1096 distributedSchema = {2, {{CLOUD_SYNC_TABLE, {{"pk", true}, {"int_field2", false}}}}};
1097 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1098 distributedSchema = {3, {{DEVICE_SYNC_TABLE, {{"pk", true}, {"int_field1", true}}},
1099 {DEVICE_SYNC_TABLE_UPGRADE, {{"pk", true}, {"int_field2", false}}}}};
1100 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1101 }
1102
1103 /**
1104 * @tc.name: SetSchema024
1105 * @tc.desc: Test SetDistributedSchema out of max schema size limit.
1106 * @tc.type: FUNC
1107 * @tc.require:
1108 * @tc.author: zqq
1109 */
1110 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema024, TestSize.Level1)
1111 {
1112 /**
1113 * @tc.steps: step1. set distributed schema for the first time
1114 * @tc.expected: step1. return OK
1115 */
1116 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1117 /**
1118 * @tc.steps: step2. generate 32 tables with 1000 field
1119 * @tc.expected: step2. return OK
1120 */
1121 auto basicSchema = GetTableSchema();
1122 const int fieldCount = 1000;
1123 Field basicField;
1124 basicField.type = TYPE_INDEX<int64_t>;
1125 basicField.colName = "generate_field_";
1126 for (int i = 0; i < fieldCount; ++i) {
1127 Field field = basicField;
1128 field.colName += std::to_string(i);
1129 basicSchema.fields.push_back(field);
1130 }
1131 /**
1132 * @tc.steps: step3. create distributed table
1133 * @tc.expected: step3. return OVER_MAX_LIMITS at last
1134 */
1135 const int tableCount = 32;
1136 DBStatus res = OK;
1137 for (int i = 0; i < tableCount; ++i) {
1138 TableSchema table = basicSchema;
1139 table.name += std::to_string(i);
1140 RDBDataGenerator::InitTable(table, false, *db_);
1141 res = delegate_->CreateDistributedTable(table.name);
1142 if (res != OK) {
1143 break;
1144 }
1145 }
1146 EXPECT_EQ(res, OVER_MAX_LIMITS);
1147 }
1148
1149 /**
1150 * @tc.name: SetSchema025
1151 * @tc.desc: Test SetDistributedSchema with isForceUpgrade.
1152 * @tc.type: FUNC
1153 * @tc.require:
1154 * @tc.author: liaoyonghuang
1155 */
1156 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema025, TestSize.Level0)
1157 {
1158 /**
1159 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1160 * @tc.expected: step1.ok
1161 */
1162 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1163 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1164 DistributedSchema distributedSchema1 = {1, {{DEVICE_SYNC_TABLE, {{"pk", true}, {"int_field1", true}}}}};
1165 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema1), OK);
1166 /**
1167 * @tc.steps: step2. Set distributed schema with isForceUpgrade
1168 * @tc.expected: step2.ok
1169 */
1170 DistributedSchema distributedSchema2 = {2, {{DEVICE_SYNC_TABLE, {{"pk", true}}}}};
1171 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema2, true), OK);
1172 }
1173
1174 /**
1175 * @tc.name: SetSchema026
1176 * @tc.desc: Test SetDistributedSchema with conflict log.
1177 * @tc.type: FUNC
1178 * @tc.require:
1179 * @tc.author: zqq
1180 */
1181 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema026, TestSize.Level0)
1182 {
1183 /**
1184 * @tc.steps: step1. Prepare db, tableMode is COLLABORATION
1185 * @tc.expected: step1.ok
1186 */
1187 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
1188 std::string createSql = "CREATE TABLE IF NOT EXISTS table_pk_int(integer_field INTEGER PRIMARY KEY AUTOINCREMENT,"
1189 "int_field INT UNIQUE);";
1190 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, createSql), E_OK);
1191 EXPECT_EQ(delegate_->CreateDistributedTable("table_pk_int", TableSyncType::DEVICE_COOPERATION), OK);
1192 /**
1193 * @tc.steps: step2. Set Distributed Schema
1194 * @tc.expected: step2. return OK
1195 */
1196 DistributedSchema distributedSchema = {1, {
1197 {"table_pk_int", {
1198 {"integer_field", true},
1199 {"int_field", true}
1200 }}}
1201 };
1202 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1203 /**
1204 * @tc.steps: step3. Local insert (1, 2), (2, 1) and delete (1, 2)
1205 * @tc.expected: step3. return OK
1206 */
1207 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, "INSERT INTO table_pk_int VALUES(1, 2)"), E_OK);
1208 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, "INSERT INTO table_pk_int VALUES(2, 1)"), E_OK);
1209 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, "DELETE FROM table_pk_int WHERE integer_field = 1"), E_OK);
1210 /**
1211 * @tc.steps: step4. Upgrade Distributed Schema and mark int_field specified
1212 * @tc.expected: step4. return OK
1213 */
1214 distributedSchema = {2, {
1215 {"table_pk_int", {
1216 {"integer_field", false},
1217 {"int_field", true, true}
1218 }}}
1219 };
1220 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema, true), OK);
1221 }
1222
1223 /**
1224 * @tc.name: SetSchema027
1225 * @tc.desc: Test two table create distributed table.
1226 * @tc.type: FUNC
1227 * @tc.require:
1228 * @tc.author: zqq
1229 */
1230 HWTEST_F(DistributedDBRDBCollaborationTest, SetSchema027, TestSize.Level0)
1231 {
1232 /**
1233 * @tc.steps: step1. Prepare db create two table
1234 * @tc.expected: step1.ok
1235 */
1236 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
1237 std::string createSql = "CREATE TABLE IF NOT EXISTS table1(integer_field INTEGER PRIMARY KEY AUTOINCREMENT,"
1238 "int_field INT UNIQUE);";
1239 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, createSql), E_OK);
1240 EXPECT_EQ(delegate_->CreateDistributedTable("table1", TableSyncType::DEVICE_COOPERATION), OK);
1241 createSql = "CREATE TABLE IF NOT EXISTS table2(integer_field INTEGER PRIMARY KEY AUTOINCREMENT,"
1242 "int_field INT UNIQUE);";
1243 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, createSql), E_OK);
1244 EXPECT_EQ(delegate_->CreateDistributedTable("table2", TableSyncType::DEVICE_COOPERATION), OK);
1245 auto table1 = std::string(DBConstant::RELATIONAL_PREFIX).append("table1_log");
1246 auto table2 = std::string(DBConstant::RELATIONAL_PREFIX).append("table2_log");
1247 RelationalTestUtils::CheckIndexCount(db_, table1, 3u); // 3 is index count
1248 RelationalTestUtils::CheckIndexCount(db_, table2, 3u); // 3 is index count
1249 }
1250
1251 /**
1252 * @tc.name: NormalSync001
1253 * @tc.desc: Test set distributed schema and sync.
1254 * @tc.type: FUNC
1255 * @tc.require:
1256 * @tc.author: zqq
1257 */
1258 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync001, TestSize.Level1)
1259 {
1260 /**
1261 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1262 * @tc.expected: step1.ok
1263 */
1264 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1265 auto schema = GetSchema();
1266 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
1267 deviceB_->SetDistributedSchema(distributedSchema);
1268 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1269 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1270 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
1271 /**
1272 * @tc.steps: step2. Insert one data
1273 * @tc.expected: step2.ok
1274 */
1275 auto tableSchema = GetTableSchema();
1276 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 10, deviceB_, tableSchema), E_OK);
1277 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1278 /**
1279 * @tc.steps: step3. Sync to real device
1280 * @tc.expected: step3.ok
1281 */
1282 Query query = Query::Select(tableSchema.name);
1283 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1284 }
1285
1286 /**
1287 * @tc.name: NormalSync002
1288 * @tc.desc: Test sync with diff distributed schema [high version -> low version].
1289 * @tc.type: FUNC
1290 * @tc.require:
1291 * @tc.author: zqq
1292 */
1293 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync002, TestSize.Level1)
1294 {
1295 /**
1296 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1297 * @tc.expected: step1.ok
1298 */
1299 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1300 /**
1301 * @tc.steps: step2. DeviceB set schema [pk, int_field1, int_field2, int_field_upgrade]
1302 * @tc.expected: step2.ok
1303 */
1304 DataBaseSchema virtualSchema;
1305 auto tableSchema = GetTableSchema(true);
1306 tableSchema.name = DEVICE_SYNC_TABLE;
1307 virtualSchema.tables.push_back(tableSchema);
1308 auto distributedSchema = RDBDataGenerator::ParseSchema(virtualSchema);
1309 deviceB_->SetDistributedSchema(distributedSchema);
1310 /**
1311 * @tc.steps: step3. Real device set schema [pk, int_field1, int_field2]
1312 * @tc.expected: step3.ok
1313 */
1314 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1315 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
1316 EXPECT_EQ(delegate_->SetDistributedSchema(RDBDataGenerator::ParseSchema(GetSchema())), OK);
1317 /**
1318 * @tc.steps: step4. Insert table info and virtual data into deviceB
1319 * @tc.expected: step4.ok
1320 */
1321 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 10, deviceB_, tableSchema), E_OK);
1322 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(DEVICE_SYNC_TABLE_UPGRADE, DEVICE_SYNC_TABLE, db_, deviceB_),
1323 E_OK);
1324 /**
1325 * @tc.steps: step5. Sync to real device
1326 * @tc.expected: step5.ok
1327 */
1328 Query query = Query::Select(tableSchema.name);
1329 EXPECT_EQ(deviceB_->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1330 }
1331
1332 /**
1333 * @tc.name: NormalSync003
1334 * @tc.desc: Test sync with diff distributed schema [low version -> high version].
1335 * @tc.type: FUNC
1336 * @tc.require:
1337 * @tc.author: zqq
1338 */
1339 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync003, TestSize.Level1)
1340 {
1341 /**
1342 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1343 * @tc.expected: step1.ok
1344 */
1345 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1346 /**
1347 * @tc.steps: step2. DeviceB set schema [pk, int_field1, int_field2]
1348 * @tc.expected: step2.ok
1349 */
1350 DataBaseSchema virtualSchema;
1351 auto tableSchema = GetTableSchema();
1352 tableSchema.name = DEVICE_SYNC_TABLE_UPGRADE;
1353 virtualSchema.tables.push_back(tableSchema);
1354 auto distributedSchema = RDBDataGenerator::ParseSchema(virtualSchema);
1355 deviceB_->SetDistributedSchema(distributedSchema);
1356 /**
1357 * @tc.steps: step3. Real device set schema [pk, int_field1, int_field2, int_field_upgrade]
1358 * @tc.expected: step3.ok
1359 */
1360 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE_UPGRADE, TableSyncType::DEVICE_COOPERATION), OK);
1361 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
1362 EXPECT_EQ(delegate_->SetDistributedSchema(RDBDataGenerator::ParseSchema(GetSchema())), OK);
1363 /**
1364 * @tc.steps: step4. Insert table info and virtual data into deviceB
1365 * @tc.expected: step4.ok
1366 */
1367 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 10, deviceB_, tableSchema), E_OK);
1368 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(DEVICE_SYNC_TABLE, DEVICE_SYNC_TABLE_UPGRADE, db_, deviceB_),
1369 E_OK);
1370 /**
1371 * @tc.steps: step5. Sync to real device
1372 * @tc.expected: step5.ok
1373 */
1374 Query query = Query::Select(tableSchema.name);
1375 EXPECT_EQ(deviceB_->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1376 }
1377
1378 /**
1379 * @tc.name: NormalSync004
1380 * @tc.desc: Test sync when distributed schema was not set.
1381 * @tc.type: FUNC
1382 * @tc.require:
1383 * @tc.author: liaoyonghuang
1384 */
1385 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync004, TestSize.Level0)
1386 {
1387 /**
1388 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1389 * @tc.expected: step1.ok
1390 */
1391 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1392 auto tableSchema = GetTableSchema();
1393 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1394 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1395 /**
1396 * @tc.steps: step2. Sync to real device
1397 * @tc.expected: step2. return SCHEMA_MISMATCH.
1398 */
1399 Query query = Query::Select(tableSchema.name);
1400 DBStatus status = delegate_->Sync({UnitTestCommonConstant::DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, nullptr, true);
1401 EXPECT_EQ(status, SCHEMA_MISMATCH);
1402 }
1403
1404 /**
1405 * @tc.name: NormalSync005
1406 * @tc.desc: Test sync with specified columns
1407 * @tc.type: FUNC
1408 * @tc.require:
1409 * @tc.author: liaoyonghuang
1410 */
1411 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync005, TestSize.Level1)
1412 {
1413 /**
1414 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1415 * @tc.expected: step1.ok
1416 */
1417 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
1418 DistributedSchema schema = GetDistributedSchema(DEVICE_SYNC_TABLE, {"pk", "int_field1"});
1419 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1420 deviceB_->SetDistributedSchema(schema);
1421 EXPECT_EQ(delegate_->SetDistributedSchema(schema), OK);
1422 /**
1423 * @tc.steps: step2. Init some data
1424 * @tc.expected: step2.ok
1425 */
1426 int64_t dataNum = 10;
1427 EXPECT_EQ(RDBDataGenerator::InsertLocalDBData(0, dataNum / 2, db_, GetTableSchema()), E_OK);
1428 std::string sql = "update " + std::string(DEVICE_SYNC_TABLE) + " set int_field1 = 1, int_field2 = 2 where pk >= 0";
1429 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
1430 auto tableSchema = GetTableSchema();
1431 std::this_thread::sleep_for(std::chrono::seconds(1));
1432 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, dataNum, deviceB_, tableSchema), E_OK);
1433 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1434 /**
1435 * @tc.steps: step3. Sync to real device and check data
1436 * @tc.expected: step3.ok
1437 */
1438 Query query = Query::Select(tableSchema.name);
1439 EXPECT_EQ(deviceB_->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_PULL, query, true), E_OK);
1440 sql = "select int_field1, int_field2 from " + std::string(DEVICE_SYNC_TABLE) + " order by pk;";
1441 sqlite3_stmt *stmt = nullptr;
1442 ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1443 int dataIndex = 0;
1444 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1445 int64_t intField1Value = sqlite3_column_int64(stmt, 0);
1446 int64_t intField2Value = sqlite3_column_int64(stmt, 1);
1447 EXPECT_EQ(intField1Value, dataIndex);
1448 dataIndex++;
1449 if (dataIndex <= dataNum / 2) {
1450 EXPECT_EQ(intField2Value, 2);
1451 } else {
1452 EXPECT_EQ(intField2Value, 0);
1453 }
1454 }
1455 EXPECT_EQ(dataIndex, dataNum);
1456 int errCode;
1457 SQLiteUtils::ResetStatement(stmt, true, errCode);
1458 }
1459
1460 /**
1461 * @tc.name: NormalSync006
1462 * @tc.desc: Test set distributed schema and sync.
1463 * @tc.type: FUNC
1464 * @tc.require:
1465 * @tc.author: zqq
1466 */
1467 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync006, TestSize.Level1)
1468 {
1469 /**
1470 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1471 * @tc.expected: step1.ok
1472 */
1473 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1474 auto schema = GetSchema();
1475 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
1476 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1477 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
1478 deviceB_->SetDistributedSchema(distributedSchema);
1479 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1480 /**
1481 * @tc.steps: step2. Insert one data
1482 * @tc.expected: step2.ok
1483 */
1484 auto tableSchema = GetTableSchema();
1485 EXPECT_EQ(RDBDataGenerator::InsertLocalDBData(0, 1, db_, GetTableSchema()), E_OK);
1486 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1487 /**
1488 * @tc.steps: step3. Sync to real device
1489 * @tc.expected: step3.ok
1490 */
1491 Query query = Query::Select(tableSchema.name);
1492 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PUSH_ONLY, OK, {deviceB_->GetDeviceId()});
1493 /**
1494 * @tc.steps: step4. Change schema to non-existent table name, then sync
1495 * @tc.expected: step4.SCHEMA_MISMATCH
1496 */
1497 tableSchema.name = "not_config_table";
1498 ASSERT_EQ(RDBDataGenerator::InitTable(tableSchema, true, *db_), SQLITE_OK);
1499 ASSERT_EQ(delegate_->CreateDistributedTable(tableSchema.name), OK);
1500 Query query2 = Query::Select(tableSchema.name);
1501 std::map<std::string, std::vector<TableStatus>> statusMap;
1502 SyncStatusCallback callBack2;
1503 DBStatus callStatus = delegate_->Sync({deviceB_->GetDeviceId()}, SYNC_MODE_PUSH_ONLY, query2, callBack2, true);
1504 EXPECT_EQ(callStatus, SCHEMA_MISMATCH);
1505 }
1506
1507 /**
1508 * @tc.name: NormalSync007
1509 * @tc.desc: Test change distributed schema and sync.
1510 * @tc.type: FUNC
1511 * @tc.require:
1512 * @tc.author: zqq
1513 */
1514 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync007, TestSize.Level1)
1515 {
1516 /**
1517 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1518 * @tc.expected: step1.ok
1519 */
1520 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1521 auto schema = GetSchema();
1522 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
1523 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1524 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
1525 deviceB_->SetDistributedSchema(distributedSchema);
1526 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1527 /**
1528 * @tc.steps: step2. Insert one data
1529 * @tc.expected: step2.ok
1530 */
1531 auto tableSchema = GetTableSchema();
1532 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_, tableSchema), E_OK);
1533 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1534 /**
1535 * @tc.steps: step3. Sync to real device
1536 * @tc.expected: step3.ok
1537 */
1538 Query query = Query::Select(tableSchema.name);
1539 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1540 std::string sql = std::string("select count(*) from ").append(DEVICE_SYNC_TABLE)
1541 .append(" where pk=0 and int_field1 is null and int_field2 is null");
1542 int count = 0;
1543 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, sql, count), E_OK);
1544 EXPECT_EQ(count, 1);
1545 /**
1546 * @tc.steps: step4. Change schema and sync again
1547 * @tc.expected: step4.ok
1548 */
1549 distributedSchema = RDBDataGenerator::ParseSchema(schema);
1550 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1551 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1552 sql = std::string("select count(*) from ").append(DEVICE_SYNC_TABLE)
1553 .append(" where pk=0 and int_field1=0 and int_field2=0");
1554 count = 0;
1555 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, sql, count), E_OK);
1556 EXPECT_EQ(count, 1);
1557 auto changeData = delegateObserver_->GetSavedChangedData()[std::string(DEVICE_SYNC_TABLE)];
1558 EXPECT_TRUE(changeData.properties.isP2pSyncDataChange);
1559 }
1560
1561 /**
1562 * @tc.name: NormalSync008
1563 * @tc.desc: Test set distributed schema and sync with diff sort.
1564 * @tc.type: FUNC
1565 * @tc.require:
1566 * @tc.author: zqq
1567 */
1568 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync008, TestSize.Level1)
1569 {
1570 /**
1571 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1572 * @tc.expected: step1.ok
1573 */
1574 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1575 auto schema = GetSchema();
1576 auto distributedSchema = RDBDataGenerator::ParseSchema(schema);
1577 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1578 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
1579 deviceB_->SetDistributedSchema(distributedSchema);
1580 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1581 /**
1582 * @tc.steps: step2. Insert one data with diff sort col
1583 * @tc.expected: step2.ok
1584 */
1585 auto tableSchema = GetTableSchema();
1586 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_,
1587 RDBDataGenerator::FlipTableSchema(tableSchema)), E_OK);
1588 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1589 /**
1590 * @tc.steps: step3. Sync to real device
1591 * @tc.expected: step3.ok
1592 */
1593 Query query = Query::Select(tableSchema.name);
1594 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1595 std::string sql = std::string("select count(*) from ").append(DEVICE_SYNC_TABLE).append(" where pk=0;");
1596 int count = 0;
1597 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, sql, count), E_OK);
1598 EXPECT_EQ(count, 1);
1599 sql = std::string("select count(*) from ")
1600 .append(RelationalStoreManager::GetDistributedLogTableName(DEVICE_SYNC_TABLE))
1601 .append(" where data_key=0 and cursor=1;");
1602 count = 0;
1603 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, sql, count), E_OK);
1604 EXPECT_EQ(count, 1);
1605 }
1606
1607 /**
1608 * @tc.name: NormalSync009
1609 * @tc.desc: Test if distributed table will be created when sync with COLLABORATION mode.
1610 * @tc.type: FUNC
1611 * @tc.require:
1612 * @tc.author: liaoyonghuang
1613 */
1614 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync009, TestSize.Level1)
1615 {
1616 /**
1617 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1618 * @tc.expected: step1.ok
1619 */
1620 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1621 auto schema = GetSchema();
1622 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
1623 deviceB_->SetDistributedSchema(distributedSchema);
1624 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1625 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1626 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
1627 /**
1628 * @tc.steps: step2. Insert one data
1629 * @tc.expected: step2.ok
1630 */
1631 auto tableSchema = GetTableSchema();
1632 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 10, deviceB_, tableSchema), E_OK);
1633 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1634 /**
1635 * @tc.steps: step3. Sync to real device
1636 * @tc.expected: step3.ok
1637 */
1638 std::string checkSql = "select count(*) from sqlite_master where type='table' and name != '" +
1639 DBCommon::GetLogTableName(DEVICE_SYNC_TABLE) + "' and name like 'naturalbase_rdb_aux_" +
1640 std::string(DEVICE_SYNC_TABLE) + "_%'";
1641 int count = 0;
1642 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkSql, count), E_OK);
1643 EXPECT_EQ(count, 0);
1644 Query query = Query::Select(tableSchema.name);
1645 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1646 /**
1647 * @tc.steps: step4. Check if the distributed table exists
1648 * @tc.expected: step4.ok
1649 */
1650 count = 0;
1651 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkSql, count), E_OK);
1652 EXPECT_EQ(count, 0);
1653 }
1654
1655 /**
1656 * @tc.name: NormalSync010
1657 * @tc.desc: Test sync without not null col.
1658 * @tc.type: FUNC
1659 * @tc.require:
1660 * @tc.author: zqq
1661 */
1662 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync010, TestSize.Level0)
1663 {
1664 /**
1665 * @tc.steps: step1. Recreate not null table
1666 * @tc.expected: step1.ok
1667 */
1668 std::string sql = std::string("DROP TABLE ").append(DEVICE_SYNC_TABLE);
1669 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
1670 auto tableSchema = GetTableSchema();
1671 ASSERT_EQ(RDBDataGenerator::InitTable(tableSchema, true, *db_), E_OK);
1672 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1673 auto schema = GetSchema();
1674 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
1675 deviceB_->SetDistributedSchema(distributedSchema);
1676 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1677 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), SCHEMA_MISMATCH);
1678 /**
1679 * @tc.steps: step2. Insert one data
1680 * @tc.expected: step2.ok
1681 */
1682 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_, tableSchema), E_OK);
1683 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1684 /**
1685 * @tc.steps: step3. Sync without str col
1686 * @tc.expected: step3.ok
1687 */
1688 Query query = Query::Select(tableSchema.name);
1689 DBStatus callStatus = delegate_->Sync({deviceB_->GetDeviceId()}, SYNC_MODE_PULL_ONLY, query, nullptr, true);
1690 EXPECT_EQ(callStatus, SCHEMA_MISMATCH);
1691 /**
1692 * @tc.steps: step4. Check if the distributed table exists
1693 * @tc.expected: step4.ok
1694 */
1695 int count = 0;
1696 sql = std::string("select count(*) from ")
1697 .append(RelationalStoreManager::GetDistributedLogTableName(DEVICE_SYNC_TABLE));
1698 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, sql, count), E_OK);
1699 EXPECT_EQ(count, 0);
1700 }
1701
1702 /**
1703 * @tc.name: NormalSync011
1704 * @tc.desc: Test set the distributed schema first then sync.
1705 * @tc.type: FUNC
1706 * @tc.require:
1707 * @tc.author: bty
1708 */
1709 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync011, TestSize.Level1)
1710 {
1711 /**
1712 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1713 * @tc.expected: step1.ok
1714 */
1715 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1716 auto schema = GetSchema();
1717 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
1718 deviceB_->SetDistributedSchema(distributedSchema);
1719 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1720 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1721 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
1722 /**
1723 * @tc.steps: step2. Insert one data
1724 * @tc.expected: step2.ok
1725 */
1726 auto tableSchema = GetTableSchema();
1727 EXPECT_EQ(RDBDataGenerator::InsertLocalDBData(0, 1, db_, GetTableSchema()), E_OK);
1728 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1729 /**
1730 * @tc.steps: step3. Sync to real device
1731 * @tc.expected: step3.ok
1732 */
1733 Query query = Query::Select().FromTable({tableSchema.name});
1734 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PUSH_ONLY, OK, {deviceB_->GetDeviceId()});
1735 }
1736
1737 /**
1738 * @tc.name: NormalSync012
1739 * @tc.desc: Test sync with autoincrement table.
1740 * @tc.type: FUNC
1741 * @tc.require:
1742 * @tc.author: zqq
1743 */
1744 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync012, TestSize.Level0)
1745 {
1746 /**
1747 * @tc.steps: step1. Create auto increment table and unique index
1748 * @tc.expected: step1.ok
1749 */
1750 auto tableSchema = GetTableSchema();
1751 tableSchema.name = DEVICE_SYNC_TABLE_AUTOINCREMENT;
1752 ASSERT_EQ(RDBDataGenerator::InitTable(tableSchema, true, true, *db_), E_OK);
1753 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1754 tableSchema = GetTableSchema(false, true);
1755 tableSchema.name = DEVICE_SYNC_TABLE_AUTOINCREMENT;
1756 auto schema = GetSchema();
1757 schema.tables.push_back(tableSchema);
1758 DistributedSchema distributedSchema = {0, {{tableSchema.name, {
1759 {"pk", false, false},
1760 {"int_field1", true, false},
1761 {"int_field2", true, false},
1762 {"123", true, true}}}}};
1763 deviceB_->SetDistributedSchema(distributedSchema);
1764 int errCode = SQLiteUtils::ExecuteRawSQL(db_, std::string("CREATE UNIQUE INDEX U_INDEX ON ")
1765 .append(tableSchema.name).append("('123')"));
1766 ASSERT_EQ(errCode, E_OK);
1767 EXPECT_EQ(delegate_->CreateDistributedTable(tableSchema.name, TableSyncType::DEVICE_COOPERATION), OK);
1768 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1769 /**
1770 * @tc.steps: step2. Insert one data
1771 * @tc.expected: step2.ok
1772 */
1773 ASSERT_EQ(RDBDataGenerator::InsertLocalDBData(0, 1, db_, tableSchema), E_OK);
1774 std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100 ms
1775 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 2, deviceB_, tableSchema), E_OK);
1776 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1777 /**
1778 * @tc.steps: step3. Sync to real device
1779 * @tc.expected: step3.ok
1780 */
1781 Query query = Query::Select(tableSchema.name);
1782 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1783 std::string sql = std::string("select count(*) from ").append(tableSchema.name);
1784 int count = 0;
1785 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, sql, count), E_OK);
1786 EXPECT_EQ(count, 2);
1787 /**
1788 * @tc.steps: step4. Update date and sync again
1789 * @tc.expected: step4.ok
1790 */
1791 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_, tableSchema), E_OK);
1792 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1793 sql = std::string("select count(*) from ").append(tableSchema.name);
1794 count = 0;
1795 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, sql, count), E_OK);
1796 EXPECT_EQ(count, 2);
1797 }
1798
1799 /**
1800 * @tc.name: NormalSync013
1801 * @tc.desc: Test chanage data after sync.
1802 * @tc.type: FUNC
1803 * @tc.require:
1804 * @tc.author: lg
1805 */
1806 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync013, TestSize.Level1)
1807 {
1808 /**
1809 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1810 * @tc.expected: step1.ok
1811 */
1812 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1813 auto schema = GetSchema();
1814 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
1815 deviceB_->SetDistributedSchema(distributedSchema);
1816 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1817 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1818 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
1819 /**
1820 * @tc.steps: step2. Insert one data
1821 * @tc.expected: step2.ok
1822 */
1823 auto tableSchema = GetTableSchema();
1824 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 10, deviceB_, tableSchema), E_OK);
1825 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1826 /**
1827 * @tc.steps: step3. Sync to real device
1828 * @tc.expected: step3.ok
1829 */
1830 Query query = Query::Select(tableSchema.name);
1831 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1832 /**
1833 * @tc.steps: step4. check changData
1834 * @tc.expected: step4.ok
1835 */
1836 auto changeData = delegateObserver_->GetSavedChangedData();
1837 EXPECT_EQ(changeData[tableSchema.name].primaryData[0].size(), 10u);
1838 EXPECT_EQ(changeData[tableSchema.name].field.size(), 1u);
1839 /**
1840 * @tc.steps: step5. Remove the last item and a cloud-only item, then check changeData
1841 * @tc.expected: step5. Only the last item is in changeData and field is primary key
1842 */
1843 delegateObserver_->ClearChangedData();
1844 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(9, 11, deviceB_, tableSchema, true), E_OK);
1845 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1846 changeData = delegateObserver_->GetSavedChangedData();
1847 ASSERT_EQ(changeData[tableSchema.name].primaryData[OP_DELETE].size(), 1u);
1848 EXPECT_EQ(changeData[tableSchema.name].primaryData[OP_DELETE][0].size(), 1u);
1849 ASSERT_EQ(changeData[tableSchema.name].field.size(), 1u);
1850 EXPECT_EQ(changeData[tableSchema.name].field[0], "pk");
1851 }
1852
1853 /**
1854 * @tc.name: NormalSync014
1855 * @tc.desc: Test chanage data after sync.
1856 * @tc.type: FUNC
1857 * @tc.require:
1858 * @tc.author: tankaisheng
1859 */
1860 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync014, TestSize.Level1)
1861 {
1862 /**
1863 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1864 * @tc.expected: step1.ok
1865 */
1866 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1867 auto schema = GetSchema();
1868 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
1869 deviceB_->SetDistributedSchema(distributedSchema);
1870 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
1871 DistributedSchema schema1 = GetDistributedSchema(DEVICE_SYNC_TABLE, {"int_field1"});
1872 EXPECT_EQ(delegate_->SetDistributedSchema(schema1), OK);
1873 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_COOPERATION);
1874 /**
1875 * @tc.steps: step2. Insert data
1876 * @tc.expected: step2.ok
1877 */
1878 auto tableSchema = GetTableSchema();
1879 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 10, deviceB_, tableSchema), E_OK);
1880 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
1881 /**
1882 * @tc.steps: step3. Sync to real device
1883 * @tc.expected: step3.ok
1884 */
1885 Query query = Query::Select(tableSchema.name);
1886 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1887 /**
1888 * @tc.steps: step4. check changData
1889 * @tc.expected: step4.ok
1890 */
1891 auto changeData = delegateObserver_->GetSavedChangedData();
1892 EXPECT_EQ(changeData[tableSchema.name].primaryData[0].size(), 10u);
1893 EXPECT_EQ(changeData[tableSchema.name].field.size(), 1u);
1894 /**
1895 * @tc.steps: step5. SetDistributedSchema again
1896 * @tc.expected: step5.ok
1897 */
1898 DistributedSchema schema2 = GetDistributedSchema(DEVICE_SYNC_TABLE, {"int_field1", "int_field2"});
1899 EXPECT_EQ(delegate_->SetDistributedSchema(schema2), OK);
1900 /**
1901 * @tc.steps: step6. Sync to real device
1902 * @tc.expected: step6.ok
1903 */
1904 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1905 /**
1906 * @tc.steps: step7. check changData
1907 * @tc.expected: step7.ok
1908 */
1909 changeData = delegateObserver_->GetSavedChangedData();
1910 EXPECT_EQ(changeData[tableSchema.name].primaryData[1].size(), 10u);
1911 EXPECT_EQ(changeData[tableSchema.name].field.size(), 1u);
1912 }
1913
1914 /**
1915 * @tc.name: NormalSync015
1916 * @tc.desc: Test sync with multi primary key table.
1917 * @tc.type: FUNC
1918 * @tc.require:
1919 * @tc.author: liaoyonghuang
1920 */
1921 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync015, TestSize.Level1)
1922 {
1923 /**
1924 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
1925 * @tc.expected: step1.ok
1926 */
1927 ASSERT_NO_FATAL_FAILURE(InitDelegate());
1928 std::string tableName = "multiPriKeyTable";
1929 std::string sql = "CREATE TABLE IF NOT EXISTS " + tableName +
1930 "(pk1 INTEGER, pk2 INT, PRIMARY KEY (pk1, pk2));";
1931 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
1932 /**
1933 * @tc.steps: step2. Create distributed table and set distributed schema
1934 * @tc.expected: step2.ok
1935 */
1936 auto distributedSchema = GetDistributedSchema(tableName, {"pk1", "pk2"});
1937 deviceB_->SetDistributedSchema(distributedSchema);
1938 EXPECT_EQ(delegate_->CreateDistributedTable(tableName, TableSyncType::DEVICE_COOPERATION), OK);
1939 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
1940 /**
1941 * @tc.steps: step3. Init data and sync to real device
1942 * @tc.expected: step3.ok
1943 */
1944 TableSchema tableSchema;
1945 tableSchema.name = tableName;
1946 Field field;
1947 field.primary = true;
1948 field.type = TYPE_INDEX<int64_t>;
1949 field.colName = "pk1";
1950 tableSchema.fields.push_back(field);
1951 field.colName = "pk2";
1952 tableSchema.fields.push_back(field);
1953 uint32_t dataCount = 10;
1954 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, dataCount, deviceB_, tableSchema), E_OK);
1955 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableName, db_, deviceB_), E_OK);
1956 Query query = Query::Select(tableName);
1957 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1958 /**
1959 * @tc.steps: step4. check changData
1960 * @tc.expected: step4.ok
1961 */
1962 auto changeData = delegateObserver_->GetSavedChangedData();
1963 ASSERT_EQ(changeData[tableName].primaryData[OP_INSERT].size(), dataCount);
1964 for (uint32_t i = 0; i < dataCount; i++) {
1965 EXPECT_EQ(changeData[tableName].primaryData[OP_INSERT][i].size(), 3u); // primary key (pk1, pk2) and rowid
1966 }
1967 EXPECT_EQ(changeData[tableName].field.size(), 3u); // primary key (pk1, pk2) and rowid
1968 /**
1969 * @tc.steps: step5. Remove the last item and a cloud-only item, then check changeData
1970 * @tc.expected: step5. Only the last item is in changeData and field is key (pk1, pk2) and rowid
1971 */
1972 delegateObserver_->ClearChangedData();
1973 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(dataCount - 1, dataCount + 1, deviceB_, tableSchema, true),
1974 E_OK);
1975 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
1976 changeData = delegateObserver_->GetSavedChangedData();
1977 ASSERT_EQ(changeData[tableName].primaryData[OP_DELETE].size(), 1u);
1978 EXPECT_EQ(changeData[tableName].primaryData[OP_DELETE][0].size(), 3u); // primary key (pk1, pk2) and rowid
1979 EXPECT_EQ(changeData[tableName].field.size(), 3u); // primary key (pk1, pk2) and rowid
1980 }
1981
1982 /**
1983 * @tc.name: NormalSync016
1984 * @tc.desc: Test sync with diff specified field.
1985 * @tc.type: FUNC
1986 * @tc.require:
1987 * @tc.author: zqq
1988 */
1989 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync016, TestSize.Level1)
1990 {
1991 /**
1992 * @tc.steps: step1. Prepare db, tableMode is COLLABORATION
1993 * @tc.expected: step1.ok
1994 */
1995 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
1996 std::string createSql = "CREATE TABLE IF NOT EXISTS table_int(integer_field INTEGER PRIMARY KEY AUTOINCREMENT,"
1997 "int_field1 INT UNIQUE, int_field2 INT UNIQUE);";
1998 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, createSql), E_OK);
1999 EXPECT_EQ(delegate_->CreateDistributedTable("table_int", TableSyncType::DEVICE_COOPERATION), OK);
2000
2001 /**
2002 * @tc.steps: step2. Test mark one specified one is field1 another is field2
2003 * @tc.expected: step2. sync return SCHEMA_MISMATCH
2004 */
2005 DistributedSchema distributedSchema = {0, {{"table_int", {
2006 {"integer_field", false, false},
2007 {"int_field1", true, false},
2008 {"int_field2", true, true}}}}};
2009 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2010 distributedSchema = {0, {{"table_int", {
2011 {"integer_field", false, false},
2012 {"int_field1", true, true},
2013 {"int_field2", true, false}}}}};
2014 deviceB_->SetDistributedSchema(distributedSchema);
2015 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv("table_int", db_, deviceB_), E_OK);
2016 Query query = Query::Select("table_int");
2017 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, SCHEMA_MISMATCH,
2018 {deviceB_->GetDeviceId()});
2019 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PUSH_ONLY, SCHEMA_MISMATCH,
2020 {deviceB_->GetDeviceId()});
2021 }
2022
2023 /**
2024 * @tc.name: NormalSync017
2025 * @tc.desc: Test delete other device's data and sync
2026 * @tc.type: FUNC
2027 * @tc.require:
2028 * @tc.author: liaoyonghuang
2029 */
2030 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync017, TestSize.Level1)
2031 {
2032 /**
2033 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2034 * @tc.expected: step1.ok
2035 */
2036 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2037 auto schema = GetSchema();
2038 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2039 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2040 deviceB_->SetDistributedSchema(distributedSchema);
2041 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2042 /**
2043 * @tc.steps: step2. Insert one data
2044 * @tc.expected: step2.ok
2045 */
2046 auto tableSchema = GetTableSchema();
2047 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_, tableSchema), E_OK);
2048 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2049 /**
2050 * @tc.steps: step3. Sync to real device
2051 * @tc.expected: step3.ok
2052 */
2053 Query query = Query::Select(tableSchema.name);
2054 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2055 std::string sql = std::string("select count(*) from ").append(DEVICE_SYNC_TABLE);
2056 int count = 0;
2057 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, sql, count), E_OK);
2058 EXPECT_EQ(count, 1);
2059 /**
2060 * @tc.steps: step4. Delete data and sync again
2061 * @tc.expected: step4.ok
2062 */
2063 EXPECT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_, tableSchema), E_OK);
2064 std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100 ms
2065 sql = std::string("delete from ").append(DEVICE_SYNC_TABLE).append(" where 0 = 0");
2066 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
2067 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2068 sql = std::string("select count(*) from ").append(DEVICE_SYNC_TABLE);
2069 count = 0;
2070 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, sql, count), E_OK);
2071 EXPECT_EQ(count, 0);
2072 auto changeData = delegateObserver_->GetSavedChangedData()[std::string(DEVICE_SYNC_TABLE)];
2073 EXPECT_TRUE(changeData.properties.isP2pSyncDataChange);
2074 }
2075
2076 /**
2077 * @tc.name: NormalSync018
2078 * @tc.desc: Test sync with no primary key table.
2079 * @tc.type: FUNC
2080 * @tc.require:
2081 * @tc.author: liaoyonghuang
2082 */
2083 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync018, TestSize.Level1)
2084 {
2085 /**
2086 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2087 * @tc.expected: step1.ok
2088 */
2089 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2090 std::string tableName = "noPriKeyTable";
2091 std::string sql = "CREATE TABLE IF NOT EXISTS " + tableName + "(pk1 INTEGER, pk2 INT);";
2092 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
2093 /**
2094 * @tc.steps: step2. Create distributed table and set distributed schema
2095 * @tc.expected: step2.ok
2096 */
2097 auto distributedSchema = GetDistributedSchema(tableName, {"pk1", "pk2"});
2098 deviceB_->SetDistributedSchema(distributedSchema);
2099 EXPECT_EQ(delegate_->CreateDistributedTable(tableName, TableSyncType::DEVICE_COOPERATION), OK);
2100 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2101 /**
2102 * @tc.steps: step3. Init data and sync to real device
2103 * @tc.expected: step3.ok
2104 */
2105 TableSchema tableSchema;
2106 tableSchema.name = tableName;
2107 Field field;
2108 field.primary = true;
2109 field.type = TYPE_INDEX<int64_t>;
2110 field.colName = "pk1";
2111 tableSchema.fields.push_back(field);
2112 field.colName = "pk2";
2113 tableSchema.fields.push_back(field);
2114 uint32_t dataCount = 10;
2115 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, dataCount, deviceB_, tableSchema), E_OK);
2116 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableName, db_, deviceB_), E_OK);
2117 Query query = Query::Select(tableName);
2118 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2119 /**
2120 * @tc.steps: step4. check changData
2121 * @tc.expected: step4.ok
2122 */
2123 auto changeData = delegateObserver_->GetSavedChangedData();
2124 ASSERT_EQ(changeData[tableName].primaryData[OP_INSERT].size(), dataCount);
2125 for (uint32_t i = 0; i < dataCount; i++) {
2126 EXPECT_EQ(changeData[tableName].primaryData[OP_INSERT][i].size(), 1u); // rowid
2127 }
2128 EXPECT_EQ(changeData[tableName].field.size(), 1u); // rowid
2129 }
2130
2131 /**
2132 * @tc.name: NormalSync019
2133 * @tc.desc: Test whether there is an observer notification when local win.
2134 * @tc.type: FUNC
2135 * @tc.require:
2136 * @tc.author: liaoyonghuang
2137 */
2138 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync019, TestSize.Level1)
2139 {
2140 /**
2141 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2142 * @tc.expected: step1.ok
2143 */
2144 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2145 auto schema = GetSchema();
2146 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2147 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2148 deviceB_->SetDistributedSchema(distributedSchema);
2149 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2150 /**
2151 * @tc.steps: step2. Insert a piece of data from the other end and then locally insert the same data.
2152 * @tc.expected: step2.ok
2153 */
2154 auto tableSchema = GetTableSchema();
2155 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_, tableSchema), E_OK);
2156 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2157 std::string sql = std::string("insert into ").append(DEVICE_SYNC_TABLE).append("(pk) values (0)");
2158 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
2159 /**
2160 * @tc.steps: step3. Sync to real device
2161 * @tc.expected: step3.ok
2162 */
2163 Query query = Query::Select(tableSchema.name);
2164 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2165 /**
2166 * @tc.steps: step4. Check observer
2167 * @tc.expected: step4.No data change notification
2168 */
2169 auto onChangeCallCount = delegateObserver_->GetCloudCallCount();
2170 EXPECT_EQ(onChangeCallCount, 0u);
2171 }
2172
2173 /**
2174 * @tc.name: NormalSync020
2175 * @tc.desc: Test set distributed schema after recreating the table.
2176 * @tc.type: FUNC
2177 * @tc.require:
2178 * @tc.author: liaoyonghuang
2179 */
2180 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync020, TestSize.Level1)
2181 {
2182 /**
2183 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2184 * @tc.expected: step1.ok
2185 */
2186 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2187 auto schema = GetSchema();
2188 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2189 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2190 deviceB_->SetDistributedSchema(distributedSchema);
2191 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2192 /**
2193 * @tc.steps: step2. Sync a piece of data
2194 * @tc.expected: step2.ok
2195 */
2196 auto tableSchema = GetTableSchema();
2197 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_, tableSchema), E_OK);
2198 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2199 Query query = Query::Select(tableSchema.name);
2200 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2201 /**
2202 * @tc.steps: step3. Recreate table and set distributed schema.
2203 * @tc.expected: step3.ok
2204 */
2205 std::string sql = std::string("drop table ").append(DEVICE_SYNC_TABLE);
2206 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
2207 RDBDataGenerator::InitTable(schema.tables.front(), false, *db_);
2208 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2209 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2210 }
2211
2212 /**
2213 * @tc.name: NormalSync021
2214 * @tc.desc: Test sync multi table.
2215 * @tc.type: FUNC
2216 * @tc.require:
2217 * @tc.author: liaoyonghuang
2218 */
2219 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync021, TestSize.Level1)
2220 {
2221 /**
2222 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2223 * @tc.expected: step1.ok
2224 */
2225 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2226 auto schema = GetSchema();
2227 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2228 deviceB_->SetDistributedSchema(distributedSchema);
2229 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2230 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2231 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE_UPGRADE, TableSyncType::DEVICE_COOPERATION), OK);
2232 /**
2233 * @tc.steps: step2. Insert 10 data
2234 * @tc.expected: step2.ok
2235 */
2236 int dataCount = 10;
2237 auto tableSchema = GetTableSchema();
2238 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, dataCount, deviceB_, tableSchema), E_OK);
2239 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2240 tableSchema = GetTableSchema(true);
2241 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, dataCount, deviceB_, tableSchema), E_OK);
2242 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2243 /**
2244 * @tc.steps: step3. Sync to real device and check data
2245 * @tc.expected: step3.ok
2246 */
2247 Query query = Query::Select().FromTable({DEVICE_SYNC_TABLE, DEVICE_SYNC_TABLE_UPGRADE});
2248 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2249 std::string sql = std::string("select count(*) from ").append(DEVICE_SYNC_TABLE);
2250 int actualCount = 0;
2251 SQLiteUtils::GetCountBySql(db_, sql, actualCount);
2252 EXPECT_EQ(actualCount, dataCount);
2253 sql = std::string("select count(*) from ").append(DEVICE_SYNC_TABLE_UPGRADE);
2254 actualCount = 0;
2255 SQLiteUtils::GetCountBySql(db_, sql, actualCount);
2256 EXPECT_EQ(actualCount, dataCount);
2257 /**
2258 * @tc.steps: step4. Sync with invalid args
2259 * @tc.expected: step4.invalid args
2260 */
2261 query.And();
2262 DBStatus callStatus = delegate_->Sync({deviceB_->GetDeviceId()}, SYNC_MODE_PUSH_ONLY, query, nullptr, true);
2263 EXPECT_EQ(callStatus, NOT_SUPPORT);
2264 }
2265
2266 /**
2267 * @tc.name: NormalSync022
2268 * @tc.desc: Test drop table after sync.
2269 * @tc.type: FUNC
2270 * @tc.require:
2271 * @tc.author: liaoyonghuang
2272 */
2273 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync022, TestSize.Level1)
2274 {
2275 /**
2276 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2277 * @tc.expected: step1.ok
2278 */
2279 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2280 std::string tableName = "noPriKeyTable";
2281 std::string sql = "CREATE TABLE IF NOT EXISTS " + tableName + "(field1 INTEGER, field2 INT);";
2282 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
2283 auto distributedSchema = GetDistributedSchema(tableName, {"field1", "field2"});
2284 deviceB_->SetDistributedSchema(distributedSchema);
2285 EXPECT_EQ(delegate_->CreateDistributedTable(tableName, TableSyncType::DEVICE_COOPERATION), OK);
2286 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2287 /**
2288 * @tc.steps: step2. Insert one piece of data at each end
2289 * @tc.expected: step2.ok
2290 */
2291 TableSchema tableSchema = {tableName, "", {{"field1", TYPE_INDEX<int64_t>}, {"field2", TYPE_INDEX<int64_t>}}};
2292 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_, tableSchema), E_OK);
2293 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2294 sql = "insert into " + tableName + " values(1, 1)";
2295 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
2296 std::string checkLogCountSql = "select count(*) from " + DBCommon::GetLogTableName(tableName);
2297 std::string checkDataCountSql = "select count(*) from " + tableName;
2298 int logCount = 0;
2299 int dataCount = 0;
2300 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkLogCountSql, logCount), E_OK);
2301 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkDataCountSql, dataCount), E_OK);
2302 EXPECT_EQ(logCount, 1);
2303 EXPECT_EQ(dataCount, 1);
2304 /**
2305 * @tc.steps: step3. Sync a piece of data
2306 * @tc.expected: step3.ok
2307 */
2308 Query query = Query::Select(tableSchema.name);
2309 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2310 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkLogCountSql, logCount), E_OK);
2311 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkDataCountSql, dataCount), E_OK);
2312 EXPECT_EQ(dataCount, 2);
2313 EXPECT_EQ(logCount, 2);
2314 /**
2315 * @tc.steps: step4. Drop table and check log count
2316 * @tc.expected: step4.ok
2317 */
2318 checkLogCountSql.append(" where data_key = -1 and flag&0x01 = 0x1;");
2319 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkLogCountSql, logCount), E_OK);
2320 EXPECT_EQ(logCount, 0);
2321 std::string dropTableSql = "drop table " + tableName;
2322 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, dropTableSql), E_OK);
2323 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkLogCountSql, logCount), E_OK);
2324 EXPECT_EQ(logCount, 2);
2325 }
2326
2327 /**
2328 * @tc.name: NormalSync023
2329 * @tc.desc: Test synchronization of autoIncremental primary key table with observer notices.
2330 * @tc.type: FUNC
2331 * @tc.require:
2332 * @tc.author: liaoyonghuang
2333 */
2334 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync023, TestSize.Level1)
2335 {
2336 /**
2337 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2338 * @tc.expected: step1.ok
2339 */
2340 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2341 std::string tableName = "autoIncPriKeyTable";
2342 std::string sql = "CREATE TABLE IF NOT EXISTS " + tableName +
2343 "(pk INTEGER PRIMARY KEY AUTOINCREMENT, field1 INT UNIQUE);";
2344 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
2345 DistributedSchema distributedSchema = {0u, {{tableName, {{"pk", false, false}, {"field1", true, true}}}}};
2346 deviceB_->SetDistributedSchema(distributedSchema);
2347 EXPECT_EQ(delegate_->CreateDistributedTable(tableName, TableSyncType::DEVICE_COOPERATION), OK);
2348 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2349 /**
2350 * @tc.steps: step2. Insert data
2351 * @tc.expected: step2.ok
2352 */
2353 uint32_t dataCount = 10;
2354 TableSchema tableSchema = {tableName, "", {{"pk", TYPE_INDEX<int64_t>, true}, {"field1", TYPE_INDEX<int64_t>}}};
2355 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, dataCount, deviceB_, tableSchema), E_OK);
2356 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2357 /**
2358 * @tc.steps: step3. Sync to real device and check data
2359 * @tc.expected: step3.ok
2360 */
2361 Query query = Query::Select(tableName);
2362 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2363 /**
2364 * @tc.steps: step4. check changData
2365 * @tc.expected: step4.ok
2366 */
2367 auto changeData = delegateObserver_->GetSavedChangedData();
2368 ASSERT_EQ(changeData[tableName].primaryData[OP_INSERT].size(), dataCount);
2369 for (uint32_t i = 0; i < changeData[tableName].primaryData[OP_INSERT].size(); i++) {
2370 auto *data = std::get_if<int64_t>(&changeData[tableName].primaryData[OP_INSERT][i].front());
2371 ASSERT_NE(data, nullptr);
2372 EXPECT_EQ(static_cast<uint32_t>(*data), i + 1);
2373 }
2374 ASSERT_EQ(changeData[tableName].field.size(), 1u);
2375 EXPECT_EQ(changeData[tableName].field.front(), "pk");
2376 }
2377
2378 /**
2379 * @tc.name: NormalSync024
2380 * @tc.desc: Test set tracker table and sync.
2381 * @tc.type: FUNC
2382 * @tc.require:
2383 * @tc.author: lg
2384 */
2385 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync024, TestSize.Level1)
2386 {
2387 /**
2388 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2389 * @tc.expected: step1.ok
2390 */
2391 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2392 auto schema = GetSchema();
2393 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2394 deviceB_->SetDistributedSchema(distributedSchema);
2395 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2396 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2397 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE_UPGRADE, TableSyncType::DEVICE_COOPERATION), OK);
2398
2399 TrackerSchema trackerSchema = {
2400 .tableName = DEVICE_SYNC_TABLE, .extendColNames = {"int_field1"}, .trackerColNames = {"int_field1"}};
2401 delegate_->SetTrackerTable(trackerSchema);
2402
2403 /**
2404 * @tc.steps: step2. close deviceA and reopen it
2405 * @tc.expected: step2.ok
2406 */
2407 RelationalStoreManager mgr(APP_ID, USER_ID);
2408 EXPECT_EQ(mgr.CloseStore(delegate_), OK);
2409 delegate_ = nullptr;
2410 RelationalStoreDelegate::Option option;
2411 option.tableMode = DistributedTableMode::COLLABORATION;
2412 option.observer = delegateObserver_;
2413 ASSERT_EQ(mgr.OpenStore(storePath_, STORE_ID_1, option, delegate_), OK);
2414 ASSERT_NE(delegate_, nullptr);
2415
2416 /**
2417 * @tc.steps: step3. Insert 10 data
2418 * @tc.expected: step3.ok
2419 */
2420 int dataCount = 10;
2421 auto tableSchema = GetTableSchema();
2422 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, dataCount, deviceB_, tableSchema), E_OK);
2423 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2424 tableSchema = GetTableSchema(true);
2425 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, dataCount, deviceB_, tableSchema), E_OK);
2426 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2427 /**
2428 * @tc.steps: step4. Sync to real device and check data
2429 * @tc.expected: step4.ok
2430 */
2431 Query query = Query::Select().FromTable({DEVICE_SYNC_TABLE, DEVICE_SYNC_TABLE_UPGRADE});
2432 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2433 std::string checkLogCountSql = std::string("SELECT COUNT(*) FROM ") + DBCommon::GetLogTableName(DEVICE_SYNC_TABLE) +
2434 " AS a LEFT JOIN " + DEVICE_SYNC_TABLE +
2435 " AS b ON (a.data_key = b._rowid_) WHERE a.data_key = b._rowid_;";
2436 int logCount = 0;
2437 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkLogCountSql, logCount), E_OK);
2438 EXPECT_EQ(logCount, 10);
2439 }
2440
2441 /**
2442 * @tc.name: NormalSync025
2443 * @tc.desc: Test drop table in split_by_device mode will only mark local data as delete in log table
2444 * @tc.type: FUNC
2445 * @tc.require:
2446 * @tc.author: liuhongyang
2447 */
2448 HWTEST_F(DistributedDBRDBCollaborationTest, NormalSync025, TestSize.Level1)
2449 {
2450 /**
2451 * @tc.steps: step1. Create SPLIT_BY_DEVICE tables
2452 * @tc.expected: step1. Ok
2453 */
2454 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::SPLIT_BY_DEVICE));
2455 std::string tableName = "noPKTable025";
2456 std::string createTableSql = "CREATE TABLE IF NOT EXISTS " + tableName + "(field1 INTEGER, field2 INT);";
2457 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, createTableSql), E_OK);
2458 EXPECT_EQ(delegate_->CreateDistributedTable(tableName, TableSyncType::DEVICE_COOPERATION), OK);
2459 /**
2460 * @tc.steps: step2. Insert one piece of data at each end
2461 * @tc.expected: step2. Ok
2462 */
2463 TableSchema tableSchema = {tableName, "", {{"field1", TYPE_INDEX<int64_t>}, {"field2", TYPE_INDEX<int64_t>}}};
2464 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_, tableSchema), E_OK);
2465 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2466 std::string sql = "insert into " + tableName + " values(1, 1)";
2467 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
2468 std::string checkLogCountSql = "select count(*) from " + DBCommon::GetLogTableName(tableName);
2469 std::string checkDataCountSql = "select count(*) from " + tableName;
2470 int logCount = 0;
2471 int dataCount = 0;
2472 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkLogCountSql, logCount), E_OK);
2473 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkDataCountSql, dataCount), E_OK);
2474 EXPECT_EQ(logCount, 1);
2475 EXPECT_EQ(dataCount, 1);
2476 /**
2477 * @tc.steps: step3. Sync to pull deviceB_ data
2478 * @tc.expected: step3. One data in device table and one data in local table
2479 */
2480 Query query = Query::Select(tableSchema.name);
2481 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2482 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkLogCountSql, logCount), E_OK);
2483 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkDataCountSql, dataCount), E_OK);
2484 EXPECT_EQ(dataCount, 1);
2485 EXPECT_EQ(logCount, 2);
2486 std::string checkDeviceTableCountSql = "select count(*) from " +
2487 DBCommon::GetDistributedTableName(deviceB_->GetDeviceId(), tableName);
2488 int deviceDataCount = 0;
2489 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkDeviceTableCountSql, deviceDataCount), E_OK);
2490 EXPECT_EQ(deviceDataCount, 1);
2491 /**
2492 * @tc.steps: step4. Check delete count in log table before drop
2493 * @tc.expected: step4. No deleted records
2494 */
2495 checkLogCountSql.append(" where data_key = -1 and flag&0x01 = 0x1;");
2496 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkLogCountSql, logCount), E_OK);
2497 EXPECT_EQ(logCount, 0);
2498 /**
2499 * @tc.steps: step5. Drop table and recreate
2500 * @tc.expected: step5. Ok
2501 */
2502 std::string dropTableSql = "drop table " + tableName;
2503 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, dropTableSql), E_OK);
2504 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, createTableSql), E_OK);
2505 EXPECT_EQ(delegate_->CreateDistributedTable(tableName, TableSyncType::DEVICE_COOPERATION), OK);
2506 /**
2507 * @tc.steps: step6. Check count
2508 * @tc.expected: step6. only the local record is marked as deleted
2509 */
2510 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkLogCountSql, logCount), E_OK);
2511 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkDataCountSql, dataCount), E_OK);
2512 EXPECT_EQ(SQLiteUtils::GetCountBySql(db_, checkDeviceTableCountSql, deviceDataCount), E_OK);
2513 EXPECT_EQ(logCount, 1);
2514 EXPECT_EQ(dataCount, 0);
2515 EXPECT_EQ(deviceDataCount, 1);
2516 }
2517
2518 /**
2519 * @tc.name: SetStoreConfig001
2520 * @tc.desc: Test set store config.
2521 * @tc.type: FUNC
2522 * @tc.require:
2523 * @tc.author: liaoyonghuang
2524 */
2525 HWTEST_F(DistributedDBRDBCollaborationTest, SetStoreConfig001, TestSize.Level1)
2526 {
2527 /**
2528 * @tc.steps: step1. Create device table and cloud table in SPLIT_BY_DEVICE
2529 * @tc.expected: step1.ok
2530 */
2531 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::SPLIT_BY_DEVICE));
2532 /**
2533 * @tc.steps: step2. Set store config.
2534 * @tc.expected: step2.ok
2535 */
2536 EXPECT_EQ(delegate_->SetStoreConfig({DistributedTableMode::COLLABORATION}), OK);
2537 auto schema = GetSchema();
2538 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2539 deviceB_->SetDistributedSchema(distributedSchema);
2540 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2541 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2542 /**
2543 * @tc.steps: step3. Sync to real device
2544 * @tc.expected: step3.ok
2545 */
2546 auto tableSchema = GetTableSchema();
2547 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 10, deviceB_, tableSchema), E_OK);
2548 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2549 Query query = Query::Select(tableSchema.name);
2550 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2551 }
2552
2553 /**
2554 * @tc.name: SetStoreConfig002
2555 * @tc.desc: Test set store config after create distributed table.
2556 * @tc.type: FUNC
2557 * @tc.require:
2558 * @tc.author: liaoyonghuang
2559 */
2560 HWTEST_F(DistributedDBRDBCollaborationTest, SetStoreConfig002, TestSize.Level0)
2561 {
2562 /**
2563 * @tc.steps: step1. Create device table and cloud table in SPLIT_BY_DEVICE
2564 * @tc.expected: step1.ok
2565 */
2566 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::SPLIT_BY_DEVICE));
2567 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2568 /**
2569 * @tc.steps: step2. Set store config.
2570 * @tc.expected: step2. return not support
2571 */
2572 EXPECT_EQ(delegate_->SetStoreConfig({DistributedTableMode::COLLABORATION}), NOT_SUPPORT);
2573 }
2574
2575 /**
2576 * @tc.name: SetStoreConfig003
2577 * @tc.desc: Test set store config after create distributed table.
2578 * @tc.type: FUNC
2579 * @tc.require:
2580 * @tc.author: lg
2581 */
2582 HWTEST_F(DistributedDBRDBCollaborationTest, SetStoreConfig003, TestSize.Level0)
2583 {
2584 /**
2585 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2586 * @tc.expected: step1.ok
2587 */
2588 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::COLLABORATION));
2589 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2590 /**
2591 * @tc.steps: step2. Set store config.
2592 * @tc.expected: step2. return not support
2593 */
2594 EXPECT_EQ(delegate_->SetStoreConfig({DistributedTableMode::SPLIT_BY_DEVICE}), NOT_SUPPORT);
2595 }
2596
2597 /**
2598 * @tc.name: SetStoreConfig004
2599 * @tc.desc: Test properties for concurrent get and set operations
2600 * @tc.type: FUNC
2601 * @tc.require:
2602 * @tc.author: bty
2603 */
2604 HWTEST_F(DistributedDBRDBCollaborationTest, SetStoreConfig004, TestSize.Level2)
2605 {
2606 /**
2607 * @tc.steps: step1. Create device table and cloud table in SPLIT_BY_DEVICE
2608 * @tc.expected: step1.ok
2609 */
2610 ASSERT_NO_FATAL_FAILURE(InitDelegate(DistributedTableMode::SPLIT_BY_DEVICE));
2611 /**
2612 * @tc.steps: step2. Set store config.
2613 * @tc.expected: step2.ok
2614 */
2615 EXPECT_EQ(delegate_->SetStoreConfig({DistributedTableMode::COLLABORATION}), OK);
2616 auto schema = GetSchema();
2617 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2618 deviceB_->SetDistributedSchema(distributedSchema);
2619 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2620 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2621 /**
2622 * @tc.steps: step3. check for concurrent interface calls
2623 * @tc.expected: step3.ok
2624 */
__anond430f6f20502() 2625 std::thread t1([this, distributedSchema]() {
2626 for (size_t i = 0; i < 10000; i++) {
2627 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2628 }
2629 });
__anond430f6f20602() 2630 std::thread t2([this, distributedSchema]() {
2631 for (size_t i = 0; i < 10000; i++) {
2632 EXPECT_EQ(delegate_->SetStoreConfig({DistributedTableMode::COLLABORATION}), OK);
2633 }
2634 });
2635 t1.join();
2636 t2.join();
2637 }
2638
2639 /**
2640 * @tc.name: InvalidSync001
2641 * @tc.desc: Test remote set empty distributed schema and sync.
2642 * @tc.type: FUNC
2643 * @tc.require:
2644 * @tc.author: bty
2645 */
2646 HWTEST_F(DistributedDBRDBCollaborationTest, InvalidSync001, TestSize.Level1)
2647 {
2648 /**
2649 * @tc.steps: step1. Remote device set empty distributed schema
2650 * @tc.expected: step1.ok
2651 */
2652 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2653 auto schema = GetSchema();
2654 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2655 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2656 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
2657 DistributedSchema emptySchema;
2658 deviceB_->SetDistributedSchema(emptySchema);
2659 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2660 /**
2661 * @tc.steps: step2. Insert one data
2662 * @tc.expected: step2.ok
2663 */
2664 auto tableSchema = GetTableSchema();
2665 EXPECT_EQ(RDBDataGenerator::InsertLocalDBData(0, 1, db_, GetTableSchema()), E_OK);
2666 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2667 /**
2668 * @tc.steps: step3. Sync to real device
2669 * @tc.expected: step3.SCHEMA_MISMATCH
2670 */
2671 Query query = Query::Select(tableSchema.name);
2672 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PUSH_ONLY, SCHEMA_MISMATCH,
2673 {deviceB_->GetDeviceId()});
2674 /**
2675 * @tc.steps: step4. Remove device data
2676 * @tc.expected: step4. NOT_SUPPORT
2677 */
2678 EXPECT_EQ(delegate_->RemoveDeviceData("dev", DEVICE_SYNC_TABLE), NOT_SUPPORT);
2679 EXPECT_EQ(delegate_->RemoveDeviceData(), NOT_SUPPORT);
2680 EXPECT_EQ(delegate_->RemoveDeviceData("dev", ClearMode::DEFAULT), NOT_SUPPORT);
2681 }
2682
2683 /**
2684 * @tc.name: InvalidSync002
2685 * @tc.desc: Test remote set distributed schema but table is not exist then sync.
2686 * @tc.type: FUNC
2687 * @tc.require:
2688 * @tc.author: tankaisheng
2689 */
2690 HWTEST_F(DistributedDBRDBCollaborationTest, InvalidSync002, TestSize.Level0)
2691 {
2692 /**
2693 * @tc.steps: step1. Remote device set distributed schema but table is not exist
2694 * @tc.expected: step1.ok
2695 */
2696 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2697 auto schema = GetSchema();
2698 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2699 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2700 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
2701 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2702 DistributedSchema distributedSchema1;
2703 deviceB_->SetDistributedSchema(distributedSchema1);
2704 /**
2705 * @tc.steps: step2. Insert one data
2706 * @tc.expected: step2.ok
2707 */
2708 auto tableSchema = GetTableSchema();
2709 EXPECT_EQ(RDBDataGenerator::InsertLocalDBData(0, 1, db_, GetTableSchema()), E_OK);
2710 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2711 /**
2712 * @tc.steps: step3. Sync to real device
2713 * @tc.expected: step3.SCHEMA_MISMATCH
2714 */
2715 Query query = Query::Select(DEVICE_SYNC_TABLE);
2716 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PUSH_ONLY, SCHEMA_MISMATCH,
2717 {deviceB_->GetDeviceId()});
2718 }
2719
2720 /**
2721 * @tc.name: InvalidSync003
2722 * @tc.desc: Test sync of deletion when the deleted data has log locally but not found in the actual data table
2723 * @tc.type: FUNC
2724 * @tc.require:
2725 * @tc.author: liuhongyang
2726 */
2727 HWTEST_F(DistributedDBRDBCollaborationTest, InvalidSync003, TestSize.Level0)
2728 {
2729 /**
2730 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2731 * @tc.expected: step1.ok
2732 */
2733 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2734 auto schema = GetSchema();
2735 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2736 deviceB_->SetDistributedSchema(distributedSchema);
2737 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2738 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2739 LOGI("[DistributedDBCloudAsyncDownloadAssetsTest] CreateDistributedTable %s", DEVICE_SYNC_TABLE);
2740 /**
2741 * @tc.steps: step2. Insert 10 data
2742 * @tc.expected: step2.ok
2743 */
2744 auto tableSchema = GetTableSchema();
2745 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 10, deviceB_, tableSchema), E_OK);
2746 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2747 /**
2748 * @tc.steps: step3. Sync to real device to make data consistent
2749 * @tc.expected: step3.ok
2750 */
2751 Query query = Query::Select(tableSchema.name);
2752 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2753 /**
2754 * @tc.steps: step4. Stop writing into log table and remove the first record locally
2755 * @tc.expected: step4. ok and the target scenario is created
2756 */
2757 std::string sql = "INSERT OR REPLACE INTO " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata" +
2758 " VALUES ('log_trigger_switch', 'false');";
2759 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
2760 sql = "DELETE FROM " + std::string(DEVICE_SYNC_TABLE) + " WHERE pk = 0;";
2761 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
2762 sql = "INSERT OR REPLACE INTO " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata" +
2763 " VALUES ('log_trigger_switch', 'true');";
2764 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
2765 /**
2766 * @tc.steps: step5. Delete the first data in virtual device and sync to deviceB_
2767 * @tc.expected: step5. ok
2768 */
2769 delegateObserver_->ClearChangedData();
2770 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, 1, deviceB_, tableSchema, true), E_OK);
2771 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, OK, {deviceB_->GetDeviceId()});
2772 /**
2773 * @tc.steps: step6. check changeData
2774 * @tc.expected: step6. OP_DELETE has one record but the record is empty
2775 */
2776 auto changeData = delegateObserver_->GetSavedChangedData();
2777 ASSERT_EQ(changeData[tableSchema.name].primaryData[OP_DELETE].size(), 1u);
2778 EXPECT_EQ(changeData[tableSchema.name].primaryData[OP_DELETE][0].size(), 0u);
2779 ASSERT_EQ(changeData[tableSchema.name].field.size(), 1u);
2780 EXPECT_EQ(changeData[tableSchema.name].field[0], "pk");
2781 }
2782
2783 /**
2784 * @tc.name: InvalidSync004
2785 * @tc.desc: Test sync with empty tables
2786 * @tc.type: FUNC
2787 * @tc.require:
2788 * @tc.author: liaoyonghuang
2789 */
2790 HWTEST_F(DistributedDBRDBCollaborationTest, InvalidSync004, TestSize.Level0)
2791 {
2792 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2793 Query query = Query::Select().FromTable({});
2794 DBStatus callStatus = delegate_->Sync({deviceB_->GetDeviceId()}, SYNC_MODE_PUSH_ONLY, query, nullptr, true);
2795 EXPECT_EQ(callStatus, INVALID_ARGS);
2796 }
2797
2798 /**
2799 * @tc.name: InvalidSync005
2800 * @tc.desc: Test error returned by the other end during sync
2801 * @tc.type: FUNC
2802 * @tc.require:
2803 * @tc.author: liaoyonghuang
2804 */
2805 HWTEST_F(DistributedDBRDBCollaborationTest, InvalidSync005, TestSize.Level1)
2806 {
2807 /**
2808 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2809 * @tc.expected: step1.ok
2810 */
2811 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2812 auto schema = GetSchema();
2813 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2814 deviceB_->SetDistributedSchema(distributedSchema);
2815 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2816 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2817 /**
2818 * @tc.steps: step2. Prepare device B
2819 * @tc.expected: step2.ok
2820 */
2821 int dataCount = 10;
2822 auto tableSchema = GetTableSchema();
2823 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, dataCount, deviceB_, tableSchema), E_OK);
2824 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2825 /**
2826 * @tc.steps: step3. Set return E_DISTRIBUTED_SCHEMA_NOT_FOUND when get sync data in device B
2827 * @tc.expected: step3.ok
2828 */
2829 deviceB_->SetGetSyncDataResult(-E_DISTRIBUTED_SCHEMA_NOT_FOUND);
2830 /**
2831 * @tc.steps: step4. Sync
2832 * @tc.expected: step4. return SCHEMA_MISMATCH
2833 */
2834 Query query = Query::Select().FromTable({DEVICE_SYNC_TABLE});
2835 DistributedDBToolsUnitTest::BlockSync(*delegate_, query, SYNC_MODE_PULL_ONLY, SCHEMA_MISMATCH,
2836 {deviceB_->GetDeviceId()});
2837 }
2838
2839 /**
2840 * @tc.name: InvalidSync006
2841 * @tc.desc: Test FromTable and other predicates are combined when sync
2842 * @tc.type: FUNC
2843 * @tc.require:
2844 * @tc.author: liaoyonghuang
2845 */
2846 HWTEST_F(DistributedDBRDBCollaborationTest, InvalidSync006, TestSize.Level0)
2847 {
2848 /**
2849 * @tc.steps: step1. Create device table and cloud table in COLLABORATION
2850 * @tc.expected: step1.ok
2851 */
2852 ASSERT_NO_FATAL_FAILURE(InitDelegate());
2853 auto schema = GetSchema();
2854 auto distributedSchema = RDBDataGenerator::ParseSchema(schema, true);
2855 deviceB_->SetDistributedSchema(distributedSchema);
2856 EXPECT_EQ(delegate_->SetDistributedSchema(distributedSchema), OK);
2857 EXPECT_EQ(delegate_->CreateDistributedTable(DEVICE_SYNC_TABLE, TableSyncType::DEVICE_COOPERATION), OK);
2858 /**
2859 * @tc.steps: step2. Prepare device B
2860 * @tc.expected: step2.ok
2861 */
2862 int dataCount = 10;
2863 auto tableSchema = GetTableSchema();
2864 ASSERT_EQ(RDBDataGenerator::InsertVirtualLocalDBData(0, dataCount, deviceB_, tableSchema), E_OK);
2865 ASSERT_EQ(RDBDataGenerator::PrepareVirtualDeviceEnv(tableSchema.name, db_, deviceB_), E_OK);
2866 /**
2867 * @tc.steps: step3. Prepare query list
2868 * @tc.expected: step3.ok
2869 */
2870 std::set<Key> keys = {{1}, {2}, {3}};
2871 std::vector<int> values = {1, 2, 3};
2872 std::vector<Query> queryList = {
2873 Query::Select().FromTable({DEVICE_SYNC_TABLE}).BeginGroup().EqualTo("pk", 1),
2874 Query::Select().FromTable({DEVICE_SYNC_TABLE}).EqualTo("pk", 1),
2875 Query::Select().FromTable({DEVICE_SYNC_TABLE}).GreaterThan("pk", 1),
2876 Query::Select().FromTable({DEVICE_SYNC_TABLE}).GreaterThanOrEqualTo("pk", 1),
2877 Query::Select().FromTable({DEVICE_SYNC_TABLE}).In("pk", values),
2878 Query::Select().FromTable({DEVICE_SYNC_TABLE}).NotIn("pk", values),
2879 Query::Select().FromTable({DEVICE_SYNC_TABLE}).IsNotNull("pk"),
2880 Query::Select().FromTable({DEVICE_SYNC_TABLE}).LessThan("pk", 1),
2881 Query::Select().FromTable({DEVICE_SYNC_TABLE}).LessThanOrEqualTo("pk", 1),
2882 Query::Select().FromTable({DEVICE_SYNC_TABLE}).Like("pk", "abc"),
2883 Query::Select().FromTable({DEVICE_SYNC_TABLE}).NotLike("pk", "abc"),
2884 Query::Select().FromTable({DEVICE_SYNC_TABLE}).OrderByWriteTime(false),
2885 Query::Select().FromTable({DEVICE_SYNC_TABLE}).SuggestIndex("pk"),
2886 Query::Select().FromTable({DEVICE_SYNC_TABLE}).PrefixKey({1, 2, 3}),
2887 Query::Select().FromTable({DEVICE_SYNC_TABLE}).InKeys(keys)
2888 };
2889 /**
2890 * @tc.steps: step4. Sync
2891 * @tc.expected: step4. return NOT_SUPPORT
2892 */
2893 for (const auto &query : queryList) {
2894 DBStatus callStatus = delegate_->Sync({deviceB_->GetDeviceId()}, SYNC_MODE_PUSH_ONLY, query, nullptr, true);
2895 EXPECT_EQ(callStatus, NOT_SUPPORT);
2896 }
2897 }
2898 }