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