1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifdef RELATIONAL_STORE 16 #include <gtest/gtest.h> 17 #include <iostream> 18 #include "cloud/cloud_storage_utils.h" 19 #include "cloud/cloud_db_constant.h" 20 #include "distributeddb_data_generate_unit_test.h" 21 #include "distributeddb_tools_unit_test.h" 22 #include "process_system_api_adapter_impl.h" 23 #include "relational_store_instance.h" 24 #include "relational_store_manager.h" 25 #include "runtime_config.h" 26 #include "sqlite_relational_store.h" 27 #include "sqlite_relational_utils.h" 28 #include "store_observer.h" 29 #include "time_helper.h" 30 #include "virtual_asset_loader.h" 31 #include "virtual_cloud_data_translate.h" 32 #include "virtual_cloud_db.h" 33 #include "virtual_communicator_aggregator.h" 34 #include "mock_asset_loader.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 string g_storeID = "Relational_Store_SYNC"; 44 const string g_tableName = "worker"; 45 const string DB_SUFFIX = ".db"; 46 const string CLOUD = "cloud"; 47 string g_testDir; 48 string g_storePath; 49 std::shared_ptr<VirtualCloudDb> g_virtualCloudDb; 50 std::shared_ptr<VirtualAssetLoader> g_virtualAssetLoader; 51 RelationalStoreObserverUnitTest *g_observer = nullptr; 52 RelationalStoreDelegate *g_delegate = nullptr; 53 const std::vector<std::string> g_tables = {g_tableName}; 54 const std::string CREATE_LOCAL_TABLE_COMPOUND_PRIMARY_KEY_SQL = 55 "CREATE TABLE IF NOT EXISTS " + g_tableName + "(" \ 56 "name TEXT," \ 57 "height REAL ," \ 58 "married BOOLEAN ," \ 59 "photo BLOB NOT NULL," \ 60 "asset BLOB," \ 61 "age INT," \ 62 "PRIMARY KEY (" \ 63 " name," \ 64 " age)" \ 65 ");"; 66 const std::vector<Field> g_cloudFiledCompoundPrimaryKey = { 67 {"name", TYPE_INDEX<std::string>, true}, {"height", TYPE_INDEX<double>}, 68 {"married", TYPE_INDEX<bool>}, {"photo", TYPE_INDEX<Bytes>, false, false}, 69 {"asset", TYPE_INDEX<Asset>}, {"age", TYPE_INDEX<int64_t>, true} 70 }; 71 InitExpectChangedData(ChangedDataType dataType,int64_t count,ChangeType changeType)72 void InitExpectChangedData(ChangedDataType dataType, int64_t count, ChangeType changeType) 73 { 74 ChangedData changedDataForTable; 75 changedDataForTable.tableName = g_tableName; 76 changedDataForTable.type = dataType; 77 changedDataForTable.field.push_back(std::string("rowid")); 78 changedDataForTable.field.push_back(std::string("name")); 79 changedDataForTable.field.push_back(std::string("age")); 80 for (int64_t i = 0; i < count; ++i) { 81 changedDataForTable.primaryData[changeType].push_back({i + 1, 82 "Cloud" + to_string(i), 13L}); // 13 is expect age 83 } 84 g_observer->SetExpectedResult(changedDataForTable); 85 } 86 87 class DistributedDBCloudTableCompoundPrimaryKeySyncTest : public testing::Test { 88 public: 89 static void SetUpTestCase(void); 90 static void TearDownTestCase(void); 91 void SetUp(); 92 void TearDown(); 93 protected: 94 sqlite3 *db = nullptr; 95 VirtualCommunicatorAggregator *communicatorAggregator_ = nullptr; 96 }; 97 SetUpTestCase(void)98 void DistributedDBCloudTableCompoundPrimaryKeySyncTest::SetUpTestCase(void) 99 { 100 DistributedDBToolsUnitTest::TestDirInit(g_testDir); 101 g_storePath = g_testDir + "/" + g_storeID + DB_SUFFIX; 102 LOGI("The test db is:%s", g_testDir.c_str()); 103 RuntimeConfig::SetCloudTranslate(std::make_shared<VirtualCloudDataTranslate>()); 104 } 105 TearDownTestCase(void)106 void DistributedDBCloudTableCompoundPrimaryKeySyncTest::TearDownTestCase(void) 107 {} 108 SetUp(void)109 void DistributedDBCloudTableCompoundPrimaryKeySyncTest::SetUp(void) 110 { 111 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { 112 LOGE("rm test db files error."); 113 } 114 DistributedDBToolsUnitTest::PrintTestCaseInfo(); 115 LOGD("Test dir is %s", g_testDir.c_str()); 116 db = RelationalTestUtils::CreateDataBase(g_storePath); 117 ASSERT_NE(db, nullptr); 118 CloudDBSyncUtilsTest::CreateUserDBAndTable(db, CREATE_LOCAL_TABLE_COMPOUND_PRIMARY_KEY_SQL); 119 CloudDBSyncUtilsTest::SetStorePath(g_storePath); 120 CloudDBSyncUtilsTest::InitSyncUtils(g_cloudFiledCompoundPrimaryKey, g_observer, g_virtualCloudDb, 121 g_virtualAssetLoader, g_delegate); 122 communicatorAggregator_ = new (std::nothrow) VirtualCommunicatorAggregator(); 123 ASSERT_TRUE(communicatorAggregator_ != nullptr); 124 RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicatorAggregator_); 125 } 126 TearDown(void)127 void DistributedDBCloudTableCompoundPrimaryKeySyncTest::TearDown(void) 128 { 129 CloudDBSyncUtilsTest::CloseDb(g_observer, g_virtualCloudDb, g_delegate); 130 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 131 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { 132 LOGE("rm test db files error."); 133 } 134 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); 135 communicatorAggregator_ = nullptr; 136 RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr); 137 } 138 139 /* 140 * @tc.name: CloudSyncTest001 141 * @tc.desc: test data sync when cloud insert 142 * @tc.type: FUNC 143 * @tc.require: 144 * @tc.author: chenchaohao 145 */ 146 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest001, TestSize.Level0) 147 { 148 /** 149 * @tc.steps:step1. insert cloud data and merge 150 * @tc.expected: step1. check the changeddata and return ok 151 */ 152 int64_t cloudCount = 10; // 10 is random cloud count 153 int64_t paddingSize = 10; // 10 is padding size 154 InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_INSERT); 155 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); 156 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 157 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 158 g_observer->ClearChangedData(); 159 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 160 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 161 } 162 163 /* 164 * @tc.name: CloudSyncTest002 165 * @tc.desc: test data sync when cloud update 166 * @tc.type: FUNC 167 * @tc.require: 168 * @tc.author: chenchaohao 169 */ 170 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest002, TestSize.Level0) 171 { 172 /** 173 * @tc.steps:step1. insert cloud data and merge 174 * @tc.expected: step1. check the changeddata and return ok 175 */ 176 int64_t cloudCount = 10; // 10 is random cloud count 177 int64_t paddingSize = 10; // 10 is padding size 178 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); 179 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 180 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 181 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 182 183 /** 184 * @tc.steps:step2. update cloud data and merge 185 * @tc.expected: step2. check the changeddata and return ok 186 */ 187 InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_UPDATE); 188 CloudDBSyncUtilsTest::UpdateCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); 189 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 190 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 191 g_observer->ClearChangedData(); 192 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 193 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 194 } 195 196 /* 197 * @tc.name: CloudSyncTest003 198 * @tc.desc: test data sync when cloud delete 199 * @tc.type: FUNC 200 * @tc.require: 201 * @tc.author: chenchaohao 202 */ 203 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest003, TestSize.Level0) 204 { 205 /** 206 * @tc.steps:step1. insert cloud data and merge 207 * @tc.expected: step1. check the changeddata and return ok 208 */ 209 int64_t cloudCount = 10; // 10 is random cloud count 210 int64_t paddingSize = 10; // 10 is padding size 211 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); 212 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 213 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 214 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 215 216 /** 217 * @tc.steps:step2. delete cloud data and merge 218 * @tc.expected: step2. check the changeddata and return ok 219 */ 220 InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_DELETE); 221 CloudDBSyncUtilsTest::DeleteCloudTableRecordByGid(0, cloudCount, g_virtualCloudDb); 222 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 223 CloudDBSyncUtilsTest::CheckCloudTotalCount({0L}, g_virtualCloudDb); 224 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 225 g_observer->ClearChangedData(); 226 CloudDBSyncUtilsTest::CheckLocalRecordNum(db, g_tableName, 0); 227 } 228 229 /* 230 * @tc.name: CloudSyncTest004 231 * @tc.desc: test asset when cloud insert 232 * @tc.type: FUNC 233 * @tc.require: 234 * @tc.author: chenchaohao 235 */ 236 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest004, TestSize.Level0) 237 { 238 /** 239 * @tc.steps:step1. insert cloud asset and merge 240 * @tc.expected: step1. check the changeddata and return ok 241 */ 242 int64_t cloudCount = 10; // 10 is random cloud count 243 int64_t paddingSize = 10; // 10 is padding size 244 InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_INSERT); 245 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); 246 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 247 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 248 g_observer->ClearChangedData(); 249 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 250 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 251 } 252 253 /* 254 * @tc.name: CloudSyncTest005 255 * @tc.desc: test asset sync when cloud insert 256 * @tc.type: FUNC 257 * @tc.require: 258 * @tc.author: chenchaohao 259 */ 260 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest005, TestSize.Level0) 261 { 262 /** 263 * @tc.steps:step1. insert cloud asset and merge 264 * @tc.expected: step1. check the changeddata and return ok 265 */ 266 int64_t cloudCount = 10; // 10 is random cloud count 267 int64_t paddingSize = 10; // 10 is padding size 268 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); 269 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 270 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 271 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 272 273 /** 274 * @tc.steps:step2. update cloud asset and merge 275 * @tc.expected: step2. check the changeddata and return ok 276 */ 277 InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_UPDATE); 278 CloudDBSyncUtilsTest::UpdateCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); 279 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 280 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 281 g_observer->ClearChangedData(); 282 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 283 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 284 } 285 286 /* 287 * @tc.name: CloudSyncTest006 288 * @tc.desc: test asset sync when cloud delete 289 * @tc.type: FUNC 290 * @tc.require: 291 * @tc.author: chenchaohao 292 */ 293 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest006, TestSize.Level0) 294 { 295 /** 296 * @tc.steps:step1. insert cloud asset and merge 297 * @tc.expected: step1. check the changeddata and return ok 298 */ 299 int64_t cloudCount = 10; // 10 is random cloud count 300 int64_t paddingSize = 10; // 10 is padding size 301 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); 302 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 303 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 304 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 305 306 /** 307 * @tc.steps:step2. insert cloud asset and merge 308 * @tc.expected: step2. check the changeddata and return ok 309 */ 310 InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_DELETE); 311 CloudDBSyncUtilsTest::DeleteCloudTableRecordByGid(0, cloudCount, g_virtualCloudDb); 312 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 313 CloudDBSyncUtilsTest::CheckCloudTotalCount({0L}, g_virtualCloudDb); 314 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 315 g_observer->ClearChangedData(); 316 CloudDBSyncUtilsTest::CheckLocalRecordNum(db, g_tableName, 0); 317 } 318 319 } 320 #endif // RELATIONAL_STORE