1 /*
2 * Copyright (c) 2022 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 #ifdef RELATIONAL_STORE
17 #include <gtest/gtest.h>
18
19 #include "distributeddb_tools_unit_test.h"
20 #include "relational_sync_able_storage.h"
21 #include "sqlite_single_relational_storage_engine.h"
22 #include "sqlite_relational_store_connection.h"
23 #include "sqlite_relational_utils.h"
24 #include "sqlite_utils.h"
25
26 using namespace testing::ext;
27 using namespace DistributedDB;
28 using namespace DistributedDBUnitTest;
29 using namespace std;
30
31 namespace {
32 constexpr const char* DB_SUFFIX = ".db";
33 constexpr const char* STORE_ID = "Relational_Store_ID";
34 std::string g_testDir;
35 std::string g_dbDir;
36
37 const std::string NORMAL_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS sync_data(" \
38 "key BLOB NOT NULL UNIQUE," \
39 "value BLOB," \
40 "timestamp INT NOT NULL," \
41 "flag INT NOT NULL," \
42 "device BLOB," \
43 "ori_device BLOB," \
44 "hash_key BLOB PRIMARY KEY NOT NULL," \
45 "w_timestamp INT," \
46 "UNIQUE(device, ori_device));" \
47 "CREATE INDEX key_index ON sync_data (key, flag);";
48 }
49
50 class DistributedDBRelationalSyncableStorageTest : public testing::Test {
51 public:
52 static void SetUpTestCase(void);
53 static void TearDownTestCase(void);
54 void SetUp();
55 void TearDown();
56 };
57
58
SetUpTestCase(void)59 void DistributedDBRelationalSyncableStorageTest::SetUpTestCase(void)
60 {}
61
TearDownTestCase(void)62 void DistributedDBRelationalSyncableStorageTest::TearDownTestCase(void)
63 {}
64
SetUp(void)65 void DistributedDBRelationalSyncableStorageTest::SetUp(void)
66 {
67 DistributedDBToolsUnitTest::PrintTestCaseInfo();
68 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
69 LOGD("Test dir is %s", g_testDir.c_str());
70 g_dbDir = g_testDir + "/";
71 }
72
TearDown(void)73 void DistributedDBRelationalSyncableStorageTest::TearDown(void)
74 {
75 DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
76 }
77
78 /**
79 * @tc.name: SchemaRefTest001
80 * @tc.desc: Test sync interface get schema
81 * @tc.type: FUNC
82 * @tc.require:
83 * @tc.author: xulianhui
84 */
85 HWTEST_F(DistributedDBRelationalSyncableStorageTest, SchemaRefTest001, TestSize.Level1)
86 {
87 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
88 ASSERT_NE(db, nullptr);
89 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
90
91 RelationalDBProperties properties;
92 auto sqliteStorageEngine = std::make_shared<SQLiteSingleRelationalStorageEngine>(properties);
93 RelationalSyncAbleStorage *syncAbleStorage = new RelationalSyncAbleStorage(sqliteStorageEngine);
94
95 static std::atomic<bool> isFinish(false);
96 int getCount = 0;
__anon807314810202() 97 std::thread th([syncAbleStorage, &getCount]() {
98 while (!isFinish.load()) {
99 RelationalSchemaObject schema = syncAbleStorage->GetSchemaInfo();
100 (void)schema.ToSchemaString();
101 getCount++;
102 }
103 });
104
105 RelationalSchemaObject schema;
106 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
107 TableInfo table;
108 SQLiteUtils::AnalysisSchema(db, "sync_data", table);
109 schema.AddRelationalTable(table);
110
111 int setCount = 0;
112 for (; setCount < 1000; setCount++) { // 1000: run times
113 RelationalSchemaObject tmpSchema = schema;
114 sqliteStorageEngine->SetSchema(tmpSchema);
115 }
116
117 isFinish.store(true);
118 th.join();
119
120 LOGD("run round set: %d, get: %d", getCount, setCount);
121
122 RefObject::DecObjRef(syncAbleStorage);
123 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
124 }
125
126 /**
127 * @tc.name: FuncExceptionTest001
128 * @tc.desc: Test the interception expection of the delegate interface when the store is empty.
129 * @tc.type: FUNC
130 * @tc.require:
131 * @tc.author: bty
132 */
133 HWTEST_F(DistributedDBRelationalSyncableStorageTest, FuncExceptionTest001, TestSize.Level1)
134 {
135 auto conn = std::make_shared<SQLiteRelationalStoreConnection>(nullptr);
136 EXPECT_EQ(conn->Close(), -E_INVALID_CONNECTION);
137 EXPECT_EQ(conn->GetIdentifier().size(), 0u);
138 EXPECT_EQ(conn->CreateDistributedTable("", {}), -E_INVALID_CONNECTION);
139 EXPECT_EQ(conn->RemoveDeviceData(), -E_INVALID_CONNECTION);
140
141 #ifdef USE_DISTRIBUTEDB_CLOUD
142 EXPECT_EQ(conn->GetCloudSyncTaskCount(), -1);
143 EXPECT_EQ(conn->DoClean({}), -E_INVALID_CONNECTION);
144 EXPECT_EQ(conn->ClearCloudWatermark({}), -E_INVALID_CONNECTION);
145 EXPECT_EQ(conn->SetCloudDB({}), -E_INVALID_CONNECTION);
146 EXPECT_EQ(conn->PrepareAndSetCloudDbSchema({}), -E_INVALID_CONNECTION);
147 EXPECT_EQ(conn->SetIAssetLoader({}), -E_INVALID_CONNECTION);
148 EXPECT_EQ(conn->SetCloudSyncConfig({}), -E_INVALID_CONNECTION);
149 EXPECT_EQ(conn->Sync({}, {}, 0L), -E_INVALID_CONNECTION);
150 EXPECT_EQ(conn->GetCloudTaskStatus(0u).errCode, DB_ERROR);
151 #endif
152 EXPECT_EQ(conn->RemoveDeviceData({}), -E_INVALID_CONNECTION);
153 std::vector<std::string> devices;
154 Query query;
155 RelationalStoreConnection::SyncInfo syncInfo{devices, {}, nullptr, query, true};
156 EXPECT_EQ(conn->SyncToDevice(syncInfo), -E_INVALID_CONNECTION);
157 EXPECT_EQ(conn->RegisterLifeCycleCallback({}), -E_INVALID_CONNECTION);
158 std::shared_ptr<ResultSet> resultSet = nullptr;
159 EXPECT_EQ(conn->RemoteQuery({}, {}, 0u, resultSet), -E_INVALID_CONNECTION);
160 std::string userId;
161 std::string appId;
162 std::string storeId;
163 EXPECT_EQ(conn->GetStoreInfo(userId, appId, storeId), -E_INVALID_CONNECTION);
164 EXPECT_EQ(conn->SetTrackerTable({}), -E_INVALID_CONNECTION);
165 std::vector<VBucket> records;
166 EXPECT_EQ(conn->ExecuteSql({}, records), -E_INVALID_CONNECTION);
167 EXPECT_EQ(conn->SetReference({}), -E_INVALID_CONNECTION);
168 EXPECT_EQ(conn->CleanTrackerData({}, 0L), -E_INVALID_CONNECTION);
169 PragmaData pragmaData;
170 PragmaCmd cmd = AUTO_SYNC;
171 EXPECT_EQ(conn->Pragma(cmd, pragmaData), -E_INVALID_CONNECTION);
172 EXPECT_EQ(conn->UpsertData({}, {}, {}), -E_INVALID_CONNECTION);
173 EXPECT_EQ(conn->SetDistributedDbSchema({}, false), -E_INVALID_CONNECTION);
174 int32_t count;
175 EXPECT_EQ(conn->GetDownloadingAssetsCount(count), -E_INVALID_CONNECTION);
176 EXPECT_EQ(conn->SetTableMode({}), -E_INVALID_CONNECTION);
177 EXPECT_EQ(conn->OperateDataStatus(0u), -E_INVALID_CONNECTION);
178 conn = nullptr;
179 }
180
181 /**
182 * @tc.name: FuncExceptionTest002
183 * @tc.desc: Test the interception expection of the delegate interface when the store is empty.
184 * @tc.type: FUNC
185 * @tc.require:
186 * @tc.author: bty
187 */
188 HWTEST_F(DistributedDBRelationalSyncableStorageTest, FuncExceptionTest002, TestSize.Level1)
189 {
190 sqlite3 *db = nullptr;
191 int64_t timeOffset;
192 EXPECT_EQ(SQLiteRelationalUtils::GetExistedDataTimeOffset(db, {}, false, timeOffset), -E_INVALID_DB);
193 std::unique_ptr<SqliteLogTableManager> logMgrPtr = nullptr;
194 SQLiteRelationalUtils::GenLogParam param;
195 param.db = db;
196 EXPECT_EQ(SQLiteRelationalUtils::GeneLogInfoForExistedData({}, {}, logMgrPtr, param), -E_INVALID_DB);
197 EXPECT_EQ(SQLiteRelationalUtils::SetLogTriggerStatus(db, false), -E_INVALID_DB);
198 EXPECT_EQ(SQLiteRelationalUtils::InitCursorToMeta(db, false, {}), -E_INVALID_DB);
199 EXPECT_EQ(SQLiteRelationalUtils::PutKvData(db, false, {}, {}), -E_INVALID_DB);
200 Value value;
201 EXPECT_EQ(SQLiteRelationalUtils::GetKvData(db, false, {}, value), -E_INVALID_DB);
202 EXPECT_EQ(SQLiteRelationalUtils::CreateRelationalMetaTable(db), -E_INVALID_DB);
203 EXPECT_EQ(SQLiteRelationalUtils::GetCurrentVirtualTime(db).first, -E_INVALID_DB);
204 int64_t tOffset;
205 EXPECT_EQ(SQLiteRelationalUtils::GetMetaLocalTimeOffset(db, tOffset), -E_INVALID_DB);
206 EXPECT_EQ(SQLiteRelationalUtils::OperateDataStatus(db, {}, 0), E_OK);
207 uint64_t cursor;
208 EXPECT_EQ(SQLiteRelationalUtils::GetCursor(db, {}, cursor), -E_INVALID_DB);
209 int64_t count;
210 EXPECT_EQ(SQLiteRelationalUtils::QueryCount(db, {}, count), -E_INVALID_DB);
211
212 LogInfo logInfo;
213 EXPECT_EQ(SQLiteRelationalUtils::GetLogInfoPre(nullptr, {}, {}, logInfo), -E_INVALID_ARGS);
214 DistributedSchema schema;
215 schema.tables.push_back({STORE_ID, {}});
216 schema.tables.push_back({STORE_ID, {}});
217 EXPECT_NE(SQLiteRelationalUtils::FilterRepeatDefine(schema).tables.size(), 0u);
218 EXPECT_EQ(SQLiteRelationalUtils::CheckDistributedSchemaValid({}, {}, false, nullptr), -E_INVALID_ARGS);
219 auto executor =
220 std::make_shared<SQLiteSingleVerRelationalStorageExecutor>(db, true, DistributedTableMode::COLLABORATION);
221 EXPECT_EQ(SQLiteRelationalUtils::CheckDistributedSchemaValid({}, {}, false, executor.get()), -E_NOT_FOUND);
222 int32_t localCount = 0;
223 EXPECT_EQ(executor->GetFlagIsLocalCount("tableName", localCount), -E_INVALID_DB);
224 }
225 #endif // RELATIONAL_STORE
226