• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "cloud_db_types.h"
18 #include "distributeddb_data_generate_unit_test.h"
19 #include "log_print.h"
20 #include "relational_store_delegate.h"
21 #include "relational_store_manager.h"
22 #include "runtime_config.h"
23 #include "virtual_asset_loader.h"
24 #include "virtual_cloud_data_translate.h"
25 #include "virtual_cloud_db.h"
26 namespace {
27 using namespace testing::ext;
28 using namespace DistributedDB;
29 using namespace DistributedDBUnitTest;
30 const char *g_createSQL =
31     "CREATE TABLE IF NOT EXISTS DistributedDBCloudCheckSyncTest(" \
32     "id TEXT PRIMARY KEY," \
33     "name TEXT," \
34     "height REAL ," \
35     "photo BLOB," \
36     "age INT);";
37 const int64_t g_syncWaitTime = 60;
38 
CreateUserDBAndTable(sqlite3 * & db)39 void CreateUserDBAndTable(sqlite3 *&db)
40 {
41     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
42     EXPECT_EQ(RelationalTestUtils::ExecSql(db, g_createSQL), SQLITE_OK);
43 }
44 
BlockSync(const Query & query,RelationalStoreDelegate * delegate)45 void BlockSync(const Query &query, RelationalStoreDelegate *delegate)
46 {
47     std::mutex dataMutex;
48     std::condition_variable cv;
49     bool finish = false;
50     auto callback = [&cv, &dataMutex, &finish](const std::map<std::string, SyncProcess> &process) {
51         for (const auto &item: process) {
52             if (item.second.process == DistributedDB::FINISHED) {
53                 {
54                     std::lock_guard<std::mutex> autoLock(dataMutex);
55                     finish = true;
56                 }
57                 cv.notify_one();
58             }
59         }
60     };
61     ASSERT_EQ(delegate->Sync({ "CLOUD" }, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), OK);
62     std::unique_lock<std::mutex> uniqueLock(dataMutex);
63     cv.wait(uniqueLock, [&finish]() {
64         return finish;
65     });
66 }
67 
68 class DistributedDBCloudCheckSyncTest : public testing::Test {
69 public:
70     static void SetUpTestCase();
71     static void TearDownTestCase();
72     void SetUp() override;
73     void TearDown() override;
74 protected:
75     void InitTestDir();
76     DataBaseSchema GetSchema();
77     void CloseDb();
78     void InsertUserTableRecord(int64_t recordCounts, int64_t begin = 0);
79     std::string testDir_;
80     std::string storePath_;
81     sqlite3 *db_ = nullptr;
82     RelationalStoreDelegate *delegate_ = nullptr;
83     std::shared_ptr<VirtualCloudDb> virtualCloudDb_ = nullptr;
84     std::shared_ptr<VirtualAssetLoader> virtualAssetLoader_ = nullptr;
85     std::shared_ptr<RelationalStoreManager> mgr_ = nullptr;
86     std::string tableName_ = "DistributedDBCloudCheckSyncTest";
87 };
88 
SetUpTestCase()89 void DistributedDBCloudCheckSyncTest::SetUpTestCase()
90 {
91     RuntimeConfig::SetCloudTranslate(std::make_shared<VirtualCloudDataTranslate>());
92 }
93 
TearDownTestCase()94 void DistributedDBCloudCheckSyncTest::TearDownTestCase()
95 {}
96 
SetUp()97 void DistributedDBCloudCheckSyncTest::SetUp()
98 {
99     DistributedDBToolsUnitTest::PrintTestCaseInfo();
100     InitTestDir();
101     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(testDir_) != 0) {
102         LOGE("rm test db files error.");
103     }
104     DistributedDBToolsUnitTest::PrintTestCaseInfo();
105     LOGD("Test dir is %s", testDir_.c_str());
106     db_ = RelationalTestUtils::CreateDataBase(storePath_);
107     ASSERT_NE(db_, nullptr);
108     CreateUserDBAndTable(db_);
109     mgr_ = std::make_shared<RelationalStoreManager>(APP_ID, USER_ID);
110     RelationalStoreDelegate::Option option;
111     ASSERT_EQ(mgr_->OpenStore(storePath_, STORE_ID_1, option, delegate_), DBStatus::OK);
112     ASSERT_NE(delegate_, nullptr);
113     ASSERT_EQ(delegate_->CreateDistributedTable(tableName_, CLOUD_COOPERATION), DBStatus::OK);
114     virtualCloudDb_ = std::make_shared<VirtualCloudDb>();
115     virtualAssetLoader_ = std::make_shared<VirtualAssetLoader>();
116     ASSERT_EQ(delegate_->SetCloudDB(virtualCloudDb_), DBStatus::OK);
117     ASSERT_EQ(delegate_->SetIAssetLoader(virtualAssetLoader_), DBStatus::OK);
118     DataBaseSchema dataBaseSchema = GetSchema();
119     ASSERT_EQ(delegate_->SetCloudDbSchema(dataBaseSchema), DBStatus::OK);
120 }
121 
TearDown()122 void DistributedDBCloudCheckSyncTest::TearDown()
123 {
124     CloseDb();
125     EXPECT_EQ(sqlite3_close_v2(db_), SQLITE_OK);
126     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(testDir_) != 0) {
127         LOGE("rm test db files error.");
128     }
129 }
130 
InitTestDir()131 void DistributedDBCloudCheckSyncTest::InitTestDir()
132 {
133     if (!testDir_.empty()) {
134         return;
135     }
136     DistributedDBToolsUnitTest::TestDirInit(testDir_);
137     storePath_ = testDir_ + "/" + STORE_ID_1 + ".db";
138     LOGI("The test db is:%s", testDir_.c_str());
139 }
140 
GetSchema()141 DataBaseSchema DistributedDBCloudCheckSyncTest::GetSchema()
142 {
143     DataBaseSchema schema;
144     TableSchema tableSchema;
145     tableSchema.name = tableName_;
146     tableSchema.fields = {
147         {"id", TYPE_INDEX<std::string>, true}, {"name", TYPE_INDEX<std::string>}, {"height", TYPE_INDEX<double>},
148         {"photo", TYPE_INDEX<Bytes>}, {"age", TYPE_INDEX<int64_t>}
149     };
150     schema.tables.push_back(tableSchema);
151     return schema;
152 }
153 
CloseDb()154 void DistributedDBCloudCheckSyncTest::CloseDb()
155 {
156     virtualCloudDb_ = nullptr;
157     EXPECT_EQ(mgr_->CloseStore(delegate_), DBStatus::OK);
158     delegate_ = nullptr;
159     mgr_ = nullptr;
160 }
161 
InsertUserTableRecord(int64_t recordCounts,int64_t begin)162 void DistributedDBCloudCheckSyncTest::InsertUserTableRecord(int64_t recordCounts, int64_t begin)
163 {
164     ASSERT_NE(db_, nullptr);
165     for (int64_t i = begin; i < recordCounts; ++i) {
166         string sql = "INSERT OR REPLACE INTO " + tableName_
167             + " (id, name, height, photo, age) VALUES ('" + std::to_string(i) + "', 'Local"
168             + std::to_string(i) + "', '155.10',  'text', '21');";
169         ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK);
170     }
171 }
172 
173 /**
174  * @tc.name: CloudSyncTest001
175  * @tc.desc: sync with device sync query
176  * @tc.type: FUNC
177  * @tc.require:
178  * @tc.author: zhangqiquan
179  */
180 HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncTest001, TestSize.Level0)
181 {
182     // prepare data
183     const int actualCount = 10;
184     InsertUserTableRecord(actualCount);
185     // sync twice
186     Query query = Query::Select().FromTable({ tableName_ });
187     BlockSync(query, delegate_);
188     BlockSync(query, delegate_);
189     // remove cloud data
190     delegate_->RemoveDeviceData("CLOUD", ClearMode::FLAG_AND_DATA);
191     // check local data
192     int dataCnt = -1;
193     std::string checkLogSql = "SELECT count(*) FROM " + tableName_;
__anon06c51c050402(sqlite3_stmt *stmt) 194     RelationalTestUtils::ExecSql(db_, checkLogSql, nullptr, [&dataCnt](sqlite3_stmt *stmt) {
195         dataCnt = sqlite3_column_int(stmt, 0);
196         return E_OK;
197     });
198     EXPECT_EQ(dataCnt, actualCount);
199 }
200 }
201 #endif