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