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 
16 #include <gtest/gtest.h>
17 
18 #include "cloud/cloud_storage_utils.h"
19 #include "cloud/cloud_db_constant.h"
20 #include "cloud/cloud_db_types.h"
21 #include "db_common.h"
22 #include "db_constant.h"
23 #include "distributeddb_data_generate_unit_test.h"
24 #include "distributeddb_tools_unit_test.h"
25 #include "relational_store_client.h"
26 #include "relational_store_delegate_impl.h"
27 #include "relational_store_manager.h"
28 #include "runtime_config.h"
29 #include "time_helper.h"
30 #include "sqlite_relational_utils.h"
31 #include "virtual_asset_loader.h"
32 #include "virtual_cloud_data_translate.h"
33 #include "virtual_cloud_db.h"
34 #include "virtual_communicator_aggregator.h"
35 #include "cloud_db_sync_utils_test.h"
36 
37 using namespace testing::ext;
38 using namespace DistributedDB;
39 using namespace DistributedDBUnitTest;
40 using namespace std;
41 
42 namespace {
43     constexpr const char *DB_SUFFIX = ".db";
44     constexpr const char *STORE_ID = "Relational_Store_ID";
45     constexpr const char *CREATE_TABLE_SQL =
46         "CREATE TABLE IF NOT EXISTS worker1(" \
47         "name TEXT PRIMARY KEY," \
48         "height REAL ," \
49         "married BOOLEAN ," \
50         "photo BLOB NOT NULL," \
51         "asset BLOB," \
52         "age INT);";
53     constexpr const char *CREATE_TABLE_WITHOUT_PRIMARY_SQL =
54         "CREATE TABLE IF NOT EXISTS worker2(" \
55         "id INT," \
56         "name TEXT," \
57         "height REAL ," \
58         "married BOOLEAN ," \
59         "photo BLOB ," \
60         "asset BLOB);";
61     constexpr const char *CREATE_SHARED_TABLE_SQL =
62         "CREATE TABLE IF NOT EXISTS worker5_shared(" \
63         "name TEXT PRIMARY KEY," \
64         "height REAL ," \
65         "married BOOLEAN ," \
66         "photo BLOB NOT NULL," \
67         "asset BLOB," \
68         "age INT);";
69     const string g_tableName1 = "worker1";
70     const string g_tableName2 = "worker2"; // do not have primary key
71     const string g_tableName3 = "Worker1";
72     const string g_tableName4 = "worker4";
73     const string g_sharedTableName1 = "worker1_shared";
74     const string g_sharedTableName2 = "worker2_shared"; // do not have primary key
75     const string g_sharedTableName3 = "Worker1_Shared";
76     const string g_sharedTableName4 = "worker4_shared";
77     const string g_sharedTableName5 = "worker5_shared";
78     const string g_distributedSharedTableName1 = "naturalbase_rdb_aux_worker1_shared_log";
79     const string g_distributedSharedTableName2 = "naturalbase_rdb_aux_worker2_shared_log";
80     const string g_distributedSharedTableName3 = "naturalbase_rdb_aux_Worker1_Shared_log";
81     const string g_distributedSharedTableName4 = "naturalbase_rdb_aux_worker4_shared_log";
82     std::string g_testDir;
83     std::string g_dbDir;
84     std::string g_storePath;
85     DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
86     RelationalStoreObserverUnitTest *g_observer = nullptr;
87     RelationalStoreDelegate *g_delegate = nullptr;
88     std::shared_ptr<VirtualCloudDb> g_virtualCloudDb = nullptr;
89     std::shared_ptr<VirtualCloudDataTranslate> g_virtualCloudDataTranslate;
90     const std::vector<Field> g_cloudField1 = {
91         {"id", TYPE_INDEX<int64_t>, true}, {"name", TYPE_INDEX<std::string>},
92         {"height", TYPE_INDEX<double>}, {"married", TYPE_INDEX<bool>},
93         {"photo", TYPE_INDEX<Bytes>}, {"asset", TYPE_INDEX<Asset>}
94     };
95     const std::vector<Field> g_cloudField2 = {
96         {"id", TYPE_INDEX<int64_t>}, {"name", TYPE_INDEX<std::string>},
97         {"height", TYPE_INDEX<double>}, {"married", TYPE_INDEX<bool>},
98         {"photo", TYPE_INDEX<Bytes>}, {"asset", TYPE_INDEX<Asset>}
99     };
100     const std::vector<Field> g_cloudField3 = {
101         {"id", TYPE_INDEX<int64_t>, true}, {"name", TYPE_INDEX<std::string>},
102         {"height", TYPE_INDEX<double>}, {"married", TYPE_INDEX<bool>},
103         {"photo", TYPE_INDEX<Bytes>}, {"age", TYPE_INDEX<int64_t>},
104         {"asset", TYPE_INDEX<Asset>}
105     };
106     const std::vector<Field> g_cloudField4 = {
107         {"id", TYPE_INDEX<int64_t>, true}, {"name", TYPE_INDEX<std::string>},
108         {"height", TYPE_INDEX<double>}, {"photo", TYPE_INDEX<Bytes>},
109         {"assets", TYPE_INDEX<Assets>}, {"age", TYPE_INDEX<int64_t>}
110     };
111     const int64_t g_syncWaitTime = 60;
112     const Asset g_localAsset = {
113         .version = 1, .name = "Phone", .assetId = "", .subpath = "/local/sync", .uri = "/local/sync",
114         .modifyTime = "123456", .createTime = "", .size = "256", .hash = "ASE"
115     };
116 
117     class DistributedDBCloudInterfacesSetCloudSchemaTest : public testing::Test {
118     public:
119         static void SetUpTestCase(void);
120         static void TearDownTestCase(void);
121         void SetUp();
122         void TearDown();
123     protected:
124         void CreateUserDBAndTable();
125         void CheckSharedTable(const std::vector<std::string> &expectedTableName);
126         void CheckDistributedSharedTable(const std::vector<std::string> &expectedTableName);
127         void InsertLocalSharedTableRecords(int64_t begin, int64_t count, const std::string &tableName,
128             bool isUpdate = false);
129         void InsertCloudTableRecord(int64_t begin, int64_t count, bool isShare = true, int64_t beginGid = -1);
130         void DeleteCloudTableRecord(int64_t beginGid, int64_t count, bool isShare = true);
131         void BlockSync(const Query &query, RelationalStoreDelegate *delegate, DBStatus errCode = OK,
132             SyncMode mode = SYNC_MODE_CLOUD_MERGE);
133         void CheckCloudTableCount(const std::string &tableName, int64_t expectCount);
134         void CloseDb();
135         void InitCloudEnv();
136         sqlite3 *db_ = nullptr;
137         std::function<void(int64_t, VBucket &)> forkInsertFunc_;
138         VirtualCommunicatorAggregator *communicatorAggregator_ = nullptr;
139     };
140 
SetUpTestCase(void)141     void DistributedDBCloudInterfacesSetCloudSchemaTest::SetUpTestCase(void)
142     {
143         DistributedDBToolsUnitTest::TestDirInit(g_testDir);
144         LOGD("Test dir is %s", g_testDir.c_str());
145         g_dbDir = g_testDir + "/";
146         g_storePath = g_dbDir + STORE_ID + DB_SUFFIX;
147         DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
148         g_virtualCloudDataTranslate = std::make_shared<VirtualCloudDataTranslate>();
149         RuntimeConfig::SetCloudTranslate(g_virtualCloudDataTranslate);
150     }
151 
TearDownTestCase(void)152     void DistributedDBCloudInterfacesSetCloudSchemaTest::TearDownTestCase(void)
153     {
154     }
155 
SetUp(void)156     void DistributedDBCloudInterfacesSetCloudSchemaTest::SetUp(void)
157     {
158         db_ = RelationalTestUtils::CreateDataBase(g_storePath);
159         ASSERT_NE(db_, nullptr);
160         CreateUserDBAndTable();
161         g_observer = new (std::nothrow) RelationalStoreObserverUnitTest();
162         ASSERT_NE(g_observer, nullptr);
163         ASSERT_EQ(g_mgr.OpenStore(g_storePath, STORE_ID, RelationalStoreDelegate::Option { .observer = g_observer },
164             g_delegate), DBStatus::OK);
165         ASSERT_NE(g_delegate, nullptr);
166         g_virtualCloudDb = std::make_shared<VirtualCloudDb>();
167         ASSERT_EQ(g_delegate->SetCloudDB(g_virtualCloudDb), DBStatus::OK);
168         ASSERT_EQ(g_delegate->SetIAssetLoader(std::make_shared<VirtualAssetLoader>()), DBStatus::OK);
169         communicatorAggregator_ = new (std::nothrow) VirtualCommunicatorAggregator();
170         ASSERT_TRUE(communicatorAggregator_ != nullptr);
171         RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicatorAggregator_);
172     }
173 
TearDown(void)174     void DistributedDBCloudInterfacesSetCloudSchemaTest::TearDown(void)
175     {
176         g_virtualCloudDb->ForkUpload(nullptr);
177         EXPECT_EQ(g_mgr.CloseStore(g_delegate), OK);
178         g_delegate = nullptr;
179         EXPECT_EQ(sqlite3_close_v2(db_), SQLITE_OK);
180         DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
181         RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
182         communicatorAggregator_ = nullptr;
183         RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr);
184     }
185 
CreateUserDBAndTable()186     void DistributedDBCloudInterfacesSetCloudSchemaTest::CreateUserDBAndTable()
187     {
188         ASSERT_EQ(RelationalTestUtils::ExecSql(db_, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
189         ASSERT_EQ(RelationalTestUtils::ExecSql(db_, CREATE_TABLE_SQL), SQLITE_OK);
190         ASSERT_EQ(RelationalTestUtils::ExecSql(db_, CREATE_TABLE_WITHOUT_PRIMARY_SQL), SQLITE_OK);
191     }
192 
CheckSharedTable(const std::vector<std::string> & expectedTableName)193     void DistributedDBCloudInterfacesSetCloudSchemaTest::CheckSharedTable(
194         const std::vector<std::string> &expectedTableName)
195     {
196         std::string sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND " \
197             "name LIKE 'worker%_shared';";
198         sqlite3_stmt *stmt = nullptr;
199         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
200         uint64_t index = 0;
201         while (SQLiteUtils::StepWithRetry(stmt) != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
202             ASSERT_EQ(sqlite3_column_type(stmt, 0), SQLITE_TEXT);
203             Type cloudValue;
204             ASSERT_EQ(SQLiteRelationalUtils::GetCloudValueByType(stmt, TYPE_INDEX<std::string>, 0, cloudValue), E_OK);
205             std::string actualTableName;
206             ASSERT_EQ(CloudStorageUtils::GetValueFromOneField(cloudValue, actualTableName), E_OK);
207             ASSERT_EQ(actualTableName, expectedTableName[index]);
208             index++;
209         }
210         ASSERT_EQ(index, expectedTableName.size());
211         int errCode;
212         SQLiteUtils::ResetStatement(stmt, true, errCode);
213     }
214 
CheckDistributedSharedTable(const std::vector<std::string> & expectedTableName)215     void DistributedDBCloudInterfacesSetCloudSchemaTest::CheckDistributedSharedTable(
216         const std::vector<std::string> &expectedTableName)
217     {
218         std::string sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND " \
219             "name LIKE 'naturalbase_rdb_aux_%_log';";
220         sqlite3_stmt *stmt = nullptr;
221         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
222         uint64_t index = 0;
223         while (SQLiteUtils::StepWithRetry(stmt) != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
224             ASSERT_EQ(sqlite3_column_type(stmt, 0), SQLITE_TEXT);
225             Type cloudValue;
226             ASSERT_EQ(SQLiteRelationalUtils::GetCloudValueByType(stmt, TYPE_INDEX<std::string>, 0, cloudValue), E_OK);
227             std::string actualTableName;
228             ASSERT_EQ(CloudStorageUtils::GetValueFromOneField(cloudValue, actualTableName), E_OK);
229             ASSERT_EQ(actualTableName, expectedTableName[index]);
230             index++;
231         }
232         ASSERT_EQ(index, expectedTableName.size());
233         int errCode;
234         SQLiteUtils::ResetStatement(stmt, true, errCode);
235     }
236 
InsertLocalSharedTableRecords(int64_t begin,int64_t count,const std::string & tableName,bool isUpdate)237     void DistributedDBCloudInterfacesSetCloudSchemaTest::InsertLocalSharedTableRecords(int64_t begin, int64_t count,
238         const std::string &tableName, bool isUpdate)
239     {
240         ASSERT_NE(db_, nullptr);
241         std::vector<uint8_t> assetBlob = g_virtualCloudDataTranslate->AssetToBlob(g_localAsset);
242         for (int64_t i = begin; i < count; ++i) {
243             string sql = "";
244             if (isUpdate) {
245                 sql = "INSERT OR REPLACE INTO " + tableName +
246                     " (cloud_owner, cloud_privilege, id, name, height, married, photo, age, asset) VALUES ('A', " +
247                     "'true', '" + std::to_string(i) + "', 'Local" + std::to_string(i) +
248                     "', '155.10', 'false', 'text', '18', ?);";
249             } else {
250                 sql = "INSERT OR REPLACE INTO " + tableName +
251                     " (cloud_owner, cloud_privilege, id, name, height, married, photo, asset) VALUES ('A', 'true', '" +
252                     std::to_string(i) + "', 'Local" + std::to_string(i) + "', '155.10', 'false', 'text', ?);";
253             }
254             sqlite3_stmt *stmt = nullptr;
255             ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
256             ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 1, assetBlob, false), E_OK);
257             EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
258             int errCode;
259             SQLiteUtils::ResetStatement(stmt, true, errCode);
260         }
261     }
262 
InsertSharingUri(int64_t index,VBucket & log)263     void InsertSharingUri(int64_t index, VBucket &log)
264     {
265         log.insert_or_assign(CloudDbConstant::SHARING_RESOURCE_FIELD, std::string("uri:") + std::to_string(index));
266     }
267 
QueryResourceCountSql(const std::string & tableName)268     std::string QueryResourceCountSql(const std::string &tableName)
269     {
270         return "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(tableName)
271             + " where sharing_resource like 'uri%'";
272     }
273 
InsertCloudTableRecord(int64_t begin,int64_t count,bool isShare,int64_t beginGid)274     void DistributedDBCloudInterfacesSetCloudSchemaTest::InsertCloudTableRecord(int64_t begin, int64_t count,
275         bool isShare, int64_t beginGid)
276     {
277         std::vector<uint8_t> photo(1, 'v');
278         std::vector<VBucket> record;
279         std::vector<VBucket> extend;
280         Timestamp now = TimeHelper::GetSysCurrentTime();
281         std::string tableName = g_tableName2;
282         if (isShare) {
283             tableName = g_sharedTableName1;
284         }
285         for (int64_t i = begin; i < begin + count; ++i) {
286             VBucket data;
287             if (isShare) {
288                 data.insert_or_assign("cloud_owner", std::string("ownerA"));
289                 data.insert_or_assign("cloud_privilege", std::string("true"));
290             }
291             data.insert_or_assign("id", i);
292             data.insert_or_assign("name", "Cloud" + std::to_string(i));
293             data.insert_or_assign("height", 166.0); // 166.0 is random double value
294             data.insert_or_assign("married", false);
295             data.insert_or_assign("photo", photo);
296             record.push_back(data);
297             VBucket log;
298             log.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND + i);
299             log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND + i);
300             log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false);
301             if (beginGid >= 0) {
302                 log.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(beginGid + i));
303             }
304             if (forkInsertFunc_) {
305                 forkInsertFunc_(i, log);
306             }
307             extend.push_back(log);
308         }
309         if (beginGid >= 0) {
310             ASSERT_EQ(g_virtualCloudDb->BatchUpdate(tableName, std::move(record), extend), DBStatus::OK);
311         } else {
312             ASSERT_EQ(g_virtualCloudDb->BatchInsert(tableName, std::move(record), extend), DBStatus::OK);
313         }
314 
315         std::this_thread::sleep_for(std::chrono::milliseconds(count));
316     }
317 
BlockSync(const Query & query,RelationalStoreDelegate * delegate,DBStatus errCode,SyncMode mode)318     void DistributedDBCloudInterfacesSetCloudSchemaTest::BlockSync(const Query &query,
319         RelationalStoreDelegate *delegate, DBStatus errCode, SyncMode mode)
320     {
321         std::mutex dataMutex;
322         std::condition_variable cv;
323         bool finish = false;
324         auto callback = [&cv, &dataMutex, &finish, &errCode](const std::map<std::string, SyncProcess> &process) {
325             for (const auto &item: process) {
326                 if (item.second.process == DistributedDB::FINISHED) {
327                     {
328                         EXPECT_EQ(item.second.errCode, errCode);
329                         std::lock_guard<std::mutex> autoLock(dataMutex);
330                         finish = true;
331                     }
332                     cv.notify_one();
333                 }
334             }
335         };
336         ASSERT_EQ(delegate->Sync({ "CLOUD" }, mode, query, callback, g_syncWaitTime), OK);
337         std::unique_lock<std::mutex> uniqueLock(dataMutex);
338         cv.wait(uniqueLock, [&finish]() {
339             return finish;
340         });
341     }
342 
CheckCloudTableCount(const std::string & tableName,int64_t expectCount)343     void DistributedDBCloudInterfacesSetCloudSchemaTest::CheckCloudTableCount(const std::string &tableName,
344         int64_t expectCount)
345     {
346         VBucket extend;
347         extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(0);
348         int64_t realCount = 0;
349         std::vector<VBucket> data;
350         g_virtualCloudDb->Query(tableName, extend, data);
351         for (size_t j = 0; j < data.size(); ++j) {
352             auto entry = data[j].find(CloudDbConstant::DELETE_FIELD);
353             if (entry != data[j].end() && std::get<bool>(entry->second)) {
354                 continue;
355             }
356             realCount++;
357         }
358         EXPECT_EQ(realCount, expectCount); // ExpectCount represents the total amount of cloud data.
359     }
360 
CloseDb()361     void DistributedDBCloudInterfacesSetCloudSchemaTest::CloseDb()
362     {
363         g_delegate->UnRegisterObserver(g_observer);
364         delete g_observer;
365         g_observer = nullptr;
366         g_virtualCloudDb = nullptr;
367         if (g_delegate != nullptr) {
368             EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
369             g_delegate = nullptr;
370         }
371     }
372 
InitCloudEnv()373     void DistributedDBCloudInterfacesSetCloudSchemaTest::InitCloudEnv()
374     {
375         DataBaseSchema dataBaseSchema;
376         TableSchema tableSchema = {
377             .name = g_tableName2,
378             .sharedTableName = g_sharedTableName1,
379             .fields = g_cloudField2
380         };
381         dataBaseSchema.tables.push_back(tableSchema);
382         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
383         ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName2, CLOUD_COOPERATION), DBStatus::OK);
384     }
385 
DeleteCloudTableRecord(int64_t beginGid,int64_t count,bool isShare)386     void DistributedDBCloudInterfacesSetCloudSchemaTest::DeleteCloudTableRecord(int64_t beginGid,
387         int64_t count, bool isShare)
388     {
389         Timestamp now = TimeHelper::GetSysCurrentTime();
390         std::vector<VBucket> extend;
391         for (int64_t i = 0; i < count; ++i) {
392             VBucket log;
393             log.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND + i);
394             log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND + i);
395             log.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(beginGid + i));
396             extend.push_back(log);
397         }
398         ASSERT_EQ(g_virtualCloudDb->BatchDelete(isShare ? g_sharedTableName1 : g_tableName2, extend), DBStatus::OK);
399         std::this_thread::sleep_for(std::chrono::milliseconds(count));
400     }
401 
402     /**
403      * @tc.name: SetCloudDbSchemaTest001
404      * @tc.desc: Test same table name for set cloud schema interface
405      * @tc.type: FUNC
406      * @tc.require:
407      * @tc.author: chenchaohao
408     */
409     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest001, TestSize.Level0)
410     {
411         /**
412          * @tc.steps:step1. table names are same but sharedtable names are empty
413          * @tc.expected: step1. return INVALID_ARGS
414          */
415         DataBaseSchema dataBaseSchema;
416         TableSchema tableSchema = {
417             .name = g_tableName1,
418             .sharedTableName = g_tableName1 + "_shared",
419             .fields = g_cloudField1
420         };
421         dataBaseSchema.tables.push_back(tableSchema);
422         dataBaseSchema.tables.push_back(tableSchema);
423         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
424 
425         /**
426          * @tc.steps:step2. table names are same but sharedtable names are different
427          * @tc.expected: step2. return INVALID_ARGS
428          */
429         dataBaseSchema.tables.clear();
430         tableSchema = {
431             .name = g_tableName1,
432             .sharedTableName = g_sharedTableName1,
433             .fields = g_cloudField1
434         };
435         dataBaseSchema.tables.push_back(tableSchema);
436         tableSchema = {
437             .name = g_tableName1,
438             .sharedTableName = g_sharedTableName2,
439             .fields = g_cloudField1
440         };
441         dataBaseSchema.tables.push_back(tableSchema);
442         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
443 
444         /**
445          * @tc.steps:step3. one table name is uppercase and the other is lowercase
446          * @tc.expected: step3. return INVALID_ARGS
447          */
448         dataBaseSchema.tables.clear();
449         tableSchema = {
450             .name = g_tableName1,
451             .sharedTableName = g_sharedTableName1,
452             .fields = g_cloudField1
453         };
454         dataBaseSchema.tables.push_back(tableSchema);
455         tableSchema = {
456             .name = g_tableName3,
457             .sharedTableName = g_sharedTableName2,
458             .fields = g_cloudField1
459         };
460         dataBaseSchema.tables.push_back(tableSchema);
461         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
462     }
463 
464     /**
465      * @tc.name: SetCloudDbSchemaTest002
466      * @tc.desc: Test same shared table name for set cloud schema interface
467      * @tc.type: FUNC
468      * @tc.require:
469      * @tc.author: chenchaohao
470     */
471     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest002, TestSize.Level0)
472     {
473         /**
474          * @tc.steps:step1. table names are different but sharedtable names are same
475          * @tc.expected: step1. return INVALID_ARGS
476          */
477         DataBaseSchema dataBaseSchema;
478         TableSchema tableSchema = {
479             .name = g_tableName1,
480             .sharedTableName = g_tableName1 + "_shared",
481             .fields = g_cloudField1
482         };
483         dataBaseSchema.tables.push_back(tableSchema);
484         tableSchema = {
485             .name = g_tableName2,
486             .sharedTableName = g_sharedTableName1,
487             .fields = g_cloudField2
488         };
489         dataBaseSchema.tables.push_back(tableSchema);
490         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
491 
492         /**
493          * @tc.steps:step2. table names are different but sharedtable names are same
494          * @tc.expected: step2. return INVALID_ARGS
495          */
496         dataBaseSchema.tables.clear();
497         tableSchema = {
498             .name = g_tableName1,
499             .sharedTableName = g_sharedTableName1,
500             .fields = g_cloudField1
501         };
502         dataBaseSchema.tables.push_back(tableSchema);
503         tableSchema = {
504             .name = g_tableName2,
505             .sharedTableName = g_sharedTableName1,
506             .fields = g_cloudField2
507         };
508         dataBaseSchema.tables.push_back(tableSchema);
509         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
510 
511         /**
512          * @tc.steps:step3. one sharedtable name is uppercase and the other is lowercase
513          * @tc.expected: step3. return INVALID_ARGS
514          */
515         dataBaseSchema.tables.clear();
516         tableSchema = { g_tableName1, g_sharedTableName1, g_cloudField1 };
517         dataBaseSchema.tables.push_back(tableSchema);
518         tableSchema = { g_tableName2, g_sharedTableName3, g_cloudField2 };
519         dataBaseSchema.tables.push_back(tableSchema);
520         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
521 
522         /**
523          * @tc.steps:step4. sharedtable name and table name is same
524          * @tc.expected: step4. return INVALID_ARGS
525          */
526         dataBaseSchema.tables.clear();
527         tableSchema = {
528             .name = g_tableName1,
529             .sharedTableName = g_tableName1,
530             .fields = g_cloudField1
531         };
532         dataBaseSchema.tables.push_back(tableSchema);
533         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
534     }
535 
536     /**
537      * @tc.name: SetCloudDbSchemaTest003
538      * @tc.desc: Test same table name and shared table name for set cloud schema interface
539      * @tc.type: FUNC
540      * @tc.require:
541      * @tc.author: chenchaohao
542     */
543     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest003, TestSize.Level0)
544     {
545         /**
546          * @tc.steps:step1. table name and shared table name are same
547          * @tc.expected: step1. return INVALID_ARGS
548          */
549         DataBaseSchema dataBaseSchema;
550         TableSchema tableSchema = {
551             .name = g_tableName1,
552             .sharedTableName = g_sharedTableName1,
553             .fields = g_cloudField1
554         };
555         dataBaseSchema.tables.push_back(tableSchema);
556         tableSchema = {
557             .name = g_sharedTableName1,
558             .sharedTableName = g_tableName2,
559             .fields = g_cloudField2
560         };
561         dataBaseSchema.tables.push_back(tableSchema);
562         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
563 
564         /**
565          * @tc.steps:step2. shared table name and table name are same
566          * @tc.expected: step2. return INVALID_ARGS
567          */
568         dataBaseSchema.tables.clear();
569         tableSchema = {
570             .name = g_tableName1,
571             .sharedTableName = g_sharedTableName1,
572             .fields = g_cloudField1
573         };
574         dataBaseSchema.tables.push_back(tableSchema);
575         tableSchema = {
576             .name = g_tableName2,
577             .sharedTableName = g_tableName1,
578             .fields = g_cloudField2
579         };
580         dataBaseSchema.tables.push_back(tableSchema);
581         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
582     }
583 
584     /**
585      * @tc.name: SetCloudDbSchemaTest004
586      * @tc.desc: Test same field for set cloud schema interface
587      * @tc.type: FUNC
588      * @tc.require:
589      * @tc.author: chenchaohao
590     */
591     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest004, TestSize.Level0)
592     {
593         /**
594          * @tc.steps:step1. fields contains same field
595          * @tc.expected: step1. return INVALID_ARGS
596          */
597         DataBaseSchema dataBaseSchema;
598         std::vector<Field> invalidFields = g_cloudField1;
599         invalidFields.push_back({"name", TYPE_INDEX<std::string>});
600         TableSchema tableSchema = {
601             .name = g_tableName1,
602             .sharedTableName = g_sharedTableName1,
603             .fields = invalidFields
604         };
605         dataBaseSchema.tables.push_back(tableSchema);
606         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
607 
608         /**
609          * @tc.steps:step2. fields contains cloud_owner
610          * @tc.expected: step2. return INVALID_ARGS
611          */
612         dataBaseSchema.tables.clear();
613         invalidFields = g_cloudField1;
614         invalidFields.push_back({"cloud_owner", TYPE_INDEX<std::string>});
615         tableSchema = {
616             .name = g_tableName1,
617             .sharedTableName = g_sharedTableName1,
618             .fields = invalidFields
619         };
620         dataBaseSchema.tables.push_back(tableSchema);
621         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
622 
623         /**
624          * @tc.steps:step3. fields contains cloud_privilege
625          * @tc.expected: step3. return INVALID_ARGS
626          */
627         dataBaseSchema.tables.clear();
628         invalidFields = g_cloudField1;
629         invalidFields.push_back({"cloud_privilege", TYPE_INDEX<std::string>});
630         tableSchema = {
631             .name = g_tableName1,
632             .sharedTableName = g_sharedTableName1,
633             .fields = invalidFields
634         };
635         dataBaseSchema.tables.push_back(tableSchema);
636         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
637 
638         /**
639          * @tc.steps:step4. fields contains same field but uppercase
640          * @tc.expected: step4. return INVALID_ARGS
641          */
642         dataBaseSchema.tables.clear();
643         invalidFields = g_cloudField1;
644         invalidFields.push_back({"Name", TYPE_INDEX<std::string>});
645         tableSchema = { g_tableName1, g_sharedTableName1, invalidFields };
646         dataBaseSchema.tables.push_back(tableSchema);
647         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
648 
649         /**
650          * @tc.steps:step5. fields contains cloud_privilege field but uppercase
651          * @tc.expected: step5. return INVALID_ARGS
652          */
653         dataBaseSchema.tables.clear();
654         invalidFields = g_cloudField1;
655         invalidFields.push_back({"Cloud_priVilege", TYPE_INDEX<std::string>});
656         tableSchema = { g_tableName1, g_sharedTableName1, invalidFields };
657         dataBaseSchema.tables.push_back(tableSchema);
658         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
659     }
660 
661     /**
662      * @tc.name: SetCloudDbSchemaTest005
663      * @tc.desc: Check shared table is existed or not
664      * @tc.type: FUNC
665      * @tc.require:
666      * @tc.author: chenchaohao
667     */
668     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest005, TestSize.Level0)
669     {
670         /**
671          * @tc.steps:step1. use SetCloudDbSchema
672          * @tc.expected: step1. return OK
673          */
674         DataBaseSchema dataBaseSchema;
675         TableSchema tableSchema = {
676             .name = g_tableName1,
677             .sharedTableName = g_sharedTableName1,
678             .fields = g_cloudField1
679         };
680         dataBaseSchema.tables.push_back(tableSchema);
681         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
682         CheckSharedTable({g_sharedTableName1});
683         CheckDistributedSharedTable({g_distributedSharedTableName1});
684 
685         /**
686          * @tc.steps:step2. re-SetCloudDbSchema and schema table changed
687          * @tc.expected: step2. return OK
688          */
689         dataBaseSchema.tables.clear();
690         tableSchema = {
691             .name = g_tableName2,
692             .sharedTableName = g_sharedTableName2,
693             .fields = g_cloudField2
694         };
695         dataBaseSchema.tables.push_back(tableSchema);
696         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
697         CheckSharedTable({g_sharedTableName2});
698         CheckDistributedSharedTable({g_distributedSharedTableName2});
699 
700         /**
701          * @tc.steps:step3. re-SetCloudDbSchema and schema fields changed
702          * @tc.expected: step3. return OK
703          */
704         dataBaseSchema.tables.clear();
705         tableSchema = {
706             .name = g_tableName2,
707             .sharedTableName = g_sharedTableName2,
708             .fields = g_cloudField1
709         };
710         dataBaseSchema.tables.push_back(tableSchema);
711         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
712         CheckSharedTable({g_sharedTableName2});
713         CheckDistributedSharedTable({g_distributedSharedTableName2});
714     }
715 
716     /**
717      * @tc.name: SetCloudDbSchemaTest006
718      * @tc.desc: Test SetCloudDbSchema in uppercase and lowercase
719      * @tc.type: FUNC
720      * @tc.require:
721      * @tc.author: chenchaohao
722     */
723     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest006, TestSize.Level0)
724     {
725         /**
726          * @tc.steps:step1. use SetCloudDbSchema
727          * @tc.expected: step1. return OK
728          */
729         DataBaseSchema dataBaseSchema;
730         TableSchema tableSchema = {
731             .name = g_tableName3,
732             .sharedTableName = g_sharedTableName3,
733             .fields = g_cloudField1
734         };
735         dataBaseSchema.tables.push_back(tableSchema);
736         tableSchema = {
737             .name = g_tableName2,
738             .sharedTableName = g_sharedTableName2,
739             .fields = g_cloudField2
740         };
741         dataBaseSchema.tables.push_back(tableSchema);
742         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
743         CheckSharedTable({g_sharedTableName3, g_sharedTableName2});
744         CheckDistributedSharedTable({g_distributedSharedTableName3, g_distributedSharedTableName2});
745     }
746 
747     /**
748      * @tc.name: SetCloudDbSchemaTest007
749      * @tc.desc: Test SetCloudDbSchema if need alter shared table name
750      * @tc.type: FUNC
751      * @tc.require:
752      * @tc.author: chenchaohao
753     */
754     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest007, TestSize.Level0)
755     {
756         /**
757          * @tc.steps:step1. use SetCloudDbSchema
758          * @tc.expected: step1. return OK
759          */
760         DataBaseSchema dataBaseSchema;
761         TableSchema tableSchema = {
762             .name = g_tableName1,
763             .sharedTableName = g_sharedTableName1,
764             .fields = g_cloudField1
765         };
766         dataBaseSchema.tables.push_back(tableSchema);
767         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
768         CheckSharedTable({g_sharedTableName1});
769         CheckDistributedSharedTable({g_distributedSharedTableName1});
770 
771         /**
772          * @tc.steps:step2. re-SetCloudDbSchema and schema shared table changed
773          * @tc.expected: step2. return OK
774          */
775         dataBaseSchema.tables.clear();
776         tableSchema = {
777             .name = g_tableName1,
778             .sharedTableName = g_sharedTableName2,
779             .fields = g_cloudField1
780         };
781         dataBaseSchema.tables.push_back(tableSchema);
782         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
783         CheckSharedTable({g_sharedTableName2});
784         CheckDistributedSharedTable({g_distributedSharedTableName2});
785 
786         /**
787          * @tc.steps:step3. re-SetCloudDbSchema and schema table changed
788          * @tc.expected: step3. return OK
789          */
790         dataBaseSchema.tables.clear();
791         tableSchema = {
792             .name = g_tableName2,
793             .sharedTableName = g_sharedTableName2,
794             .fields = g_cloudField1
795         };
796         dataBaseSchema.tables.push_back(tableSchema);
797         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
798         CheckSharedTable({g_sharedTableName2});
799         CheckDistributedSharedTable({g_distributedSharedTableName2});
800     }
801 
802     /**
803      * @tc.name: SetCloudDbSchemaTest008
804      * @tc.desc: Test SetCloudDbSchema when A-B C-D update B-D
805      * @tc.type: FUNC
806      * @tc.require:
807      * @tc.author: chenchaohao
808     */
809     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest008, TestSize.Level0)
810     {
811         /**
812          * @tc.steps:step1. use SetCloudDbSchema A-B C-D
813          * @tc.expected: step1. return OK
814          */
815         DataBaseSchema dataBaseSchema;
816         TableSchema tableSchema = {
817             .name = g_tableName1,
818             .sharedTableName = g_sharedTableName1,
819             .fields = g_cloudField1
820         };
821         dataBaseSchema.tables.push_back(tableSchema);
822         tableSchema = {
823             .name = g_tableName2,
824             .sharedTableName = g_sharedTableName2,
825             .fields = g_cloudField1
826         };
827         dataBaseSchema.tables.push_back(tableSchema);
828         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
829         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
830         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
831 
832         /**
833          * @tc.steps:step2. re-SetCloudDbSchema B-D
834          * @tc.expected: step2. return INVALID_ARGS
835          */
836         dataBaseSchema.tables.clear();
837         tableSchema = {
838             .name = g_sharedTableName1,
839             .sharedTableName = g_sharedTableName2,
840             .fields = g_cloudField1
841         };
842         dataBaseSchema.tables.push_back(tableSchema);
843         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
844         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
845         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
846     }
847 
848     /**
849      * @tc.name: SetCloudDbSchemaTest009
850      * @tc.desc: Test SetCloudDbSchema when A-B C-D update A-D
851      * @tc.type: FUNC
852      * @tc.require:
853      * @tc.author: chenchaohao
854     */
855     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest009, TestSize.Level0)
856     {
857         /**
858          * @tc.steps:step1. use SetCloudDbSchema
859          * @tc.expected: step1. return OK
860          */
861         DataBaseSchema dataBaseSchema;
862         TableSchema tableSchema = {
863             .name = g_tableName1,
864             .sharedTableName = g_sharedTableName1,
865             .fields = g_cloudField1
866         };
867         dataBaseSchema.tables.push_back(tableSchema);
868         tableSchema = {
869             .name = g_tableName2,
870             .sharedTableName = g_sharedTableName2,
871             .fields = g_cloudField1
872         };
873         dataBaseSchema.tables.push_back(tableSchema);
874         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
875         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
876         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
877 
878         /**
879          * @tc.steps:step2. re-SetCloudDbSchema and schema shared table changed
880          * @tc.expected: step2. return OK
881          */
882         dataBaseSchema.tables.clear();
883         tableSchema = {
884             .name = g_tableName1,
885             .sharedTableName = g_sharedTableName2,
886             .fields = g_cloudField1
887         };
888         dataBaseSchema.tables.push_back(tableSchema);
889         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
890         CheckSharedTable({g_sharedTableName2});
891         CheckDistributedSharedTable({g_distributedSharedTableName2});
892     }
893 
894     /**
895      * @tc.name: SetCloudDbSchemaTest010
896      * @tc.desc: Test SetCloudDbSchema when A-B C-D update A-E C-B
897      * @tc.type: FUNC
898      * @tc.require:
899      * @tc.author: chenchaohao
900     */
901     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest010, TestSize.Level0)
902     {
903         /**
904          * @tc.steps:step1. use SetCloudDbSchema
905          * @tc.expected: step1. return OK
906          */
907         DataBaseSchema dataBaseSchema;
908         TableSchema tableSchema = {
909             .name = g_tableName1,
910             .sharedTableName = g_sharedTableName1,
911             .fields = g_cloudField1
912         };
913         dataBaseSchema.tables.push_back(tableSchema);
914         tableSchema = {
915             .name = g_tableName2,
916             .sharedTableName = g_sharedTableName2,
917             .fields = g_cloudField1
918         };
919         dataBaseSchema.tables.push_back(tableSchema);
920         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
921         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
922         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
923 
924         /**
925          * @tc.steps:step2. re-SetCloudDbSchema and schema shared table changed
926          * @tc.expected: step2. return OK
927          */
928         dataBaseSchema.tables.clear();
929         tableSchema = {
930             .name = g_tableName1,
931             .sharedTableName = g_sharedTableName4,
932             .fields = g_cloudField1
933         };
934         dataBaseSchema.tables.push_back(tableSchema);
935         tableSchema = {
936             .name = g_tableName2,
937             .sharedTableName = g_sharedTableName1,
938             .fields = g_cloudField1
939         };
940         dataBaseSchema.tables.push_back(tableSchema);
941         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
942         CheckSharedTable({g_sharedTableName4, g_sharedTableName1});
943         CheckDistributedSharedTable({g_distributedSharedTableName4, g_distributedSharedTableName1});
944     }
945 
946     /**
947      * @tc.name: SetCloudDbSchemaTest011
948      * @tc.desc: Test SetCloudDbSchema if local exists user table
949      * @tc.type: FUNC
950      * @tc.require:
951      * @tc.author: chenchaohao
952     */
953     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest011, TestSize.Level0)
954     {
955         /**
956          * @tc.steps:step1. local exists worker1 then use SetCloudDbSchema
957          * @tc.expected: step1. return INVALID_ARGS
958          */
959         DataBaseSchema dataBaseSchema;
960         TableSchema tableSchema = {
961             .name = g_tableName2,
962             .sharedTableName = g_tableName1,
963             .fields = g_cloudField1
964         };
965         dataBaseSchema.tables.push_back(tableSchema);
966         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
967 
968         /**
969          * @tc.steps:step2. SetCloudDbSchema
970          * @tc.expected: step2. return OK
971          */
972         dataBaseSchema.tables.clear();
973         tableSchema = {
974             .name = g_tableName1,
975             .sharedTableName = g_sharedTableName1,
976             .fields = g_cloudField1
977         };
978         dataBaseSchema.tables.push_back(tableSchema);
979         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
980         CheckSharedTable({g_sharedTableName1});
981         CheckDistributedSharedTable({g_distributedSharedTableName1});
982 
983         /**
984          * @tc.steps:step3. add field and SetCloudDbSchema
985          * @tc.expected: step3. return OK
986          */
987         dataBaseSchema.tables.clear();
988         tableSchema = {
989             .name = g_tableName1,
990             .sharedTableName = g_sharedTableName2,
991             .fields = g_cloudField3
992         };
993         dataBaseSchema.tables.push_back(tableSchema);
994         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
995         CheckSharedTable({g_sharedTableName2});
996         CheckDistributedSharedTable({g_distributedSharedTableName2});
997     }
998 
999     /**
1000      * @tc.name: SetCloudDbSchemaTest012
1001      * @tc.desc: Test SetCloudDbSchema if local exists user table
1002      * @tc.type: FUNC
1003      * @tc.require:
1004      * @tc.author: chenchaohao
1005     */
1006     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest012, TestSize.Level0)
1007     {
1008         /**
1009          * @tc.steps:step1. use SetCloudDbSchema
1010          * @tc.expected: step1. return OK
1011          */
1012         ASSERT_EQ(RelationalTestUtils::ExecSql(db_, CREATE_SHARED_TABLE_SQL), SQLITE_OK);
1013         DataBaseSchema dataBaseSchema;
1014         TableSchema tableSchema = {
1015             .name = g_tableName1,
1016             .sharedTableName = g_sharedTableName1,
1017             .fields = g_cloudField1
1018         };
1019         dataBaseSchema.tables.push_back(tableSchema);
1020         tableSchema = {
1021             .name = g_tableName2,
1022             .sharedTableName = g_sharedTableName2,
1023             .fields = g_cloudField1
1024         };
1025         dataBaseSchema.tables.push_back(tableSchema);
1026         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1027         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
1028 
1029         /**
1030          * @tc.steps:step2. re-SetCloudDbSchema and schema shared table changed
1031          * @tc.expected: step2. return OK
1032          */
1033         dataBaseSchema.tables.clear();
1034         tableSchema = {
1035             .name = g_tableName1,
1036             .sharedTableName = g_sharedTableName4,
1037             .fields = g_cloudField1
1038         };
1039         dataBaseSchema.tables.push_back(tableSchema);
1040         tableSchema = {
1041             .name = g_tableName2,
1042             .sharedTableName = g_sharedTableName1,
1043             .fields = g_cloudField1
1044         };
1045         dataBaseSchema.tables.push_back(tableSchema);
1046         tableSchema = {
1047             .name = g_tableName4,
1048             .sharedTableName = g_sharedTableName5,
1049             .fields = g_cloudField1
1050         };
1051         dataBaseSchema.tables.push_back(tableSchema);
1052         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
1053     }
1054 
1055     /**
1056      * @tc.name: SetCloudDbSchemaTest013
1057      * @tc.desc: Test SetCloudDbSchema after close db
1058      * @tc.type: FUNC
1059      * @tc.require:
1060      * @tc.author: chenchaohao
1061     */
1062     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest013, TestSize.Level0)
1063     {
1064         /**
1065          * @tc.steps:step1. use SetCloudDbSchema
1066          * @tc.expected: step1. return OK
1067          */
1068         DataBaseSchema dataBaseSchema;
1069         TableSchema tableSchema = {
1070             .name = g_tableName1,
1071             .sharedTableName = g_sharedTableName1,
1072             .fields = g_cloudField1
1073         };
1074         dataBaseSchema.tables.push_back(tableSchema);
1075         tableSchema = {
1076             .name = g_tableName2,
1077             .sharedTableName = g_sharedTableName2,
1078             .fields = g_cloudField1
1079         };
1080         dataBaseSchema.tables.push_back(tableSchema);
1081         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1082         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
1083         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
1084 
1085         /**
1086          * @tc.steps:step2. close db and then open store
1087          * @tc.expected: step2. return OK
1088          */
1089         CloseDb();
1090         DBStatus status = g_mgr.OpenStore(g_storePath, STORE_ID, {}, g_delegate);
1091         ASSERT_EQ(status, OK);
1092         g_virtualCloudDb = std::make_shared<VirtualCloudDb>();
1093         ASSERT_EQ(g_delegate->SetCloudDB(g_virtualCloudDb), DBStatus::OK);
1094 
1095         /**
1096          * @tc.steps:step3. re-SetCloudDbSchema and schema is same
1097          * @tc.expected: step3. return OK
1098          */
1099         dataBaseSchema.tables.clear();
1100         tableSchema = {
1101             .name = g_tableName1,
1102             .sharedTableName = g_sharedTableName1,
1103             .fields = g_cloudField1
1104         };
1105         dataBaseSchema.tables.push_back(tableSchema);
1106         tableSchema = {
1107             .name = g_tableName2,
1108             .sharedTableName = g_sharedTableName2,
1109             .fields = g_cloudField1
1110         };
1111         dataBaseSchema.tables.push_back(tableSchema);
1112         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1113         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
1114         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
1115     }
1116 
1117     /**
1118      * @tc.name: SetCloudDbSchemaTest014
1119      * @tc.desc: Test SetCloudDbSchema after set tracker table
1120      * @tc.type: FUNC
1121      * @tc.require:
1122      * @tc.author: chenchaohao
1123     */
1124     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest014, TestSize.Level0)
1125     {
1126         /**
1127          * @tc.steps:step1. use SetTrackerTable
1128          * @tc.expected: step1. return OK
1129          */
1130         TrackerSchema trackerSchema = {
1131             .tableName = g_tableName1,
1132             .extendColName = "married",
1133             .trackerColNames = {"married"}
1134         };
1135         ASSERT_EQ(g_delegate->SetTrackerTable(trackerSchema), DBStatus::OK);
1136         ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName1, CLOUD_COOPERATION), DBStatus::OK);
1137 
1138         /**
1139          * @tc.steps:step2. use SetCloudDbSchema
1140          * @tc.expected: step2. return OK
1141          */
1142         DataBaseSchema dataBaseSchema;
1143         TableSchema tableSchema = {
1144             .name = g_tableName1,
1145             .sharedTableName = g_sharedTableName1,
1146             .fields = g_cloudField1
1147         };
1148         dataBaseSchema.tables.push_back(tableSchema);
1149         tableSchema = {
1150             .name = g_tableName2,
1151             .sharedTableName = g_sharedTableName2,
1152             .fields = g_cloudField1
1153         };
1154         dataBaseSchema.tables.push_back(tableSchema);
1155         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1156         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
1157     }
1158 
1159     /**
1160      * @tc.name: SharedTableSync001
1161      * @tc.desc: Test sharedtable without primary key sync
1162      * @tc.type: FUNC
1163      * @tc.require:
1164      * @tc.author: chenchaohao
1165     */
1166     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync001, TestSize.Level0)
1167     {
1168         /**
1169          * @tc.steps:step1. use set shared table without primary key
1170          * @tc.expected: step1. return OK
1171          */
1172         DataBaseSchema dataBaseSchema;
1173         TableSchema tableSchema = {
1174             .name = g_tableName2,
1175             .sharedTableName = g_sharedTableName2,
1176             .fields = g_cloudField2
1177         };
1178         dataBaseSchema.tables.push_back(tableSchema);
1179         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1180 
1181         /**
1182          * @tc.steps:step2. insert local shared table records and sync
1183          * @tc.expected: step2. return OK
1184          */
1185         InsertLocalSharedTableRecords(0, 10, g_sharedTableName2);
1186         Query query = Query::Select().FromTable({ g_sharedTableName2 });
1187         BlockSync(query, g_delegate);
1188         CheckCloudTableCount(g_sharedTableName2, 10);
1189     }
1190 
1191     /**
1192      * @tc.name: SharedTableSync002
1193      * @tc.desc: Test sharedtable sync when version abnormal
1194      * @tc.type: FUNC
1195      * @tc.require:
1196      * @tc.author: chenchaohao
1197     */
1198     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync002, TestSize.Level0)
1199     {
1200         /**
1201          * @tc.steps:step1. use set shared table
1202          * @tc.expected: step1. return OK
1203          */
1204         DataBaseSchema dataBaseSchema;
1205         TableSchema tableSchema = {
1206             .name = g_tableName1,
1207             .sharedTableName = g_sharedTableName1,
1208             .fields = g_cloudField1
1209         };
1210         dataBaseSchema.tables.push_back(tableSchema);
1211         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1212 
1213         /**
1214          * @tc.steps:step2. insert local shared table records and sync
1215          * @tc.expected: step2. return OK
1216          */
1217         InsertLocalSharedTableRecords(0, 10, g_sharedTableName1);
__anon8f2187a20402(const std::string &tableName, VBucket &extend) 1218         g_virtualCloudDb->ForkUpload([](const std::string &tableName, VBucket &extend) {
1219             extend.erase(CloudDbConstant::VERSION_FIELD);
1220         });
1221         Query query = Query::Select().FromTable({ g_sharedTableName1 });
1222         BlockSync(query, g_delegate, DBStatus::OK);
1223 
__anon8f2187a20502(const std::string &tableName, VBucket &extend) 1224         g_virtualCloudDb->ForkUpload([](const std::string &tableName, VBucket &extend) {
1225             if (extend.find(CloudDbConstant::VERSION_FIELD) != extend.end()) {
1226                 extend[CloudDbConstant::VERSION_FIELD] = "";
1227             }
1228         });
1229         query = Query::Select().FromTable({ g_sharedTableName1 });
1230         BlockSync(query, g_delegate, DBStatus::OK);
1231     }
1232 
1233     /**
1234      * @tc.name: SharedTableSync003
1235      * @tc.desc: Test weather the shared table is fill assetId under nochange
1236      * @tc.type: FUNC
1237      * @tc.require:
1238      * @tc.author: bty
1239     */
1240     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync003, TestSize.Level0)
1241     {
1242         /**
1243          * @tc.steps:step1. insert local shared table records and sync
1244          * @tc.expected: step1. return OK
1245          */
1246         DataBaseSchema dataBaseSchema;
1247         TableSchema tableSchema = {
1248             .name = g_tableName1,
1249             .sharedTableName = g_sharedTableName1,
1250             .fields = g_cloudField1
1251         };
1252         dataBaseSchema.tables.push_back(tableSchema);
1253         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1254         InsertLocalSharedTableRecords(0, 10, g_sharedTableName1); // 10 is records num
1255         Query query = Query::Select().FromTable({ g_sharedTableName1 });
1256         BlockSync(query, g_delegate);
1257 
1258         /**
1259          * @tc.steps:step2. sync again, cloud data containing assetId will be query
1260          * @tc.expected: step2. return OK
1261          */
1262         BlockSync(query, g_delegate);
1263 
1264         /**
1265          * @tc.steps:step3. check if the hash of assets in db is empty
1266          * @tc.expected: step3. OK
1267          */
1268         std::string sql = "SELECT asset from " + g_sharedTableName1;
1269         sqlite3_stmt *stmt = nullptr;
1270         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1271         while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1272             ASSERT_EQ(sqlite3_column_type(stmt, 0), SQLITE_BLOB);
1273             Type cloudValue;
1274             ASSERT_EQ(SQLiteRelationalUtils::GetCloudValueByType(stmt, TYPE_INDEX<Asset>, 0, cloudValue), E_OK);
1275             std::vector<uint8_t> assetBlob;
1276             Asset asset;
1277             ASSERT_EQ(CloudStorageUtils::GetValueFromOneField(cloudValue, assetBlob), E_OK);
1278             ASSERT_EQ(RuntimeContext::GetInstance()->BlobToAsset(assetBlob, asset), E_OK);
1279             EXPECT_EQ(asset.assetId, "");
1280         }
1281         int errCode;
1282         SQLiteUtils::ResetStatement(stmt, true, errCode);
1283     }
1284 
1285     /**
1286      * @tc.name: SharedTableSync004
1287      * @tc.desc: Test sharedtable sync when alter shared table name
1288      * @tc.type: FUNC
1289      * @tc.require:
1290      * @tc.author: chenchaohao
1291     */
1292     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync004, TestSize.Level0)
1293     {
1294         /**
1295          * @tc.steps:step1. use set shared table
1296          * @tc.expected: step1. return OK
1297          */
1298         DataBaseSchema dataBaseSchema;
1299         TableSchema tableSchema = {
1300             .name = g_tableName1,
1301             .sharedTableName = g_sharedTableName1,
1302             .fields = g_cloudField1
1303         };
1304         dataBaseSchema.tables.push_back(tableSchema);
1305         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1306         CheckSharedTable({g_sharedTableName1});
1307 
1308         /**
1309          * @tc.steps:step2. insert local shared table records and alter shared table name then sync
1310          * @tc.expected: step2. return OK
1311          */
1312         InsertLocalSharedTableRecords(0, 10, g_sharedTableName1);
1313         dataBaseSchema.tables.clear();
1314         tableSchema = {
1315             .name = g_tableName1,
1316             .sharedTableName = g_sharedTableName5,
1317             .fields = g_cloudField1
1318         };
1319         dataBaseSchema.tables.push_back(tableSchema);
1320         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1321         CheckSharedTable({g_sharedTableName5});
1322         Query query = Query::Select().FromTable({ g_sharedTableName5 });
1323         BlockSync(query, g_delegate);
1324         CheckCloudTableCount(g_sharedTableName5, 10);
1325     }
1326 
1327     /**
1328      * @tc.name: SharedTableSync006
1329      * @tc.desc: Test sharedtable sync when sharedtable add column
1330      * @tc.type: FUNC
1331      * @tc.require:
1332      * @tc.author: chenchaohao
1333     */
1334     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync006, TestSize.Level0)
1335     {
1336         /**
1337          * @tc.steps:step1. set shared table and sync
1338          * @tc.expected: step1. return OK
1339          */
1340         DataBaseSchema dataBaseSchema;
1341         TableSchema tableSchema = {
1342             .name = g_tableName1,
1343             .sharedTableName = g_sharedTableName1,
1344             .fields = g_cloudField1
1345         };
1346         dataBaseSchema.tables.push_back(tableSchema);
1347         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1348 
1349         int localCount = 10;
1350         InsertLocalSharedTableRecords(0, localCount, g_sharedTableName1);
1351         Query query = Query::Select().FromTable({ g_sharedTableName1 });
1352         BlockSync(query, g_delegate, DBStatus::OK);
1353         CheckCloudTableCount(g_sharedTableName1, localCount);
1354 
1355         /**
1356          * @tc.steps:step2. add shared table column and sync
1357          * @tc.expected: step2. return OK
1358          */
1359         dataBaseSchema.tables.clear();
1360         tableSchema = {
1361             .name = g_tableName1,
1362             .sharedTableName = g_sharedTableName1,
1363             .fields = g_cloudField3
1364         };
1365         dataBaseSchema.tables.push_back(tableSchema);
1366         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1367         int cloudCount = 20;
1368         InsertLocalSharedTableRecords(localCount, cloudCount, g_sharedTableName1, true);
1369         BlockSync(query, g_delegate, DBStatus::OK);
1370         CheckCloudTableCount(g_sharedTableName1, cloudCount);
1371     }
1372 
1373     /**
1374      * @tc.name: SetCloudDbSchemaTest015
1375      * @tc.desc: Test SetCloudDbSchema sharedTableName is ""
1376      * @tc.type: FUNC
1377      * @tc.require:
1378      * @tc.author: wangxiangdong
1379     */
1380     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest015, TestSize.Level0)
1381     {
1382         /**
1383          * @tc.steps:step1. set sharedTableName ""
1384          * @tc.expected: step1. return OK
1385          */
1386         DataBaseSchema dataBaseSchema;
1387         TableSchema tableSchema = {
1388             .name = g_tableName1,
1389             .sharedTableName = "",
1390             .fields = g_cloudField1
1391         };
1392         dataBaseSchema.tables.push_back(tableSchema);
1393         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1394 
1395         /**
1396          * @tc.steps:step2. check sharedTable not exist
1397          * @tc.expected: step2. return OK
1398          */
1399         std::string sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND " \
1400             "name LIKE 'worker%_shared';";
1401         sqlite3_stmt *stmt = nullptr;
1402         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1403         ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1404         int ret = E_OK;
1405         SQLiteUtils::ResetStatement(stmt, true, ret);
1406         ASSERT_EQ(ret, E_OK);
1407     }
1408 
1409     /**
1410      * @tc.name: SetCloudDbSchemaTest016
1411      * @tc.desc: Test SetCloudDbSchema if it will delete sharedtable when set sharedtable is empty
1412      * @tc.type: FUNC
1413      * @tc.require:
1414      * @tc.author: chenchaohao
1415     */
1416     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest016, TestSize.Level0)
1417     {
1418         /**
1419          * @tc.steps:step1. use SetCloudDbSchema to create g_sharedTableName1
1420          * @tc.expected: step1. return OK
1421          */
1422         DataBaseSchema dataBaseSchema;
1423         TableSchema tableSchema = {
1424             .name = g_tableName1,
1425             .sharedTableName = g_sharedTableName1,
1426             .fields = g_cloudField1
1427         };
1428         dataBaseSchema.tables.push_back(tableSchema);
1429         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1430         CheckSharedTable({g_sharedTableName1});
1431         CheckDistributedSharedTable({g_distributedSharedTableName1});
1432 
1433         /**
1434          * @tc.steps:step2. re-SetCloudDbSchema and sharedtable name is empty
1435          * @tc.expected: step2. return INVALID_ARS
1436          */
1437         dataBaseSchema.tables.clear();
1438         tableSchema = {
1439             .name = g_tableName1,
1440             .sharedTableName = "",
1441             .fields = g_cloudField1
1442         };
1443         dataBaseSchema.tables.push_back(tableSchema);
1444         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1445         std::string sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND " \
1446             "name LIKE 'worker%_shared';";
1447         sqlite3_stmt *stmt = nullptr;
1448         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1449         ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1450         int ret = E_OK;
1451         SQLiteUtils::ResetStatement(stmt, true, ret);
1452         ASSERT_EQ(ret, E_OK);
1453 
1454         /**
1455          * @tc.steps:step3. re-SetCloudDbSchema and set sharedtable
1456          * @tc.expected: step3. return INVALID_ARS
1457          */
1458         dataBaseSchema.tables.clear();
1459         tableSchema = {
1460             .name = g_tableName1,
1461             .sharedTableName = g_sharedTableName1,
1462             .fields = g_cloudField3
1463         };
1464         dataBaseSchema.tables.push_back(tableSchema);
1465         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1466         CheckSharedTable({g_sharedTableName1});
1467         CheckDistributedSharedTable({g_distributedSharedTableName1});
1468     }
1469 
1470     /**
1471      * @tc.name: SetCloudDbSchemaTest017
1472      * @tc.desc: Test SetCloudDbSchema if table fields are less than old table
1473      * @tc.type: FUNC
1474      * @tc.require:
1475      * @tc.author: chenchaohao
1476     */
1477     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest017, TestSize.Level0)
1478     {
1479         /**
1480          * @tc.steps:step1. use SetCloudDbSchema
1481          * @tc.expected: step1. return OK
1482          */
1483         DataBaseSchema dataBaseSchema;
1484         TableSchema tableSchema = {
1485             .name = g_tableName1,
1486             .sharedTableName = "",
1487             .fields = g_cloudField3
1488         };
1489         dataBaseSchema.tables.push_back(tableSchema);
1490         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1491 
1492         /**
1493          * @tc.steps:step2. re-SetCloudDbSchema and fields are less than old
1494          * @tc.expected: step2. return INVALID_ARS
1495          */
1496         dataBaseSchema.tables.clear();
1497         tableSchema = {
1498             .name = g_tableName1,
1499             .sharedTableName = "",
1500             .fields = g_cloudField1
1501         };
1502         dataBaseSchema.tables.push_back(tableSchema);
1503         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
1504     }
1505 
1506     /**
1507      * @tc.name: SharedTableSync007
1508      * @tc.desc: Test the sharing_resource for ins data into the cloud
1509      * @tc.type: FUNC
1510      * @tc.require:
1511      * @tc.author: bty
1512     */
1513     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync007, TestSize.Level0)
1514     {
1515         /**
1516          * @tc.steps:step1. init cloud share data contains sharing_resource
1517          * @tc.expected: step1. return OK
1518          */
1519         InitCloudEnv();
1520         int cloudCount = 10;
1521         forkInsertFunc_ = InsertSharingUri;
1522         InsertCloudTableRecord(0, cloudCount, false);
1523         InsertCloudTableRecord(0, cloudCount);
1524 
1525         /**
1526          * @tc.steps:step2. sync
1527          * @tc.expected: step2. return OK
1528          */
1529         Query query = Query::Select().FromTable({ g_tableName2, g_sharedTableName1 });
1530         BlockSync(query, g_delegate, DBStatus::OK);
1531         forkInsertFunc_ = nullptr;
1532 
1533         /**
1534          * @tc.steps:step3. check sync insert
1535          * @tc.expected: step3. return OK
1536          */
1537         std::string sql = QueryResourceCountSql(g_tableName2);
1538         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1539             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1540         sql = QueryResourceCountSql(g_sharedTableName1);
1541         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1542             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1543     }
1544 
1545     /**
1546      * @tc.name: SharedTableSync008
1547      * @tc.desc: Test the sharing_resource for upd data into the cloud
1548      * @tc.type: FUNC
1549      * @tc.require:
1550      * @tc.author: bty
1551     */
1552     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync008, TestSize.Level0)
1553     {
1554         /**
1555          * @tc.steps:step1. init cloud data and sync
1556          * @tc.expected: step1. return OK
1557          */
1558         InitCloudEnv();
1559         int cloudCount = 10;
1560         InsertCloudTableRecord(0, cloudCount, false);
1561         InsertCloudTableRecord(0, cloudCount);
1562         Query query = Query::Select().FromTable({ g_tableName2, g_sharedTableName1 });
1563         BlockSync(query, g_delegate, DBStatus::OK);
1564 
1565         /**
1566          * @tc.steps:step2. update cloud sharing_resource and sync
1567          * @tc.expected: step2. return OK
1568          */
1569         int beginGid = 0;
1570         forkInsertFunc_ = InsertSharingUri;
1571         InsertCloudTableRecord(0, cloudCount, false, beginGid);
1572         InsertCloudTableRecord(0, cloudCount, true, cloudCount);
1573         BlockSync(query, g_delegate, DBStatus::OK);
1574         forkInsertFunc_ = nullptr;
1575 
1576         /**
1577          * @tc.steps:step3. check sync update
1578          * @tc.expected: step3. return OK
1579          */
1580         std::string sql = QueryResourceCountSql(g_tableName2);
1581         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1582             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1583         sql = QueryResourceCountSql(g_sharedTableName1);
1584         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1585             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1586 
1587         /**
1588          * @tc.steps:step4. remove cloud sharing_resource and sync
1589          * @tc.expected: step4. return OK
1590          */
1591         InsertCloudTableRecord(0, cloudCount, false, beginGid);
1592         InsertCloudTableRecord(0, cloudCount, true, cloudCount);
1593         BlockSync(query, g_delegate, DBStatus::OK);
1594 
1595         /**
1596          * @tc.steps:step5. check sync update
1597          * @tc.expected: step5. return OK
1598          */
1599         sql = QueryResourceCountSql(g_tableName2);
1600         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1601             reinterpret_cast<void *>(0L), nullptr), SQLITE_OK);
1602         sql = QueryResourceCountSql(g_sharedTableName1);
1603         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1604             reinterpret_cast<void *>(0L), nullptr), SQLITE_OK);
1605     }
1606 
1607     /**
1608      * @tc.name: SharedTableSync009
1609      * @tc.desc: Test the sharing_resource when the local data is newer than the cloud
1610      * @tc.type: FUNC
1611      * @tc.require:
1612      * @tc.author: bty
1613     */
1614     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync009, TestSize.Level0)
1615     {
1616         /**
1617          * @tc.steps:step1. init cloud data and sync
1618          * @tc.expected: step1. return OK
1619          */
1620         InitCloudEnv();
1621         const std::vector<std::string> tables = { g_tableName2, g_sharedTableName1 };
1622         int cloudCount = 10;
1623         InsertCloudTableRecord(0, cloudCount, false);
1624         InsertCloudTableRecord(0, cloudCount);
1625         Query query = Query::Select().FromTable(tables);
1626         BlockSync(query, g_delegate, DBStatus::OK);
1627 
1628         /**
1629          * @tc.steps:step2. update cloud data, generate share uri
1630          * @tc.expected: step2. return OK
1631          */
1632         int beginGid = 0;
1633         forkInsertFunc_ = InsertSharingUri;
1634         InsertCloudTableRecord(0, cloudCount, false, beginGid);
1635         InsertCloudTableRecord(0, cloudCount, true, cloudCount);
1636         forkInsertFunc_ = nullptr;
1637 
1638         /**
1639          * @tc.steps:step3. update local data
1640          * @tc.expected: step3. return OK
1641          */
1642         for (const auto &tableName: tables) {
1643             std::string sql = "update " + tableName + " SET height='199';";
1644             sqlite3_stmt *stmt = nullptr;
1645             ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1646             EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1647             int errCode;
1648             SQLiteUtils::ResetStatement(stmt, true, errCode);
1649         }
1650 
1651         /**
1652          * @tc.steps:step4. sync and check count
1653          * @tc.expected: step4. return OK
1654          */
1655         BlockSync(query, g_delegate, DBStatus::OK);
1656         std::string sql = QueryResourceCountSql(g_tableName2);
1657         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1658             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1659         sql = QueryResourceCountSql(g_sharedTableName1);
1660         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1661             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1662         sql = "SELECT COUNT(*) FROM " + g_tableName2 + " where height='199'";
1663         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1664             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1665         sql = "SELECT COUNT(*) FROM " + g_sharedTableName1 + " where height='199'";
1666         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1667             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1668     }
1669 
1670     /**
1671      * @tc.name: SharedTableSync010
1672      * @tc.desc: Test the sharing_resource for del data into the cloud
1673      * @tc.type: FUNC
1674      * @tc.require:
1675      * @tc.author: bty
1676     */
1677     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync010, TestSize.Level0)
1678     {
1679         /**
1680          * @tc.steps:step1. init cloud share data and sync
1681          * @tc.expected: step1. return OK
1682          */
1683         InitCloudEnv();
1684         int cloudCount = 10;
1685         forkInsertFunc_ = InsertSharingUri;
1686         InsertCloudTableRecord(0, cloudCount, false);
1687         InsertCloudTableRecord(0, cloudCount);
1688         Query query = Query::Select().FromTable({ g_tableName2, g_sharedTableName1 });
1689         BlockSync(query, g_delegate, DBStatus::OK);
1690         forkInsertFunc_ = nullptr;
1691 
1692         /**
1693          * @tc.steps:step2. delete cloud data
1694          * @tc.expected: step2. return OK
1695          */
1696         int beginGid = 0;
1697         int delCount = 5;
1698         DeleteCloudTableRecord(beginGid, delCount, false);
1699         DeleteCloudTableRecord(cloudCount, delCount);
1700         BlockSync(query, g_delegate, DBStatus::OK);
1701 
1702         /**
1703          * @tc.steps:step3. sync and check count
1704          * @tc.expected: step3. return OK
1705          */
1706         std::string sql = QueryResourceCountSql(g_tableName2);
1707         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1708             reinterpret_cast<void *>(cloudCount - delCount), nullptr), SQLITE_OK);
1709         sql = QueryResourceCountSql(g_sharedTableName1);
1710         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1711             reinterpret_cast<void *>(cloudCount - delCount), nullptr), SQLITE_OK);
1712 
1713         /**
1714          * @tc.steps:step4. remove device data and check count
1715          * @tc.expected: step4. return OK
1716          */
1717         g_delegate->RemoveDeviceData("", FLAG_ONLY);
1718         sql = QueryResourceCountSql(g_tableName2);
1719         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1720             reinterpret_cast<void *>(0L), nullptr), SQLITE_OK);
1721         g_delegate->RemoveDeviceData("", CLEAR_SHARED_TABLE);
1722         sql = QueryResourceCountSql(g_sharedTableName1);
1723         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1724             reinterpret_cast<void *>(0L), nullptr), SQLITE_OK);
1725     }
1726 
1727     /**
1728      * @tc.name: SharedTableSync011
1729      * @tc.desc: Test the sharing_resource when the local data is newer than the cloud
1730      * @tc.type: FUNC
1731      * @tc.require:
1732      * @tc.author: bty
1733     */
1734     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync011, TestSize.Level0)
1735     {
1736         /**
1737          * @tc.steps:step1. init cloud data and sync
1738          * @tc.expected: step1. return OK
1739          */
1740         InitCloudEnv();
1741         const std::vector<std::string> tables = { g_tableName2, g_sharedTableName1 };
1742         int cloudCount = 10;
1743         InsertCloudTableRecord(0, cloudCount, false);
1744         InsertCloudTableRecord(0, cloudCount);
1745         Query query = Query::Select().FromTable(tables);
1746         BlockSync(query, g_delegate, DBStatus::OK);
1747 
1748         /**
1749          * @tc.steps:step2. update cloud data, generate share uri
1750          * @tc.expected: step2. return OK
1751          */
1752         int beginGid = 0;
1753         forkInsertFunc_ = InsertSharingUri;
1754         InsertCloudTableRecord(0, cloudCount, false, beginGid);
1755         InsertCloudTableRecord(0, cloudCount, true, cloudCount);
1756         forkInsertFunc_ = nullptr;
1757 
1758         /**
1759          * @tc.steps:step3. update local data
1760          * @tc.expected: step3. return OK
1761          */
1762         for (const auto &tableName: tables) {
1763             std::string sql = "update " + tableName + " SET height='199';";
1764             sqlite3_stmt *stmt = nullptr;
1765             ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1766             EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1767             int errCode;
1768             SQLiteUtils::ResetStatement(stmt, true, errCode);
1769         }
1770 
1771         /**
1772          * @tc.steps:step4. push sync and check count
1773          * @tc.expected: step4. return OK
1774          */
1775         BlockSync(query, g_delegate, DBStatus::OK, SyncMode::SYNC_MODE_CLOUD_FORCE_PUSH);
1776         std::string sql = QueryResourceCountSql(g_tableName2);
1777         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1778             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1779         sql = QueryResourceCountSql(g_sharedTableName1);
1780         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1781             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1782     }
1783 
1784     /**
1785      * @tc.name: SharedTableSync012
1786      * @tc.desc: Test the flag for uploaded data
1787      * @tc.type: FUNC
1788      * @tc.require:
1789      * @tc.author: bty
1790     */
1791     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync012, TestSize.Level0)
1792     {
1793         /**
1794          * @tc.steps:step1. init local share data and sync
1795          * @tc.expected: step1. return OK
1796          */
1797         InitCloudEnv();
1798         int cloudCount = 10;
1799         InsertLocalSharedTableRecords(0, 10, g_sharedTableName1);
1800         Query query = Query::Select().FromTable({ g_sharedTableName1 });
1801         BlockSync(query, g_delegate, DBStatus::OK);
1802 
1803         /**
1804          * @tc.steps:step2. update local share uri
1805          * @tc.expected: step2. return OK
1806          */
1807         std::string sql = "update " + DBCommon::GetLogTableName(g_sharedTableName1) + " SET sharing_resource='199';";
1808         sqlite3_stmt *stmt = nullptr;
1809         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1810         EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1811         int errCode;
1812         SQLiteUtils::ResetStatement(stmt, true, errCode);
1813 
1814         /**
1815          * @tc.steps:step3. sync and check flag
1816          * @tc.expected: step3. return OK
1817          */
1818         BlockSync(query, g_delegate, DBStatus::OK);
1819         sql = "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(g_sharedTableName1) + " where flag&0x02=0x02";
1820         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1821             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1822     }
1823 
1824     /**
1825      * @tc.name: SharedTableSync013
1826      * @tc.desc: Test the sharing_resource after data deleted
1827      * @tc.type: FUNC
1828      * @tc.require:
1829      * @tc.author: bty
1830     */
1831     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync013, TestSize.Level0)
1832     {
1833         /**
1834          * @tc.steps:step1. init cloud data and sync
1835          * @tc.expected: step1. return OK
1836          */
1837         InitCloudEnv();
1838         forkInsertFunc_ = InsertSharingUri;
1839         const std::vector<std::string> tables = { g_tableName2, g_sharedTableName1 };
1840         int cloudCount = 10;
1841         InsertCloudTableRecord(0, cloudCount, false);
1842         InsertCloudTableRecord(0, cloudCount);
1843         Query query = Query::Select().FromTable(tables);
1844         BlockSync(query, g_delegate, DBStatus::OK);
1845         forkInsertFunc_ = nullptr;
1846 
1847         /**
1848          * @tc.steps:step2. logic delete cloud data and sync, check sharing_resource
1849          * @tc.expected: step2. return OK
1850          */
1851         bool logicDelete = true;
1852         auto data = static_cast<PragmaData>(&logicDelete);
1853         EXPECT_EQ(g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data), OK);
1854         DeleteCloudTableRecord(0, cloudCount, false);
1855         DeleteCloudTableRecord(cloudCount, cloudCount);
1856         BlockSync(query, g_delegate, DBStatus::OK);
1857         std::string sql = "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(g_tableName2)
1858             + " where sharing_resource!=''";
1859         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1860             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1861 
1862         /**
1863          * @tc.steps:step3. drop logic data, check sharing_resource
1864          * @tc.expected: step3. return OK
1865          */
1866         EXPECT_EQ(DropLogicDeletedData(db_, g_tableName2, 0u), OK);
1867         sql = "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(g_tableName2) + " where sharing_resource=''";
1868         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1869             reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1870     }
1871 
1872     /**
1873      * @tc.name: SetCloudDbSchemaTest018
1874      * @tc.desc: Check SetCloudDBSchema while conn is nullptr.
1875      * @tc.type: FUNC
1876      * @tc.require:
1877      * @tc.author: caihaoting
1878     */
1879     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest018, TestSize.Level0)
1880     {
1881         /**
1882          * @tc.steps:step1. use SetCloudDBSchema while conn is nullptr
1883          * @tc.expected: step1. return DB_ERROR
1884          */
1885         DataBaseSchema dataBaseSchema;
1886         TableSchema tableSchema = {
1887             .name = g_tableName1,
1888             .sharedTableName = g_sharedTableName1,
1889             .fields = g_cloudField1
1890         };
1891         dataBaseSchema.tables.push_back(tableSchema);
1892         auto relationalStoreImpl = static_cast<RelationalStoreDelegateImpl *>(g_delegate);
1893         EXPECT_EQ(relationalStoreImpl->Close(), OK);
1894         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::DB_ERROR);
1895     }
1896 
1897     /**
1898      * @tc.name: SharedTableSync019
1899      * @tc.desc: Test falg_only has notify.
1900      * @tc.type: FUNC
1901      * @tc.require:
1902      * @tc.author: wangxiangdong
1903     */
1904     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync019, TestSize.Level0)
1905     {
1906         /**
1907          * @tc.steps:step1. init cloud data and sync
1908          * @tc.expected: step1. return OK
1909          */
1910         InitCloudEnv();
1911         int cloudCount = 10;
1912         InsertCloudTableRecord(0, cloudCount);
1913         Query query = Query::Select().FromTable({ g_tableName2 });
1914         BlockSync(query, g_delegate, DBStatus::OK);
1915 
1916         /**
1917          * @tc.steps:step2. remove device data and check notify
1918          * @tc.expected: step2. return OK
1919          */
1920         g_delegate->RemoveDeviceData("", FLAG_ONLY);
1921         ChangedData changedData;
1922         changedData.type = ChangedDataType::DATA;
1923         changedData.tableName = g_tableName2;
1924         std::vector<DistributedDB::Type> dataVec;
1925         DistributedDB::Type type = std::string(CloudDbConstant::FLAG_ONLY_MODE_NOTIFY);
1926         dataVec.push_back(type);
1927         changedData.primaryData[ChangeType::OP_DELETE].push_back(dataVec);
1928         g_observer->SetExpectedResult(changedData);
1929         EXPECT_EQ(g_observer->IsAllChangedDataEq(), true);
1930     }
1931 } // namespace