• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifdef RELATIONAL_STORE
16 #include <gtest/gtest.h>
17 #include <iostream>
18 #include "cloud/cloud_storage_utils.h"
19 #include "cloud/cloud_db_constant.h"
20 #include "distributeddb_data_generate_unit_test.h"
21 #include "distributeddb_tools_unit_test.h"
22 #include "process_system_api_adapter_impl.h"
23 #include "relational_store_client.h"
24 #include "relational_store_instance.h"
25 #include "relational_store_manager.h"
26 #include "runtime_config.h"
27 #include "sqlite_relational_store.h"
28 #include "sqlite_relational_utils.h"
29 #include "store_observer.h"
30 #include "time_helper.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 "mock_asset_loader.h"
36 #include "cloud_db_sync_utils_test.h"
37 
38 using namespace testing::ext;
39 using namespace DistributedDB;
40 using namespace DistributedDBUnitTest;
41 using namespace std;
42 
43 namespace {
44     string g_storeID = "Relational_Store_SYNC";
45     const string g_tableName1 = "worker1";
46     const string g_tableName2 = "worker2";
47     const string g_tableName3 = "worker3";
48     const string g_tableName4 = "worker4";
49     const string DEVICE_CLOUD = "cloud_dev";
50     const string DB_SUFFIX = ".db";
51     const int64_t g_syncWaitTime = 60;
52     const int g_arrayHalfSub = 2;
53     int g_syncIndex = 0;
54     string g_testDir;
55     string g_storePath;
56     std::mutex g_processMutex;
57     std::condition_variable g_processCondition;
58     std::shared_ptr<VirtualCloudDb> g_virtualCloudDb;
59     std::shared_ptr<VirtualAssetLoader> g_virtualAssetLoader;
60     DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
61     RelationalStoreObserverUnitTest *g_observer = nullptr;
62     RelationalStoreDelegate *g_delegate = nullptr;
63     VirtualCommunicatorAggregator *communicatorAggregator_ = nullptr;
64     SyncProcess g_syncProcess;
65     using CloudSyncStatusCallback = std::function<void(const std::map<std::string, SyncProcess> &onProcess)>;
66     const std::string CREATE_LOCAL_TABLE_SQL =
67             "CREATE TABLE IF NOT EXISTS " + g_tableName1 + "(" \
68     "name TEXT PRIMARY KEY," \
69     "height REAL ," \
70     "married BOOLEAN ," \
71     "photo BLOB NOT NULL," \
72     "assert BLOB," \
73     "age INT);";
74     const std::string INTEGER_PRIMARY_KEY_TABLE_SQL =
75             "CREATE TABLE IF NOT EXISTS " + g_tableName2 + "(" \
76     "id INTEGER PRIMARY KEY," \
77     "name TEXT ," \
78     "height REAL ," \
79     "photo BLOB ," \
80     "asserts BLOB," \
81     "age INT);";
82     const std::string DROP_INTEGER_PRIMARY_KEY_TABLE_SQL = "DROP TABLE " + g_tableName2 + ";";
83     const std::string CREATE_LOCAL_TABLE_WITHOUT_PRIMARY_KEY_SQL =
84             "CREATE TABLE IF NOT EXISTS " + g_tableName3 + "(" \
85     "name TEXT," \
86     "height REAL ," \
87     "married BOOLEAN ," \
88     "photo BLOB NOT NULL," \
89     "assert BLOB," \
90     "age INT);";
91     const std::string INTEGER_PRIMARY_KEY_TABLE_SQL_WRONG_SYNC_MODE =
92             "CREATE TABLE IF NOT EXISTS " + g_tableName4 + "(" \
93     "id INTEGER PRIMARY KEY," \
94     "name TEXT ," \
95     "height REAL ," \
96     "photo BLOB ," \
97     "asserts BLOB," \
98     "age INT);";
99     const std::vector<Field> g_cloudFiled1 = {
100         {"name", TYPE_INDEX<std::string>, true}, {"height", TYPE_INDEX<double>},
101         {"married", TYPE_INDEX<bool>}, {"photo", TYPE_INDEX<Bytes>, false, false},
102         {"assert", TYPE_INDEX<Asset>}, {"age", TYPE_INDEX<int64_t>}
103     };
104     const std::vector<Field> g_invalidCloudFiled1 = {
105         {"name", TYPE_INDEX<std::string>, true}, {"height", TYPE_INDEX<int>},
106         {"married", TYPE_INDEX<bool>}, {"photo", TYPE_INDEX<Bytes>, false, false},
107         {"assert", TYPE_INDEX<Bytes>}, {"age", TYPE_INDEX<int64_t>}
108     };
109     const std::vector<Field> g_cloudFiled2 = {
110         {"id", TYPE_INDEX<int64_t>, true}, {"name", TYPE_INDEX<std::string>},
111         {"height", TYPE_INDEX<double>},  {"photo", TYPE_INDEX<Bytes>},
112         {"asserts", TYPE_INDEX<Assets>}, {"age", TYPE_INDEX<int64_t>}
113     };
114     const std::vector<Field> g_cloudFiledWithOutPrimaryKey3 = {
115         {"name", TYPE_INDEX<std::string>, false, true}, {"height", TYPE_INDEX<double>},
116         {"married", TYPE_INDEX<bool>}, {"photo", TYPE_INDEX<Bytes>, false, false},
117         {"assert", TYPE_INDEX<Bytes>}, {"age", TYPE_INDEX<int64_t>}
118     };
119     const std::vector<std::string> g_tables = {g_tableName1, g_tableName2};
120     const std::vector<std::string> g_shareTables = {g_tableName1 + CloudDbConstant::SHARED,
121         g_tableName2 + CloudDbConstant::SHARED};
122     const std::vector<std::string> g_tablesPKey = {g_cloudFiled1[0].colName, g_cloudFiled2[0].colName};
123     const std::vector<string> g_prefix = {"Local", ""};
124     const Asset g_localAsset = {
125         .version = 1, .name = "Phone", .assetId = "0", .subpath = "/local/sync", .uri = "/local/sync",
126         .modifyTime = "123456", .createTime = "", .size = "256", .hash = "ASE"
127     };
128     const Asset g_cloudAsset = {
129         .version = 2, .name = "Phone", .assetId = "0", .subpath = "/local/sync", .uri = "/cloud/sync",
130         .modifyTime = "123456", .createTime = "0", .size = "1024", .hash = "DEC"
131     };
132 
CreateUserDBAndTable(sqlite3 * & db)133     void CreateUserDBAndTable(sqlite3 *&db)
134     {
135         EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
136         EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_LOCAL_TABLE_SQL), SQLITE_OK);
137         EXPECT_EQ(RelationalTestUtils::ExecSql(db, INTEGER_PRIMARY_KEY_TABLE_SQL), SQLITE_OK);
138         EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_LOCAL_TABLE_WITHOUT_PRIMARY_KEY_SQL), SQLITE_OK);
139     }
140 
InsertUserTableRecord(sqlite3 * & db,int64_t begin,int64_t count,int64_t photoSize,bool assetIsNull)141     void InsertUserTableRecord(sqlite3 *&db, int64_t begin, int64_t count, int64_t photoSize, bool assetIsNull)
142     {
143         std::string photo(photoSize, 'v');
144         int errCode;
145         std::vector<uint8_t> assetBlob;
146         for (int64_t i = begin; i < begin + count; ++i) {
147             Asset asset = g_localAsset;
148             asset.name = asset.name + std::to_string(i);
149             RuntimeContext::GetInstance()->AssetToBlob(asset, assetBlob);
150             string sql = "INSERT OR REPLACE INTO " + g_tableName1
151                          + " (name, height, married, photo, assert, age) VALUES ('Local" + std::to_string(i) +
152                          "', '175.8', '0', '" + photo + "', ? , '18');";
153             sqlite3_stmt *stmt = nullptr;
154             ASSERT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
155             if (assetIsNull) {
156                 ASSERT_EQ(sqlite3_bind_null(stmt, 1), SQLITE_OK);
157             } else {
158                 ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 1, assetBlob, false), E_OK);
159             }
160             EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
161             SQLiteUtils::ResetStatement(stmt, true, errCode);
162         }
163         for (int64_t i = begin; i < begin + count; ++i) {
164             std::vector<Asset> assets;
165             Asset asset = g_localAsset;
166             asset.name = g_localAsset.name + std::to_string(i);
167             assets.push_back(asset);
168             asset.name = g_localAsset.name + std::to_string(i + 1);
169             assets.push_back(asset);
170             RuntimeContext::GetInstance()->AssetsToBlob(assets, assetBlob);
171             string sql = "INSERT OR REPLACE INTO " + g_tableName2
172                          + " (id, name, height, photo, asserts, age) VALUES ('" + std::to_string(i) + "', 'Local"
173                          + std::to_string(i) + "', '155.10', '"+ photo + "',  ? , '21');";
174             sqlite3_stmt *stmt = nullptr;
175             ASSERT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
176             if (assetIsNull) {
177                 ASSERT_EQ(sqlite3_bind_null(stmt, 1), E_OK);
178             } else {
179                 ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 1, assetBlob, false), E_OK);
180             }
181             EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
182             SQLiteUtils::ResetStatement(stmt, true, errCode);
183         }
184         LOGD("insert user record worker1[primary key]:[Local%" PRId64 " - Local%" PRId64
185             ") , worker2[primary key]:[%" PRId64 "- %" PRId64")", begin, count, begin, count);
186     }
187 
InsertCloudTableRecord(int64_t begin,int64_t count,int64_t photoSize,bool assetIsNull)188     void InsertCloudTableRecord(int64_t begin, int64_t count, int64_t photoSize, bool assetIsNull)
189     {
190         std::vector<uint8_t> photo(photoSize, 'v');
191         std::vector<VBucket> record1;
192         std::vector<VBucket> extend1;
193         std::vector<VBucket> record2;
194         std::vector<VBucket> extend2;
195         Timestamp now = TimeHelper::GetSysCurrentTime();
196         for (int64_t i = begin; i < begin + count; ++i) {
197             VBucket data;
198             data.insert_or_assign("name", "Cloud" + std::to_string(i));
199             data.insert_or_assign("height", 166.0); // 166.0 is random double value
200             data.insert_or_assign("married", false);
201             data.insert_or_assign("photo", photo);
202             data.insert_or_assign("age", 13L);
203             Asset asset = g_cloudAsset;
204             asset.name = asset.name + std::to_string(i);
205             assetIsNull ? data.insert_or_assign("assert", Nil()) : data.insert_or_assign("assert", asset);
206             record1.push_back(data);
207             VBucket log;
208             log.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND + i);
209             log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND + i);
210             log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false);
211             extend1.push_back(log);
212 
213             std::vector<Asset> assets;
214             data.insert_or_assign("id", i);
215             data.insert_or_assign("height", 180.3); // 180.3 is random double value
216             for (int64_t j = i; j <= i + 2; j++) { // 2 extra num
217                 asset.name = g_cloudAsset.name + std::to_string(j);
218                 assets.push_back(asset);
219             }
220             data.erase("assert");
221             data.erase("married");
222             assetIsNull ? data.insert_or_assign("asserts", Nil()) : data.insert_or_assign("asserts", assets);
223             record2.push_back(data);
224             extend2.push_back(log);
225         }
226         ASSERT_EQ(g_virtualCloudDb->BatchInsert(g_tableName1, std::move(record1), extend1), DBStatus::OK);
227         ASSERT_EQ(g_virtualCloudDb->BatchInsert(g_tableName2, std::move(record2), extend2), DBStatus::OK);
228         LOGD("insert cloud record worker1[primary key]:[cloud%" PRId64 " - cloud%" PRId64
229             ") , worker2[primary key]:[%" PRId64 "- %" PRId64")", begin, count, begin, count);
230         std::this_thread::sleep_for(std::chrono::milliseconds(count));
231     }
232 
DeleteUserTableRecord(sqlite3 * & db,int64_t begin,int64_t count)233     void DeleteUserTableRecord(sqlite3 *&db, int64_t begin, int64_t count)
234     {
235         for (size_t i = 0; i < g_tables.size(); i++) {
236             string updateAge = "Delete from " + g_tables[i] + " where " + g_tablesPKey[i] + " in (";
237             for (int64_t j = begin; j < count; ++j) {
238                 updateAge += "'" + g_prefix[i] + std::to_string(j) + "',";
239             }
240             updateAge.pop_back();
241             updateAge += ");";
242             ASSERT_EQ(RelationalTestUtils::ExecSql(db, updateAge), SQLITE_OK);
243         }
244         LOGD("delete local record worker1[primary key]:[local%" PRId64 " - local%" PRId64
245             ") , worker2[primary key]:[%" PRId64 "- %" PRId64")", begin, count, begin, count);
246     }
247 
UpdateUserTableRecord(sqlite3 * & db,int64_t begin,int64_t count)248     void UpdateUserTableRecord(sqlite3 *&db, int64_t begin, int64_t count)
249     {
250         for (size_t i = 0; i < g_tables.size(); i++) {
251             string updateAge = "UPDATE " + g_tables[i] + " SET height = 111.11 where " + g_tablesPKey[i] + " in (";
252             for (int64_t j = begin; j < count; ++j) {
253                 updateAge += "'" + g_prefix[i] + std::to_string(j) + "',";
254             }
255             updateAge.pop_back();
256             updateAge += ");";
257             ASSERT_EQ(RelationalTestUtils::ExecSql(db, updateAge), SQLITE_OK);
258         }
259         LOGD("update local record worker1[primary key]:[local%" PRId64 " - local%" PRId64
260             ") , worker2[primary key]:[%" PRId64 "- %" PRId64")", begin, count, begin, count);
261     }
262 
DeleteCloudTableRecordByGid(int64_t begin,int64_t count)263     void DeleteCloudTableRecordByGid(int64_t begin, int64_t count)
264     {
265         for (int64_t i = begin; i < begin + count; ++i) {
266             VBucket data;
267             data.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(i));
268             ASSERT_EQ(g_virtualCloudDb->DeleteByGid(g_tableName1, data), DBStatus::OK);
269         }
270         LOGD("delete cloud record worker[primary key]:[cloud%" PRId64 " - cloud%" PRId64")", begin, count);
271         std::this_thread::sleep_for(std::chrono::milliseconds(count));
272     }
273 
GetCloudDbSchema(DataBaseSchema & dataBaseSchema)274     void GetCloudDbSchema(DataBaseSchema &dataBaseSchema)
275     {
276         TableSchema tableSchema1 = {
277             .name = g_tableName1,
278             .sharedTableName = g_tableName1 + "_shared",
279             .fields = g_cloudFiled1
280         };
281         TableSchema tableSchema2 = {
282             .name = g_tableName2,
283             .sharedTableName = g_tableName2 + "_shared",
284             .fields = g_cloudFiled2
285         };
286         TableSchema tableSchemaWithOutPrimaryKey = {
287             .name = g_tableName3,
288             .sharedTableName = g_tableName3 + "_shared",
289             .fields = g_cloudFiledWithOutPrimaryKey3
290         };
291         TableSchema tableSchema4 = {
292             .name = g_tableName4,
293             .sharedTableName = g_tableName4 + "_shared",
294             .fields = g_cloudFiled2
295         };
296         dataBaseSchema.tables.push_back(tableSchema1);
297         dataBaseSchema.tables.push_back(tableSchema2);
298         dataBaseSchema.tables.push_back(tableSchemaWithOutPrimaryKey);
299         dataBaseSchema.tables.push_back(tableSchema4);
300     }
301 
QueryCountCallback(void * data,int count,char ** colValue,char ** colName)302     int QueryCountCallback(void *data, int count, char **colValue, char **colName)
303     {
304         if (count != 1) {
305             return 0;
306         }
307         auto expectCount = reinterpret_cast<int64_t>(data);
308         EXPECT_EQ(strtol(colValue[0], nullptr, 10), expectCount); // 10: decimal
309         return 0;
310     }
311 
CheckCloudTotalCount(const std::vector<std::string> & tableNames,std::vector<int64_t> expectCounts)312     void CheckCloudTotalCount(const std::vector<std::string> &tableNames, std::vector<int64_t> expectCounts)
313     {
314         VBucket extend;
315         for (size_t i = 0; i < tableNames.size(); ++i) {
316             extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(0);
317             int64_t realCount = 0;
318             std::vector<VBucket> data;
319             g_virtualCloudDb->Query(tableNames[i], extend, data);
320             for (size_t j = 0; j < data.size(); ++j) {
321                 auto entry = data[j].find(CloudDbConstant::DELETE_FIELD);
322                 if (entry != data[j].end() && std::get<bool>(entry->second)) {
323                     continue;
324                 }
325                 realCount++;
326             }
327             EXPECT_EQ(realCount, expectCounts[i]); // ExpectCount represents the total amount of cloud data.
328         }
329     }
330 
CheckCloudRecordNum(sqlite3 * & db,std::vector<std::string> tableList,std::vector<int> countList)331     void CheckCloudRecordNum(sqlite3 *&db, std::vector<std::string> tableList, std::vector<int> countList)
332     {
333         int i = 0;
334         for (const auto &tableName: tableList) {
335             std::string sql = "select count(*) from " + DBCommon::GetLogTableName(tableName) +
336                 " where device = 'cloud'" + " and cloud_gid is not null and cloud_gid != '' and " +
337                     "(flag & 0x2 = 0 or flag & 0x20 = 0);";
338             EXPECT_EQ(sqlite3_exec(db, sql.c_str(), QueryCountCallback,
339                 reinterpret_cast<void *>(countList[i]), nullptr), SQLITE_OK);
340             i++;
341         }
342     }
343 
CheckCompensatedNum(sqlite3 * & db,std::vector<std::string> tableList,std::vector<int> countList)344     void CheckCompensatedNum(sqlite3 *&db, std::vector<std::string> tableList, std::vector<int> countList)
345     {
346         int i = 0;
347         for (const auto &tableName: tableList) {
348             std::string sql = "select count(*) from " + DBCommon::GetLogTableName(tableName) +
349                 " where flag & 0x10 != 0;";
350             EXPECT_EQ(sqlite3_exec(db, sql.c_str(), QueryCountCallback,
351                 reinterpret_cast<void *>(countList[i]), nullptr), SQLITE_OK);
352             i++;
353         }
354     }
355 
CheckLocalLogCount(sqlite3 * & db,const std::vector<std::string> & tableList,const std::vector<int> & countList)356     void CheckLocalLogCount(sqlite3 *&db, const std::vector<std::string> &tableList, const std::vector<int> &countList)
357     {
358         int i = 0;
359         for (const auto &tableName: tableList) {
360             std::string sql = "select count(*) from " + DBCommon::GetLogTableName(tableName);
361             EXPECT_EQ(sqlite3_exec(db, sql.c_str(), QueryCountCallback,
362                 reinterpret_cast<void *>(countList[i]), nullptr), SQLITE_OK);
363             i++;
364         }
365     }
366 
CheckLogoutLogCount(sqlite3 * & db,const std::vector<std::string> & tableList,const std::vector<int> & countList)367     void CheckLogoutLogCount(sqlite3 *&db, const std::vector<std::string> &tableList, const std::vector<int> &countList)
368     {
369         int i = 0;
370         for (const auto &tableName: tableList) {
371             std::string sql = "select count(*) from " + DBCommon::GetLogTableName(tableName) +
372                 " where flag & 0x800 = 0x800";
373             EXPECT_EQ(sqlite3_exec(db, sql.c_str(), QueryCountCallback,
374                 reinterpret_cast<void *>(countList[i]), nullptr), SQLITE_OK);
375             i++;
376         }
377     }
378 
CheckCleanLogNum(sqlite3 * & db,const std::vector<std::string> tableList,int count)379     void CheckCleanLogNum(sqlite3 *&db, const std::vector<std::string> tableList, int count)
380     {
381         for (const auto &tableName: tableList) {
382             std::string sql1 = "select count(*) from " + DBCommon::GetLogTableName(tableName) +
383                 " where device = 'cloud';";
384             EXPECT_EQ(sqlite3_exec(db, sql1.c_str(), QueryCountCallback,
385                 reinterpret_cast<void *>(count), nullptr), SQLITE_OK);
386             std::string sql2 = "select count(*) from " + DBCommon::GetLogTableName(tableName) +
387                 " where cloud_gid " + " is not null and cloud_gid != '';";
388             EXPECT_EQ(sqlite3_exec(db, sql2.c_str(), QueryCountCallback,
389                 reinterpret_cast<void *>(count), nullptr), SQLITE_OK);
390             std::string sql3 = "select count(*) from " + DBCommon::GetLogTableName(tableName) +
391                 " where (flag & 0x2 = 0 or flag & 0x20 = 0);";
392             EXPECT_EQ(sqlite3_exec(db, sql3.c_str(), QueryCountCallback,
393                 reinterpret_cast<void *>(count), nullptr), SQLITE_OK);
394         }
395     }
396 
CheckCleanDataNum(sqlite3 * & db,const std::vector<std::string> & tableList,const std::vector<int> & countList)397     void CheckCleanDataNum(sqlite3 *&db, const std::vector<std::string> &tableList, const std::vector<int> &countList)
398     {
399         int i = 0;
400         for (const auto &tableName: tableList) {
401             std::string local_sql = "select count(*) from " + tableName + ";";
402             EXPECT_EQ(sqlite3_exec(db, local_sql.c_str(), QueryCountCallback,
403                 reinterpret_cast<void *>(countList[i]), nullptr), SQLITE_OK);
404             i++;
405         }
406     }
407 
CheckCleanDataAndLogNum(sqlite3 * & db,const std::vector<std::string> tableList,int count,std::vector<int> localNum)408     void CheckCleanDataAndLogNum(sqlite3 *&db, const std::vector<std::string> tableList, int count,
409         std::vector<int> localNum)
410     {
411         int i = 0;
412         for (const auto &tableName: tableList) {
413             std::string sql1 = "select count(*) from " + DBCommon::GetLogTableName(tableName) +
414                 " where device = 'cloud';";
415             EXPECT_EQ(sqlite3_exec(db, sql1.c_str(), QueryCountCallback,
416                 reinterpret_cast<void *>(count), nullptr), SQLITE_OK);
417             std::string sql2 = "select count(*) from " + DBCommon::GetLogTableName(tableName) + " where cloud_gid "
418                 " is not null and cloud_gid != '';";
419             EXPECT_EQ(sqlite3_exec(db, sql2.c_str(), QueryCountCallback,
420                 reinterpret_cast<void *>(count), nullptr), SQLITE_OK);
421             std::string sql3 = "select count(*) from " + DBCommon::GetLogTableName(tableName) +
422                 " where (flag & 0x2 = 0 or flag & 0x20 = 0);";
423             EXPECT_EQ(sqlite3_exec(db, sql3.c_str(), QueryCountCallback,
424                 reinterpret_cast<void *>(count), nullptr), SQLITE_OK);
425             std::string local_sql = "select count(*) from " + tableName +";";
426             EXPECT_EQ(sqlite3_exec(db, local_sql.c_str(), QueryCountCallback,
427                 reinterpret_cast<void *>(localNum[i]), nullptr), SQLITE_OK);
428             i++;
429         }
430     }
431 
InitProcessForCleanCloudData1(const uint32_t & cloudCount,std::vector<SyncProcess> & expectProcess)432     void InitProcessForCleanCloudData1(const uint32_t &cloudCount, std::vector<SyncProcess> &expectProcess)
433     {
434         // cloudCount also means data count in one batch
435         expectProcess.clear();
436         std::vector<TableProcessInfo> infos;
437         uint32_t index = 1;
438         infos.push_back(TableProcessInfo{
439             FINISHED, {index, cloudCount, cloudCount, 0}, {0, 0, 0, 0}
440         });
441         infos.push_back(TableProcessInfo{
442             PREPARED, {0, 0, 0, 0}, {0, 0, 0, 0}
443         });
444 
445         infos.push_back(TableProcessInfo{
446             FINISHED, {index, cloudCount, cloudCount, 0}, {0, 0, 0, 0}
447         });
448         infos.push_back(TableProcessInfo{
449             FINISHED, {index, cloudCount, cloudCount, 0}, {0, 0, 0, 0}
450         });
451 
452         for (size_t i = 0; i < infos.size() / g_arrayHalfSub; ++i) {
453             SyncProcess syncProcess;
454             syncProcess.errCode = OK;
455             syncProcess.process = i == infos.size() ? FINISHED : PROCESSING;
456             syncProcess.tableProcess.insert_or_assign(g_tables[0], std::move(infos[g_arrayHalfSub * i]));
457             syncProcess.tableProcess.insert_or_assign(g_tables[1], std::move(infos[g_arrayHalfSub * i + 1]));
458             expectProcess.push_back(syncProcess);
459         }
460     }
461 
GetCallback(SyncProcess & syncProcess,CloudSyncStatusCallback & callback,std::vector<SyncProcess> & expectProcess)462     void GetCallback(SyncProcess &syncProcess, CloudSyncStatusCallback &callback,
463         std::vector<SyncProcess> &expectProcess)
464     {
465         g_syncIndex = 0;
466         callback = [&syncProcess, &expectProcess](const std::map<std::string, SyncProcess> &process) {
467             LOGI("devices size = %d", process.size());
468             ASSERT_EQ(process.size(), 1u);
469             syncProcess = std::move(process.begin()->second);
470             ASSERT_EQ(process.begin()->first, DEVICE_CLOUD);
471             ASSERT_NE(syncProcess.tableProcess.empty(), true);
472             LOGI("current sync process status:%d, db status:%d ", syncProcess.process, syncProcess.errCode);
473             std::for_each(g_tables.begin(), g_tables.end(), [&](const auto &item) {
474                 auto table1 = syncProcess.tableProcess.find(item);
475                 if (table1 != syncProcess.tableProcess.end()) {
476                     LOGI("table[%s], table process status:%d, [downloadInfo](batchIndex:%u, total:%u, successCount:%u, "
477                          "failCount:%u) [uploadInfo](batchIndex:%u, total:%u, successCount:%u,failCount:%u",
478                          item.c_str(), table1->second.process, table1->second.downLoadInfo.batchIndex,
479                          table1->second.downLoadInfo.total, table1->second.downLoadInfo.successCount,
480                          table1->second.downLoadInfo.failCount, table1->second.upLoadInfo.batchIndex,
481                          table1->second.upLoadInfo.total, table1->second.upLoadInfo.successCount,
482                          table1->second.upLoadInfo.failCount);
483                 }
484             });
485             if (expectProcess.empty()) {
486                 if (syncProcess.process == FINISHED) {
487                     g_processCondition.notify_one();
488                 }
489                 return;
490             }
491             ASSERT_LE(static_cast<size_t>(g_syncIndex), expectProcess.size());
492             for (size_t i = 0; i < g_tables.size() && static_cast<size_t>(g_syncIndex) < expectProcess.size(); ++i) {
493                 SyncProcess head = expectProcess[g_syncIndex];
494                 for (auto &expect : head.tableProcess) {
495                     auto real = syncProcess.tableProcess.find(expect.first);
496                     ASSERT_NE(real, syncProcess.tableProcess.end());
497                     EXPECT_EQ(expect.second.process, real->second.process);
498                     EXPECT_EQ(expect.second.downLoadInfo.batchIndex, real->second.downLoadInfo.batchIndex);
499                     EXPECT_EQ(expect.second.downLoadInfo.total, real->second.downLoadInfo.total);
500                     EXPECT_EQ(expect.second.downLoadInfo.successCount, real->second.downLoadInfo.successCount);
501                     EXPECT_EQ(expect.second.downLoadInfo.failCount, real->second.downLoadInfo.failCount);
502                     EXPECT_EQ(expect.second.upLoadInfo.batchIndex, real->second.upLoadInfo.batchIndex);
503                     EXPECT_EQ(expect.second.upLoadInfo.total, real->second.upLoadInfo.total);
504                     EXPECT_EQ(expect.second.upLoadInfo.successCount, real->second.upLoadInfo.successCount);
505                     EXPECT_EQ(expect.second.upLoadInfo.failCount, real->second.upLoadInfo.failCount);
506                 }
507             }
508             g_syncIndex++;
509             if (syncProcess.process == FINISHED) {
510                 g_processCondition.notify_one();
511             }
512         };
513     }
514 
CopySharedDataFromOriginalTable(sqlite3 * & db,const std::vector<std::string> & tableNames)515     void CopySharedDataFromOriginalTable(sqlite3 *&db, const std::vector<std::string> &tableNames)
516     {
517         for (const auto &tableName: tableNames) {
518             std::string sql = "INSERT OR REPLACE INTO " + tableName + CloudDbConstant::SHARED + " SELECT " +
519                 "*," + std::string(DBConstant::SQLITE_INNER_ROWID) + ",''" + " FROM " + tableName;
520             EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK);
521         }
522     }
523 
CheckCloudSharedRecordNum(sqlite3 * & db,std::vector<std::string> tableList,std::vector<int> countList)524     void CheckCloudSharedRecordNum(sqlite3 *&db, std::vector<std::string> tableList, std::vector<int> countList)
525     {
526         int i = 0;
527         for (const auto &tableName: tableList) {
528             std::string sql = "select count(*) from " + DBCommon::GetLogTableName(tableName);
529             EXPECT_EQ(sqlite3_exec(db, sql.c_str(), QueryCountCallback,
530                 reinterpret_cast<void *>(countList[i]), nullptr), SQLITE_OK);
531             sql = "select count(*) from " + tableName;
532             EXPECT_EQ(sqlite3_exec(db, sql.c_str(), QueryCountCallback,
533                 reinterpret_cast<void *>(countList[i]), nullptr), SQLITE_OK);
534             i++;
535         }
536     }
537 
WaitForSyncFinish(SyncProcess & syncProcess,const int64_t & waitTime)538     void WaitForSyncFinish(SyncProcess &syncProcess, const int64_t &waitTime)
539     {
540         std::unique_lock<std::mutex> lock(g_processMutex);
541         bool result = g_processCondition.wait_for(lock, std::chrono::seconds(waitTime), [&syncProcess]() {
542             return syncProcess.process == FINISHED;
543         });
544         ASSERT_EQ(result, true);
545         LOGD("-------------------sync end--------------");
546     }
547 
CloseDb()548     void CloseDb()
549     {
550         if (g_delegate != nullptr) {
551             g_delegate->UnRegisterObserver(g_observer);
552         }
553         if (g_delegate != nullptr) {
554             EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
555             g_delegate = nullptr;
556         }
557         delete g_observer;
558         g_observer = nullptr;
559         g_virtualCloudDb = nullptr;
560     }
561 
562     class DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest : public testing::Test {
563     public:
564         static void SetUpTestCase(void);
565         static void TearDownTestCase(void);
566         void SetUp();
567         void TearDown();
568     protected:
569         sqlite3 *db = nullptr;
570     };
571 
SetUpTestCase(void)572     void DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest::SetUpTestCase(void)
573     {
574         DistributedDBToolsUnitTest::TestDirInit(g_testDir);
575         g_storePath = g_testDir + "/" + g_storeID + DB_SUFFIX;
576         LOGI("The test db is:%s", g_testDir.c_str());
577         RuntimeConfig::SetCloudTranslate(std::make_shared<VirtualCloudDataTranslate>());
578     }
579 
TearDownTestCase(void)580     void DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest::TearDownTestCase(void)
581     {}
582 
SetUp(void)583     void DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest::SetUp(void)
584     {
585         if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
586             LOGE("rm test db files error.");
587         }
588         DistributedDBToolsUnitTest::PrintTestCaseInfo();
589         LOGD("Test dir is %s", g_testDir.c_str());
590         db = RelationalTestUtils::CreateDataBase(g_storePath);
591         ASSERT_NE(db, nullptr);
592         CreateUserDBAndTable(db);
593         g_observer = new (std::nothrow) RelationalStoreObserverUnitTest();
594         ASSERT_NE(g_observer, nullptr);
595         ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option { .observer = g_observer },
596             g_delegate), DBStatus::OK);
597         ASSERT_NE(g_delegate, nullptr);
598         ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName1, CLOUD_COOPERATION), DBStatus::OK);
599         ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName2, CLOUD_COOPERATION), DBStatus::OK);
600         ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName3, CLOUD_COOPERATION), DBStatus::OK);
601         g_virtualCloudDb = make_shared<VirtualCloudDb>();
602         g_virtualAssetLoader = make_shared<VirtualAssetLoader>();
603         g_syncProcess = {};
604         ASSERT_EQ(g_delegate->SetCloudDB(g_virtualCloudDb), DBStatus::OK);
605         ASSERT_EQ(g_delegate->SetIAssetLoader(g_virtualAssetLoader), DBStatus::OK);
606         // sync before setting cloud db schema,it should return SCHEMA_MISMATCH
607         Query query = Query::Select().FromTable(g_tables);
608         CloudSyncStatusCallback callback;
609         ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime),
610             DBStatus::SCHEMA_MISMATCH);
611         DataBaseSchema dataBaseSchema;
612         GetCloudDbSchema(dataBaseSchema);
613         ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
614         communicatorAggregator_ = new (std::nothrow) VirtualCommunicatorAggregator();
615         ASSERT_TRUE(communicatorAggregator_ != nullptr);
616         RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicatorAggregator_);
617     }
618 
TearDown(void)619     void DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest::TearDown(void)
620     {
621         EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
622         if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
623             LOGE("rm test db files error.");
624         }
625         RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
626         communicatorAggregator_ = nullptr;
627         RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr);
628     }
629 
630 /*
631  * @tc.name: CleanCloudDataTest001
632  * @tc.desc: Test FLAG_ONLY mode of RemoveDeviceData, and invalid mode else.
633  * @tc.type: FUNC
634  * @tc.require:
635  * @tc.author: huangboxin
636  */
637 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest001, TestSize.Level1)
638 {
639     int64_t paddingSize = 10;
640     int localCount = 10;
641     int cloudCount = 20;
642     InsertCloudTableRecord(0, cloudCount, paddingSize, false);
643     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
644     Query query = Query::Select().FromTable(g_tables);
645     std::vector<SyncProcess> expectProcess;
646     InitProcessForCleanCloudData1(cloudCount, expectProcess);
647     CloudSyncStatusCallback callback;
648     GetCallback(g_syncProcess, callback, expectProcess);
649     ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_FORCE_PULL, query, callback, g_syncWaitTime),
650         DBStatus::OK);
651     WaitForSyncFinish(g_syncProcess, g_syncWaitTime);
652     std::string device = "";
653     CheckCloudRecordNum(db, g_tables, {20, 20});
654     ASSERT_EQ(g_delegate->RemoveDeviceData(device, FLAG_ONLY), DBStatus::OK);
655     CheckCleanLogNum(db, g_tables, 0);
656 
657     ASSERT_EQ(g_delegate->RemoveDeviceData(device, ClearMode(BUTT + 1)), DBStatus::INVALID_ARGS);
658     ASSERT_EQ(g_delegate->RemoveDeviceData(device, ClearMode(-1)), DBStatus::INVALID_ARGS);
659 
660     CloseDb();
661 }
662 
663 /*
664  * @tc.name: CleanCloudDataTest002
665  * @tc.desc: Test FLAG_AND_DATA mode of RemoveDeviceData
666  * @tc.type: FUNC
667  * @tc.require:
668  * @tc.author: huangboxin
669  */
670 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest002, TestSize.Level1)
671 {
672     int64_t paddingSize = 10;
673     int localCount = 10;
674     int cloudCount = 20;
675     InsertCloudTableRecord(0, cloudCount, paddingSize, false);
676     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
677     Query query = Query::Select().FromTable(g_tables);
678     std::vector<SyncProcess> expectProcess;
679     InitProcessForCleanCloudData1(cloudCount, expectProcess);
680     CloudSyncStatusCallback callback;
681     GetCallback(g_syncProcess, callback, expectProcess);
682     ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_FORCE_PULL, query, callback, g_syncWaitTime),
683         DBStatus::OK);
684     WaitForSyncFinish(g_syncProcess, g_syncWaitTime);
685     std::string device = "";
686     CheckCloudRecordNum(db, g_tables, {20, 20});    // 20 means cloud data num
687     ASSERT_EQ(g_delegate->RemoveDeviceData(device, FLAG_AND_DATA), DBStatus::OK);
688     CheckCleanDataAndLogNum(db, g_tables, 0, {localCount, 0});
689     CloseDb();
690 }
691 
692 /*
693  * @tc.name: CleanCloudDataTest003
694  * @tc.desc: Test FLAG_ONLY mode of RemoveDeviceData concurrently with Sync
695  * @tc.type: FUNC
696  * @tc.require:
697  * @tc.author: huangboxin
698  */
699 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest003, TestSize.Level1)
700 {
701     /**
702      * @tc.steps: step1. make data: 10 records on local and 20 records on cloud
703      */
704     int64_t paddingSize = 10;
705     int localCount = 10;
706     int cloudCount = 20;
707     InsertCloudTableRecord(0, cloudCount, paddingSize, false);
708     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
709     /**
710      * @tc.steps: step2. call Sync with cloud force pull strategy, and after that, local will has 20 records.
711      */
712     Query query = Query::Select().FromTable(g_tables);
713     std::vector<SyncProcess> expectProcess;
714     InitProcessForCleanCloudData1(cloudCount, expectProcess);
715     CloudSyncStatusCallback callback;
716     GetCallback(g_syncProcess, callback, expectProcess);
717     ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_FORCE_PULL, query, callback, g_syncWaitTime),
718         DBStatus::OK);
719     WaitForSyncFinish(g_syncProcess, g_syncWaitTime);
720     CheckCloudRecordNum(db, g_tables, {20, 20});    // 20 means cloud data num
721 
722     /**
723      * @tc.steps: step3. insert 10 records into local, so local will has 20 local records and 20 cloud records.
724      */
725     InsertUserTableRecord(db, 21, localCount, paddingSize, false);  // 21 means insert start index
726     /**
727      * @tc.steps: step4. call RemoveDeviceData synchronize with Sync with cloud force push strategy.
728      */
729     g_syncProcess = {};
730     std::vector<SyncProcess> expectProcess2;
731     InitProcessForCleanCloudData1(cloudCount, expectProcess2);
732     CloudSyncStatusCallback callback2;
733     GetCallback(g_syncProcess, callback2, expectProcess2);
734     std::string device = "";
735 
__anonba1d04ba0502() 736     std::thread thread1([&]() {
737         ASSERT_EQ(g_delegate->RemoveDeviceData(device, FLAG_AND_DATA), DBStatus::OK);
738     });
__anonba1d04ba0602() 739     std::thread thread2([&]() {
740         ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_FORCE_PULL, query, callback2, g_syncWaitTime),
741             DBStatus::OK);
742         LOGD("-------------------sync end--------------");
743     });
744     thread1.join();
745     thread2.join();
746     WaitForSyncFinish(g_syncProcess, g_syncWaitTime);
747     CheckCleanLogNum(db, g_tables, 20);
748     LOGD("================================== test clean cloud data 003 end ===================================");
749     CloseDb();
750 }
751 
InitGetCloudSyncTaskCountTest001(sqlite3 * & db)752 static void InitGetCloudSyncTaskCountTest001(sqlite3 *&db)
753 {
754     int64_t localCount = 20;
755     int64_t cloudCount = 10;
756     int64_t paddingSize = 100;
757     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
758     InsertCloudTableRecord(0, cloudCount, paddingSize, false);
759 }
760 
GetSyncOption()761 static CloudSyncOption GetSyncOption()
762 {
763     CloudSyncOption option;
764     option.devices = {DEVICE_CLOUD};
765     std::vector<std::string> pk = {"test"};
766     option.query = Query::Select().From(g_tableName1).In("name", pk);
767     option.priorityTask = true;
768     option.waitTime = g_syncWaitTime;
769     return option;
770 }
771 
772 /*
773  * @tc.name: GetCloudSyncTaskCountTest001
774  * @tc.desc: Test FLAG_ONLY mode of RemoveDeviceData concurrently with Sync
775  * @tc.type: FUNC
776  * @tc.require:
777  * @tc.author: huangboxin
778  */
779 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, GetCloudSyncTaskCountTest001, TestSize.Level1)
780 {
781     InitGetCloudSyncTaskCountTest001(db);
782     Query query = Query::Select().FromTable(g_tables);
783     std::mutex dataMutex1, dataMutex2;
784     std::condition_variable cv1, cv2;
785     bool finish1 = false, finish2 = false;
786     /**
787      * @tc.steps: step1. Call Sync once.
788      * @tc.expected: OK.
789      */
790     CloudSyncStatusCallback callback1 = [&dataMutex1, &cv1, &finish1](
__anonba1d04ba0702( const std::map<std::string, SyncProcess> &process) 791         const std::map<std::string, SyncProcess> &process) {
792         std::map<std::string, SyncProcess> syncProcess;
793         {
794             std::lock_guard<std::mutex> autoLock(dataMutex1);
795             syncProcess = process;
796             if (syncProcess[DEVICE_CLOUD].process == FINISHED) {
797                 finish1 = true;
798             }
799         }
800         cv1.notify_one();
801     };
802     /**
803      * @tc.steps: step2. Call Sync twice.
804      * @tc.expected: OK.
805      */
806     ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback1, g_syncWaitTime), DBStatus::OK);
807 
808     CloudSyncStatusCallback callback2 = [&dataMutex2, &cv2, &finish2](
__anonba1d04ba0802( const std::map<std::string, SyncProcess> &process) 809         const std::map<std::string, SyncProcess> &process) {
810         std::map<std::string, SyncProcess> syncProcess;
811         {
812             std::lock_guard<std::mutex> autoLock(dataMutex2);
813             syncProcess = process;
814             if (syncProcess[DEVICE_CLOUD].process == FINISHED) {
815                 finish2 = true;
816             }
817         }
818         cv2.notify_one();
819     };
820     ASSERT_EQ(g_delegate->Sync(GetSyncOption(), callback2), DBStatus::OK);
821     /**
822      * @tc.steps: step3. Call Get Cloud Sync Task Count
823      * @tc.expected: OK.
824      */
825     EXPECT_EQ(g_delegate->GetCloudSyncTaskCount(), 2);  // 2 is task count
826     /**
827      * @tc.steps: step3. Wait For Sync Task Finished
828      * @tc.expected: OK.
829      */
830     {
831         std::unique_lock<std::mutex> uniqueLock(dataMutex1);
__anonba1d04ba0902null832         cv1.wait(uniqueLock, [&finish1] {
833             return finish1;
834         });
835     }
836     {
837         std::unique_lock<std::mutex> uniqueLock(dataMutex2);
__anonba1d04ba0a02null838         cv2.wait(uniqueLock, [&finish2] {
839             return finish2;
840         });
841     }
842     CloseDb();
843 }
844 
845 /*
846  * @tc.name: CleanCloudDataTest004
847  * @tc.desc: Test  RemoveDeviceData when cloudSchema doesn't have local table
848  * @tc.type: FUNC
849  * @tc.require:
850  * @tc.author: huangboxin
851  */
852 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest004, TestSize.Level1)
853 {
854     DataBaseSchema dataBaseSchema;
855     TableSchema tableSchema1 = {
856         .name = "table_not_existed",
857         .sharedTableName = "table_not_existed_shared",
858         .fields = g_cloudFiled1
859     };
860     dataBaseSchema.tables.push_back(tableSchema1);
861     GetCloudDbSchema(dataBaseSchema);
862     ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
863     std::string device = "";
864     ASSERT_EQ(g_delegate->RemoveDeviceData(device, FLAG_AND_DATA), DBStatus::OK);
865     CloseDb();
866 }
867 
868 /*
869  * @tc.name: CleanCloudDataTest005
870  * @tc.desc: Test RemoveDeviceData when cloud data is deleted
871  * @tc.type: FUNC
872  * @tc.require:
873  * @tc.author: chenchaohao
874  */
875 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest005, TestSize.Level1)
876 {
877     /**
878      * @tc.steps: step1. cloud and device data is same
879      * @tc.expected: OK.
880      */
881     int64_t paddingSize = 10; // 10 is padding size
882     int64_t cloudCount = 10; // 10 is cloud count
883     InsertCloudTableRecord(0, cloudCount, paddingSize, true);
884     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
885 
886     /**
887      * @tc.steps: step2. cloud delete data and merge
888      * @tc.expected: OK.
889      */
890     DeleteCloudTableRecordByGid(0, cloudCount);
891     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
892     CheckCloudRecordNum(db, g_tables, {0, 10}); // 10 is cloud record num in table2 log
893     CheckCloudTotalCount(g_tables, {0, 10}); // // 10 is cloud data num in table2
894 
895     /**
896      * @tc.steps: step3. removedevicedata FLAG_AND_DATA and check log
897      * @tc.expected: OK.
898      */
899     std::string device = "";
900     ASSERT_EQ(g_delegate->RemoveDeviceData(device, FLAG_AND_DATA), DBStatus::OK);
901     CheckCleanDataAndLogNum(db, g_tables, 0, {0, 0});
902     CloseDb();
903 }
904 
905 /*
906  * @tc.name: CleanCloudDataTest006
907  * @tc.desc: Test FLAG_ONLY mode of RemoveDeviceData before Sync
908  * @tc.type: FUNC
909  * @tc.require:
910  * @tc.author: zhangqiquan
911  */
912 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest006, TestSize.Level1)
913 {
914     /**
915      * @tc.steps: step1. make data: 10 records on local
916      */
917     int64_t paddingSize = 10;
918     int localCount = 10;
919     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
920     /**
921      * @tc.steps: step2. call Sync with cloud merge strategy, and after that, local will has 20 records.
922      */
923     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
924     LOGW("check 10-10");
925     CheckCloudTotalCount(g_tables, {10, 10}); // 10 is cloud data num in table2
926     g_virtualCloudDb->ClearAllData();
927     LOGW("check 0-0");
928     CheckCloudTotalCount(g_tables, {0, 0}); // 0 is cloud data num in table2
929     /**
930      * @tc.steps: step3. removedevicedata FLAG_AND_DATA and sync again
931      * @tc.expected: OK.
932      */
933     std::string device;
934     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_ONLY), DBStatus::OK);
935     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
936     LOGW("check 10-10");
937     CheckCloudTotalCount(g_tables, {10, 10}); // 10 is cloud data num in table2
938     CloseDb();
939 }
940 
941 /*
942  * @tc.name: CleanCloudDataTest007
943  * @tc.desc: Test CLEAR_SHARED_TABLE mode of RemoveDeviceData before Sync
944  * @tc.type: FUNC
945  * @tc.require:
946  * @tc.author: bty
947  */
948 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest007, TestSize.Level1)
949 {
950     /**
951      * @tc.steps: step1. make data: 10 records on local
952      */
953     int64_t paddingSize = 1;
954     int localCount = 10;
955     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
956     /**
957      * @tc.steps: step2. call Sync with cloud merge strategy, and after that, local will has 20 records.
958      */
959     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
960     CheckCloudTotalCount(g_tables, {10, 10}); // 10 is cloud data num
961     g_virtualCloudDb->ClearAllData();
962     CheckCloudTotalCount(g_tables, {0, 0});
963     /**
964      * @tc.steps: step3. removedevicedata in CLEAR_SHARED_TABLE mode will not delete unShare table data
965      * @tc.expected: OK.
966      */
967     std::string device;
968     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::CLEAR_SHARED_TABLE), DBStatus::OK);
969     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
970     CheckCloudTotalCount(g_tables, {0, 0});
971     /**
972      * @tc.steps: step4. copy db data to share table,then sync to check total count
973      * @tc.expected: OK.
974      */
975     CopySharedDataFromOriginalTable(db, g_tables);
976     CloudDBSyncUtilsTest::callSync(g_shareTables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
977     CheckCloudTotalCount(g_tables, {0, 0});
978     CheckCloudTotalCount(g_shareTables, {10, 10}); // 10 is cloud data num
979     g_virtualCloudDb->ClearAllData();
980     CheckCloudTotalCount(g_shareTables, {0, 0});
981     /**
982      * @tc.steps: step5. removedevicedata in CLEAR_SHARED_TABLE mode,then sync and check data
983      * @tc.expected: OK.
984      */
985     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::CLEAR_SHARED_TABLE), DBStatus::OK);
986     CheckCloudSharedRecordNum(db, g_shareTables, {0, 0, 0, 0});
987     CloudDBSyncUtilsTest::callSync(g_shareTables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
988     CheckCloudTotalCount(g_shareTables, {0, 0});
989     CloseDb();
990 }
991 
992 /*
993  * @tc.name: CleanCloudDataTest008
994  * @tc.desc: Test CLEAR_SHARED_TABLE mode of RemoveDeviceData after close DB
995  * @tc.type: FUNC
996  * @tc.require:
997  * @tc.author: chenchaohao
998  */
999 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest008, TestSize.Level1)
1000 {
1001     /**
1002      * @tc.steps: step1. make data: 10 records on local
1003      */
1004     int64_t paddingSize = 1;
1005     int localCount = 10;
1006     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1007     /**
1008      * @tc.steps: step2. call Sync with cloud merge strategy, and after that, local will has 20 records.
1009      */
1010     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1011     CheckCloudTotalCount(g_tables, {10, 10}); // 10 is cloud data num
1012     g_virtualCloudDb->ClearAllData();
1013     CheckCloudTotalCount(g_tables, {0, 0});
1014     /**
1015      * @tc.steps: step3. removedevicedata in CLEAR_SHARED_TABLE mode will not delete unShare table data
1016      * @tc.expected: OK.
1017      */
1018     std::string device;
1019     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::CLEAR_SHARED_TABLE), DBStatus::OK);
1020     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1021     CheckCloudTotalCount(g_tables, {0, 0});
1022     /**
1023      * @tc.steps: step4. copy db data to share table,then sync to check total count
1024      * @tc.expected: OK.
1025      */
1026     CopySharedDataFromOriginalTable(db, g_tables);
1027     CloudDBSyncUtilsTest::callSync(g_shareTables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1028     CheckCloudTotalCount(g_tables, {0, 0});
1029     CheckCloudTotalCount(g_shareTables, {10, 10}); // 10 is cloud data num
1030     g_virtualCloudDb->ClearAllData();
1031     CheckCloudTotalCount(g_shareTables, {0, 0});
1032     /**
1033      * @tc.steps: step5. removedevicedata in CLEAR_SHARED_TABLE mode after close db, then sync and check data
1034      * @tc.expected: OK.
1035      */
1036     CloseDb();
1037     g_observer = new (std::nothrow) RelationalStoreObserverUnitTest();
1038     ASSERT_NE(g_observer, nullptr);
1039     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option { .observer = g_observer },
1040         g_delegate), DBStatus::OK);
1041     ASSERT_NE(g_delegate, nullptr);
1042     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::CLEAR_SHARED_TABLE), DBStatus::OK);
1043     CheckCloudSharedRecordNum(db, g_shareTables, {0, 0, 0, 0});
1044     CloseDb();
1045 }
1046 
1047 /*
1048  * @tc.name: CleanCloudDataTest008
1049  * @tc.desc: Test RemoveDeviceData after Sync
1050  * @tc.type: FUNC
1051  * @tc.require:
1052  * @tc.author: zhangqiquan
1053  */
1054 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest009, TestSize.Level1)
1055 {
1056     /**
1057      * @tc.steps: step1. make data: 10 records on local
1058      */
1059     int64_t paddingSize = 10;
1060     int localCount = 10;
1061     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1062     /**
1063      * @tc.steps: step2. call Sync with cloud merge strategy, and after that, local will has 10 records.
1064      */
1065     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1066     LOGW("check 10-10");
1067     CheckCloudTotalCount(g_tables, {10, 10}); // 10 is cloud data num in table2
1068     /**
1069      * @tc.steps: step3. remove cloud and sync again
1070      * @tc.expected: OK.
1071      */
1072     DeleteCloudTableRecordByGid(0, localCount);
1073     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1074     g_delegate->RemoveDeviceData();
1075     CheckLocalLogCount(db, { g_tableName1 }, { localCount });
1076     CloseDb();
1077 }
1078 
1079 /*
1080  * @tc.name: CleanCloudDataTest010
1081  * @tc.desc: Test if log is delete when removedevicedata after sync
1082  * @tc.type: FUNC
1083  * @tc.require:
1084  * @tc.author: chenchaohao
1085  */
1086 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest010, TestSize.Level1)
1087 {
1088     /**
1089      * @tc.steps: step1. make data: 10 records on local
1090      */
1091     int64_t paddingSize = 10;
1092     int localCount = 10;
1093     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1094     /**
1095      * @tc.steps: step2. call Sync with cloud merge strategy, and after that, local will has 10 records.
1096      */
1097     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1098     LOGW("check 10-10");
1099     CheckCloudTotalCount(g_tables, {10, 10}); // 10 is cloud data num in table2
1100     /**
1101      * @tc.steps: step3. remove cloud and sync again
1102      * @tc.expected: OK.
1103      */
1104     int deleteCount = 5;
1105     DeleteCloudTableRecordByGid(0, deleteCount);
1106     DeleteUserTableRecord(db, deleteCount, localCount);
1107     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1108     std::string device;
1109     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_ONLY), DBStatus::OK);
1110     CheckLocalLogCount(db, { g_tableName1 }, { deleteCount });
1111     CloseDb();
1112 }
1113 
1114 /*
1115  * @tc.name: CleanCloudDataTest011
1116  * @tc.desc: Test if the version in the log table has been cleared after RemoveDeviceData.
1117  * @tc.type: FUNC
1118  * @tc.require:
1119  * @tc.author: liaoyonghuang
1120  */
1121 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest011, TestSize.Level1)
1122 {
1123     /**
1124      * @tc.steps: step1. make data: 10 records on local
1125      */
1126     int64_t paddingSize = 10;
1127     int localCount = 10;
1128     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1129     std::string device;
1130     /**
1131      * @tc.steps: step2. call Sync with cloud merge strategy, and after that, local will has 10 records.
1132      */
1133     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1134     LOGW("check 10-10");
1135     CheckCloudTotalCount(g_tables, {10, 10}); // 10 is cloud data num in table2
1136     /**
1137      * @tc.steps: step3. remove device data
1138      * @tc.expected: OK.
1139      */
1140     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1141     /**
1142      * @tc.steps: step4. Check if the version in the log table has been cleared.
1143      * @tc.expected: OK.
1144      */
1145     for (auto tableName : g_tables) {
1146         std::string sql = "select count(*) from " + DBCommon::GetLogTableName(tableName) +
1147             " where ((flag & 0x08 != 0) or cloud_gid is null or cloud_gid == '') and version != '';";
1148         EXPECT_EQ(sqlite3_exec(db, sql.c_str(), QueryCountCallback,
1149                     reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1150     }
1151     CloseDb();
1152 }
1153 
1154 /*
1155  * @tc.name: CleanCloudDataTest012
1156  * @tc.desc: Test modify data will not be deleted before upload to cloud when remove device data.
1157  * @tc.type: FUNC
1158  * @tc.require:
1159  * @tc.author: wangxiangdong
1160  */
1161 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest012, TestSize.Level1)
1162 {
1163     /**
1164      * @tc.steps: step1. make data: 20 records on local
1165      */
1166     int64_t paddingSize = 20;
1167     int localCount = 20;
1168     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1169     /**
1170      * @tc.steps: step2. call Sync with cloud merge strategy, and after that, local will has 20 records.
1171      */
1172     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1173     /**
1174      * @tc.steps: step3. modify local data
1175      * @tc.expected: OK.
1176      */
1177     InsertUserTableRecord(db, 20, localCount, paddingSize, false);
1178     UpdateUserTableRecord(db, 5, 10);
1179     DeleteUserTableRecord(db, 10, 15);
1180     /**
1181      * @tc.steps: step4. check cloud record data and remove device data.
1182      * @tc.expected: OK.
1183      */
1184     CheckCloudRecordNum(db, g_tables, {0, 0});
1185     std::string device;
1186     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1187     CheckCleanDataNum(db, g_tables, {25, 25});
1188     CheckLocalLogCount(db, g_tables, {30, 30});
1189     /**
1190      * @tc.steps: step5. do sync again and remove device data, then check local data and log.
1191      * @tc.expected: OK.
1192      */
1193     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1194     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1195     CheckCleanDataNum(db, g_tables, {0, 0});
1196     CheckLocalLogCount(db, g_tables, {0, 0});
1197     CloseDb();
1198 }
1199 
1200 /*
1201  * @tc.name: CleanCloudDataTest013
1202  * @tc.desc: Test modify data will not be deleted before upload to cloud when remove device data when set logicDelete.
1203  * @tc.type: FUNC
1204  * @tc.require:
1205  * @tc.author: wangxiangdong
1206  */
1207 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest013, TestSize.Level1)
1208 {
1209     /**
1210      * @tc.steps: step1. Set data is logicDelete
1211      */
1212     bool logicDelete = true;
1213     auto data = static_cast<PragmaData>(&logicDelete);
1214     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1215     /**
1216      * @tc.steps: step2. make data: 20 records on local
1217      */
1218     int64_t paddingSize = 20;
1219     int localCount = 20;
1220     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1221     /**
1222      * @tc.steps: step3. call Sync with cloud merge strategy, and after that, local will has 20 records.
1223      */
1224     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1225     /**
1226      * @tc.steps: step4. modify local data
1227      * @tc.expected: OK.
1228      */
1229     InsertUserTableRecord(db, 20, localCount, paddingSize, false);
1230     UpdateUserTableRecord(db, 5, 10);
1231     DeleteUserTableRecord(db, 10, 15);
1232     /**
1233      * @tc.steps: step5. check cloud record data and remove device data.
1234      * @tc.expected: OK.
1235      */
1236     CheckCloudRecordNum(db, g_tables, {0, 0});
1237     std::string device;
1238     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1239     CheckCleanDataNum(db, g_tables, {35, 35});
1240     CheckLocalLogCount(db, g_tables, {40, 40});
1241     CheckLogoutLogCount(db, g_tables, {10, 10});
1242     /**
1243      * @tc.steps: step6. do sync again and remove device data, then check local data and log.
1244      * @tc.expected: OK.
1245      */
1246     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1247     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1248     CheckCleanDataNum(db, g_tables, {40, 35});
1249     CheckLocalLogCount(db, g_tables, {40, 40});
1250     CheckLogoutLogCount(db, g_tables, {15, 10});
1251     CloseDb();
1252 }
1253 
1254 /*
1255  * @tc.name: CleanCloudDataTest014
1256  * @tc.desc: Test when remove device data at flag only mode.
1257  * @tc.type: FUNC
1258  * @tc.require:
1259  * @tc.author: wangxiangdong
1260  */
1261 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest014, TestSize.Level1)
1262 {
1263     /**
1264      * @tc.steps: step1. make data: 20 records on local
1265      */
1266     int64_t paddingSize = 20;
1267     int localCount = 20;
1268     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1269     /**
1270      * @tc.steps: step2. call Sync with cloud merge strategy, and after that, local will has 20 records.
1271      */
1272     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1273     /**
1274      * @tc.steps: step3. modify local data
1275      * @tc.expected: OK.
1276      */
1277     InsertUserTableRecord(db, 20, localCount, paddingSize, false);
1278     UpdateUserTableRecord(db, 5, 10);
1279     DeleteUserTableRecord(db, 10, 15);
1280     /**
1281      * @tc.steps: step4. check cloud record data and remove device data.
1282      * @tc.expected: OK.
1283      */
1284     CheckCloudRecordNum(db, g_tables, {0, 0});
1285     std::string device;
1286     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_ONLY), DBStatus::OK);
1287     CheckCleanDataNum(db, g_tables, {35, 35});
1288     CheckLogoutLogCount(db, g_tables, {40, 40});
1289     CloseDb();
1290 }
1291 
1292 /*
1293  * @tc.name: CleanCloudDataTest015
1294  * @tc.desc: Test get schema from db is ok when local has not been set.
1295  * @tc.type: FUNC
1296  * @tc.require:
1297  * @tc.author: wangxiangdong
1298  */
1299 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest015, TestSize.Level1)
1300 {
1301     /**
1302      * @tc.steps: step1. Set data is logicDelete
1303      */
1304     bool logicDelete = true;
1305     auto data = static_cast<PragmaData>(&logicDelete);
1306     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1307     /**
1308      * @tc.steps: step2. make data: 10 records on local
1309      */
1310     int64_t paddingSize = 20;
1311     int localCount = 10;
1312     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1313     /**
1314      * @tc.steps: step3. call Sync with cloud merge strategy, and after that, local will has 20 records.
1315      */
1316     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1317     /**
1318      * @tc.steps: step4. remove and check
1319      * @tc.expected: OK.
1320      */
1321     CheckCloudRecordNum(db, g_tables, {0, 0});
1322     std::string device;
1323     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1324     CheckCleanDataNum(db, g_tables, {10, 10});
1325     CheckLocalLogCount(db, g_tables, {10, 10});
1326     CheckLogoutLogCount(db, g_tables, {10, 10});
1327     CloseDb();
1328 }
1329 /*
1330  * @tc.name: CleanCloudDataTest016
1331  * @tc.desc: Test compensated flag should be clear after remove device data.
1332  * @tc.type: FUNC
1333  * @tc.require:
1334  * @tc.author: wangxiangdong
1335  */
1336 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest016, TestSize.Level1)
1337 {
1338     /**
1339      * @tc.steps: step1. Set data is logicDelete
1340      */
1341     bool logicDelete = true;
1342     auto data = static_cast<PragmaData>(&logicDelete);
1343     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1344     /**
1345      * @tc.steps: step2. make data: 20 records on local
1346      */
1347     int64_t paddingSize = 20;
1348     int localCount = 20;
1349     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1350     /**
1351      * @tc.steps: step3. make 2th data exist
1352      */
1353     int upIdx = 0;
__anonba1d04ba0b02(const std::string &tableName, VBucket &extend) 1354     g_virtualCloudDb->ForkUpload([&upIdx](const std::string &tableName, VBucket &extend) {
1355         LOGD("cloud db upload index:%d", ++upIdx);
1356         if (upIdx == 2) { // 2 is index
1357             extend[CloudDbConstant::ERROR_FIELD] = static_cast<int64_t>(DBStatus::CLOUD_RECORD_ALREADY_EXISTED);
1358         }
1359     });
1360     /**
1361      * @tc.steps: step4. call Sync with cloud merge strategy, and check flag before and after.
1362      */
1363     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1364     g_virtualCloudDb->ForkUpload(nullptr);
1365     CheckCompensatedNum(db, g_tables, {1, 0});
1366     /**
1367      * @tc.steps: step5. remove device data and check flag do not has compensated.
1368      * @tc.expected: OK.
1369      */
1370     std::string device;
1371     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_ONLY), DBStatus::OK);
1372     CheckCompensatedNum(db, g_tables, {0, 0});
1373     CloseDb();
1374 }
1375 
1376 /*
1377  * @tc.name: CleanCloudDataTest017
1378  * @tc.desc: Test deleted data and logic delete will not have flag logout.
1379  * @tc.type: FUNC
1380  * @tc.require:
1381  * @tc.author: wangxiangdong
1382  */
1383 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest017, TestSize.Level1)
1384 {
1385     /**
1386      * @tc.steps: step1. Set data is logicDelete
1387      */
1388     bool logicDelete = true;
1389     auto data = static_cast<PragmaData>(&logicDelete);
1390     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1391     /**
1392      * @tc.steps: step2. make data: 20 records on local
1393      */
1394     int64_t paddingSize = 20;
1395     int localCount = 20;
1396     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1397     /**
1398      * @tc.steps: step3. call Sync with cloud merge strategy, and check flag before and after.
1399      */
1400     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1401     /**
1402      * @tc.steps: step4. make logic delete and local delete then call Sync.
1403      */
1404     DeleteCloudTableRecordByGid(0, 5);
1405     DeleteUserTableRecord(db, 5, 10);
1406     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1407     /**
1408      * @tc.steps: step5. remove device data and check flag do not has logout.
1409      * @tc.expected: OK.
1410      */
1411     std::string device;
1412     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1413     CheckLogoutLogCount(db, g_tables, {10, 15});
1414     CloseDb();
1415 }
1416 
1417 /*
1418  * @tc.name: CleanCloudDataTest018
1419  * @tc.desc: Test remove device data then sync, check cursor do not increase twice.
1420  * @tc.type: FUNC
1421  * @tc.require:
1422  * @tc.author: wangxiangdong
1423  */
1424 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest018, TestSize.Level1)
1425 {
1426     /**
1427      * @tc.steps: step1. Set data is logicDelete
1428      */
1429     bool logicDelete = true;
1430     auto data = static_cast<PragmaData>(&logicDelete);
1431     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1432     /**
1433      * @tc.steps: step2. make data: 10 records on local
1434      */
1435     int64_t paddingSize = 10;
1436     int localCount = 10;
1437     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1438     /**
1439      * @tc.steps: step3. call Sync with cloud merge strategy, and check flag before and after.
1440      */
1441     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1442 
1443     /**
1444      * @tc.steps: step4. remove device data.
1445      * @tc.expected: OK.
1446      */
1447     std::string device;
1448     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1449     /**
1450      * @tc.steps: step5.call Sync then check cursor.
1451      */
1452     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1453     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1454         " where cursor='40';";
1455     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1456         reinterpret_cast<void *>(1), nullptr), SQLITE_OK);
1457     CloseDb();
1458 }
1459 
1460 /*
1461  * @tc.name: CleanCloudDataTest019
1462  * @tc.desc: Test remove device data then sync, check cursor do not increase twice.
1463  * @tc.type: FUNC
1464  * @tc.require:
1465  * @tc.author: wangxiangdong
1466  */
1467 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest019, TestSize.Level1)
1468 {
1469     /**
1470      * @tc.steps: step1. make data: 20 records on local
1471      */
1472     int64_t paddingSize = 20;
1473     int localCount = 20;
1474     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1475     /**
1476      * @tc.steps: step2. call Sync with cloud merge strategy, and check flag before and after.
1477      */
1478     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1479     /**
1480      * @tc.steps: step3.make logic delete and local delete then call Sync.
1481      * @tc.expected: OK.
1482      */
1483     DeleteCloudTableRecordByGid(0, 5);
1484     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1485     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1486         " where cursor='20';";
1487     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1488         reinterpret_cast<void *>(1), nullptr), SQLITE_OK);
1489     CloseDb();
1490 }
1491 
1492 /*
1493  * @tc.name: CleanCloudDataTest020
1494  * @tc.desc: Test drop logic delete data will not have flag logout.
1495  * @tc.type: FUNC
1496  * @tc.require:
1497  * @tc.author: wangxiangdong
1498  */
1499 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest020, TestSize.Level1)
1500 {
1501     /**
1502      * @tc.steps: step1. Set data is logicDelete
1503      */
1504     bool logicDelete = true;
1505     auto data = static_cast<PragmaData>(&logicDelete);
1506     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1507     /**
1508      * @tc.steps: step2. make data: 20 records on local
1509      */
1510     int64_t paddingSize = 20;
1511     int localCount = 20;
1512     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1513     /**
1514      * @tc.steps: step3. call Sync with cloud merge strategy, and check flag before and after.
1515      */
1516     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1517     /**
1518      * @tc.steps: step4. make logic delete and local delete then call Sync.
1519      */
1520     DeleteCloudTableRecordByGid(0, 5);
1521     DeleteUserTableRecord(db, 5, 10);
1522     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1523     /**
1524      * @tc.steps: step5. remove device data and check flag do not has logout.
1525      * @tc.expected: OK.
1526      */
1527     std::string device;
1528     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1529     CheckLogoutLogCount(db, g_tables, {10, 15});
1530     /**
1531      * @tc.steps: step6. drop logic delete data and check flag do not has logout.
1532      * @tc.expected: OK.
1533      */
1534     EXPECT_EQ(DropLogicDeletedData(db, g_tables[0], 0u), OK);
1535     EXPECT_EQ(DropLogicDeletedData(db, g_tables[1], 0u), OK);
1536     CheckLogoutLogCount(db, g_tables, {0, 0});
1537     CloseDb();
1538 }
1539 
1540 /*
1541  * @tc.name: CleanCloudDataTest021
1542  * @tc.desc: Test conflict, not found, exist errCode of cloudSpace will deal.
1543  * @tc.type: FUNC
1544  * @tc.require:
1545  * @tc.author: wangxiangdong
1546  */
1547 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest021, TestSize.Level1)
1548 {
1549     /**
1550      * @tc.steps: step1. Set data is logicDelete
1551      */
1552     bool logicDelete = true;
1553     auto data = static_cast<PragmaData>(&logicDelete);
1554     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1555     /**
1556      * @tc.steps: step2. make data: 20 records on local
1557      */
1558     int64_t paddingSize = 20;
1559     int localCount = 20;
1560     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1561     /**
1562      * @tc.steps: step3. make 2-5th data errCode.
1563      */
1564     int upIdx = 0;
__anonba1d04ba0c02(const std::string &tableName, VBucket &extend) 1565     g_virtualCloudDb->ForkUpload([&upIdx](const std::string &tableName, VBucket &extend) {
1566         LOGD("cloud db upload index:%d", ++upIdx);
1567         if (upIdx == 2) {
1568             extend[CloudDbConstant::ERROR_FIELD] = static_cast<int64_t>(DBStatus::CLOUD_RECORD_ALREADY_EXISTED);
1569         }
1570         if (upIdx == 3) {
1571             extend[CloudDbConstant::ERROR_FIELD] = static_cast<int64_t>(DBStatus::CLOUD_RECORD_EXIST_CONFLICT);
1572         }
1573         if (upIdx == 4) {
1574             // CLOUD_RECORD_NOT_FOUND means cloud and terminal is consistency
1575             extend[CloudDbConstant::ERROR_FIELD] = static_cast<int64_t>(DBStatus::CLOUD_RECORD_NOT_FOUND);
1576         }
1577         if (upIdx == 5) {
1578             // std::string("x") means no error
1579             extend[CloudDbConstant::ERROR_FIELD] = std::string("x");
1580         }
1581     });
1582     /**
1583      * @tc.steps: step4. call Sync, and check consistency.
1584      */
1585     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1586     g_virtualCloudDb->ForkUpload(nullptr);
1587     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1588         " where flag & 0x20 = 0;";
1589     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1590         reinterpret_cast<void *>(18), nullptr), SQLITE_OK);
1591     CloseDb();
1592 }
1593 
1594 /*
1595  * @tc.name: CleanCloudDataTest022
1596  * @tc.desc: Test deleted data and flag_and_data mode, flag have no logout.
1597  * @tc.type: FUNC
1598  * @tc.require:
1599  * @tc.author: wangxiangdong
1600  */
1601 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest022, TestSize.Level1)
1602 {
1603     /**
1604      * @tc.steps: step1. make data: 20 records on local
1605      */
1606     int64_t paddingSize = 20;
1607     int localCount = 20;
1608     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1609     /**
1610      * @tc.steps: step2. call Sync with cloud merge strategy, and check flag before and after.
1611      */
1612     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1613     /**
1614      * @tc.steps: step3. make local delete then call Sync.
1615      */
1616     DeleteUserTableRecord(db, 0, 5);
1617     /**
1618      * @tc.steps: step4. remove device data and check flag has no logout.
1619      * @tc.expected: OK.
1620      */
1621     std::string device;
1622     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1623     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1624         " where flag & 0x800 == 0;";
1625     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1626         reinterpret_cast<void *>(5), nullptr), SQLITE_OK);
1627     sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1628         " where flag & 0x800 != 0;";
1629     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1630         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1631     CloseDb();
1632 }
1633 
1634 /*
1635  * @tc.name: CleanCloudDataTest023
1636  * @tc.desc: Test deleted data and logic deletedata will clear gid but no logout.
1637  * @tc.type: FUNC
1638  * @tc.require:
1639  * @tc.author: wangxiangdong
1640  */
1641 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest023, TestSize.Level1)
1642 {
1643     /**
1644      * @tc.steps: step1. Set data is logicDelete
1645      */
1646     bool logicDelete = true;
1647     auto data = static_cast<PragmaData>(&logicDelete);
1648     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1649     /**
1650      * @tc.steps: step2. make data: 20 records on local
1651      */
1652     int64_t paddingSize = 20;
1653     int localCount = 20;
1654     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1655     /**
1656      * @tc.steps: step3. call Sync with cloud merge strategy.
1657      */
1658     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1659     /**
1660      * @tc.steps: step4. make local delete and cloud delete then call Sync.
1661      */
1662     DeleteUserTableRecord(db, 0, 5);
1663     DeleteCloudTableRecordByGid(5, 10);
1664     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1665 
1666     /**
1667      * @tc.steps: step5. remove device data and check cursor, cloud_gid, version sharing_resource.
1668      * @tc.expected: OK.
1669      */
1670     DeleteUserTableRecord(db, 10, 15);
1671     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1672         " where cursor = '40';";
1673     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1674         reinterpret_cast<void *>(1), nullptr), SQLITE_OK);
1675     std::string device;
1676     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1677     // check flag no logout
1678     sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1679         " where flag & 0x800 == 0 and cloud_gid = '' and version = '' and sharing_resource = '';";
1680     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1681         reinterpret_cast<void *>(15), nullptr), SQLITE_OK);
1682     // check flag has logout
1683     sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1684         " where flag & 0x800 != 0;";
1685     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1686         reinterpret_cast<void *>(5), nullptr), SQLITE_OK);
1687     // check flag has no logout and delete
1688     sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1689         " where flag & 0x800 == 0 and data_key = -1;";
1690     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1691         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
1692     // check flag has no logout and delete
1693     sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1694         " where flag & 0x800 == 0 and data_key = -1 and cloud_gid = '' and version = '' and sharing_resource = '';";
1695     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1696         reinterpret_cast<void *>(10), nullptr), SQLITE_OK);
1697     // check flag has no logout and logic delete
1698     sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1699         " where flag & 0x800 == 0 and flag & 0x08 != 0 and cloud_gid = '' and version = '' and sharing_resource = '';";
1700     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1701         reinterpret_cast<void *>(5), nullptr), SQLITE_OK);
1702     // check cursor has been increase to 50
1703     sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1704         " where cursor = '30';";
1705     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1706         reinterpret_cast<void *>(1), nullptr), SQLITE_OK);
1707     CloseDb();
1708 }
1709 
1710 /*
1711  * @tc.name: CleanCloudDataTest024
1712  * @tc.desc: Test logic deleted data and log will deleted after DropLogicDeletedData.
1713  * @tc.type: FUNC
1714  * @tc.require:
1715  * @tc.author: wangxiangdong
1716  */
1717 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest024, TestSize.Level1)
1718 {
1719     /**
1720      * @tc.steps: step1. Set data is logicDelete
1721      */
1722     bool logicDelete = true;
1723     auto data = static_cast<PragmaData>(&logicDelete);
1724     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1725     /**
1726      * @tc.steps: step2. make data: 20 records on local
1727      */
1728     int64_t paddingSize = 20;
1729     int localCount = 20;
1730     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1731     /**
1732      * @tc.steps: step3. call Sync with cloud merge strategy, and check flag before and after.
1733      */
1734     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1735     /**
1736      * @tc.steps: step4.make local logic delete then call Sync.
1737      */
1738     DeleteCloudTableRecordByGid(0, 5);
1739     DeleteUserTableRecord(db, 5, 10);
1740     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1741     /**
1742      * @tc.steps: step5. before remove device data and check log num.
1743      * @tc.expected: OK.
1744      */
1745     std::string device;
1746     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1747     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1748         " where flag & 0x08 == 0x08;";
1749     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1750         reinterpret_cast<void *>(15), nullptr), SQLITE_OK);
1751     /**
1752      * @tc.steps: step6. DropLogicDeletedData and check log num.
1753      * @tc.expected: OK.
1754      */
1755     EXPECT_EQ(DropLogicDeletedData(db, g_tables[0], 0u), OK);
1756     sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1757         " where flag & 0x08 == 0x08;";
1758     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1759         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1760     CloseDb();
1761 }
1762 
1763 /*
1764  * @tc.name: CleanCloudDataTest025
1765  * @tc.desc: Test sync after dropping logic deleted device data, cursor do not decrease.
1766  * @tc.type: FUNC
1767  * @tc.require:
1768  * @tc.author: suyuchen
1769  */
1770 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest025, TestSize.Level1)
1771 {
1772     /**
1773      * @tc.steps: step1. Set logicDelete
1774      */
1775     bool logicDelete = true;
1776     auto data = static_cast<PragmaData>(&logicDelete);
1777     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1778 
1779     /**
1780      * @tc.steps: step2. insert 10 records locally, then sync to cloud
1781      */
1782     int64_t paddingSize = 10;
1783     int localCount = 10;
1784     InsertUserTableRecord(db, 0, localCount, paddingSize, false);
1785     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1786 
1787     /**
1788      * @tc.steps: step3. logic delete record 1 and 2 from cloud, then sync
1789      */
1790     DeleteCloudTableRecordByGid(0, 2);
1791     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1792 
1793     /**
1794      * @tc.steps: step4. clear logically deleted data
1795      */
1796     DropLogicDeletedData(db, g_tables[0], 0);
1797 
1798     /**
1799      * @tc.steps: step5. logic delete record 3 from cloud, then sync
1800      */
1801     DeleteCloudTableRecordByGid(3, 1);
1802     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1803 
1804     /**
1805      * @tc.steps: step6. check cursor
1806      */
1807     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1808         " where cursor='13';";
1809     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1810         reinterpret_cast<void *>(1), nullptr), SQLITE_OK);
1811 
1812     CloseDb();
1813 }
1814 
1815 /*
1816  * @tc.name: CleanCloudDataTest026
1817  * @tc.desc: Test logic deleted data and flag_only.
1818  * @tc.type: FUNC
1819  * @tc.require:
1820  * @tc.author: wangxiangdong
1821  */
1822 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest026, TestSize.Level1)
1823 {
1824     /**
1825      * @tc.steps: step1. Set data is logicDelete
1826      * @tc.expected: OK.
1827      */
1828     bool logicDelete = true;
1829     auto data = static_cast<PragmaData>(&logicDelete);
1830     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1831     /**
1832      * @tc.steps: step2. make data: 20 records on cloud
1833      * @tc.expected: OK.
1834      */
1835     int64_t paddingSize = 20;
1836     int cloudCount = 20;
1837     InsertCloudTableRecord(0, cloudCount, paddingSize, false);
1838     /**
1839      * @tc.steps: step3. call Sync with cloud merge strategy.
1840      * @tc.expected: OK.
1841      */
1842     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1843     /**
1844      * @tc.steps: step4. after remove device data and check log num.
1845      * @tc.expected: OK.
1846      */
1847     std::string device;
1848     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_ONLY), DBStatus::OK);
1849     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1850         " where flag & 0x02 == 0x02;";
1851     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1852         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1853     CloseDb();
1854 }
1855 
1856 /*
1857  * @tc.name: CleanCloudDataTest027
1858  * @tc.desc: Test flag_only not logic delete.
1859  * @tc.type: FUNC
1860  * @tc.require:
1861  * @tc.author: wangxiangdong
1862  */
1863 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest027, TestSize.Level1)
1864 {
1865     /**
1866      * @tc.steps: step1. make data: 20 records on cloud
1867      * @tc.expected: OK.
1868      */
1869     int64_t paddingSize = 20;
1870     int cloudCount = 20;
1871     InsertCloudTableRecord(0, cloudCount, paddingSize, false);
1872     /**
1873      * @tc.steps: step2. call Sync with cloud merge strategy.
1874      * @tc.expected: OK.
1875      */
1876     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1877     /**
1878      * @tc.steps: step3. after remove device data and check log num.
1879      * @tc.expected: OK.
1880      */
1881     std::string device;
1882     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_ONLY), DBStatus::OK);
1883     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1884         " where flag & 0x02 == 0x02;";
1885     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1886         reinterpret_cast<void *>(cloudCount), nullptr), SQLITE_OK);
1887     EXPECT_EQ(g_observer->GetLastOrigin(), Origin::ORIGIN_CLOUD);
1888     CloseDb();
1889 }
1890 
1891 /*
1892  * @tc.name: CleanCloudDataTest028
1893  * @tc.desc: Test flag_only and logic delete.
1894  * @tc.type: FUNC
1895  * @tc.require:
1896  * @tc.author: wangxiangdong
1897  */
1898 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest028, TestSize.Level1)
1899 {
1900     /**
1901      * @tc.steps: step1. Set data is logicDelete
1902      * @tc.expected: OK.
1903      */
1904     bool logicDelete = true;
1905     auto data = static_cast<PragmaData>(&logicDelete);
1906     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1907     /**
1908      * @tc.steps: step2. make data: 20 records on cloud
1909      * @tc.expected: OK.
1910      */
1911     int64_t paddingSize = 20;
1912     int cloudCount = 20;
1913     InsertCloudTableRecord(0, cloudCount, paddingSize, false);
1914     /**
1915      * @tc.steps: step3. call Sync with cloud merge strategy.
1916      * @tc.expected: OK.
1917      */
1918     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1919     /**
1920      * @tc.steps: step4. after remove device data and check log num.
1921      * @tc.expected: OK.
1922      */
1923     std::string device;
1924     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_ONLY), DBStatus::OK);
1925     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1926         " where flag & 0x02 == 0x02;";
1927     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1928         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1929     /**
1930      * @tc.steps: step5. call Sync with cloud merge strategy after delete by cloud.
1931      * @tc.expected: OK.
1932      */
1933     DeleteCloudTableRecordByGid(0, 2);
1934     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1935 
1936     /**
1937      * @tc.steps: step6. call Sync with cloud merge strategy.
1938      * @tc.expected: OK.
1939      */
1940     DeleteCloudTableRecordByGid(4, 2);
1941     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1942     sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1943         " where cloud_gid = '';";
1944     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1945         reinterpret_cast<void *>(2), nullptr), SQLITE_OK);
1946     CheckCloudTotalCount(g_tables, {18, 20});
1947     CloseDb();
1948 }
1949 
1950 /*
1951  * @tc.name: CleanCloudDataTest029
1952  * @tc.desc: Test flag_and_data and logic delete to remove cloud and inconsistency data.
1953  * @tc.type: FUNC
1954  * @tc.require:
1955  * @tc.author: wangxiangdong
1956  */
1957 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest029, TestSize.Level1)
1958 {
1959     /**
1960      * @tc.steps: step1. Set data is logicDelete
1961      * @tc.expected: OK.
1962      */
1963     bool logicDelete = true;
1964     auto data = static_cast<PragmaData>(&logicDelete);
1965     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
1966     /**
1967      * @tc.steps: step2. make data: 20 records on cloud
1968      * @tc.expected: OK.
1969      */
1970     int64_t paddingSize = 20;
1971     int cloudCount = 20;
1972     InsertCloudTableRecord(0, cloudCount, paddingSize, false);
1973     /**
1974      * @tc.steps: step3. call Sync with cloud merge strategy.
1975      * @tc.expected: OK.
1976      */
1977     g_virtualAssetLoader->SetDownloadStatus(CLOUD_ASSET_SPACE_INSUFFICIENT);
1978     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1979     /**
1980      * @tc.steps: step4. remove device data and check log num.
1981      * @tc.expected: OK.
1982      */
1983     std::string device;
1984     ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK);
1985     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
1986         " where flag & 0x809 == 0x809;";
1987     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1988         reinterpret_cast<void *>(20), nullptr), SQLITE_OK);
1989     DropLogicDeletedData(db, g_tables[0], 0);
1990     /**
1991      * @tc.steps: step5. call Sync with cloud merge strategy after set asset download ok.
1992      * @tc.expected: OK.
1993      */
1994     g_virtualAssetLoader->SetDownloadStatus(DBStatus::OK);
1995     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
1996     /**
1997      * @tc.steps: step6. check data is consistence.
1998      * @tc.expected: OK.
1999      */
2000     sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
2001         " where flag & 0x20 = 0;";
2002     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2003         reinterpret_cast<void *>(20), nullptr), SQLITE_OK);
2004     CheckCloudTotalCount(g_tables, {20, 20});
2005     CloseDb();
2006 }
2007 
2008 /*
2009  * @tc.name: CleanCloudDataTest030
2010  * @tc.desc: Test flag_and_data and logic delete to remove cloud and inconsistency data.
2011  * @tc.type: FUNC
2012  * @tc.require:
2013  * @tc.author: tankaisheng
2014  */
2015 HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest030, TestSize.Level1)
2016 {
2017     /**
2018      * @tc.steps: step1. Set data is logicDelete
2019      * @tc.expected: OK.
2020      */
2021     bool logicDelete = true;
2022     auto data = static_cast<PragmaData>(&logicDelete);
2023     g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data);
2024     /**
2025      * @tc.steps: step2. make data: 20 records on cloud
2026      * @tc.expected: OK.
2027      */
2028     int64_t paddingSize = 50;
2029     int cloudCount = 50;
2030     InsertCloudTableRecord(0, cloudCount, paddingSize, false);
2031     /**
2032      * @tc.steps: step3. call Sync with cloud merge strategy.
2033      * @tc.expected: OK.
2034      */
2035     g_virtualAssetLoader->SetDownloadStatus(CLOUD_ASSET_SPACE_INSUFFICIENT);
2036     CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate);
2037     /**
2038      * @tc.steps: step4. remove device data and check log num.
2039      * @tc.expected: OK.
2040      */
2041     ASSERT_EQ(g_delegate->RemoveDeviceData("", DistributedDB::FLAG_AND_DATA), DBStatus::OK);
2042     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(g_tables[0]) +
2043         " where flag & 0x22 = 0;";
2044     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2045         reinterpret_cast<void *>(50), nullptr), SQLITE_OK);
2046     DropLogicDeletedData(db, g_tables[0], 0);
2047     CloseDb();
2048 }
2049 }
2050 #endif // RELATIONAL_STORE