• 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 "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         if (g_observer != nullptr) {
185             delete g_observer;
186             g_observer = nullptr;
187         }
188     }
189 
CreateUserDBAndTable()190     void DistributedDBCloudInterfacesSetCloudSchemaTest::CreateUserDBAndTable()
191     {
192         ASSERT_EQ(RelationalTestUtils::ExecSql(db_, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
193         ASSERT_EQ(RelationalTestUtils::ExecSql(db_, CREATE_TABLE_SQL), SQLITE_OK);
194         ASSERT_EQ(RelationalTestUtils::ExecSql(db_, CREATE_TABLE_WITHOUT_PRIMARY_SQL), SQLITE_OK);
195     }
196 
CheckSharedTable(const std::vector<std::string> & expectedTableName)197     void DistributedDBCloudInterfacesSetCloudSchemaTest::CheckSharedTable(
198         const std::vector<std::string> &expectedTableName)
199     {
200         std::string sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND " \
201             "name LIKE 'worker%_shared';";
202         sqlite3_stmt *stmt = nullptr;
203         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
204         uint64_t index = 0;
205         while (SQLiteUtils::StepWithRetry(stmt) != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
206             ASSERT_EQ(sqlite3_column_type(stmt, 0), SQLITE_TEXT);
207             Type cloudValue;
208             ASSERT_EQ(SQLiteRelationalUtils::GetCloudValueByType(stmt, TYPE_INDEX<std::string>, 0, cloudValue), E_OK);
209             std::string actualTableName;
210             ASSERT_EQ(CloudStorageUtils::GetValueFromOneField(cloudValue, actualTableName), E_OK);
211             ASSERT_EQ(actualTableName, expectedTableName[index]);
212             index++;
213         }
214         ASSERT_EQ(index, expectedTableName.size());
215         int errCode;
216         SQLiteUtils::ResetStatement(stmt, true, errCode);
217     }
218 
CheckDistributedSharedTable(const std::vector<std::string> & expectedTableName)219     void DistributedDBCloudInterfacesSetCloudSchemaTest::CheckDistributedSharedTable(
220         const std::vector<std::string> &expectedTableName)
221     {
222         std::string sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND " \
223             "name LIKE 'naturalbase_rdb_aux_%_log';";
224         sqlite3_stmt *stmt = nullptr;
225         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
226         uint64_t index = 0;
227         while (SQLiteUtils::StepWithRetry(stmt) != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
228             ASSERT_EQ(sqlite3_column_type(stmt, 0), SQLITE_TEXT);
229             Type cloudValue;
230             ASSERT_EQ(SQLiteRelationalUtils::GetCloudValueByType(stmt, TYPE_INDEX<std::string>, 0, cloudValue), E_OK);
231             std::string actualTableName;
232             ASSERT_EQ(CloudStorageUtils::GetValueFromOneField(cloudValue, actualTableName), E_OK);
233             ASSERT_EQ(actualTableName, expectedTableName[index]);
234             index++;
235         }
236         ASSERT_EQ(index, expectedTableName.size());
237         int errCode;
238         SQLiteUtils::ResetStatement(stmt, true, errCode);
239     }
240 
InsertLocalSharedTableRecords(int64_t begin,int64_t count,const std::string & tableName,bool isUpdate)241     void DistributedDBCloudInterfacesSetCloudSchemaTest::InsertLocalSharedTableRecords(int64_t begin, int64_t count,
242         const std::string &tableName, bool isUpdate)
243     {
244         ASSERT_NE(db_, nullptr);
245         std::vector<uint8_t> assetBlob = g_virtualCloudDataTranslate->AssetToBlob(g_localAsset);
246         for (int64_t i = begin; i < count; ++i) {
247             string sql = "";
248             if (isUpdate) {
249                 sql = "INSERT OR REPLACE INTO " + tableName +
250                     " (cloud_owner, cloud_privilege, id, name, height, married, photo, age, asset) VALUES ('A', " +
251                     "'true', '" + std::to_string(i) + "', 'Local" + std::to_string(i) +
252                     "', '155.10', 'false', 'text', '18', ?);";
253             } else {
254                 sql = "INSERT OR REPLACE INTO " + tableName +
255                     " (cloud_owner, cloud_privilege, id, name, height, married, photo, asset) VALUES ('A', 'true', '" +
256                     std::to_string(i) + "', 'Local" + std::to_string(i) + "', '155.10', 'false', 'text', ?);";
257             }
258             sqlite3_stmt *stmt = nullptr;
259             ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
260             ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 1, assetBlob, false), E_OK);
261             EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
262             int errCode;
263             SQLiteUtils::ResetStatement(stmt, true, errCode);
264         }
265     }
266 
InsertSharingUri(int64_t index,VBucket & log)267     void InsertSharingUri(int64_t index, VBucket &log)
268     {
269         log.insert_or_assign(CloudDbConstant::SHARING_RESOURCE_FIELD, std::string("uri:") + std::to_string(index));
270     }
271 
QueryResourceCountSql(const std::string & tableName)272     std::string QueryResourceCountSql(const std::string &tableName)
273     {
274         return "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(tableName)
275             + " where sharing_resource like 'uri%'";
276     }
277 
QueryLogicDeleteCountSql(const std::string & tableName)278     std::string QueryLogicDeleteCountSql(const std::string &tableName)
279     {
280         return "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(tableName)
281             + " where flag&0x08!=0";
282     }
283 
QueryAllCountSql(const std::string & tableName)284     std::string QueryAllCountSql(const std::string &tableName)
285     {
286         return "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(tableName);
287     }
288 
QueryByCursorSql(const std::string & tableName,int cursor)289     std::string QueryByCursorSql(const std::string &tableName, int cursor)
290     {
291         return "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(tableName)
292             + " where cursor > " + std::to_string(cursor) + " and sharing_resource='' and cloud_gid=''";
293     }
294 
InsertCloudTableRecord(int64_t begin,int64_t count,bool isShare,int64_t beginGid)295     void DistributedDBCloudInterfacesSetCloudSchemaTest::InsertCloudTableRecord(int64_t begin, int64_t count,
296         bool isShare, int64_t beginGid)
297     {
298         std::vector<uint8_t> photo(1, 'v');
299         std::vector<VBucket> record;
300         std::vector<VBucket> extend;
301         Timestamp now = TimeHelper::GetSysCurrentTime();
302         std::string tableName = g_tableName2;
303         if (isShare) {
304             tableName = g_sharedTableName1;
305         }
306         for (int64_t i = begin; i < begin + count; ++i) {
307             VBucket data;
308             if (isShare) {
309                 data.insert_or_assign("cloud_owner", std::string("ownerA"));
310                 data.insert_or_assign("cloud_privilege", std::string("true"));
311             }
312             data.insert_or_assign("id", i);
313             data.insert_or_assign("name", "Cloud" + std::to_string(i));
314             data.insert_or_assign("height", 166.0); // 166.0 is random double value
315             data.insert_or_assign("married", false);
316             data.insert_or_assign("photo", photo);
317             record.push_back(data);
318             VBucket log;
319             log.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND + i);
320             log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND + i);
321             log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false);
322             if (beginGid >= 0) {
323                 log.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(beginGid + i));
324             }
325             if (forkInsertFunc_) {
326                 forkInsertFunc_(i, log);
327             }
328             extend.push_back(log);
329         }
330         if (beginGid >= 0) {
331             ASSERT_EQ(g_virtualCloudDb->BatchUpdate(tableName, std::move(record), extend), DBStatus::OK);
332         } else {
333             ASSERT_EQ(g_virtualCloudDb->BatchInsert(tableName, std::move(record), extend), DBStatus::OK);
334         }
335 
336         std::this_thread::sleep_for(std::chrono::milliseconds(count));
337     }
338 
BlockSync(const Query & query,RelationalStoreDelegate * delegate,DBStatus errCode,SyncMode mode)339     void DistributedDBCloudInterfacesSetCloudSchemaTest::BlockSync(const Query &query,
340         RelationalStoreDelegate *delegate, DBStatus errCode, SyncMode mode)
341     {
342         std::mutex dataMutex;
343         std::condition_variable cv;
344         bool finish = false;
345         auto callback = [&cv, &dataMutex, &finish, &errCode](const std::map<std::string, SyncProcess> &process) {
346             for (const auto &item: process) {
347                 if (item.second.process == DistributedDB::FINISHED) {
348                     {
349                         EXPECT_EQ(item.second.errCode, errCode);
350                         std::lock_guard<std::mutex> autoLock(dataMutex);
351                         finish = true;
352                     }
353                     cv.notify_one();
354                 }
355             }
356         };
357         ASSERT_EQ(delegate->Sync({ "CLOUD" }, mode, query, callback, g_syncWaitTime), OK);
358         std::unique_lock<std::mutex> uniqueLock(dataMutex);
359         cv.wait(uniqueLock, [&finish]() {
360             return finish;
361         });
362     }
363 
CheckCloudTableCount(const std::string & tableName,int64_t expectCount)364     void DistributedDBCloudInterfacesSetCloudSchemaTest::CheckCloudTableCount(const std::string &tableName,
365         int64_t expectCount)
366     {
367         VBucket extend;
368         extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(0);
369         int64_t realCount = 0;
370         std::vector<VBucket> data;
371         g_virtualCloudDb->Query(tableName, extend, data);
372         for (size_t j = 0; j < data.size(); ++j) {
373             auto entry = data[j].find(CloudDbConstant::DELETE_FIELD);
374             if (entry != data[j].end() && std::get<bool>(entry->second)) {
375                 continue;
376             }
377             realCount++;
378         }
379         EXPECT_EQ(realCount, expectCount); // ExpectCount represents the total amount of cloud data.
380     }
381 
CloseDb()382     void DistributedDBCloudInterfacesSetCloudSchemaTest::CloseDb()
383     {
384         if (g_delegate != nullptr) {
385             g_delegate->UnRegisterObserver(g_observer);
386         }
387         delete g_observer;
388         g_observer = nullptr;
389         g_virtualCloudDb = nullptr;
390         if (g_delegate != nullptr) {
391             EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
392             g_delegate = nullptr;
393         }
394     }
395 
InitCloudEnv()396     void DistributedDBCloudInterfacesSetCloudSchemaTest::InitCloudEnv()
397     {
398         DataBaseSchema dataBaseSchema;
399         TableSchema tableSchema = {
400             .name = g_tableName2,
401             .sharedTableName = g_sharedTableName1,
402             .fields = g_cloudField2
403         };
404         dataBaseSchema.tables.push_back(tableSchema);
405         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
406         ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName2, CLOUD_COOPERATION), DBStatus::OK);
407     }
408 
DeleteCloudTableRecord(int64_t beginGid,int64_t count,bool isShare)409     void DistributedDBCloudInterfacesSetCloudSchemaTest::DeleteCloudTableRecord(int64_t beginGid,
410         int64_t count, bool isShare)
411     {
412         Timestamp now = TimeHelper::GetSysCurrentTime();
413         std::vector<VBucket> extend;
414         for (int64_t i = 0; i < count; ++i) {
415             VBucket log;
416             log.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND + i);
417             log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND + i);
418             log.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(beginGid + i));
419             extend.push_back(log);
420         }
421         ASSERT_EQ(g_virtualCloudDb->BatchDelete(isShare ? g_sharedTableName1 : g_tableName2, extend), DBStatus::OK);
422         std::this_thread::sleep_for(std::chrono::milliseconds(count));
423     }
424 
425     /**
426      * @tc.name: SetCloudDbSchemaTest001
427      * @tc.desc: Test same table name for set cloud schema interface
428      * @tc.type: FUNC
429      * @tc.require:
430      * @tc.author: chenchaohao
431     */
432     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest001, TestSize.Level0)
433     {
434         /**
435          * @tc.steps:step1. table names are same but sharedtable names are empty
436          * @tc.expected: step1. return INVALID_ARGS
437          */
438         DataBaseSchema dataBaseSchema;
439         TableSchema tableSchema = {
440             .name = g_tableName1,
441             .sharedTableName = g_tableName1 + "_shared",
442             .fields = g_cloudField1
443         };
444         dataBaseSchema.tables.push_back(tableSchema);
445         dataBaseSchema.tables.push_back(tableSchema);
446         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
447 
448         /**
449          * @tc.steps:step2. table names are same but sharedtable names are different
450          * @tc.expected: step2. return INVALID_ARGS
451          */
452         dataBaseSchema.tables.clear();
453         tableSchema = {
454             .name = g_tableName1,
455             .sharedTableName = g_sharedTableName1,
456             .fields = g_cloudField1
457         };
458         dataBaseSchema.tables.push_back(tableSchema);
459         tableSchema = {
460             .name = g_tableName1,
461             .sharedTableName = g_sharedTableName2,
462             .fields = g_cloudField1
463         };
464         dataBaseSchema.tables.push_back(tableSchema);
465         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
466 
467         /**
468          * @tc.steps:step3. one table name is uppercase and the other is lowercase
469          * @tc.expected: step3. return INVALID_ARGS
470          */
471         dataBaseSchema.tables.clear();
472         tableSchema = {
473             .name = g_tableName1,
474             .sharedTableName = g_sharedTableName1,
475             .fields = g_cloudField1
476         };
477         dataBaseSchema.tables.push_back(tableSchema);
478         tableSchema = {
479             .name = g_tableName3,
480             .sharedTableName = g_sharedTableName2,
481             .fields = g_cloudField1
482         };
483         dataBaseSchema.tables.push_back(tableSchema);
484         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
485     }
486 
487     /**
488      * @tc.name: SetCloudDbSchemaTest002
489      * @tc.desc: Test same shared table name for set cloud schema interface
490      * @tc.type: FUNC
491      * @tc.require:
492      * @tc.author: chenchaohao
493     */
494     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest002, TestSize.Level0)
495     {
496         /**
497          * @tc.steps:step1. table names are different but sharedtable names are same
498          * @tc.expected: step1. return INVALID_ARGS
499          */
500         DataBaseSchema dataBaseSchema;
501         TableSchema tableSchema = {
502             .name = g_tableName1,
503             .sharedTableName = g_tableName1 + "_shared",
504             .fields = g_cloudField1
505         };
506         dataBaseSchema.tables.push_back(tableSchema);
507         tableSchema = {
508             .name = g_tableName2,
509             .sharedTableName = g_sharedTableName1,
510             .fields = g_cloudField2
511         };
512         dataBaseSchema.tables.push_back(tableSchema);
513         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
514 
515         /**
516          * @tc.steps:step2. table names are different but sharedtable names are same
517          * @tc.expected: step2. return INVALID_ARGS
518          */
519         dataBaseSchema.tables.clear();
520         tableSchema = {
521             .name = g_tableName1,
522             .sharedTableName = g_sharedTableName1,
523             .fields = g_cloudField1
524         };
525         dataBaseSchema.tables.push_back(tableSchema);
526         tableSchema = {
527             .name = g_tableName2,
528             .sharedTableName = g_sharedTableName1,
529             .fields = g_cloudField2
530         };
531         dataBaseSchema.tables.push_back(tableSchema);
532         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
533 
534         /**
535          * @tc.steps:step3. one sharedtable name is uppercase and the other is lowercase
536          * @tc.expected: step3. return INVALID_ARGS
537          */
538         dataBaseSchema.tables.clear();
539         tableSchema = { g_tableName1, g_sharedTableName1, g_cloudField1 };
540         dataBaseSchema.tables.push_back(tableSchema);
541         tableSchema = { g_tableName2, g_sharedTableName3, g_cloudField2 };
542         dataBaseSchema.tables.push_back(tableSchema);
543         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
544 
545         /**
546          * @tc.steps:step4. sharedtable name and table name is same
547          * @tc.expected: step4. return INVALID_ARGS
548          */
549         dataBaseSchema.tables.clear();
550         tableSchema = {
551             .name = g_tableName1,
552             .sharedTableName = g_tableName1,
553             .fields = g_cloudField1
554         };
555         dataBaseSchema.tables.push_back(tableSchema);
556         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
557     }
558 
559     /**
560      * @tc.name: SetCloudDbSchemaTest003
561      * @tc.desc: Test same table name and shared table name for set cloud schema interface
562      * @tc.type: FUNC
563      * @tc.require:
564      * @tc.author: chenchaohao
565     */
566     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest003, TestSize.Level0)
567     {
568         /**
569          * @tc.steps:step1. table name and shared table name are same
570          * @tc.expected: step1. return INVALID_ARGS
571          */
572         DataBaseSchema dataBaseSchema;
573         TableSchema tableSchema = {
574             .name = g_tableName1,
575             .sharedTableName = g_sharedTableName1,
576             .fields = g_cloudField1
577         };
578         dataBaseSchema.tables.push_back(tableSchema);
579         tableSchema = {
580             .name = g_sharedTableName1,
581             .sharedTableName = g_tableName2,
582             .fields = g_cloudField2
583         };
584         dataBaseSchema.tables.push_back(tableSchema);
585         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
586 
587         /**
588          * @tc.steps:step2. shared table name and table name are same
589          * @tc.expected: step2. return INVALID_ARGS
590          */
591         dataBaseSchema.tables.clear();
592         tableSchema = {
593             .name = g_tableName1,
594             .sharedTableName = g_sharedTableName1,
595             .fields = g_cloudField1
596         };
597         dataBaseSchema.tables.push_back(tableSchema);
598         tableSchema = {
599             .name = g_tableName2,
600             .sharedTableName = g_tableName1,
601             .fields = g_cloudField2
602         };
603         dataBaseSchema.tables.push_back(tableSchema);
604         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
605     }
606 
607     /**
608      * @tc.name: SetCloudDbSchemaTest004
609      * @tc.desc: Test same field for set cloud schema interface
610      * @tc.type: FUNC
611      * @tc.require:
612      * @tc.author: chenchaohao
613     */
614     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest004, TestSize.Level0)
615     {
616         /**
617          * @tc.steps:step1. fields contains same field
618          * @tc.expected: step1. return INVALID_ARGS
619          */
620         DataBaseSchema dataBaseSchema;
621         std::vector<Field> invalidFields = g_cloudField1;
622         invalidFields.push_back({"name", TYPE_INDEX<std::string>});
623         TableSchema tableSchema = {
624             .name = g_tableName1,
625             .sharedTableName = g_sharedTableName1,
626             .fields = invalidFields
627         };
628         dataBaseSchema.tables.push_back(tableSchema);
629         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
630 
631         /**
632          * @tc.steps:step2. fields contains cloud_owner
633          * @tc.expected: step2. return INVALID_ARGS
634          */
635         dataBaseSchema.tables.clear();
636         invalidFields = g_cloudField1;
637         invalidFields.push_back({"cloud_owner", TYPE_INDEX<std::string>});
638         tableSchema = {
639             .name = g_tableName1,
640             .sharedTableName = g_sharedTableName1,
641             .fields = invalidFields
642         };
643         dataBaseSchema.tables.push_back(tableSchema);
644         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
645 
646         /**
647          * @tc.steps:step3. fields contains cloud_privilege
648          * @tc.expected: step3. return INVALID_ARGS
649          */
650         dataBaseSchema.tables.clear();
651         invalidFields = g_cloudField1;
652         invalidFields.push_back({"cloud_privilege", TYPE_INDEX<std::string>});
653         tableSchema = {
654             .name = g_tableName1,
655             .sharedTableName = g_sharedTableName1,
656             .fields = invalidFields
657         };
658         dataBaseSchema.tables.push_back(tableSchema);
659         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
660 
661         /**
662          * @tc.steps:step4. fields contains same field but uppercase
663          * @tc.expected: step4. return INVALID_ARGS
664          */
665         dataBaseSchema.tables.clear();
666         invalidFields = g_cloudField1;
667         invalidFields.push_back({"Name", TYPE_INDEX<std::string>});
668         tableSchema = { g_tableName1, g_sharedTableName1, invalidFields };
669         dataBaseSchema.tables.push_back(tableSchema);
670         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
671 
672         /**
673          * @tc.steps:step5. fields contains cloud_privilege field but uppercase
674          * @tc.expected: step5. return INVALID_ARGS
675          */
676         dataBaseSchema.tables.clear();
677         invalidFields = g_cloudField1;
678         invalidFields.push_back({"Cloud_priVilege", TYPE_INDEX<std::string>});
679         tableSchema = { g_tableName1, g_sharedTableName1, invalidFields };
680         dataBaseSchema.tables.push_back(tableSchema);
681         EXPECT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
682     }
683 
684     /**
685      * @tc.name: SetCloudDbSchemaTest005
686      * @tc.desc: Check shared table is existed or not
687      * @tc.type: FUNC
688      * @tc.require:
689      * @tc.author: chenchaohao
690     */
691     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest005, TestSize.Level0)
692     {
693         /**
694          * @tc.steps:step1. use SetCloudDbSchema
695          * @tc.expected: step1. return OK
696          */
697         DataBaseSchema dataBaseSchema;
698         TableSchema tableSchema = {
699             .name = g_tableName1,
700             .sharedTableName = g_sharedTableName1,
701             .fields = g_cloudField1
702         };
703         dataBaseSchema.tables.push_back(tableSchema);
704         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
705         CheckSharedTable({g_sharedTableName1});
706         CheckDistributedSharedTable({g_distributedSharedTableName1});
707 
708         /**
709          * @tc.steps:step2. re-SetCloudDbSchema and schema table changed
710          * @tc.expected: step2. return OK
711          */
712         dataBaseSchema.tables.clear();
713         tableSchema = {
714             .name = g_tableName2,
715             .sharedTableName = g_sharedTableName2,
716             .fields = g_cloudField2
717         };
718         dataBaseSchema.tables.push_back(tableSchema);
719         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
720         CheckSharedTable({g_sharedTableName2});
721         CheckDistributedSharedTable({g_distributedSharedTableName2});
722 
723         /**
724          * @tc.steps:step3. re-SetCloudDbSchema and schema fields changed
725          * @tc.expected: step3. return OK
726          */
727         dataBaseSchema.tables.clear();
728         tableSchema = {
729             .name = g_tableName2,
730             .sharedTableName = g_sharedTableName2,
731             .fields = g_cloudField1
732         };
733         dataBaseSchema.tables.push_back(tableSchema);
734         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
735         CheckSharedTable({g_sharedTableName2});
736         CheckDistributedSharedTable({g_distributedSharedTableName2});
737     }
738 
739     /**
740      * @tc.name: SetCloudDbSchemaTest006
741      * @tc.desc: Test SetCloudDbSchema in uppercase and lowercase
742      * @tc.type: FUNC
743      * @tc.require:
744      * @tc.author: chenchaohao
745     */
746     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest006, 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_tableName3,
755             .sharedTableName = g_sharedTableName3,
756             .fields = g_cloudField1
757         };
758         dataBaseSchema.tables.push_back(tableSchema);
759         tableSchema = {
760             .name = g_tableName2,
761             .sharedTableName = g_sharedTableName2,
762             .fields = g_cloudField2
763         };
764         dataBaseSchema.tables.push_back(tableSchema);
765         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
766         CheckSharedTable({g_sharedTableName3, g_sharedTableName2});
767         CheckDistributedSharedTable({g_distributedSharedTableName3, g_distributedSharedTableName2});
768     }
769 
770     /**
771      * @tc.name: SetCloudDbSchemaTest007
772      * @tc.desc: Test SetCloudDbSchema if need alter shared table name
773      * @tc.type: FUNC
774      * @tc.require:
775      * @tc.author: chenchaohao
776     */
777     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest007, TestSize.Level0)
778     {
779         /**
780          * @tc.steps:step1. use SetCloudDbSchema
781          * @tc.expected: step1. return OK
782          */
783         DataBaseSchema dataBaseSchema;
784         TableSchema tableSchema = {
785             .name = g_tableName1,
786             .sharedTableName = g_sharedTableName1,
787             .fields = g_cloudField1
788         };
789         dataBaseSchema.tables.push_back(tableSchema);
790         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
791         CheckSharedTable({g_sharedTableName1});
792         CheckDistributedSharedTable({g_distributedSharedTableName1});
793 
794         /**
795          * @tc.steps:step2. re-SetCloudDbSchema and schema shared table changed
796          * @tc.expected: step2. return OK
797          */
798         dataBaseSchema.tables.clear();
799         tableSchema = {
800             .name = g_tableName1,
801             .sharedTableName = g_sharedTableName2,
802             .fields = g_cloudField1
803         };
804         dataBaseSchema.tables.push_back(tableSchema);
805         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
806         CheckSharedTable({g_sharedTableName2});
807         CheckDistributedSharedTable({g_distributedSharedTableName2});
808 
809         /**
810          * @tc.steps:step3. re-SetCloudDbSchema and schema table changed
811          * @tc.expected: step3. return OK
812          */
813         dataBaseSchema.tables.clear();
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_sharedTableName2});
822         CheckDistributedSharedTable({g_distributedSharedTableName2});
823     }
824 
825     /**
826      * @tc.name: SetCloudDbSchemaTest008
827      * @tc.desc: Test SetCloudDbSchema when A-B C-D update B-D
828      * @tc.type: FUNC
829      * @tc.require:
830      * @tc.author: chenchaohao
831     */
832     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest008, TestSize.Level0)
833     {
834         /**
835          * @tc.steps:step1. use SetCloudDbSchema A-B C-D
836          * @tc.expected: step1. return OK
837          */
838         DataBaseSchema dataBaseSchema;
839         TableSchema tableSchema = {
840             .name = g_tableName1,
841             .sharedTableName = g_sharedTableName1,
842             .fields = g_cloudField1
843         };
844         dataBaseSchema.tables.push_back(tableSchema);
845         tableSchema = {
846             .name = g_tableName2,
847             .sharedTableName = g_sharedTableName2,
848             .fields = g_cloudField1
849         };
850         dataBaseSchema.tables.push_back(tableSchema);
851         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
852         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
853         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
854 
855         /**
856          * @tc.steps:step2. re-SetCloudDbSchema B-D
857          * @tc.expected: step2. return INVALID_ARGS
858          */
859         dataBaseSchema.tables.clear();
860         tableSchema = {
861             .name = g_sharedTableName1,
862             .sharedTableName = g_sharedTableName2,
863             .fields = g_cloudField1
864         };
865         dataBaseSchema.tables.push_back(tableSchema);
866         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
867         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
868         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
869     }
870 
871     /**
872      * @tc.name: SetCloudDbSchemaTest009
873      * @tc.desc: Test SetCloudDbSchema when A-B C-D update A-D
874      * @tc.type: FUNC
875      * @tc.require:
876      * @tc.author: chenchaohao
877     */
878     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest009, TestSize.Level0)
879     {
880         /**
881          * @tc.steps:step1. use SetCloudDbSchema
882          * @tc.expected: step1. return OK
883          */
884         DataBaseSchema dataBaseSchema;
885         TableSchema tableSchema = {
886             .name = g_tableName1,
887             .sharedTableName = g_sharedTableName1,
888             .fields = g_cloudField1
889         };
890         dataBaseSchema.tables.push_back(tableSchema);
891         tableSchema = {
892             .name = g_tableName2,
893             .sharedTableName = g_sharedTableName2,
894             .fields = g_cloudField1
895         };
896         dataBaseSchema.tables.push_back(tableSchema);
897         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
898         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
899         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
900 
901         /**
902          * @tc.steps:step2. re-SetCloudDbSchema and schema shared table changed
903          * @tc.expected: step2. return OK
904          */
905         dataBaseSchema.tables.clear();
906         tableSchema = {
907             .name = g_tableName1,
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_sharedTableName2});
914         CheckDistributedSharedTable({g_distributedSharedTableName2});
915     }
916 
917     /**
918      * @tc.name: SetCloudDbSchemaTest010
919      * @tc.desc: Test SetCloudDbSchema when A-B C-D update A-E C-B
920      * @tc.type: FUNC
921      * @tc.require:
922      * @tc.author: chenchaohao
923     */
924     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest010, TestSize.Level1)
925     {
926         /**
927          * @tc.steps:step1. use SetCloudDbSchema
928          * @tc.expected: step1. return OK
929          */
930         DataBaseSchema dataBaseSchema;
931         TableSchema tableSchema = {
932             .name = g_tableName1,
933             .sharedTableName = g_sharedTableName1,
934             .fields = g_cloudField1
935         };
936         dataBaseSchema.tables.push_back(tableSchema);
937         tableSchema = {
938             .name = g_tableName2,
939             .sharedTableName = g_sharedTableName2,
940             .fields = g_cloudField1
941         };
942         dataBaseSchema.tables.push_back(tableSchema);
943         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
944         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
945         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
946 
947         /**
948          * @tc.steps:step2. re-SetCloudDbSchema and schema shared table changed
949          * @tc.expected: step2. return OK
950          */
951         dataBaseSchema.tables.clear();
952         tableSchema = {
953             .name = g_tableName1,
954             .sharedTableName = g_sharedTableName4,
955             .fields = g_cloudField1
956         };
957         dataBaseSchema.tables.push_back(tableSchema);
958         tableSchema = {
959             .name = g_tableName2,
960             .sharedTableName = g_sharedTableName1,
961             .fields = g_cloudField1
962         };
963         dataBaseSchema.tables.push_back(tableSchema);
964         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
965         CheckSharedTable({g_sharedTableName4, g_sharedTableName1});
966         CheckDistributedSharedTable({g_distributedSharedTableName4, g_distributedSharedTableName1});
967     }
968 
969     /**
970      * @tc.name: SetCloudDbSchemaTest011
971      * @tc.desc: Test SetCloudDbSchema if local exists user table
972      * @tc.type: FUNC
973      * @tc.require:
974      * @tc.author: chenchaohao
975     */
976     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest011, TestSize.Level0)
977     {
978         /**
979          * @tc.steps:step1. local exists worker1 then use SetCloudDbSchema
980          * @tc.expected: step1. return INVALID_ARGS
981          */
982         DataBaseSchema dataBaseSchema;
983         TableSchema tableSchema = {
984             .name = g_tableName2,
985             .sharedTableName = g_tableName1,
986             .fields = g_cloudField1
987         };
988         dataBaseSchema.tables.push_back(tableSchema);
989         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
990 
991         /**
992          * @tc.steps:step2. SetCloudDbSchema
993          * @tc.expected: step2. return OK
994          */
995         dataBaseSchema.tables.clear();
996         tableSchema = {
997             .name = g_tableName1,
998             .sharedTableName = g_sharedTableName1,
999             .fields = g_cloudField1
1000         };
1001         dataBaseSchema.tables.push_back(tableSchema);
1002         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1003         CheckSharedTable({g_sharedTableName1});
1004         CheckDistributedSharedTable({g_distributedSharedTableName1});
1005 
1006         /**
1007          * @tc.steps:step3. add field and SetCloudDbSchema
1008          * @tc.expected: step3. return OK
1009          */
1010         dataBaseSchema.tables.clear();
1011         tableSchema = {
1012             .name = g_tableName1,
1013             .sharedTableName = g_sharedTableName2,
1014             .fields = g_cloudField3
1015         };
1016         dataBaseSchema.tables.push_back(tableSchema);
1017         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1018         CheckSharedTable({g_sharedTableName2});
1019         CheckDistributedSharedTable({g_distributedSharedTableName2});
1020     }
1021 
1022     /**
1023      * @tc.name: SetCloudDbSchemaTest012
1024      * @tc.desc: Test SetCloudDbSchema if local exists user table
1025      * @tc.type: FUNC
1026      * @tc.require:
1027      * @tc.author: chenchaohao
1028     */
1029     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest012, TestSize.Level0)
1030     {
1031         /**
1032          * @tc.steps:step1. use SetCloudDbSchema
1033          * @tc.expected: step1. return OK
1034          */
1035         ASSERT_EQ(RelationalTestUtils::ExecSql(db_, CREATE_SHARED_TABLE_SQL), SQLITE_OK);
1036         DataBaseSchema dataBaseSchema;
1037         TableSchema tableSchema = {
1038             .name = g_tableName1,
1039             .sharedTableName = g_sharedTableName1,
1040             .fields = g_cloudField1
1041         };
1042         dataBaseSchema.tables.push_back(tableSchema);
1043         tableSchema = {
1044             .name = g_tableName2,
1045             .sharedTableName = g_sharedTableName2,
1046             .fields = g_cloudField1
1047         };
1048         dataBaseSchema.tables.push_back(tableSchema);
1049         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1050         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
1051 
1052         /**
1053          * @tc.steps:step2. re-SetCloudDbSchema and schema shared table changed
1054          * @tc.expected: step2. return OK
1055          */
1056         dataBaseSchema.tables.clear();
1057         tableSchema = {
1058             .name = g_tableName1,
1059             .sharedTableName = g_sharedTableName4,
1060             .fields = g_cloudField1
1061         };
1062         dataBaseSchema.tables.push_back(tableSchema);
1063         tableSchema = {
1064             .name = g_tableName2,
1065             .sharedTableName = g_sharedTableName1,
1066             .fields = g_cloudField1
1067         };
1068         dataBaseSchema.tables.push_back(tableSchema);
1069         tableSchema = {
1070             .name = g_tableName4,
1071             .sharedTableName = g_sharedTableName5,
1072             .fields = g_cloudField1
1073         };
1074         dataBaseSchema.tables.push_back(tableSchema);
1075         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
1076     }
1077 
1078     /**
1079      * @tc.name: SetCloudDbSchemaTest013
1080      * @tc.desc: Test SetCloudDbSchema after close db
1081      * @tc.type: FUNC
1082      * @tc.require:
1083      * @tc.author: chenchaohao
1084     */
1085     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest013, TestSize.Level1)
1086     {
1087         /**
1088          * @tc.steps:step1. use SetCloudDbSchema
1089          * @tc.expected: step1. return OK
1090          */
1091         DataBaseSchema dataBaseSchema;
1092         TableSchema 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          * @tc.steps:step2. close db and then open store
1110          * @tc.expected: step2. return OK
1111          */
1112         CloseDb();
1113         DBStatus status = g_mgr.OpenStore(g_storePath, STORE_ID, {}, g_delegate);
1114         ASSERT_EQ(status, OK);
1115         g_virtualCloudDb = std::make_shared<VirtualCloudDb>();
1116         ASSERT_EQ(g_delegate->SetCloudDB(g_virtualCloudDb), DBStatus::OK);
1117 
1118         /**
1119          * @tc.steps:step3. re-SetCloudDbSchema and schema is same
1120          * @tc.expected: step3. return OK
1121          */
1122         dataBaseSchema.tables.clear();
1123         tableSchema = {
1124             .name = g_tableName1,
1125             .sharedTableName = g_sharedTableName1,
1126             .fields = g_cloudField1
1127         };
1128         dataBaseSchema.tables.push_back(tableSchema);
1129         tableSchema = {
1130             .name = g_tableName2,
1131             .sharedTableName = g_sharedTableName2,
1132             .fields = g_cloudField1
1133         };
1134         dataBaseSchema.tables.push_back(tableSchema);
1135         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1136         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
1137         CheckDistributedSharedTable({g_distributedSharedTableName1, g_distributedSharedTableName2});
1138     }
1139 
1140     /**
1141      * @tc.name: SetCloudDbSchemaTest014
1142      * @tc.desc: Test SetCloudDbSchema after set tracker table
1143      * @tc.type: FUNC
1144      * @tc.require:
1145      * @tc.author: chenchaohao
1146     */
1147     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest014, TestSize.Level0)
1148     {
1149         /**
1150          * @tc.steps:step1. use SetTrackerTable
1151          * @tc.expected: step1. return OK
1152          */
1153         TrackerSchema trackerSchema = {
1154             .tableName = g_tableName1,
1155             .extendColNames = {"married"},
1156             .trackerColNames = {"married"}
1157         };
1158         ASSERT_EQ(g_delegate->SetTrackerTable(trackerSchema), DBStatus::OK);
1159         ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName1, CLOUD_COOPERATION), DBStatus::OK);
1160 
1161         /**
1162          * @tc.steps:step2. use SetCloudDbSchema
1163          * @tc.expected: step2. return OK
1164          */
1165         DataBaseSchema dataBaseSchema;
1166         TableSchema tableSchema = {
1167             .name = g_tableName1,
1168             .sharedTableName = g_sharedTableName1,
1169             .fields = g_cloudField1
1170         };
1171         dataBaseSchema.tables.push_back(tableSchema);
1172         tableSchema = {
1173             .name = g_tableName2,
1174             .sharedTableName = g_sharedTableName2,
1175             .fields = g_cloudField1
1176         };
1177         dataBaseSchema.tables.push_back(tableSchema);
1178         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1179         CheckSharedTable({g_sharedTableName1, g_sharedTableName2});
1180     }
1181 
1182     /**
1183      * @tc.name: SharedTableSync001
1184      * @tc.desc: Test sharedtable without primary key sync
1185      * @tc.type: FUNC
1186      * @tc.require:
1187      * @tc.author: chenchaohao
1188     */
1189     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync001, TestSize.Level1)
1190     {
1191         /**
1192          * @tc.steps:step1. use set shared table without primary key
1193          * @tc.expected: step1. return OK
1194          */
1195         DataBaseSchema dataBaseSchema;
1196         TableSchema tableSchema = {
1197             .name = g_tableName2,
1198             .sharedTableName = g_sharedTableName2,
1199             .fields = g_cloudField2
1200         };
1201         dataBaseSchema.tables.push_back(tableSchema);
1202         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1203 
1204         /**
1205          * @tc.steps:step2. insert local shared table records and sync
1206          * @tc.expected: step2. return OK
1207          */
1208         InsertLocalSharedTableRecords(0, 10, g_sharedTableName2);
1209         Query query = Query::Select().FromTable({ g_sharedTableName2 });
1210         BlockSync(query, g_delegate);
1211         CheckCloudTableCount(g_sharedTableName2, 10);
1212     }
1213 
1214     /**
1215      * @tc.name: SharedTableSync002
1216      * @tc.desc: Test sharedtable sync when version abnormal
1217      * @tc.type: FUNC
1218      * @tc.require:
1219      * @tc.author: chenchaohao
1220     */
1221     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync002, TestSize.Level1)
1222     {
1223         /**
1224          * @tc.steps:step1. use set shared table
1225          * @tc.expected: step1. return OK
1226          */
1227         DataBaseSchema dataBaseSchema;
1228         TableSchema tableSchema = {
1229             .name = g_tableName1,
1230             .sharedTableName = g_sharedTableName1,
1231             .fields = g_cloudField1
1232         };
1233         dataBaseSchema.tables.push_back(tableSchema);
1234         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1235 
1236         /**
1237          * @tc.steps:step2. insert local shared table records and sync
1238          * @tc.expected: step2. return OK
1239          */
1240         InsertLocalSharedTableRecords(0, 10, g_sharedTableName1);
__anona24994cc0402(const std::string &tableName, VBucket &extend) 1241         g_virtualCloudDb->ForkUpload([](const std::string &tableName, VBucket &extend) {
1242             extend.erase(CloudDbConstant::VERSION_FIELD);
1243         });
1244         Query query = Query::Select().FromTable({ g_sharedTableName1 });
1245         BlockSync(query, g_delegate, DBStatus::OK);
1246 
__anona24994cc0502(const std::string &tableName, VBucket &extend) 1247         g_virtualCloudDb->ForkUpload([](const std::string &tableName, VBucket &extend) {
1248             if (extend.find(CloudDbConstant::VERSION_FIELD) != extend.end()) {
1249                 extend[CloudDbConstant::VERSION_FIELD] = "";
1250             }
1251         });
1252         query = Query::Select().FromTable({ g_sharedTableName1 });
1253         BlockSync(query, g_delegate, DBStatus::OK);
1254     }
1255 
1256     /**
1257      * @tc.name: SharedTableSync003
1258      * @tc.desc: Test weather the shared table is fill assetId under nochange
1259      * @tc.type: FUNC
1260      * @tc.require:
1261      * @tc.author: bty
1262     */
1263     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync003, TestSize.Level1)
1264     {
1265         /**
1266          * @tc.steps:step1. insert local shared table records and sync
1267          * @tc.expected: step1. return OK
1268          */
1269         DataBaseSchema dataBaseSchema;
1270         TableSchema tableSchema = {
1271             .name = g_tableName1,
1272             .sharedTableName = g_sharedTableName1,
1273             .fields = g_cloudField1
1274         };
1275         dataBaseSchema.tables.push_back(tableSchema);
1276         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1277         InsertLocalSharedTableRecords(0, 10, g_sharedTableName1); // 10 is records num
1278         Query query = Query::Select().FromTable({ g_sharedTableName1 });
1279         BlockSync(query, g_delegate);
1280 
1281         /**
1282          * @tc.steps:step2. sync again, cloud data containing assetId will be query
1283          * @tc.expected: step2. return OK
1284          */
1285         BlockSync(query, g_delegate);
1286 
1287         /**
1288          * @tc.steps:step3. check if the hash of assets in db is empty
1289          * @tc.expected: step3. OK
1290          */
1291         std::string sql = "SELECT asset from " + g_sharedTableName1;
1292         sqlite3_stmt *stmt = nullptr;
1293         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1294         while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1295             ASSERT_EQ(sqlite3_column_type(stmt, 0), SQLITE_BLOB);
1296             Type cloudValue;
1297             ASSERT_EQ(SQLiteRelationalUtils::GetCloudValueByType(stmt, TYPE_INDEX<Asset>, 0, cloudValue), E_OK);
1298             std::vector<uint8_t> assetBlob;
1299             Asset asset;
1300             ASSERT_EQ(CloudStorageUtils::GetValueFromOneField(cloudValue, assetBlob), E_OK);
1301             ASSERT_EQ(RuntimeContext::GetInstance()->BlobToAsset(assetBlob, asset), E_OK);
1302             EXPECT_EQ(asset.assetId, "");
1303         }
1304         int errCode;
1305         SQLiteUtils::ResetStatement(stmt, true, errCode);
1306     }
1307 
1308     /**
1309      * @tc.name: SharedTableSync004
1310      * @tc.desc: Test sharedtable sync when alter shared table name
1311      * @tc.type: FUNC
1312      * @tc.require:
1313      * @tc.author: chenchaohao
1314     */
1315     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync004, TestSize.Level1)
1316     {
1317         /**
1318          * @tc.steps:step1. use set shared table
1319          * @tc.expected: step1. return OK
1320          */
1321         DataBaseSchema dataBaseSchema;
1322         TableSchema tableSchema = {
1323             .name = g_tableName1,
1324             .sharedTableName = g_sharedTableName1,
1325             .fields = g_cloudField1
1326         };
1327         dataBaseSchema.tables.push_back(tableSchema);
1328         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1329         CheckSharedTable({g_sharedTableName1});
1330 
1331         /**
1332          * @tc.steps:step2. insert local shared table records and alter shared table name then sync
1333          * @tc.expected: step2. return OK
1334          */
1335         InsertLocalSharedTableRecords(0, 10, g_sharedTableName1);
1336         dataBaseSchema.tables.clear();
1337         tableSchema = {
1338             .name = g_tableName1,
1339             .sharedTableName = g_sharedTableName5,
1340             .fields = g_cloudField1
1341         };
1342         dataBaseSchema.tables.push_back(tableSchema);
1343         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1344         CheckSharedTable({g_sharedTableName5});
1345         Query query = Query::Select().FromTable({ g_sharedTableName5 });
1346         BlockSync(query, g_delegate);
1347         CheckCloudTableCount(g_sharedTableName5, 10);
1348     }
1349 
1350     /**
1351      * @tc.name: SharedTableSync006
1352      * @tc.desc: Test sharedtable sync when sharedtable add column
1353      * @tc.type: FUNC
1354      * @tc.require:
1355      * @tc.author: chenchaohao
1356     */
1357     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync006, TestSize.Level1)
1358     {
1359         /**
1360          * @tc.steps:step1. set shared table and sync
1361          * @tc.expected: step1. return OK
1362          */
1363         DataBaseSchema dataBaseSchema;
1364         TableSchema tableSchema = {
1365             .name = g_tableName1,
1366             .sharedTableName = g_sharedTableName1,
1367             .fields = g_cloudField1
1368         };
1369         dataBaseSchema.tables.push_back(tableSchema);
1370         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1371 
1372         int localCount = 10;
1373         InsertLocalSharedTableRecords(0, localCount, g_sharedTableName1);
1374         Query query = Query::Select().FromTable({ g_sharedTableName1 });
1375         BlockSync(query, g_delegate, DBStatus::OK);
1376         CheckCloudTableCount(g_sharedTableName1, localCount);
1377 
1378         /**
1379          * @tc.steps:step2. add shared table column and sync
1380          * @tc.expected: step2. return OK
1381          */
1382         dataBaseSchema.tables.clear();
1383         tableSchema = {
1384             .name = g_tableName1,
1385             .sharedTableName = g_sharedTableName1,
1386             .fields = g_cloudField3
1387         };
1388         dataBaseSchema.tables.push_back(tableSchema);
1389         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1390         int cloudCount = 20;
1391         InsertLocalSharedTableRecords(localCount, cloudCount, g_sharedTableName1, true);
1392         BlockSync(query, g_delegate, DBStatus::OK);
1393         CheckCloudTableCount(g_sharedTableName1, cloudCount);
1394     }
1395 
1396     /**
1397      * @tc.name: SetCloudDbSchemaTest015
1398      * @tc.desc: Test SetCloudDbSchema sharedTableName is ""
1399      * @tc.type: FUNC
1400      * @tc.require:
1401      * @tc.author: wangxiangdong
1402     */
1403     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest015, TestSize.Level0)
1404     {
1405         /**
1406          * @tc.steps:step1. set sharedTableName ""
1407          * @tc.expected: step1. return OK
1408          */
1409         DataBaseSchema dataBaseSchema;
1410         TableSchema tableSchema = {
1411             .name = g_tableName1,
1412             .sharedTableName = "",
1413             .fields = g_cloudField1
1414         };
1415         dataBaseSchema.tables.push_back(tableSchema);
1416         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1417 
1418         /**
1419          * @tc.steps:step2. check sharedTable not exist
1420          * @tc.expected: step2. return OK
1421          */
1422         std::string sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND " \
1423             "name LIKE 'worker%_shared';";
1424         sqlite3_stmt *stmt = nullptr;
1425         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1426         ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1427         int ret = E_OK;
1428         SQLiteUtils::ResetStatement(stmt, true, ret);
1429         ASSERT_EQ(ret, E_OK);
1430     }
1431 
1432     /**
1433      * @tc.name: SetCloudDbSchemaTest016
1434      * @tc.desc: Test SetCloudDbSchema if it will delete sharedtable when set sharedtable is empty
1435      * @tc.type: FUNC
1436      * @tc.require:
1437      * @tc.author: chenchaohao
1438     */
1439     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest016, TestSize.Level0)
1440     {
1441         /**
1442          * @tc.steps:step1. use SetCloudDbSchema to create g_sharedTableName1
1443          * @tc.expected: step1. return OK
1444          */
1445         DataBaseSchema dataBaseSchema;
1446         TableSchema tableSchema = {
1447             .name = g_tableName1,
1448             .sharedTableName = g_sharedTableName1,
1449             .fields = g_cloudField1
1450         };
1451         dataBaseSchema.tables.push_back(tableSchema);
1452         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1453         CheckSharedTable({g_sharedTableName1});
1454         CheckDistributedSharedTable({g_distributedSharedTableName1});
1455 
1456         /**
1457          * @tc.steps:step2. re-SetCloudDbSchema and sharedtable name is empty
1458          * @tc.expected: step2. return INVALID_ARS
1459          */
1460         dataBaseSchema.tables.clear();
1461         tableSchema = {
1462             .name = g_tableName1,
1463             .sharedTableName = "",
1464             .fields = g_cloudField1
1465         };
1466         dataBaseSchema.tables.push_back(tableSchema);
1467         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1468         std::string sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND " \
1469             "name LIKE 'worker%_shared';";
1470         sqlite3_stmt *stmt = nullptr;
1471         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1472         ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1473         int ret = E_OK;
1474         SQLiteUtils::ResetStatement(stmt, true, ret);
1475         ASSERT_EQ(ret, E_OK);
1476 
1477         /**
1478          * @tc.steps:step3. re-SetCloudDbSchema and set sharedtable
1479          * @tc.expected: step3. return INVALID_ARS
1480          */
1481         dataBaseSchema.tables.clear();
1482         tableSchema = {
1483             .name = g_tableName1,
1484             .sharedTableName = g_sharedTableName1,
1485             .fields = g_cloudField3
1486         };
1487         dataBaseSchema.tables.push_back(tableSchema);
1488         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1489         CheckSharedTable({g_sharedTableName1});
1490         CheckDistributedSharedTable({g_distributedSharedTableName1});
1491     }
1492 
1493     /**
1494      * @tc.name: SetCloudDbSchemaTest017
1495      * @tc.desc: Test SetCloudDbSchema if table fields are less than old table
1496      * @tc.type: FUNC
1497      * @tc.require:
1498      * @tc.author: chenchaohao
1499     */
1500     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest017, TestSize.Level0)
1501     {
1502         /**
1503          * @tc.steps:step1. use SetCloudDbSchema
1504          * @tc.expected: step1. return OK
1505          */
1506         DataBaseSchema dataBaseSchema;
1507         TableSchema tableSchema = {
1508             .name = g_tableName1,
1509             .sharedTableName = "",
1510             .fields = g_cloudField3
1511         };
1512         dataBaseSchema.tables.push_back(tableSchema);
1513         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
1514 
1515         /**
1516          * @tc.steps:step2. re-SetCloudDbSchema and fields are less than old
1517          * @tc.expected: step2. return INVALID_ARS
1518          */
1519         dataBaseSchema.tables.clear();
1520         tableSchema = {
1521             .name = g_tableName1,
1522             .sharedTableName = "",
1523             .fields = g_cloudField1
1524         };
1525         dataBaseSchema.tables.push_back(tableSchema);
1526         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::INVALID_ARGS);
1527     }
1528 
1529     /**
1530      * @tc.name: SharedTableSync007
1531      * @tc.desc: Test the sharing_resource for ins data into the cloud
1532      * @tc.type: FUNC
1533      * @tc.require:
1534      * @tc.author: bty
1535     */
1536     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync007, TestSize.Level1)
1537     {
1538         /**
1539          * @tc.steps:step1. init cloud share data contains sharing_resource
1540          * @tc.expected: step1. return OK
1541          */
1542         InitCloudEnv();
1543         int cloudCount = 10;
1544         forkInsertFunc_ = InsertSharingUri;
1545         InsertCloudTableRecord(0, cloudCount, false);
1546         InsertCloudTableRecord(0, cloudCount);
1547 
1548         /**
1549          * @tc.steps:step2. sync
1550          * @tc.expected: step2. return OK
1551          */
1552         Query query = Query::Select().FromTable({ g_tableName2, g_sharedTableName1 });
1553         BlockSync(query, g_delegate, DBStatus::OK);
1554         forkInsertFunc_ = nullptr;
1555 
1556         /**
1557          * @tc.steps:step3. check sync insert
1558          * @tc.expected: step3. return OK
1559          */
1560         std::string sql = QueryResourceCountSql(g_tableName2);
1561         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1562             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1563         sql = QueryResourceCountSql(g_sharedTableName1);
1564         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1565             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1566     }
1567 
1568     /**
1569      * @tc.name: SharedTableSync008
1570      * @tc.desc: Test the sharing_resource for upd data into the cloud
1571      * @tc.type: FUNC
1572      * @tc.require:
1573      * @tc.author: bty
1574     */
1575     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync008, TestSize.Level1)
1576     {
1577         /**
1578          * @tc.steps:step1. init cloud data and sync
1579          * @tc.expected: step1. return OK
1580          */
1581         InitCloudEnv();
1582         int cloudCount = 10;
1583         InsertCloudTableRecord(0, cloudCount, false);
1584         InsertCloudTableRecord(0, cloudCount);
1585         Query query = Query::Select().FromTable({ g_tableName2, g_sharedTableName1 });
1586         BlockSync(query, g_delegate, DBStatus::OK);
1587 
1588         /**
1589          * @tc.steps:step2. update cloud sharing_resource and sync
1590          * @tc.expected: step2. return OK
1591          */
1592         int beginGid = 0;
1593         forkInsertFunc_ = InsertSharingUri;
1594         InsertCloudTableRecord(0, cloudCount, false, beginGid);
1595         InsertCloudTableRecord(0, cloudCount, true, cloudCount);
1596         BlockSync(query, g_delegate, DBStatus::OK);
1597         forkInsertFunc_ = nullptr;
1598 
1599         /**
1600          * @tc.steps:step3. check sync update
1601          * @tc.expected: step3. return OK
1602          */
1603         std::string sql = QueryResourceCountSql(g_tableName2);
1604         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1605             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1606         sql = QueryResourceCountSql(g_sharedTableName1);
1607         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1608             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1609 
1610         /**
1611          * @tc.steps:step4. remove cloud sharing_resource and sync
1612          * @tc.expected: step4. return OK
1613          */
1614         InsertCloudTableRecord(0, cloudCount, false, beginGid);
1615         InsertCloudTableRecord(0, cloudCount, true, cloudCount);
1616         BlockSync(query, g_delegate, DBStatus::OK);
1617 
1618         /**
1619          * @tc.steps:step5. check sync update
1620          * @tc.expected: step5. return OK
1621          */
1622         sql = QueryResourceCountSql(g_tableName2);
1623         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1624             reinterpret_cast<void *>(0L), nullptr), SQLITE_OK);
1625         sql = QueryResourceCountSql(g_sharedTableName1);
1626         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1627             reinterpret_cast<void *>(0L), nullptr), SQLITE_OK);
1628     }
1629 
1630     /**
1631      * @tc.name: SharedTableSync009
1632      * @tc.desc: Test the sharing_resource when the local data is newer than the cloud
1633      * @tc.type: FUNC
1634      * @tc.require:
1635      * @tc.author: bty
1636     */
1637     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync009, TestSize.Level1)
1638     {
1639         /**
1640          * @tc.steps:step1. init cloud data and sync
1641          * @tc.expected: step1. return OK
1642          */
1643         InitCloudEnv();
1644         const std::vector<std::string> tables = { g_tableName2, g_sharedTableName1 };
1645         int cloudCount = 10;
1646         InsertCloudTableRecord(0, cloudCount, false);
1647         InsertCloudTableRecord(0, cloudCount);
1648         Query query = Query::Select().FromTable(tables);
1649         BlockSync(query, g_delegate, DBStatus::OK);
1650 
1651         /**
1652          * @tc.steps:step2. update cloud data, generate share uri
1653          * @tc.expected: step2. return OK
1654          */
1655         int beginGid = 0;
1656         forkInsertFunc_ = InsertSharingUri;
1657         InsertCloudTableRecord(0, cloudCount, false, beginGid);
1658         InsertCloudTableRecord(0, cloudCount, true, cloudCount);
1659         forkInsertFunc_ = nullptr;
1660 
1661         /**
1662          * @tc.steps:step3. update local data
1663          * @tc.expected: step3. return OK
1664          */
1665         for (const auto &tableName: tables) {
1666             std::string sql = "update " + tableName + " SET height='199';";
1667             sqlite3_stmt *stmt = nullptr;
1668             ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1669             EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1670             int errCode;
1671             SQLiteUtils::ResetStatement(stmt, true, errCode);
1672         }
1673 
1674         /**
1675          * @tc.steps:step4. sync and check count
1676          * @tc.expected: step4. return OK
1677          */
1678         BlockSync(query, g_delegate, DBStatus::OK);
1679         std::string sql = QueryResourceCountSql(g_tableName2);
1680         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1681             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1682         sql = QueryResourceCountSql(g_sharedTableName1);
1683         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1684             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1685         sql = "SELECT COUNT(*) FROM " + g_tableName2 + " where height='199'";
1686         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1687             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1688         sql = "SELECT COUNT(*) FROM " + g_sharedTableName1 + " where height='199'";
1689         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1690             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1691     }
1692 
1693     /**
1694      * @tc.name: SharedTableSync010
1695      * @tc.desc: Test the sharing_resource for del data into the cloud
1696      * @tc.type: FUNC
1697      * @tc.require:
1698      * @tc.author: bty
1699     */
1700     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync010, TestSize.Level1)
1701     {
1702         /**
1703          * @tc.steps:step1. init cloud share data and sync
1704          * @tc.expected: step1. return OK
1705          */
1706         InitCloudEnv();
1707         int cloudCount = 10;
1708         forkInsertFunc_ = InsertSharingUri;
1709         InsertCloudTableRecord(0, cloudCount, false);
1710         InsertCloudTableRecord(0, cloudCount);
1711         Query query = Query::Select().FromTable({ g_tableName2, g_sharedTableName1 });
1712         BlockSync(query, g_delegate, DBStatus::OK);
1713         forkInsertFunc_ = nullptr;
1714 
1715         /**
1716          * @tc.steps:step2. delete cloud data
1717          * @tc.expected: step2. return OK
1718          */
1719         int beginGid = 0;
1720         int delCount = 5;
1721         DeleteCloudTableRecord(beginGid, delCount, false);
1722         DeleteCloudTableRecord(cloudCount, delCount);
1723         BlockSync(query, g_delegate, DBStatus::OK);
1724 
1725         /**
1726          * @tc.steps:step3. sync and check count
1727          * @tc.expected: step3. return OK
1728          */
1729         std::string sql = QueryResourceCountSql(g_tableName2);
1730         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1731             reinterpret_cast<void *>(cloudCount - delCount), nullptr), SQLITE_OK);
1732         sql = QueryResourceCountSql(g_sharedTableName1);
1733         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1734             reinterpret_cast<void *>(cloudCount - delCount), nullptr), SQLITE_OK);
1735 
1736         /**
1737          * @tc.steps:step4. remove device data and check count
1738          * @tc.expected: step4. return OK
1739          */
1740         g_delegate->RemoveDeviceData("", FLAG_ONLY);
1741         sql = QueryResourceCountSql(g_tableName2);
1742         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1743             reinterpret_cast<void *>(0L), nullptr), SQLITE_OK);
1744         g_delegate->RemoveDeviceData("", CLEAR_SHARED_TABLE);
1745         sql = QueryResourceCountSql(g_sharedTableName1);
1746         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1747             reinterpret_cast<void *>(0L), nullptr), SQLITE_OK);
1748     }
1749 
1750     /**
1751      * @tc.name: SharedTableSync011
1752      * @tc.desc: Test the sharing_resource when the local data is newer than the cloud
1753      * @tc.type: FUNC
1754      * @tc.require:
1755      * @tc.author: bty
1756     */
1757     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync011, TestSize.Level1)
1758     {
1759         /**
1760          * @tc.steps:step1. init cloud data and sync
1761          * @tc.expected: step1. return OK
1762          */
1763         InitCloudEnv();
1764         const std::vector<std::string> tables = { g_tableName2, g_sharedTableName1 };
1765         int cloudCount = 10;
1766         InsertCloudTableRecord(0, cloudCount, false);
1767         InsertCloudTableRecord(0, cloudCount);
1768         Query query = Query::Select().FromTable(tables);
1769         BlockSync(query, g_delegate, DBStatus::OK);
1770 
1771         /**
1772          * @tc.steps:step2. update cloud data, generate share uri
1773          * @tc.expected: step2. return OK
1774          */
1775         int beginGid = 0;
1776         forkInsertFunc_ = InsertSharingUri;
1777         InsertCloudTableRecord(0, cloudCount, false, beginGid);
1778         InsertCloudTableRecord(0, cloudCount, true, cloudCount);
1779         forkInsertFunc_ = nullptr;
1780 
1781         /**
1782          * @tc.steps:step3. update local data
1783          * @tc.expected: step3. return OK
1784          */
1785         for (const auto &tableName: tables) {
1786             std::string sql = "update " + tableName + " SET height='199';";
1787             sqlite3_stmt *stmt = nullptr;
1788             ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1789             EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1790             int errCode;
1791             SQLiteUtils::ResetStatement(stmt, true, errCode);
1792         }
1793 
1794         /**
1795          * @tc.steps:step4. push sync and check count
1796          * @tc.expected: step4. return OK
1797          */
1798         BlockSync(query, g_delegate, DBStatus::OK, SyncMode::SYNC_MODE_CLOUD_FORCE_PUSH);
1799         std::string sql = QueryResourceCountSql(g_tableName2);
1800         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1801             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1802         sql = QueryResourceCountSql(g_sharedTableName1);
1803         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1804             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1805     }
1806 
1807     /**
1808      * @tc.name: SharedTableSync012
1809      * @tc.desc: Test the flag for uploaded data
1810      * @tc.type: FUNC
1811      * @tc.require:
1812      * @tc.author: bty
1813     */
1814     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync012, TestSize.Level1)
1815     {
1816         /**
1817          * @tc.steps:step1. init local share data and sync
1818          * @tc.expected: step1. return OK
1819          */
1820         InitCloudEnv();
1821         int cloudCount = 10;
1822         InsertLocalSharedTableRecords(0, 10, g_sharedTableName1);
1823         Query query = Query::Select().FromTable({ g_sharedTableName1 });
1824         BlockSync(query, g_delegate, DBStatus::OK);
1825 
1826         /**
1827          * @tc.steps:step2. update local share uri
1828          * @tc.expected: step2. return OK
1829          */
1830         std::string sql = "update " + DBCommon::GetLogTableName(g_sharedTableName1) + " SET sharing_resource='199';";
1831         sqlite3_stmt *stmt = nullptr;
1832         ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK);
1833         EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1834         int errCode;
1835         SQLiteUtils::ResetStatement(stmt, true, errCode);
1836 
1837         /**
1838          * @tc.steps:step3. sync and check flag
1839          * @tc.expected: step3. return OK
1840          */
1841         BlockSync(query, g_delegate, DBStatus::OK);
1842         sql = "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(g_sharedTableName1) + " where flag&0x02=0x02";
1843         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1844             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1845     }
1846 
1847     /**
1848      * @tc.name: SharedTableSync013
1849      * @tc.desc: Test the sharing_resource after data deleted
1850      * @tc.type: FUNC
1851      * @tc.require:
1852      * @tc.author: bty
1853     */
1854     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync013, TestSize.Level1)
1855     {
1856         /**
1857          * @tc.steps:step1. init cloud data and sync
1858          * @tc.expected: step1. return OK
1859          */
1860         InitCloudEnv();
1861         forkInsertFunc_ = InsertSharingUri;
1862         const std::vector<std::string> tables = { g_tableName2, g_sharedTableName1 };
1863         int cloudCount = 10;
1864         InsertCloudTableRecord(0, cloudCount, false);
1865         InsertCloudTableRecord(0, cloudCount);
1866         Query query = Query::Select().FromTable(tables);
1867         BlockSync(query, g_delegate, DBStatus::OK);
1868         forkInsertFunc_ = nullptr;
1869 
1870         /**
1871          * @tc.steps:step2. logic delete cloud data and sync, check sharing_resource
1872          * @tc.expected: step2. return OK
1873          */
1874         bool logicDelete = true;
1875         auto data = static_cast<PragmaData>(&logicDelete);
1876         EXPECT_EQ(g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data), OK);
1877         DeleteCloudTableRecord(0, cloudCount, false);
1878         DeleteCloudTableRecord(cloudCount, cloudCount);
1879         BlockSync(query, g_delegate, DBStatus::OK);
1880         std::string sql = "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(g_tableName2)
1881             + " where sharing_resource!=''";
1882         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1883             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1884 
1885         /**
1886          * @tc.steps:step3. drop logic data, check sharing_resource
1887          * @tc.expected: step3. return OK
1888          */
1889         EXPECT_EQ(DropLogicDeletedData(db_, g_tableName2, 0u), OK);
1890         sql = "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(g_tableName2) + " where sharing_resource=''";
1891         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1892             reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1893     }
1894 
1895     /**
1896      * @tc.name: SharedTableSync014
1897      * @tc.desc: Test shared table logic delete.
1898      * @tc.type: FUNC
1899      * @tc.require:
1900      * @tc.author: wangxiangdong
1901     */
1902     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync014, TestSize.Level1)
1903     {
1904         /**
1905          * @tc.steps: step1. Set data is logicDelete
1906          * @tc.expected: step1. return OK
1907          */
1908         bool logicDelete = true;
1909         auto data = static_cast<PragmaData>(&logicDelete);
1910         g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1911 
1912         /**
1913          * @tc.steps:step2. init cloud share data and sync
1914          * @tc.expected: step2. return OK
1915          */
1916         InitCloudEnv();
1917         int cloudCount = 10;
1918         forkInsertFunc_ = InsertSharingUri;
1919         InsertCloudTableRecord(0, cloudCount, false);
1920         InsertCloudTableRecord(0, cloudCount);
1921         Query query = Query::Select().FromTable({ g_tableName2, g_sharedTableName1 });
1922         BlockSync(query, g_delegate, DBStatus::OK);
1923         forkInsertFunc_ = nullptr;
1924 
1925         /**
1926          * @tc.steps:step3. delete cloud data
1927          * @tc.expected: step3. return OK
1928          */
1929         int beginGid = 0;
1930         int delCount = 5;
1931         DeleteCloudTableRecord(beginGid, delCount, false);
1932         DeleteCloudTableRecord(cloudCount, delCount);
1933         BlockSync(query, g_delegate, DBStatus::OK);
1934 
1935         /**
1936          * @tc.steps:step4. sync and check count
1937          * @tc.expected: step4. return OK
1938          */
1939         std::string sql = QueryLogicDeleteCountSql(g_tableName2);
1940         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1941             reinterpret_cast<void *>(cloudCount - delCount), nullptr), SQLITE_OK);
1942         sql = QueryLogicDeleteCountSql(g_sharedTableName1);
1943         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1944             reinterpret_cast<void *>(cloudCount - delCount), nullptr), SQLITE_OK);
1945     }
1946 
1947     /**
1948      * @tc.name: SharedTableSync015
1949      * @tc.desc: Test shared table remove logic delete.
1950      * @tc.type: FUNC
1951      * @tc.require:
1952      * @tc.author: wangxiangdong
1953     */
1954     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync015, TestSize.Level1)
1955     {
1956         /**
1957          * @tc.steps: step1. Set data is logicDelete
1958          * @tc.expected: step1. return OK
1959          */
1960         bool logicDelete = true;
1961         auto data = static_cast<PragmaData>(&logicDelete);
1962         g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1963 
1964         /**
1965          * @tc.steps:step2. init cloud share data and sync
1966          * @tc.expected: step2. return OK
1967          */
1968         InitCloudEnv();
1969         int cloudCount = 10;
1970         forkInsertFunc_ = InsertSharingUri;
1971         InsertCloudTableRecord(0, cloudCount, false);
1972         InsertCloudTableRecord(0, cloudCount);
1973         Query query = Query::Select().FromTable({ g_tableName2, g_sharedTableName1 });
1974         BlockSync(query, g_delegate, DBStatus::OK);
1975         forkInsertFunc_ = nullptr;
1976 
1977         /**
1978          * @tc.steps:step3. delete cloud data and sync
1979          * @tc.expected: step3. return OK
1980          */
1981         int beginGid = 0;
1982         int delCount = 5;
1983         DeleteCloudTableRecord(beginGid, delCount, false);
1984         DeleteCloudTableRecord(cloudCount, delCount);
1985         BlockSync(query, g_delegate, DBStatus::OK);
1986 
1987         /**
1988          * @tc.steps:step4. check count
1989          * @tc.expected: step4. return OK
1990          */
1991         std::string sql = QueryResourceCountSql(g_sharedTableName1);
1992         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1993             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1994         sql = QueryLogicDeleteCountSql(g_sharedTableName1);
1995         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1996             reinterpret_cast<void *>(cloudCount - delCount), nullptr), SQLITE_OK);
1997 
1998         /**
1999          * @tc.steps:step5. remove device data and check count
2000          * @tc.expected: step5. return OK
2001          */
2002         g_delegate->RemoveDeviceData("", CLEAR_SHARED_TABLE);
2003         sql = QueryResourceCountSql(g_sharedTableName1);
2004         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2005             reinterpret_cast<void *>(0L), nullptr), SQLITE_OK);
2006         sql = QueryAllCountSql(g_sharedTableName1);
2007         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2008             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
2009         sql = QueryByCursorSql(g_sharedTableName1, 15);
2010         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2011             reinterpret_cast<void *>(cloudCount - delCount), nullptr), SQLITE_OK);
2012 
2013         /**
2014          * @tc.steps:step6. drop logic delete data and check count.
2015          * @tc.expected: step6. return OK
2016          */
2017         EXPECT_EQ(DropLogicDeletedData(db_, g_sharedTableName1, 0u), OK);
2018         sql = QueryAllCountSql(g_sharedTableName1);
2019         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2020             reinterpret_cast<void *>(0L), nullptr), SQLITE_OK);
2021     }
2022 
2023     /**
2024      * @tc.name: SharedTableSync016
2025      * @tc.desc: Test remove device data of shared table and notify.
2026      * @tc.type: FUNC
2027      * @tc.require:
2028      * @tc.author: wangxiangdong
2029     */
2030     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync016, TestSize.Level1)
2031     {
2032         /**
2033          * @tc.steps: step1. Set data is logicDelete
2034          * @tc.expected: step1. return OK
2035          */
2036         bool logicDelete = true;
2037         auto data = static_cast<PragmaData>(&logicDelete);
2038         g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
2039 
2040         /**
2041          * @tc.steps:step2. init cloud share data and sync
2042          * @tc.expected: step2. return OK
2043          */
2044         InitCloudEnv();
2045         int cloudCount = 10;
2046         forkInsertFunc_ = InsertSharingUri;
2047         InsertCloudTableRecord(0, cloudCount, false);
2048         InsertCloudTableRecord(0, cloudCount);
2049         Query query = Query::Select().FromTable({ g_tableName2, g_sharedTableName1 });
2050         BlockSync(query, g_delegate, DBStatus::OK);
2051         forkInsertFunc_ = nullptr;
2052 
2053         /**
2054          * @tc.steps:step3. delete cloud data and sync
2055          * @tc.expected: step3. return OK
2056          */
2057         int beginGid = 0;
2058         int delCount = 5;
2059         DeleteCloudTableRecord(beginGid, delCount, false);
2060         DeleteCloudTableRecord(cloudCount, delCount);
2061         BlockSync(query, g_delegate, DBStatus::OK);
2062 
2063         /**
2064          * @tc.steps:step4. remove device data and check notify
2065          * @tc.expected: step4. return OK
2066          */
2067         g_delegate->RemoveDeviceData("", CLEAR_SHARED_TABLE);
2068         ChangedData changedData;
2069         changedData.type = ChangedDataType::DATA;
2070         changedData.tableName = g_sharedTableName1;
2071         std::vector<DistributedDB::Type> dataVec;
2072         DistributedDB::Type type = std::string(CloudDbConstant::FLAG_AND_DATA_MODE_NOTIFY);
2073         dataVec.push_back(type);
2074         changedData.primaryData[ChangeType::OP_DELETE].push_back(dataVec);
2075         g_observer->SetExpectedResult(changedData);
2076         EXPECT_EQ(g_observer->IsAllChangedDataEq(), true);
2077 
2078         /**
2079          * @tc.steps:step5. drop logic delete data and check count.
2080          * @tc.expected: step5. return OK
2081          */
2082         EXPECT_EQ(DropLogicDeletedData(db_, g_sharedTableName1, 0u), OK);
2083         std::string sql = QueryAllCountSql(g_sharedTableName1);
2084         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2085             reinterpret_cast<void *>(0L), nullptr), SQLITE_OK);
2086     }
2087 
2088     /**
2089      * @tc.name: SharedTableSync017
2090      * @tc.desc: Test Inconsistent Data Between Devices and Clouds after Remove Device Data.
2091      * @tc.type: FUNC
2092      * @tc.require:
2093      * @tc.author: luoguo
2094     */
2095     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync017, TestSize.Level1)
2096     {
2097         /**
2098          * @tc.steps: step1. Set data is logicDelete
2099          * @tc.expected: step1. return OK
2100          */
2101         bool logicDelete = true;
2102         auto data = static_cast<PragmaData>(&logicDelete);
2103         g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
2104 
2105         /**
2106          * @tc.steps:step2. init cloud share data and sync
2107          * @tc.expected: step2. return OK
2108          */
2109         InitCloudEnv();
2110         int cloudCount = 20;
2111         forkInsertFunc_ = InsertSharingUri;
2112         InsertCloudTableRecord(0, cloudCount, false);
2113         InsertCloudTableRecord(0, cloudCount);
2114         Query query = Query::Select().FromTable({ g_tableName2, g_sharedTableName1 });
2115         BlockSync(query, g_delegate, DBStatus::OK);
2116         forkInsertFunc_ = nullptr;
2117 
2118         /**
2119          * @tc.steps:step3. update local share data
2120          * @tc.expected: step3. return OK
2121          */
2122         InsertLocalSharedTableRecords(11, 10, g_sharedTableName1, true);
2123 
2124         /**
2125          * @tc.steps:step4. insert local share data
2126          * @tc.expected: step4. return OK
2127          */
2128         InsertLocalSharedTableRecords(21, 10, g_sharedTableName1);
2129 
2130         /**
2131          * @tc.steps:step5. remove device data and check notify
2132          * @tc.expected: step5. return OK
2133          */
2134         g_delegate->RemoveDeviceData("", CLEAR_SHARED_TABLE);
2135         std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_sharedTableName1) +
2136         " where flag & 0x08 == 0x08;";
2137         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2138             reinterpret_cast<void *>(20), nullptr), SQLITE_OK);
2139         sql = "select count(*) from " + DBCommon::GetLogTableName(g_sharedTableName1) +
2140         " where flag & 0x800 == 0x800;";
2141         EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2142         reinterpret_cast<void *>(20), nullptr), SQLITE_OK);
2143     }
2144 
2145     /**
2146      * @tc.name: SetCloudDbSchemaTest018
2147      * @tc.desc: Check SetCloudDBSchema while conn is nullptr.
2148      * @tc.type: FUNC
2149      * @tc.require:
2150      * @tc.author: caihaoting
2151     */
2152     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetCloudDbSchemaTest018, TestSize.Level0)
2153     {
2154         /**
2155          * @tc.steps:step1. use SetCloudDbSchema while conn is nullptr
2156          * @tc.expected: step1. return DB_ERROR
2157          */
2158         DataBaseSchema dataBaseSchema;
2159         TableSchema tableSchema = {
2160             .name = g_tableName1,
2161             .sharedTableName = g_sharedTableName1,
2162             .fields = g_cloudField1
2163         };
2164         dataBaseSchema.tables.push_back(tableSchema);
2165         auto relationalStoreImpl = static_cast<RelationalStoreDelegateImpl *>(g_delegate);
2166         EXPECT_EQ(relationalStoreImpl->Close(), OK);
2167         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::DB_ERROR);
2168     }
2169 
2170     /**
2171      * @tc.name: SharedTableSync019
2172      * @tc.desc: Test flag_only has notify.
2173      * @tc.type: FUNC
2174      * @tc.require:
2175      * @tc.author: wangxiangdong
2176     */
2177     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync019, TestSize.Level1)
2178     {
2179         /**
2180          * @tc.steps:step1. init cloud data and sync
2181          * @tc.expected: step1. return OK
2182          */
2183         InitCloudEnv();
2184         int cloudCount = 10;
2185         InsertCloudTableRecord(0, cloudCount);
2186         Query query = Query::Select().FromTable({ g_tableName2 });
2187         BlockSync(query, g_delegate, DBStatus::OK);
2188 
2189         /**
2190          * @tc.steps:step2. remove device data and check notify
2191          * @tc.expected: step2. return OK
2192          */
2193         g_delegate->RemoveDeviceData("", FLAG_ONLY);
2194         ChangedData changedData;
2195         changedData.type = ChangedDataType::DATA;
2196         changedData.tableName = g_tableName2;
2197         std::vector<DistributedDB::Type> dataVec;
2198         DistributedDB::Type type = std::string(CloudDbConstant::FLAG_ONLY_MODE_NOTIFY);
2199         dataVec.push_back(type);
2200         changedData.primaryData[ChangeType::OP_DELETE].push_back(dataVec);
2201         g_observer->SetExpectedResult(changedData);
2202         EXPECT_EQ(g_observer->IsAllChangedDataEq(), true);
2203     }
2204 
2205     /**
2206      * @tc.name: SetTrackerTable001
2207      * @tc.desc: Test set tracker table before cloud sync
2208      * @tc.type: FUNC
2209      * @tc.require:
2210      * @tc.author: liaoyonghuang
2211     */
2212     HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SetTrackerTable001, TestSize.Level1)
2213     {
2214         /**
2215          * @tc.steps:step1. init cloud data
2216          * @tc.expected: step1. return OK
2217          */
2218         InitCloudEnv();
2219         int cloudCount = 10;
2220         InsertCloudTableRecord(0, cloudCount, false);
2221         /**
2222          * @tc.steps:step2. set tracker table and sync cloud data
2223          * @tc.expected: step2. return OK
2224          */
2225         TrackerSchema schema = {g_tableName2, {"height", "name"}, {"name"}};
2226         g_delegate->SetTrackerTable(schema);
2227         Query query = Query::Select().FromTable({ g_tableName2 });
2228         BlockSync(query, g_delegate, DBStatus::OK);
2229         /**
2230          * @tc.steps:step3. Check extend_field
2231          * @tc.expected: step3. Return E_OK.
2232          */
2233         std::string checkValidJsonSql = "select count(*) from " + DBCommon::GetLogTableName(g_tableName2) +
2234             " where json_valid(extend_field) = 1";
2235         EXPECT_EQ(sqlite3_exec(db_, checkValidJsonSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2236             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
2237 
2238         std::string checkHeightSql = "select count(*) from " + DBCommon::GetLogTableName(g_tableName2) +
2239             " where json_extract(extend_field, '$.height') = 166.0";
2240         EXPECT_EQ(sqlite3_exec(db_, checkHeightSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2241             reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
2242 
2243         for (int i = 0; i < cloudCount; i++) {
2244             std::string expectName = "Local" + std::to_string(i);
2245             std::string checkNameSql = "select count(*) from " + DBCommon::GetLogTableName(g_tableName2) +
2246                 " where json_extract(extend_field, '$.name') = 'Cloud" + std::to_string(i) + "'";
2247             EXPECT_EQ(sqlite3_exec(db_, checkNameSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2248                 reinterpret_cast<void *>(1u), nullptr), SQLITE_OK);
2249         }
2250     }
2251 } // namespace