1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifdef RELATIONAL_STORE
16 #include <gtest/gtest.h>
17 #include "cloud/cloud_storage_utils.h"
18 #include "cloud/cloud_db_constant.h"
19 #include "cloud/cloud_db_types.h"
20 #include "db_common.h"
21 #include "distributeddb_data_generate_unit_test.h"
22 #include "log_print.h"
23 #include "relational_store_delegate.h"
24 #include "relational_store_manager.h"
25 #include "runtime_config.h"
26 #include "sqlite_relational_utils.h"
27 #include "time_helper.h"
28 #include "virtual_asset_loader.h"
29 #include "virtual_cloud_data_translate.h"
30 #include "virtual_cloud_db.h"
31 #include "virtual_communicator_aggregator.h"
32
33 namespace {
34 using namespace testing::ext;
35 using namespace DistributedDB;
36 using namespace DistributedDBUnitTest;
37 class DistributedDBCloudReferenceSyncTest : public testing::Test {
38 public:
39 static void SetUpTestCase();
40 static void TearDownTestCase();
41 void SetUp() override;
42 void TearDown() override;
43 protected:
44 void InitTestDir();
45 DataBaseSchema GetSchema();
46 void CloseDb();
47 void SetReference();
48 void InsertUserTableRecord(const std::string &tableName, int64_t recordCounts, bool isShared = false,
49 int64_t begin = 0, std::string owner = "");
50 void UpdateUserTableRecord(const std::string &tableName, int64_t begin, int64_t count);
51 void DeleteUserTableRecord(const std::string &tableName, int64_t begin, int64_t count);
52 void InsertCloudSharedTableRecord(int64_t begin, int64_t count, int64_t photoSize, bool assetIsNull);
53 void UpdateCloudSharedTableRecord(int64_t begin, int64_t count, int64_t photoSize, bool assetIsNull);
54 void DeleteCloudSharedTableRecordByGid(int64_t begin, int64_t count);
55 void CheckCloudData(const std::string &tableName, bool hasRef, const std::vector<Entries> &refData);
56 void CheckDistributedSharedData(const std::vector<std::string> &expect);
57 void CheckSharedDataAfterUpdated(const std::vector<double> &expect);
58 DataBaseSchema GetSchema(const std::vector<std::string> &tableNames);
59 std::vector<std::string> InitMultiTable(int count);
60 static void InitWalModeAndTable(sqlite3 *db, const std::vector<std::string> &tableName);
61 std::string testDir_;
62 std::string storePath_;
63 sqlite3 *db_ = nullptr;
64 RelationalStoreDelegate *delegate_ = nullptr;
65 std::shared_ptr<VirtualCloudDb> virtualCloudDb_ = nullptr;
66 VirtualCommunicatorAggregator *communicatorAggregator_ = nullptr;
67 std::shared_ptr<RelationalStoreManager> mgr_ = nullptr;
68 const std::string parentTableName_ = "parent";
69 const std::string sharedParentTableName_ = "parent_shared";
70 const std::string childTableName_ = "child";
71 const std::string sharedChildTableName_ = "child_shared";
72 const std::vector<std::string> sharedTables_ = { sharedParentTableName_, sharedChildTableName_ };
73 const Asset cloudAsset1_ = {
74 .version = 2, .name = "Phone", .assetId = "0", .subpath = "/local/sync", .uri = "/cloud/sync",
75 .modifyTime = "123456", .createTime = "0", .size = "1024", .hash = "DEC"
76 };
77 const Asset cloudAsset2_ = {
78 .version = 2, .name = "Phone", .assetId = "0", .subpath = "/local/sync", .uri = "/cloud/sync",
79 .modifyTime = "123456", .createTime = "0", .size = "1024", .hash = "UPDATE"
80 };
81 };
82
SetUpTestCase()83 void DistributedDBCloudReferenceSyncTest::SetUpTestCase()
84 {
85 RuntimeConfig::SetCloudTranslate(std::make_shared<VirtualCloudDataTranslate>());
86 }
87
TearDownTestCase()88 void DistributedDBCloudReferenceSyncTest::TearDownTestCase()
89 {}
90
SetUp()91 void DistributedDBCloudReferenceSyncTest::SetUp()
92 {
93 DistributedDBToolsUnitTest::PrintTestCaseInfo();
94 InitTestDir();
95 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(testDir_) != 0) {
96 LOGE("rm test db files error.");
97 }
98 DistributedDBToolsUnitTest::PrintTestCaseInfo();
99 LOGD("Test dir is %s", testDir_.c_str());
100 db_ = RelationalTestUtils::CreateDataBase(storePath_);
101 ASSERT_NE(db_, nullptr);
102 InitWalModeAndTable(db_, { parentTableName_, childTableName_ });
103 mgr_ = std::make_shared<RelationalStoreManager>(APP_ID, USER_ID);
104 RelationalStoreDelegate::Option option;
105 ASSERT_EQ(mgr_->OpenStore(storePath_, STORE_ID_1, option, delegate_), DBStatus::OK);
106 ASSERT_NE(delegate_, nullptr);
107 virtualCloudDb_ = std::make_shared<VirtualCloudDb>();
108 ASSERT_EQ(delegate_->SetCloudDB(virtualCloudDb_), DBStatus::OK);
109 ASSERT_EQ(delegate_->SetIAssetLoader(std::make_shared<VirtualAssetLoader>()), DBStatus::OK);
110 ASSERT_EQ(delegate_->CreateDistributedTable(parentTableName_, CLOUD_COOPERATION), DBStatus::OK);
111 ASSERT_EQ(delegate_->CreateDistributedTable(childTableName_, CLOUD_COOPERATION), DBStatus::OK);
112 SetReference();
113 DataBaseSchema dataBaseSchema = GetSchema();
114 ASSERT_EQ(delegate_->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
115 communicatorAggregator_ = new (std::nothrow) VirtualCommunicatorAggregator();
116 ASSERT_TRUE(communicatorAggregator_ != nullptr);
117 RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicatorAggregator_);
118 }
119
TearDown()120 void DistributedDBCloudReferenceSyncTest::TearDown()
121 {
122 virtualCloudDb_->ForkQuery(nullptr);
123 CloseDb();
124 EXPECT_EQ(sqlite3_close_v2(db_), SQLITE_OK);
125 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(testDir_) != E_OK) {
126 LOGE("rm test db files error.");
127 }
128 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
129 communicatorAggregator_ = nullptr;
130 RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr);
131 }
132
InitTestDir()133 void DistributedDBCloudReferenceSyncTest::InitTestDir()
134 {
135 if (!testDir_.empty()) {
136 return;
137 }
138 DistributedDBToolsUnitTest::TestDirInit(testDir_);
139 storePath_ = testDir_ + "/" + STORE_ID_1 + ".db";
140 LOGI("The test db is:%s", testDir_.c_str());
141 }
142
GetSchema()143 DataBaseSchema DistributedDBCloudReferenceSyncTest::GetSchema()
144 {
145 DataBaseSchema schema;
146 TableSchema tableSchema;
147 tableSchema.name = parentTableName_;
148 tableSchema.sharedTableName = sharedParentTableName_;
149 tableSchema.fields = {
150 {"id", TYPE_INDEX<std::string>, true}, {"name", TYPE_INDEX<std::string>}, {"height", TYPE_INDEX<double>},
151 {"photo", TYPE_INDEX<Bytes>}, {"age", TYPE_INDEX<int64_t>}
152 };
153 TableSchema childSchema;
154 childSchema.name = childTableName_;
155 childSchema.sharedTableName = sharedChildTableName_;
156 childSchema.fields = {
157 {"id", TYPE_INDEX<std::string>, true}, {"name", TYPE_INDEX<std::string>}, {"height", TYPE_INDEX<double>},
158 {"photo", TYPE_INDEX<Bytes>}, {"age", TYPE_INDEX<int64_t>}
159 };
160 schema.tables.push_back(tableSchema);
161 schema.tables.push_back(childSchema);
162 return schema;
163 }
164
GetSchema(const std::vector<std::string> & tableNames)165 DataBaseSchema DistributedDBCloudReferenceSyncTest::GetSchema(const std::vector<std::string> &tableNames)
166 {
167 DataBaseSchema schema;
168 for (const auto &table : tableNames) {
169 TableSchema tableSchema;
170 tableSchema.name = table;
171 tableSchema.sharedTableName = table + "_shared";
172 tableSchema.fields = {
173 {"id", TYPE_INDEX<std::string>, true}, {"name", TYPE_INDEX<std::string>}, {"height", TYPE_INDEX<double>},
174 {"photo", TYPE_INDEX<Bytes>}, {"age", TYPE_INDEX<int64_t>}
175 };
176 schema.tables.push_back(tableSchema);
177 }
178 return schema;
179 }
180
CloseDb()181 void DistributedDBCloudReferenceSyncTest::CloseDb()
182 {
183 virtualCloudDb_ = nullptr;
184 EXPECT_EQ(mgr_->CloseStore(delegate_), DBStatus::OK);
185 delegate_ = nullptr;
186 mgr_ = nullptr;
187 }
188
SetReference()189 void DistributedDBCloudReferenceSyncTest::SetReference()
190 {
191 std::vector<TableReferenceProperty> tableReferenceProperty;
192 TableReferenceProperty property;
193 property.sourceTableName = childTableName_;
194 property.targetTableName = parentTableName_;
195 property.columns["name"] = "name";
196 tableReferenceProperty.push_back(property);
197 delegate_->SetReference(tableReferenceProperty);
198 }
199
InitWalModeAndTable(sqlite3 * db,const std::vector<std::string> & tableName)200 void DistributedDBCloudReferenceSyncTest::InitWalModeAndTable(sqlite3 *db, const std::vector<std::string> &tableName)
201 {
202 ASSERT_NE(db, nullptr);
203 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
204 static constexpr const char *createSQLBegin = "CREATE TABLE IF NOT EXISTS ";
205 static constexpr const char *createSQLEnd = " (" \
206 "id TEXT PRIMARY KEY," \
207 "name TEXT," \
208 "height REAL ," \
209 "photo BLOB," \
210 "age INT);";
211 for (const auto &table : tableName) {
212 std::string createSQL = createSQLBegin + table + createSQLEnd;
213 LOGD("[DistributedDBCloudReferenceSyncTest] create sql is %s", createSQL.c_str());
214 EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSQL), SQLITE_OK);
215 }
216 }
217
InsertUserTableRecord(const std::string & tableName,int64_t recordCounts,bool isShared,int64_t begin,std::string owner)218 void DistributedDBCloudReferenceSyncTest::InsertUserTableRecord(const std::string &tableName,
219 int64_t recordCounts, bool isShared, int64_t begin, std::string owner)
220 {
221 ASSERT_NE(db_, nullptr);
222 for (int64_t i = begin; i < recordCounts; ++i) {
223 string sql = "INSERT OR REPLACE INTO " + tableName + " (";
224 if (isShared) {
225 sql += " cloud_owner, cloud_privilege,";
226 }
227 sql += " id, name, height, photo, age) VALUES (";
228 if (isShared) {
229 if (owner.empty()) {
230 sql += "'mock_owner', 'true', ";
231 } else {
232 sql += "'" + owner + "', 'true', ";
233 }
234 }
235 sql += "'" + std::to_string(i) + "', 'Local";
236 sql += std::to_string(i) + "', '155.10', 'text', '21');";
237 ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
238 }
239 }
240
UpdateUserTableRecord(const std::string & tableName,int64_t begin,int64_t count)241 void DistributedDBCloudReferenceSyncTest::UpdateUserTableRecord(const std::string &tableName, int64_t begin,
242 int64_t count)
243 {
244 string updateAge = "UPDATE " + tableName + " SET age = '99' where id in (";
245 for (int64_t j = begin; j < begin + count; ++j) {
246 updateAge += "'" + std::to_string(j) + "',";
247 }
248 updateAge.pop_back();
249 updateAge += ");";
250 ASSERT_EQ(RelationalTestUtils::ExecSql(db_, updateAge), SQLITE_OK);
251 }
252
DeleteUserTableRecord(const std::string & tableName,int64_t begin,int64_t count)253 void DistributedDBCloudReferenceSyncTest::DeleteUserTableRecord(const std::string &tableName, int64_t begin,
254 int64_t count)
255 {
256 for (int64_t i = begin; i < begin + count; i++) {
257 string sql = "Delete from " + tableName + " where id = " + std::to_string(i) + ";";
258 ASSERT_EQ(RelationalTestUtils::ExecSql(db_, sql), SQLITE_OK);
259 }
260 }
261
InsertCloudSharedTableRecord(int64_t begin,int64_t count,int64_t photoSize,bool assetIsNull)262 void DistributedDBCloudReferenceSyncTest::InsertCloudSharedTableRecord(int64_t begin, int64_t count, int64_t photoSize,
263 bool assetIsNull)
264 {
265 std::vector<uint8_t> photo(photoSize, 'v');
266 std::vector<VBucket> record1;
267 std::vector<VBucket> record2;
268 std::vector<VBucket> extend1;
269 std::vector<VBucket> extend2;
270 Timestamp now = TimeHelper::GetSysCurrentTime();
271 for (int64_t i = begin; i < begin + count; ++i) {
272 VBucket data;
273 data.insert_or_assign(std::string("id"), std::to_string(i));
274 data.insert_or_assign(std::string("name"), std::string("Cloud") + std::to_string(i));
275 data.insert_or_assign(std::string("height"), 166.0); // 166.0 is random double value
276 data.insert_or_assign(std::string("photo"), photo);
277 data.insert_or_assign(std::string("age"), 13L); // 13 is random int64_t value
278 data.insert_or_assign(std::string("cloud_owner"), std::string("a_owner"));
279 data.insert_or_assign(std::string("cloud_privilege"), std::string("true"));
280 Asset asset = cloudAsset1_;
281 asset.name = asset.name + std::to_string(i);
282 assetIsNull ? data.insert_or_assign(std::string("asset"), Nil()) :
283 data.insert_or_assign(std::string("asset"), asset);
284 record1.push_back(data);
285 record2.push_back(data);
286 VBucket log;
287 log.insert_or_assign(CloudDbConstant::CREATE_FIELD,
288 static_cast<int64_t>(now / CloudDbConstant::TEN_THOUSAND + i));
289 log.insert_or_assign(CloudDbConstant::MODIFY_FIELD,
290 static_cast<int64_t>(now / CloudDbConstant::TEN_THOUSAND + i));
291 log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false);
292 extend1.push_back(log);
293 extend2.push_back(log);
294 }
295 ASSERT_EQ(virtualCloudDb_->BatchInsert(sharedParentTableName_, std::move(record1), extend1), DBStatus::OK);
296 ASSERT_EQ(virtualCloudDb_->BatchInsert(sharedChildTableName_, std::move(record2), extend2), DBStatus::OK);
297 std::this_thread::sleep_for(std::chrono::milliseconds(count));
298 }
299
UpdateCloudSharedTableRecord(int64_t begin,int64_t count,int64_t photoSize,bool assetIsNull)300 void DistributedDBCloudReferenceSyncTest::UpdateCloudSharedTableRecord(int64_t begin, int64_t count, int64_t photoSize,
301 bool assetIsNull)
302 {
303 std::vector<uint8_t> photo(photoSize, 'v');
304 std::vector<VBucket> record1;
305 std::vector<VBucket> record2;
306 std::vector<VBucket> extend1;
307 std::vector<VBucket> extend2;
308 Timestamp now = TimeHelper::GetSysCurrentTime();
309 for (int64_t i = begin; i < begin + 2 * count; ++i) { // 2 is two tables shared only one gid
310 VBucket data;
311 data.insert_or_assign("id", std::to_string(i));
312 data.insert_or_assign("name", std::string("Cloud") + std::to_string(i));
313 data.insert_or_assign("height", 188.0); // 188.0 is random double value
314 data.insert_or_assign("photo", photo);
315 data.insert_or_assign("age", 13L); // 13 is random int64_t value
316 data.insert_or_assign("cloud_owner", std::string("b_owner"));
317 data.insert_or_assign("cloud_privilege", std::string("true"));
318 Asset asset = cloudAsset2_;
319 asset.name = asset.name + std::to_string(i);
320 assetIsNull ? data.insert_or_assign("asset", Nil()) : data.insert_or_assign("asset", asset);
321 record1.push_back(data);
322 record2.push_back(data);
323 VBucket log;
324 log.insert_or_assign(CloudDbConstant::CREATE_FIELD,
325 static_cast<int64_t>(now / CloudDbConstant::TEN_THOUSAND + i));
326 log.insert_or_assign(CloudDbConstant::MODIFY_FIELD,
327 static_cast<int64_t>(now / CloudDbConstant::TEN_THOUSAND + i));
328 log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false);
329 log.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(i));
330 extend1.push_back(log);
331 log.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(++i));
332 extend2.push_back(log);
333 }
334 ASSERT_EQ(virtualCloudDb_->BatchUpdate(sharedParentTableName_, std::move(record1), extend1), DBStatus::OK);
335 ASSERT_EQ(virtualCloudDb_->BatchUpdate(sharedChildTableName_, std::move(record2), extend2), DBStatus::OK);
336 std::this_thread::sleep_for(std::chrono::milliseconds(count));
337 }
338
DeleteCloudSharedTableRecordByGid(int64_t begin,int64_t count)339 void DistributedDBCloudReferenceSyncTest::DeleteCloudSharedTableRecordByGid(int64_t begin, int64_t count)
340 {
341 for (size_t i = 0; i < sharedTables_.size(); i++) {
342 for (int64_t j = begin; j < begin + count; ++j) {
343 VBucket data;
344 data.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(j));
345 ASSERT_EQ(virtualCloudDb_->DeleteByGid(sharedTables_[i], data), DBStatus::OK);
346 }
347 }
348 std::this_thread::sleep_for(std::chrono::milliseconds(count));
349 }
350
CheckCloudData(const std::string & tableName,bool hasRef,const std::vector<Entries> & refData)351 void DistributedDBCloudReferenceSyncTest::CheckCloudData(const std::string &tableName, bool hasRef,
352 const std::vector<Entries> &refData)
353 {
354 VBucket extend;
355 extend[CloudDbConstant::CURSOR_FIELD] = std::string();
356 std::vector<VBucket> queryRes;
357 (void) virtualCloudDb_->Query(tableName, extend, queryRes);
358 if (hasRef) {
359 ASSERT_EQ(refData.size(), queryRes.size());
360 }
361 int index = 0;
362 for (const auto &data : queryRes) {
363 if (!hasRef) {
364 EXPECT_EQ(data.find(CloudDbConstant::REFERENCE_FIELD), data.end());
365 continue;
366 }
367 ASSERT_NE(data.find(CloudDbConstant::REFERENCE_FIELD), data.end());
368 Entries entries = std::get<Entries>(data.at(CloudDbConstant::REFERENCE_FIELD));
369 EXPECT_EQ(refData[index], entries);
370 index++;
371 }
372 }
373
CheckDistributedSharedData(const std::vector<std::string> & expect)374 void DistributedDBCloudReferenceSyncTest::CheckDistributedSharedData(const std::vector<std::string> &expect)
375 {
376 for (size_t i = 0; i < sharedTables_.size(); i++) {
377 std::string sql = "SELECT version FROM " + DBCommon::GetLogTableName(sharedTables_[i]) + " WHERE rowid = 1;";
378 sqlite3_stmt *stmt = nullptr;
379 ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
380 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
381 ASSERT_EQ(sqlite3_column_type(stmt, 0), SQLITE_TEXT);
382 Type cloudValue;
383 ASSERT_EQ(SQLiteRelationalUtils::GetCloudValueByType(stmt, TYPE_INDEX<std::string>, 0, cloudValue), E_OK);
384 std::string versionValue;
385 ASSERT_EQ(CloudStorageUtils::GetValueFromOneField(cloudValue, versionValue), E_OK);
386 ASSERT_EQ(versionValue, expect[i]);
387 }
388 int errCode;
389 SQLiteUtils::ResetStatement(stmt, true, errCode);
390 }
391 }
392
CheckSharedDataAfterUpdated(const std::vector<double> & expect)393 void DistributedDBCloudReferenceSyncTest::CheckSharedDataAfterUpdated(const std::vector<double> &expect)
394 {
395 for (size_t i = 0; i < sharedTables_.size(); i++) {
396 std::string sql = "SELECT height FROM " + sharedTables_[i] + " WHERE _rowid_ = 1;";
397 sqlite3_stmt *stmt = nullptr;
398 ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
399 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
400 ASSERT_EQ(sqlite3_column_type(stmt, 0), SQLITE_FLOAT);
401 Type cloudValue;
402 ASSERT_EQ(SQLiteRelationalUtils::GetCloudValueByType(stmt, TYPE_INDEX<double>, 0, cloudValue), E_OK);
403 double heightValue;
404 ASSERT_EQ(CloudStorageUtils::GetValueFromOneField(cloudValue, heightValue), E_OK);
405 EXPECT_EQ(heightValue, expect[i]);
406 }
407 int errCode;
408 SQLiteUtils::ResetStatement(stmt, true, errCode);
409 }
410 }
411
InitMultiTable(int count)412 std::vector<std::string> DistributedDBCloudReferenceSyncTest::InitMultiTable(int count)
413 {
414 std::vector<std::string> tableName;
415 for (int i = 0; i < count; ++i) {
416 std::string table = "table_";
417 table += static_cast<char>(static_cast<int>('a') + i);
418 tableName.push_back(table);
419 }
420 InitWalModeAndTable(db_, tableName);
421 for (const auto &table : tableName) {
422 EXPECT_EQ(delegate_->CreateDistributedTable(table, CLOUD_COOPERATION), DBStatus::OK);
423 LOGW("table %s", table.c_str());
424 }
425 return tableName;
426 }
427
428 /**
429 * @tc.name: CloudSyncTest001
430 * @tc.desc: sync table with reference
431 * @tc.type: FUNC
432 * @tc.require:
433 * @tc.author: zhangqiquan
434 */
435 HWTEST_F(DistributedDBCloudReferenceSyncTest, CloudSyncTest001, TestSize.Level0)
436 {
437 std::vector<std::string> tableNames = { parentTableName_, childTableName_ };
438 Query query = Query::Select().FromTable(tableNames);
439 RelationalTestUtils::CloudBlockSync(query, delegate_);
440
441 InsertUserTableRecord(parentTableName_, 1);
442 InsertUserTableRecord(childTableName_, 1);
443 RelationalTestUtils::CloudBlockSync(query, delegate_);
444 LOGD("check parent table");
445 CheckCloudData(parentTableName_, false, {});
446 LOGD("check child table");
447 std::vector<Entries> expectEntries;
448 Entries entries;
449 entries[parentTableName_] = "0";
450 expectEntries.push_back(entries);
451 CheckCloudData(childTableName_, true, expectEntries);
452 }
453
454 /**
455 * @tc.name: CloudSyncTest002
456 * @tc.desc: sync shared table with reference
457 * @tc.type: FUNC
458 * @tc.require:
459 * @tc.author: zhangqiquan
460 */
461 HWTEST_F(DistributedDBCloudReferenceSyncTest, CloudSyncTest002, TestSize.Level0)
462 {
463 std::vector<std::string> tableNames = { sharedParentTableName_, sharedChildTableName_ };
464 Query query = Query::Select().FromTable(tableNames);
465 RelationalTestUtils::CloudBlockSync(query, delegate_);
466
467 InsertUserTableRecord(sharedParentTableName_, 1, true);
468 InsertUserTableRecord(sharedChildTableName_, 1, true);
469 RelationalTestUtils::CloudBlockSync(query, delegate_);
470 LOGD("check parent table");
471 CheckCloudData(sharedParentTableName_, false, {});
472 LOGD("check child table");
473 std::vector<Entries> expectEntries;
474 Entries entries;
475 entries[sharedParentTableName_] = "0";
476 expectEntries.push_back(entries);
477 CheckCloudData(sharedChildTableName_, true, expectEntries);
478 }
479
480 /**
481 * @tc.name: CloudSyncTest003
482 * @tc.desc: sync with invalid table reference
483 * @tc.type: FUNC
484 * @tc.require:
485 * @tc.author: zhangqiquan
486 */
487 HWTEST_F(DistributedDBCloudReferenceSyncTest, CloudSyncTest003, TestSize.Level0)
488 {
489 std::vector<std::string> tableNames = { childTableName_, parentTableName_ };
490 Query query = Query::Select().FromTable(tableNames);
491 RelationalTestUtils::CloudBlockSync(query, delegate_, DistributedDB::INVALID_ARGS);
492
493 tableNames = { sharedChildTableName_, sharedParentTableName_ };
494 query = Query::Select().FromTable(tableNames);
495 RelationalTestUtils::CloudBlockSync(query, delegate_, DistributedDB::INVALID_ARGS);
496
497 tableNames = { sharedChildTableName_, parentTableName_ };
498 query = Query::Select().FromTable(tableNames);
499 RelationalTestUtils::CloudBlockSync(query, delegate_, DistributedDB::OK);
500
501 tableNames = { childTableName_, sharedParentTableName_ };
502 query = Query::Select().FromTable(tableNames);
503 RelationalTestUtils::CloudBlockSync(query, delegate_, DistributedDB::OK);
504 }
505
506 /**
507 * @tc.name: CloudSyncTest004
508 * @tc.desc: sync shared table and check version, cloud insert, local update, local delete
509 * @tc.type: FUNC
510 * @tc.require:
511 * @tc.author: chenchaohao
512 */
513 HWTEST_F(DistributedDBCloudReferenceSyncTest, CloudSyncTest004, TestSize.Level0)
514 {
515 /**
516 * @tc.steps: step1. cloud insert records then sync, check distributed shared table
517 * @tc.expected: OK.
518 */
519 int64_t num = 200;
520 std::vector<std::string> tableNames = { sharedParentTableName_, sharedChildTableName_ };
521 Query query = Query::Select().FromTable(tableNames);
522 RelationalTestUtils::CloudBlockSync(query, delegate_);
523 InsertCloudSharedTableRecord(0, num, 10240, true);
524 RelationalTestUtils::CloudBlockSync(query, delegate_);
525 CheckDistributedSharedData({"0", "200"});
526
527 /**
528 * @tc.steps: step2. user update records then sync, check distributed shared table
529 * @tc.expected: OK.
530 */
531 UpdateUserTableRecord(sharedParentTableName_, 0, num);
532 UpdateUserTableRecord(sharedChildTableName_, 0, num);
533 RelationalTestUtils::CloudBlockSync(query, delegate_);
534 CheckDistributedSharedData({"400", "600"});
535 CheckCloudData(sharedParentTableName_, false, {});
536 std::vector<Entries> expectEntries;
537 Entries entries;
538 for (size_t i = 0; i < 100; i++) { // 100 is max cloud query num
539 entries[sharedParentTableName_] = std::to_string(i);
540 expectEntries.push_back(entries);
541 }
542 CheckCloudData(sharedChildTableName_, true, expectEntries);
543
544 /**
545 * @tc.steps: step3. user delete records then sync, check distributed shared table
546 * @tc.expected: OK.
547 */
548 DeleteUserTableRecord(sharedParentTableName_, 0, 1);
549 DeleteUserTableRecord(sharedChildTableName_, 0, 1);
550 RelationalTestUtils::CloudBlockSync(query, delegate_);
551 CheckDistributedSharedData({"400", "600"});
552 }
553
554 /**
555 * @tc.name: CloudSyncTest005
556 * @tc.desc: sync shared table and check version, local insert, cloud delete, local update
557 * @tc.type: FUNC
558 * @tc.require:
559 * @tc.author: chenchaohao
560 */
561 HWTEST_F(DistributedDBCloudReferenceSyncTest, CloudSyncTest005, TestSize.Level0)
562 {
563 /**
564 * @tc.steps: step1. user insert records then sync, check distributed shared table
565 * @tc.expected: OK.
566 */
567 std::vector<std::string> tableNames = { sharedParentTableName_, sharedChildTableName_ };
568 Query query = Query::Select().FromTable(tableNames);
569 RelationalTestUtils::CloudBlockSync(query, delegate_);
570 InsertUserTableRecord(sharedParentTableName_, 1, true, 0);
571 InsertUserTableRecord(sharedChildTableName_, 1, true, 0);
572 RelationalTestUtils::CloudBlockSync(query, delegate_);
573 CheckDistributedSharedData({"0", "1"});
574
575 /**
576 * @tc.steps: step2. user update records then sync, check distributed shared table
577 * @tc.expected: OK.
578 */
579 DeleteCloudSharedTableRecordByGid(0, 2);
580 UpdateUserTableRecord(sharedParentTableName_, 0, 1);
581 UpdateUserTableRecord(sharedChildTableName_, 0, 1);
582 RelationalTestUtils::CloudBlockSync(query, delegate_);
583 CheckDistributedSharedData({"2", "3"});
584 CheckCloudData(sharedParentTableName_, false, {});
585 std::vector<Entries> expectEntries;
586 Entries entries;
587 entries[sharedParentTableName_] = "0";
588 expectEntries.push_back(entries);
589 entries = {};
590 entries[sharedParentTableName_] = "2";
591 expectEntries.push_back(entries);
592 CheckCloudData(sharedChildTableName_, true, expectEntries);
593 }
594
595 /**
596 * @tc.name: CloudSyncTest006
597 * @tc.desc: sync shared table and check version, cloud insert, cloud update
598 * @tc.type: FUNC
599 * @tc.require:
600 * @tc.author: chenchaohao
601 */
602 HWTEST_F(DistributedDBCloudReferenceSyncTest, CloudSyncTest006, TestSize.Level0)
603 {
604 /**
605 * @tc.steps: step1. user insert records then sync, check distributed shared table
606 * @tc.expected: OK.
607 */
608 std::vector<std::string> tableNames = { sharedParentTableName_, sharedChildTableName_ };
609 Query query = Query::Select().FromTable(tableNames);
610 RelationalTestUtils::CloudBlockSync(query, delegate_);
611 InsertCloudSharedTableRecord(0, 1, 1, true);
612 RelationalTestUtils::CloudBlockSync(query, delegate_);
613 CheckDistributedSharedData({"0", "1"});
614
615 /**
616 * @tc.steps: step2. cloud update records then sync, check distributed shared table
617 * @tc.expected: OK.
618 */
619 UpdateCloudSharedTableRecord(0, 1, 1, true);
620 RelationalTestUtils::CloudBlockSync(query, delegate_);
621 CheckDistributedSharedData({"2", "3"});
622 }
623
624 /**
625 * @tc.name: CloudSyncTest007
626 * @tc.desc: there is no gid locally, shared table sync
627 * @tc.type: FUNC
628 * @tc.require:
629 * @tc.author: bty
630 */
631 HWTEST_F(DistributedDBCloudReferenceSyncTest, CloudSyncTest007, TestSize.Level0)
632 {
633 /**
634 * @tc.steps: step1. user insert records then sync, check distributed shared table
635 * @tc.expected: OK.
636 */
637 std::vector<std::string> tableNames = { sharedParentTableName_, sharedChildTableName_ };
638 Query query = Query::Select().FromTable(tableNames);
639 RelationalTestUtils::CloudBlockSync(query, delegate_);
640 InsertUserTableRecord(sharedParentTableName_, 1, true, 0, "a_owner");
641 InsertUserTableRecord(sharedChildTableName_, 1, true, 0, "a_owner");
642 std::this_thread::sleep_for(std::chrono::milliseconds(1));
643 InsertCloudSharedTableRecord(0, 1, 1, true);
644 RelationalTestUtils::CloudBlockSync(query, delegate_);
645 CheckSharedDataAfterUpdated({166.0, 166.0}); // 166.0 is the height col val on the cloud
646 }
647
648 /**
649 * @tc.name: CloudSyncTest008
650 * @tc.desc: sync with dot storeId
651 * @tc.type: FUNC
652 * @tc.require:
653 * @tc.author: zhangqiquan
654 */
655 HWTEST_F(DistributedDBCloudReferenceSyncTest, CloudSyncTest008, TestSize.Level0)
656 {
657 /**
658 * @tc.steps: step1. open store with dot store id
659 * @tc.expected: open ok.
660 */
661 RelationalStoreDelegate::Option option;
662 RelationalStoreDelegate *delegate = nullptr;
663 ASSERT_EQ(mgr_->OpenStore(storePath_, STORE_ID_1 + ".test", option, delegate), DBStatus::OK);
664 ASSERT_NE(delegate, nullptr);
665 EXPECT_EQ(delegate->SetCloudDB(virtualCloudDb_), DBStatus::OK);
666 EXPECT_EQ(delegate->SetIAssetLoader(std::make_shared<VirtualAssetLoader>()), DBStatus::OK);
667 EXPECT_EQ(delegate->CreateDistributedTable(parentTableName_, CLOUD_COOPERATION), DBStatus::OK);
668 EXPECT_EQ(delegate->CreateDistributedTable(childTableName_, CLOUD_COOPERATION), DBStatus::OK);
669 SetReference();
670 DataBaseSchema dataBaseSchema = GetSchema();
671 EXPECT_EQ(delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
672 /**
673 * @tc.steps: step2. call cloud sync
674 * @tc.expected: sync ok.
675 */
676 std::vector<std::string> tableNames = { parentTableName_, childTableName_ };
677 Query query = Query::Select().FromTable(tableNames);
678 RelationalTestUtils::CloudBlockSync(query, delegate_);
679 /**
680 * @tc.steps: step3. insert data and cloud sync again
681 * @tc.expected: sync ok.
682 */
683 InsertUserTableRecord(parentTableName_, 1);
684 InsertUserTableRecord(childTableName_, 1);
685 RelationalTestUtils::CloudBlockSync(query, delegate_);
686 /**
687 * @tc.steps: step4. close store
688 * @tc.expected: close ok.
689 */
690 EXPECT_EQ(mgr_->CloseStore(delegate), DBStatus::OK);
691 }
692
ComplexReferenceCheck001SetReference(RelationalStoreDelegate * delegate)693 void ComplexReferenceCheck001SetReference(RelationalStoreDelegate *delegate)
694 {
695 // the reference like this
696 // h <- a
697 // b c
698 // d e f g
699 std::vector<TableReferenceProperty> tableReferenceProperty;
700 TableReferenceProperty property;
701 property.sourceTableName = "table_d";
702 property.targetTableName = "table_b";
703 property.columns["name"] = "name";
704 tableReferenceProperty.push_back(property);
705
706 property.sourceTableName = "table_e";
707 property.targetTableName = "table_b";
708 tableReferenceProperty.push_back(property);
709
710 property.sourceTableName = "table_f";
711 property.targetTableName = "table_c";
712 tableReferenceProperty.push_back(property);
713
714 property.sourceTableName = "table_g";
715 property.targetTableName = "table_c";
716 tableReferenceProperty.push_back(property);
717
718 property.sourceTableName = "table_b";
719 property.targetTableName = "table_a";
720 tableReferenceProperty.push_back(property);
721
722 property.sourceTableName = "table_b";
723 property.targetTableName = "table_h";
724 tableReferenceProperty.push_back(property);
725
726 property.sourceTableName = "table_c";
727 property.targetTableName = "table_a";
728 tableReferenceProperty.push_back(property);
729
730 property.sourceTableName = "table_a";
731 property.targetTableName = "table_h";
732 tableReferenceProperty.push_back(property);
733 delegate->SetReference(tableReferenceProperty);
734 }
735
736 /**
737 * @tc.name: ComplexReferenceCheck001
738 * @tc.desc: sync with complex table reference
739 * @tc.type: FUNC
740 * @tc.require:
741 * @tc.author: zhangqiquan
742 */
743 HWTEST_F(DistributedDBCloudReferenceSyncTest, ComplexReferenceCheck001, TestSize.Level0)
744 {
745 auto tableName = InitMultiTable(8); // 8 table
746 ComplexReferenceCheck001SetReference(delegate_);
747 ASSERT_EQ(delegate_->SetCloudDbSchema(GetSchema(tableName)), DBStatus::OK);
748
749 std::vector<std::string> tableNames = { "table_a", "table_b", "table_d" };
750 Query query = Query::Select().FromTable(tableNames);
751 RelationalTestUtils::CloudBlockSync(query, delegate_);
752
753 tableNames = { "table_a", "table_b", "table_c", "table_h" };
754 query = Query::Select().FromTable(tableNames);
755 RelationalTestUtils::CloudBlockSync(query, delegate_, INVALID_ARGS);
756
757 tableNames = { "table_h", "table_e" };
758 query = Query::Select().FromTable(tableNames);
759 RelationalTestUtils::CloudBlockSync(query, delegate_);
760
761 tableNames = { "table_e" };
762 query = Query::Select().FromTable(tableNames);
763 RelationalTestUtils::CloudBlockSync(query, delegate_);
764 }
765
ComplexReferenceCheck002SetReference(RelationalStoreDelegate * delegate)766 void ComplexReferenceCheck002SetReference(RelationalStoreDelegate *delegate)
767 {
768 // the reference like this
769 // a -> b -> c -> d -> e
770 std::vector<TableReferenceProperty> tableReferenceProperty;
771 TableReferenceProperty property;
772 property.sourceTableName = "table_a";
773 property.targetTableName = "table_b";
774 property.columns["name"] = "name";
775 tableReferenceProperty.push_back(property);
776
777 property.sourceTableName = "table_c";
778 property.targetTableName = "table_d";
779 tableReferenceProperty.push_back(property);
780
781 property.sourceTableName = "table_d";
782 property.targetTableName = "table_e";
783 tableReferenceProperty.push_back(property);
784
785 property.sourceTableName = "table_b";
786 property.targetTableName = "table_c";
787 tableReferenceProperty.push_back(property);
788
789 delegate->SetReference(tableReferenceProperty);
790 }
791
792 /**
793 * @tc.name: ComplexReferenceCheck002
794 * @tc.desc: sync with complex table reference
795 * @tc.type: FUNC
796 * @tc.require:
797 * @tc.author: zhangqiquan
798 */
799 HWTEST_F(DistributedDBCloudReferenceSyncTest, ComplexReferenceCheck002, TestSize.Level0)
800 {
801 auto tableName = InitMultiTable(5); // 5 table
802 ASSERT_EQ(delegate_->SetCloudDbSchema(GetSchema(tableName)), DBStatus::OK);
803 ComplexReferenceCheck002SetReference(delegate_);
804
805 std::vector<std::string> tableNames = { "table_a", "table_e" };
806 Query query = Query::Select().FromTable(tableNames);
807 RelationalTestUtils::CloudBlockSync(query, delegate_, DistributedDB::INVALID_ARGS);
808
809 tableNames = { "table_e", "table_a" };
810 query = Query::Select().FromTable(tableNames);
811 RelationalTestUtils::CloudBlockSync(query, delegate_);
812
813 tableNames = { "table_a", "table_a_shared" };
814 query = Query::Select().FromTable(tableNames);
815 std::vector<std::string> actualTables;
816 std::set<std::string> addTables;
__anon789e90cf0202(const std::string &table, VBucket &) 817 virtualCloudDb_->ForkQuery([&addTables, &actualTables](const std::string &table, VBucket &) {
818 if (addTables.find(table) != addTables.end()) {
819 return ;
820 }
821 actualTables.push_back(table);
822 addTables.insert(table);
823 });
824 RelationalTestUtils::CloudBlockSync(query, delegate_);
825 virtualCloudDb_->ForkQuery(nullptr);
826 for (const auto &item : actualTables) {
827 LOGW("table is %s", item.c_str());
828 }
829 ASSERT_EQ(actualTables.size(), tableName.size() * 2); // 2 is table size + shared table size
830 // expect res table is table_e table_d ... table_e_shared table_a_shared
831 for (size_t i = 0; i < tableName.size(); ++i) {
832 size_t expectIndex = tableName.size() - 1 - i;
833 size_t expectSharedIndex = expectIndex + tableName.size();
834 const std::string actualTable = actualTables[expectIndex];
835 const std::string actualSharedTable = actualTables[expectSharedIndex];
836 bool equal = (actualTable == tableName[i]);
837 equal = equal && (actualSharedTable == (tableName[i] + "_shared"));
838 LOGW("index %zu expectIndex %zu expectSharedIndex %zu actualTable %s actualSharedTable %s",
839 i, expectIndex, expectSharedIndex, actualTable.c_str(), actualSharedTable.c_str());
840 EXPECT_TRUE(equal);
841 }
842 }
843
844 /**
845 * @tc.name: ComplexReferenceCheck003
846 * @tc.desc: sync with complex table reference
847 * @tc.type: FUNC
848 * @tc.require:
849 * @tc.author: bty
850 */
851 HWTEST_F(DistributedDBCloudReferenceSyncTest, ComplexReferenceCheck003, TestSize.Level0)
852 {
853 /**
854 * @tc.steps: step1. init reference table, and reopen db
855 * @tc.expected: OK.
856 */
857 auto tableName = InitMultiTable(8); // 8 table
858 ComplexReferenceCheck001SetReference(delegate_);
859 ASSERT_EQ(delegate_->SetCloudDbSchema(GetSchema(tableName)), DBStatus::OK);
860 virtualCloudDb_ = nullptr;
861 EXPECT_EQ(mgr_->CloseStore(delegate_), DBStatus::OK);
862 delegate_ = nullptr;
863 RelationalStoreDelegate::Option option;
864 ASSERT_EQ(mgr_->OpenStore(storePath_, STORE_ID_1, option, delegate_), DBStatus::OK);
865 ASSERT_NE(delegate_, nullptr);
866 virtualCloudDb_ = std::make_shared<VirtualCloudDb>();
867 ASSERT_EQ(delegate_->SetCloudDB(virtualCloudDb_), DBStatus::OK);
868 ASSERT_EQ(delegate_->SetIAssetLoader(std::make_shared<VirtualAssetLoader>()), DBStatus::OK);
869 ASSERT_EQ(delegate_->SetCloudDbSchema(GetSchema(tableName)), DBStatus::OK);
870 tableName = InitMultiTable(8);
871
872 /**
873 * @tc.steps: step2. init local data, sync
874 * @tc.expected: OK.
875 */
876 int64_t num = 10;
877 InsertUserTableRecord("table_a", num);
878 InsertUserTableRecord("table_b", num);
879 InsertUserTableRecord("table_c", num);
880 std::vector<std::string> tableNames = { "table_a", "table_b", "table_c" };
881 Query query = Query::Select().FromTable(tableNames);
882 RelationalTestUtils::CloudBlockSync(query, delegate_);
883
884 /**
885 * @tc.steps: step3. operator target table, check source table timeStamp
886 * @tc.expected: OK.
887 */
888 sqlite3_stmt *stmt = nullptr;
889 ASSERT_EQ(SQLiteUtils::GetStatement(db_, "SELECT max(timestamp) FROM " + DBCommon::GetLogTableName("table_c"),
890 stmt), E_OK);
891 ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt, false), SQLiteUtils::MapSQLiteErrno(SQLITE_ROW));
892 int64_t timeStamp = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
893 int errCode;
894 SQLiteUtils::ResetStatement(stmt, true, errCode);
895 std::string updateSql = "UPDATE table_a SET name = '99' where id = 1";
896 ASSERT_EQ(RelationalTestUtils::ExecSql(db_, updateSql), SQLITE_OK);
897 std::string deleteSql = "DELETE FROM table_a where id = 2";
898 ASSERT_EQ(RelationalTestUtils::ExecSql(db_, deleteSql), SQLITE_OK);
899 updateSql = "UPDATE table_a SET age = '99' where id = 3";
900 ASSERT_EQ(RelationalTestUtils::ExecSql(db_, updateSql), SQLITE_OK);
901 stmt = nullptr;
902 ASSERT_EQ(SQLiteUtils::GetStatement(db_, "SELECT count(*) FROM " + DBCommon::GetLogTableName("table_c") +
903 " WHERE timestamp > '" + std::to_string(timeStamp) + "';", stmt), E_OK);
904 ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt, false), SQLiteUtils::MapSQLiteErrno(SQLITE_ROW));
905 int64_t count = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
906 SQLiteUtils::ResetStatement(stmt, true, errCode);
907 EXPECT_EQ(count, 2L); // 2 is changed log num
908 RelationalTestUtils::CloudBlockSync(query, delegate_);
909 }
910
911 /**
912 * @tc.name: ComplexReferenceCheck004
913 * @tc.desc: sync with complex table reference
914 * @tc.type: FUNC
915 * @tc.require:
916 * @tc.author: bty
917 */
918 HWTEST_F(DistributedDBCloudReferenceSyncTest, ComplexReferenceCheck004, TestSize.Level0)
919 {
920 /**
921 * @tc.steps: step1. init table and set reference twice
922 * @tc.expected: OK.
923 */
924 auto tableName = InitMultiTable(8); // 8 table
925 ASSERT_EQ(delegate_->SetCloudDbSchema(GetSchema(tableName)), DBStatus::OK);
926 ComplexReferenceCheck001SetReference(delegate_);
927 ComplexReferenceCheck001SetReference(delegate_);
928
929 /**
930 * @tc.steps: step2. init local data, sync
931 * @tc.expected: OK.
932 */
933 InsertUserTableRecord("table_b", 10);
934 InsertUserTableRecord("table_d", 10);
935 InsertUserTableRecord("table_e", 10);
936 std::vector<std::string> tableNames = { "table_b", "table_d", "table_e" };
937 Query query = Query::Select().FromTable(tableNames);
938 RelationalTestUtils::CloudBlockSync(query, delegate_);
939
940 /**
941 * @tc.steps: step3. operator target table, check source table timeStamp
942 * @tc.expected: OK.
943 */
944 sqlite3_stmt *stmt = nullptr;
945 ASSERT_EQ(SQLiteUtils::GetStatement(db_, "SELECT max(timestamp) FROM " + DBCommon::GetLogTableName("table_d"),
946 stmt), E_OK);
947 ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt, false), SQLiteUtils::MapSQLiteErrno(SQLITE_ROW));
948 int64_t timeStamp = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
949 int errCode;
950 SQLiteUtils::ResetStatement(stmt, true, errCode);
951 std::string updateSql = "UPDATE table_b SET name = '99' where id = 4";
952 ASSERT_EQ(RelationalTestUtils::ExecSql(db_, updateSql), SQLITE_OK);
953 std::string deleteSql = "DELETE FROM table_b where id = 6";
954 ASSERT_EQ(RelationalTestUtils::ExecSql(db_, deleteSql), SQLITE_OK);
955 updateSql = "UPDATE table_b SET age = '99' where id = 7";
956 ASSERT_EQ(RelationalTestUtils::ExecSql(db_, updateSql), SQLITE_OK);
957 stmt = nullptr;
958 ASSERT_EQ(SQLiteUtils::GetStatement(db_, "SELECT count(*) FROM " + DBCommon::GetLogTableName("table_d") +
959 " WHERE timestamp > '" + std::to_string(timeStamp) + "';", stmt), E_OK);
960 ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt, false), SQLiteUtils::MapSQLiteErrno(SQLITE_ROW));
961 int64_t count = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
962 SQLiteUtils::ResetStatement(stmt, true, errCode);
963 EXPECT_EQ(count, 2L);
964 RelationalTestUtils::CloudBlockSync(query, delegate_);
965 }
966
967 /**
968 * @tc.name: ComplexReferenceCheck005
969 * @tc.desc: sync with complex table reference
970 * @tc.type: FUNC
971 * @tc.require:
972 * @tc.author: zhangqiquan
973 */
974 HWTEST_F(DistributedDBCloudReferenceSyncTest, ComplexReferenceCheck005, TestSize.Level1)
975 {
976 auto tableName = InitMultiTable(26); // 26 table is alphabet count
977 ASSERT_EQ(delegate_->SetCloudDbSchema(GetSchema(tableName)), DBStatus::OK);
978 std::vector<TableReferenceProperty> tableReferenceProperty;
979 TableReferenceProperty property;
980 property.columns["name"] = "name";
981 for (size_t i = 0; i < tableName.size() - 1; ++i) {
982 property.sourceTableName = tableName[i];
983 property.targetTableName = tableName[i + 1];
984 tableReferenceProperty.push_back(property);
985 }
986 delegate_->SetReference(tableReferenceProperty);
987
988 std::vector<std::string> tableNames = { "table_e" };
989 Query query = Query::Select().FromTable(tableNames);
990 RelationalTestUtils::CloudBlockSync(query, delegate_);
991 }
992
993 /**
994 * @tc.name: ComplexReferenceCheck006
995 * @tc.desc: sync with upper table reference
996 * @tc.type: FUNC
997 * @tc.require:
998 * @tc.author: zhangqiquan
999 */
1000 HWTEST_F(DistributedDBCloudReferenceSyncTest, ComplexReferenceCheck006, TestSize.Level1)
1001 {
1002 auto tableName = InitMultiTable(2); // 2 table is alphabet count
1003 ASSERT_EQ(delegate_->SetCloudDbSchema(GetSchema(tableName)), DBStatus::OK);
1004 std::vector<TableReferenceProperty> tableReferenceProperty;
1005 TableReferenceProperty property;
1006 property.columns["name"] = "name";
1007 for (size_t i = 0; i < tableName.size() - 1; ++i) {
1008 property.sourceTableName = tableName[i];
1009 property.targetTableName = DBCommon::ToUpperCase(tableName[i + 1]);
1010 tableReferenceProperty.push_back(property);
1011 }
1012 delegate_->SetReference(tableReferenceProperty);
1013
1014 std::vector<std::string> tableNames = { "table_a" };
1015 Query query = Query::Select().FromTable(tableNames);
1016 RelationalTestUtils::CloudBlockSync(query, delegate_);
1017 }
1018
1019 /**
1020 * @tc.name: SetSharedReference001
1021 * @tc.desc: test set shared table
1022 * @tc.type: FUNC
1023 * @tc.require:
1024 * @tc.author: zhangqiquan
1025 */
1026 HWTEST_F(DistributedDBCloudReferenceSyncTest, SetSharedReference001, TestSize.Level0)
1027 {
1028 std::vector<TableReferenceProperty> tableReferenceProperty;
1029 TableReferenceProperty property;
1030 property.columns["name"] = "name";
1031 property.sourceTableName = childTableName_;
1032 property.targetTableName = sharedParentTableName_;
1033 tableReferenceProperty.push_back(property);
1034 EXPECT_EQ(delegate_->SetReference(tableReferenceProperty), NOT_SUPPORT);
1035
1036 property.sourceTableName = sharedChildTableName_;
1037 property.targetTableName = parentTableName_;
1038 tableReferenceProperty.clear();
1039 tableReferenceProperty.push_back(property);
1040 EXPECT_EQ(delegate_->SetReference(tableReferenceProperty), NOT_SUPPORT);
1041
1042 property.sourceTableName = sharedChildTableName_;
1043 property.targetTableName = sharedParentTableName_;
1044 tableReferenceProperty.clear();
1045 tableReferenceProperty.push_back(property);
1046 EXPECT_EQ(delegate_->SetReference(tableReferenceProperty), NOT_SUPPORT);
1047 }
1048 }
1049 #endif // RELATIONAL_STORE