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