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