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 "mock_asset_loader.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 string g_storeID = "Relational_Store_SYNC"; 43 const string g_tableName = "worker"; 44 const string DB_SUFFIX = ".db"; 45 const string CLOUD = "cloud"; 46 string g_testDir; 47 string g_storePath; 48 std::shared_ptr<VirtualCloudDb> g_virtualCloudDb; 49 std::shared_ptr<VirtualAssetLoader> g_virtualAssetLoader; 50 RelationalStoreObserverUnitTest *g_observer = nullptr; 51 RelationalStoreDelegate *g_delegate = nullptr; 52 const std::vector<std::string> g_tables = {g_tableName}; 53 const std::string CREATE_LOCAL_TABLE_COMPOUND_PRIMARY_KEY_SQL = 54 "CREATE TABLE IF NOT EXISTS " + g_tableName + "(" \ 55 "name TEXT," \ 56 "height REAL ," \ 57 "married BOOLEAN ," \ 58 "photo BLOB NOT NULL," \ 59 "asset BLOB," \ 60 "age INT," \ 61 "PRIMARY KEY (" \ 62 " name," \ 63 " age)" \ 64 ");"; 65 const std::vector<Field> g_cloudFiledCompoundPrimaryKey = { 66 {"name", TYPE_INDEX<std::string>, true}, {"height", TYPE_INDEX<double>}, 67 {"married", TYPE_INDEX<bool>}, {"photo", TYPE_INDEX<Bytes>, false, false}, 68 {"asset", TYPE_INDEX<Asset>}, {"age", TYPE_INDEX<int64_t>, true} 69 }; 70 InitExpectChangedData(ChangedDataType dataType,int64_t count,ChangeType changeType)71 void InitExpectChangedData(ChangedDataType dataType, int64_t count, ChangeType changeType) 72 { 73 ChangedData changedDataForTable; 74 changedDataForTable.tableName = g_tableName; 75 changedDataForTable.type = dataType; 76 changedDataForTable.field.push_back(std::string("rowid")); 77 changedDataForTable.field.push_back(std::string("name")); 78 changedDataForTable.field.push_back(std::string("age")); 79 for (int64_t i = 0; i < count; ++i) { 80 changedDataForTable.primaryData[changeType].push_back({i + 1, 81 "Cloud" + to_string(i), 13L}); // 13 is expect age 82 } 83 g_observer->SetExpectedResult(changedDataForTable); 84 } 85 86 class DistributedDBCloudTableCompoundPrimaryKeySyncTest : public testing::Test { 87 public: 88 static void SetUpTestCase(void); 89 static void TearDownTestCase(void); 90 void SetUp(); 91 void TearDown(); 92 protected: 93 sqlite3 *db = nullptr; 94 }; 95 SetUpTestCase(void)96 void DistributedDBCloudTableCompoundPrimaryKeySyncTest::SetUpTestCase(void) 97 { 98 DistributedDBToolsUnitTest::TestDirInit(g_testDir); 99 g_storePath = g_testDir + "/" + g_storeID + DB_SUFFIX; 100 LOGI("The test db is:%s", g_testDir.c_str()); 101 RuntimeConfig::SetCloudTranslate(std::make_shared<VirtualCloudDataTranslate>()); 102 } 103 TearDownTestCase(void)104 void DistributedDBCloudTableCompoundPrimaryKeySyncTest::TearDownTestCase(void) 105 {} 106 SetUp(void)107 void DistributedDBCloudTableCompoundPrimaryKeySyncTest::SetUp(void) 108 { 109 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { 110 LOGE("rm test db files error."); 111 } 112 DistributedDBToolsUnitTest::PrintTestCaseInfo(); 113 LOGD("Test dir is %s", g_testDir.c_str()); 114 db = RelationalTestUtils::CreateDataBase(g_storePath); 115 ASSERT_NE(db, nullptr); 116 CloudDBSyncUtilsTest::CreateUserDBAndTable(db, CREATE_LOCAL_TABLE_COMPOUND_PRIMARY_KEY_SQL); 117 CloudDBSyncUtilsTest::SetStorePath(g_storePath); 118 CloudDBSyncUtilsTest::InitSyncUtils(g_cloudFiledCompoundPrimaryKey, g_observer, g_virtualCloudDb, 119 g_virtualAssetLoader, g_delegate); 120 } 121 TearDown(void)122 void DistributedDBCloudTableCompoundPrimaryKeySyncTest::TearDown(void) 123 { 124 CloudDBSyncUtilsTest::CloseDb(g_observer, g_virtualCloudDb, g_delegate); 125 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); 126 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { 127 LOGE("rm test db files error."); 128 } 129 } 130 131 /* 132 * @tc.name: CloudSyncTest001 133 * @tc.desc: test data sync when cloud insert 134 * @tc.type: FUNC 135 * @tc.require: 136 * @tc.author: chenchaohao 137 */ 138 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest001, TestSize.Level0) 139 { 140 /** 141 * @tc.steps:step1. insert cloud data and merge 142 * @tc.expected: step1. check the changeddata and return ok 143 */ 144 int64_t cloudCount = 10; // 10 is random cloud count 145 int64_t paddingSize = 10; // 10 is padding size 146 InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_INSERT); 147 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); 148 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 149 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 150 g_observer->ClearChangedData(); 151 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 152 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 153 } 154 155 /* 156 * @tc.name: CloudSyncTest002 157 * @tc.desc: test data sync when cloud update 158 * @tc.type: FUNC 159 * @tc.require: 160 * @tc.author: chenchaohao 161 */ 162 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest002, TestSize.Level0) 163 { 164 /** 165 * @tc.steps:step1. insert cloud data and merge 166 * @tc.expected: step1. check the changeddata and return ok 167 */ 168 int64_t cloudCount = 10; // 10 is random cloud count 169 int64_t paddingSize = 10; // 10 is padding size 170 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); 171 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 172 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 173 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 174 175 /** 176 * @tc.steps:step2. update cloud data and merge 177 * @tc.expected: step2. check the changeddata and return ok 178 */ 179 InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_UPDATE); 180 CloudDBSyncUtilsTest::UpdateCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); 181 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 182 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 183 g_observer->ClearChangedData(); 184 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 185 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 186 } 187 188 /* 189 * @tc.name: CloudSyncTest003 190 * @tc.desc: test data sync when cloud delete 191 * @tc.type: FUNC 192 * @tc.require: 193 * @tc.author: chenchaohao 194 */ 195 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest003, TestSize.Level0) 196 { 197 /** 198 * @tc.steps:step1. insert cloud data and merge 199 * @tc.expected: step1. check the changeddata and return ok 200 */ 201 int64_t cloudCount = 10; // 10 is random cloud count 202 int64_t paddingSize = 10; // 10 is padding size 203 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); 204 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 205 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 206 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 207 208 /** 209 * @tc.steps:step2. delete cloud data and merge 210 * @tc.expected: step2. check the changeddata and return ok 211 */ 212 InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_DELETE); 213 CloudDBSyncUtilsTest::DeleteCloudTableRecordByGid(0, cloudCount, g_virtualCloudDb); 214 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 215 CloudDBSyncUtilsTest::CheckCloudTotalCount({0L}, g_virtualCloudDb); 216 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 217 g_observer->ClearChangedData(); 218 CloudDBSyncUtilsTest::CheckLocalRecordNum(db, g_tableName, 0); 219 } 220 221 /* 222 * @tc.name: CloudSyncTest004 223 * @tc.desc: test asset when cloud insert 224 * @tc.type: FUNC 225 * @tc.require: 226 * @tc.author: chenchaohao 227 */ 228 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest004, TestSize.Level0) 229 { 230 /** 231 * @tc.steps:step1. insert cloud asset and merge 232 * @tc.expected: step1. check the changeddata and return ok 233 */ 234 int64_t cloudCount = 10; // 10 is random cloud count 235 int64_t paddingSize = 10; // 10 is padding size 236 InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_INSERT); 237 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); 238 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 239 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 240 g_observer->ClearChangedData(); 241 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 242 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 243 } 244 245 /* 246 * @tc.name: CloudSyncTest005 247 * @tc.desc: test asset sync when cloud insert 248 * @tc.type: FUNC 249 * @tc.require: 250 * @tc.author: chenchaohao 251 */ 252 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest005, TestSize.Level0) 253 { 254 /** 255 * @tc.steps:step1. insert cloud asset and merge 256 * @tc.expected: step1. check the changeddata and return ok 257 */ 258 int64_t cloudCount = 10; // 10 is random cloud count 259 int64_t paddingSize = 10; // 10 is padding size 260 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); 261 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 262 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 263 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 264 265 /** 266 * @tc.steps:step2. update cloud asset and merge 267 * @tc.expected: step2. check the changeddata and return ok 268 */ 269 InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_UPDATE); 270 CloudDBSyncUtilsTest::UpdateCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); 271 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 272 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 273 g_observer->ClearChangedData(); 274 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 275 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 276 } 277 278 /* 279 * @tc.name: CloudSyncTest006 280 * @tc.desc: test asset sync when cloud delete 281 * @tc.type: FUNC 282 * @tc.require: 283 * @tc.author: chenchaohao 284 */ 285 HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest006, TestSize.Level0) 286 { 287 /** 288 * @tc.steps:step1. insert cloud asset and merge 289 * @tc.expected: step1. check the changeddata and return ok 290 */ 291 int64_t cloudCount = 10; // 10 is random cloud count 292 int64_t paddingSize = 10; // 10 is padding size 293 CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); 294 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 295 CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); 296 CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); 297 298 /** 299 * @tc.steps:step2. insert cloud asset and merge 300 * @tc.expected: step2. check the changeddata and return ok 301 */ 302 InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_DELETE); 303 CloudDBSyncUtilsTest::DeleteCloudTableRecordByGid(0, cloudCount, g_virtualCloudDb); 304 CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); 305 CloudDBSyncUtilsTest::CheckCloudTotalCount({0L}, g_virtualCloudDb); 306 EXPECT_TRUE(g_observer->IsAllChangedDataEq()); 307 g_observer->ClearChangedData(); 308 CloudDBSyncUtilsTest::CheckLocalRecordNum(db, g_tableName, 0); 309 } 310 311 } 312 #endif // RELATIONAL_STORE