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