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