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 #include <gtest/gtest.h>
17
18 #include "distributeddb_tools_unit_test.h"
19 #include "native_sqlite.h"
20 #include "platform_specific.h"
21 #include "sqlite_import.h"
22 #include "sqlite_log_table_manager.h"
23
24 using namespace testing::ext;
25 using namespace DistributedDB;
26 using namespace DistributedDBUnitTest;
27 using namespace std;
28
29 namespace {
30 string g_testDir;
31 string g_dbDir;
32 sqlite3 *g_db = nullptr;
33
34 const int MAX_BLOB_READ_SIZE = 64 * 1024 * 1024; // 64M limit
35 const int MAX_TEXT_READ_SIZE = 5 * 1024 * 1024; // 5M limit
36 }
37
38 class DistributedDBSqliteUtilsTest : public testing::Test {
39 public:
40 static void SetUpTestCase(void);
41 static void TearDownTestCase(void);
42 void SetUp();
43 void TearDown();
44 };
45
SetUpTestCase(void)46 void DistributedDBSqliteUtilsTest::SetUpTestCase(void)
47 {
48 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
49 LOGI("The test db is:%s", g_testDir.c_str());
50 g_dbDir = g_testDir + "/";
51 }
52
TearDownTestCase(void)53 void DistributedDBSqliteUtilsTest::TearDownTestCase(void)
54 {
55 }
56
SetUp()57 void DistributedDBSqliteUtilsTest::SetUp()
58 {
59 DistributedDBToolsUnitTest::PrintTestCaseInfo();
60
61 g_db = NativeSqlite::CreateDataBase(g_dbDir + "test.db");
62 }
63
TearDown()64 void DistributedDBSqliteUtilsTest::TearDown()
65 {
66 sqlite3_close_v2(g_db);
67 g_db = nullptr;
68 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
69 LOGE("rm test db files error.");
70 }
71 }
72
73 /**
74 * @tc.name: GetBlobTest001
75 * @tc.desc: Get blob size over limit
76 * @tc.type: FUNC
77 * @tc.require:
78 * @tc.author: lianhuix
79 */
80 HWTEST_F(DistributedDBSqliteUtilsTest, GetBlobTest001, TestSize.Level1)
81 {
82 NativeSqlite::ExecSql(g_db, "CREATE TABLE IF NOT EXISTS t1 (a INT, b BLOB);");
83
84 vector<uint8_t> blob;
85 blob.resize(MAX_BLOB_READ_SIZE + 2); // 2: over limit
86 std::fill(blob.begin(), blob.end(), static_cast<uint8_t>('a'));
87
__anonac7fc7d20202(sqlite3_stmt *stmt) 88 NativeSqlite::ExecSql(g_db, "INSERT INTO t1 VALUES(?, ?)", [&blob](sqlite3_stmt *stmt) {
89 (void)SQLiteUtils::BindInt64ToStatement(stmt, 1, 1);
90 (void)SQLiteUtils::BindBlobToStatement(stmt, 2, blob); // 2: bind index
91 return E_OK;
92 }, nullptr);
93
__anonac7fc7d20302(sqlite3_stmt *stmt) 94 NativeSqlite::ExecSql(g_db, "SELECT b FROM t1", nullptr, [](sqlite3_stmt *stmt) {
95 Value val;
96 EXPECT_EQ(SQLiteUtils::GetColumnBlobValue(stmt, 0, val), E_OK);
97 EXPECT_EQ(static_cast<int>(val.size()), MAX_BLOB_READ_SIZE + 1);
98 return E_OK;
99 });
100 }
101
102 /**
103 * @tc.name: GetBlobTest002
104 * @tc.desc: Get blob size equal limit
105 * @tc.type: FUNC
106 * @tc.require:
107 * @tc.author: lianhuix
108 */
109 HWTEST_F(DistributedDBSqliteUtilsTest, GetBlobTest002, TestSize.Level1)
110 {
111 NativeSqlite::ExecSql(g_db, "CREATE TABLE IF NOT EXISTS t1 (a INT, b BLOB);");
112
113 vector<uint8_t> blob;
114 blob.resize(MAX_BLOB_READ_SIZE);
115 std::fill(blob.begin(), blob.end(), static_cast<uint8_t>('a'));
116
__anonac7fc7d20402(sqlite3_stmt *stmt) 117 NativeSqlite::ExecSql(g_db, "INSERT INTO t1 VALUES(?, ?)", [&blob](sqlite3_stmt *stmt) {
118 (void)SQLiteUtils::BindInt64ToStatement(stmt, 1, 1);
119 (void)SQLiteUtils::BindBlobToStatement(stmt, 2, blob); // 2: bind index
120 return E_OK;
121 }, nullptr);
122
__anonac7fc7d20502(sqlite3_stmt *stmt) 123 NativeSqlite::ExecSql(g_db, "SELECT b FROM t1", nullptr, [&blob](sqlite3_stmt *stmt) {
124 Value val;
125 EXPECT_EQ(SQLiteUtils::GetColumnBlobValue(stmt, 0, val), E_OK);
126 EXPECT_EQ(val, blob);
127 return E_OK;
128 });
129 }
130
131 /**
132 * @tc.name: GetBlobTest003
133 * @tc.desc: Get blob size equal zero
134 * @tc.type: FUNC
135 * @tc.require:
136 * @tc.author: lianhuix
137 */
138 HWTEST_F(DistributedDBSqliteUtilsTest, GetBlobTest003, TestSize.Level1)
139 {
140 NativeSqlite::ExecSql(g_db, "CREATE TABLE IF NOT EXISTS t1 (a INT, b BLOB);");
141
142 vector<uint8_t> blob;
143 blob.resize(0);
144
__anonac7fc7d20602(sqlite3_stmt *stmt) 145 NativeSqlite::ExecSql(g_db, "INSERT INTO t1 VALUES(?, ?)", [&blob](sqlite3_stmt *stmt) {
146 (void)SQLiteUtils::BindInt64ToStatement(stmt, 1, 1);
147 (void)SQLiteUtils::BindBlobToStatement(stmt, 2, blob); // 2: bind index
148 return E_OK;
149 }, nullptr);
150
__anonac7fc7d20702(sqlite3_stmt *stmt) 151 NativeSqlite::ExecSql(g_db, "SELECT b FROM t1", nullptr, [&blob](sqlite3_stmt *stmt) {
152 Value val;
153 EXPECT_EQ(SQLiteUtils::GetColumnBlobValue(stmt, 0, val), E_OK);
154 EXPECT_EQ(val, blob);
155 return E_OK;
156 });
157 }
158
159 /**
160 * @tc.name: GetTextTest001
161 * @tc.desc: Get text size over limit
162 * @tc.type: FUNC
163 * @tc.require:
164 * @tc.author: lianhuix
165 */
166 HWTEST_F(DistributedDBSqliteUtilsTest, GetTextTest001, TestSize.Level1)
167 {
168 NativeSqlite::ExecSql(g_db, "CREATE TABLE IF NOT EXISTS t1 (a INT, b TEXT);");
169
170 std::string text;
171 text.resize(MAX_TEXT_READ_SIZE + 2); // 2: over limit
172 std::fill(text.begin(), text.end(), 'a');
173
__anonac7fc7d20802(sqlite3_stmt *stmt) 174 NativeSqlite::ExecSql(g_db, "INSERT INTO t1 VALUES(?, ?)", [&text](sqlite3_stmt *stmt) {
175 (void)SQLiteUtils::BindInt64ToStatement(stmt, 1, 1);
176 (void)SQLiteUtils::BindTextToStatement(stmt, 2, text); // 2: bind index
177 return E_OK;
178 }, nullptr);
179
__anonac7fc7d20902(sqlite3_stmt *stmt) 180 NativeSqlite::ExecSql(g_db, "SELECT b FROM t1", nullptr, [](sqlite3_stmt *stmt) {
181 std::string val;
182 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, val), E_OK);
183 EXPECT_EQ(static_cast<int>(val.size()), MAX_TEXT_READ_SIZE + 1);
184 return E_OK;
185 });
186 }
187
188 /**
189 * @tc.name: GetTextTest002
190 * @tc.desc: Get text size equal limit
191 * @tc.type: FUNC
192 * @tc.require:
193 * @tc.author: lianhuix
194 */
195 HWTEST_F(DistributedDBSqliteUtilsTest, GetTextTest002, TestSize.Level1)
196 {
197 NativeSqlite::ExecSql(g_db, "CREATE TABLE IF NOT EXISTS t1 (a INT, b TEXT);");
198
199 std::string text;
200 text.resize(MAX_TEXT_READ_SIZE);
201 std::fill(text.begin(), text.end(), 'a');
202
__anonac7fc7d20a02(sqlite3_stmt *stmt) 203 NativeSqlite::ExecSql(g_db, "INSERT INTO t1 VALUES(?, ?)", [&text](sqlite3_stmt *stmt) {
204 (void)SQLiteUtils::BindInt64ToStatement(stmt, 1, 1);
205 (void)SQLiteUtils::BindTextToStatement(stmt, 2, text); // 2: bind index
206 return E_OK;
207 }, nullptr);
208
__anonac7fc7d20b02(sqlite3_stmt *stmt) 209 NativeSqlite::ExecSql(g_db, "SELECT b FROM t1", nullptr, [&text](sqlite3_stmt *stmt) {
210 std::string val;
211 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, val), E_OK);
212 EXPECT_EQ(val, text);
213 return E_OK;
214 });
215 }
216
217 /**
218 * @tc.name: GetTextTest003
219 * @tc.desc: Get text size equal zero
220 * @tc.type: FUNC
221 * @tc.require:
222 * @tc.author: lianhuix
223 */
224 HWTEST_F(DistributedDBSqliteUtilsTest, GetTextTest003, TestSize.Level1)
225 {
226 NativeSqlite::ExecSql(g_db, "CREATE TABLE IF NOT EXISTS t1 (a INT, b TEXT);");
227
228 std::string text;
229 text.resize(0);
230
__anonac7fc7d20c02(sqlite3_stmt *stmt) 231 NativeSqlite::ExecSql(g_db, "INSERT INTO t1 VALUES(?, ?)", [&text](sqlite3_stmt *stmt) {
232 (void)SQLiteUtils::BindInt64ToStatement(stmt, 1, 1);
233 (void)SQLiteUtils::BindTextToStatement(stmt, 2, text); // 2: bind index
234 return E_OK;
235 }, nullptr);
236
__anonac7fc7d20d02(sqlite3_stmt *stmt) 237 NativeSqlite::ExecSql(g_db, "SELECT b FROM t1", nullptr, [&text](sqlite3_stmt *stmt) {
238 std::string val;
239 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, val), E_OK);
240 EXPECT_EQ(val, text);
241 return E_OK;
242 });
243 }
244
245 /**
246 * @tc.name: KVLogUpgrade001
247 * @tc.desc: Get blob size over limit
248 * @tc.type: FUNC
249 * @tc.require:
250 * @tc.author: zhangqiquan
251 */
252 HWTEST_F(DistributedDBSqliteUtilsTest, KVLogUpgrade001, TestSize.Level0)
253 {
254 const std::string tableName = "naturalbase_kv_aux_sync_data_log";
255 const std::string primaryKey = "PRIMARY KEY(userid, hash_key)";
256 std::string createTableSql = "CREATE TABLE IF NOT EXISTS " + tableName + "(" \
257 "userid TEXT NOT NULL," + \
258 "hash_key BLOB NOT NULL," + \
259 "cloud_gid TEXT," + \
260 "version TEXT," + \
261 primaryKey + ");";
262 int errCode = SQLiteUtils::ExecuteRawSQL(g_db, createTableSql);
263 ASSERT_EQ(errCode, E_OK);
264 EXPECT_EQ(SqliteLogTableManager::CreateKvSyncLogTable(g_db), E_OK);
265 }
266
267 /**
268 * @tc.name: BindErr
269 * @tc.desc: Test bind err
270 * @tc.type: FUNC
271 * @tc.require:
272 * @tc.author: lijun
273 */
274 HWTEST_F(DistributedDBSqliteUtilsTest, BindErr, TestSize.Level1)
275 {
276 NativeSqlite::ExecSql(g_db, "CREATE TABLE IF NOT EXISTS t1 (a INT, b TEXT);");
277
278 std::string text;
279 text.resize(0);
__anonac7fc7d20e02(sqlite3_stmt *stmt) 280 NativeSqlite::ExecSql(g_db, "INSERT INTO t1 VALUES(?, ?)", [&text](sqlite3_stmt *stmt) {
281 (void)SQLiteUtils::BindInt64ToStatement(stmt, 1, 1);
282 (void)SQLiteUtils::BindTextToStatement(stmt, 2, "text"); // 2: bind index
283 EXPECT_NE(SQLiteUtils::BindTextToStatement(stmt, 5, text), E_OK);
284 EXPECT_EQ(SQLiteUtils::BindTextToStatement(nullptr, 2, text), -E_INVALID_ARGS);
285 EXPECT_NE(SQLiteUtils::BindInt64ToStatement(nullptr, -6, 0), E_OK);
286 EXPECT_NE(SQLiteUtils::BindBlobToStatement(stmt, 7, {}), E_OK);
287 EXPECT_NE(SQLiteUtils::BindPrefixKey(stmt, 8, {}), E_OK);
288 EXPECT_NE(SQLiteUtils::BindPrefixKey(stmt, 2, {}), E_OK);
289 return E_OK;
290 }, nullptr);
291
__anonac7fc7d20f02(sqlite3_stmt *stmt) 292 NativeSqlite::ExecSql(g_db, "SELECT b FROM t1", nullptr, [&text](sqlite3_stmt *stmt) {
293 std::string val;
294 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(nullptr, 0, val), -E_INVALID_ARGS);
295 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, val), E_OK);
296 EXPECT_EQ(val, text);
297 return E_OK;
298 });
299 }
300
301 /**
302 * @tc.name: AbnormalBranchErr
303 * @tc.desc: Test abnormal branch error
304 * @tc.type: FUNC
305 * @tc.require:
306 * @tc.author: lijun
307 */
308 HWTEST_F(DistributedDBSqliteUtilsTest, AbnormalBranchErr, TestSize.Level1)
309 {
310 CipherPassword passwd;
311 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::SetKey(nullptr, CipherType::DEFAULT, passwd, true,
312 DBConstant::DEFAULT_ITER_TIMES));
313 EXPECT_EQ(-1, SQLiteUtils::AttachNewDatabaseInner(g_db, CipherType::DEFAULT, {}, "path", "asname ? "));
314 EXPECT_EQ(-E_SQLITE_CANT_OPEN, SQLiteUtils::CreateMetaDatabase("/axxbxxc/d sdsda"));
315
316 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::CheckIntegrity(nullptr, ""));
317 TableInfo table;
318 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::AnalysisSchema(nullptr, "", table, true));
319 EXPECT_EQ(-E_NOT_SUPPORT, SQLiteUtils::AnalysisSchema(g_db, "###", table, true));
320 EXPECT_EQ(-E_NOT_FOUND, SQLiteUtils::AnalysisSchema(g_db, "t2", table, true));
321 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::AnalysisSchemaFieldDefine(nullptr, "ttt", table));
322
323 int version;
324 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::GetVersion(nullptr, version));
325 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::SetUserVer(nullptr, version));
326 std::string mode;
327 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::GetJournalMode(nullptr, mode));
328
329 EXPECT_EQ(-SQLITE_IOERR, SQLiteUtils::MapSQLiteErrno(SQLITE_IOERR));
330 int oldErr = errno;
331 errno = EKEYREVOKED;
332 EXPECT_EQ(-E_EKEYREVOKED, SQLiteUtils::MapSQLiteErrno(SQLITE_IOERR));
333 EXPECT_EQ(-E_EKEYREVOKED, SQLiteUtils::MapSQLiteErrno(SQLITE_ERROR));
334 errno = oldErr;
335 EXPECT_EQ(-E_SQLITE_CANT_OPEN, SQLiteUtils::MapSQLiteErrno(SQLITE_CANTOPEN));
336 std::string strSchema;
337 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::SaveSchema(nullptr, strSchema));
338 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::GetSchema(nullptr, strSchema));
339
340 IndexName name;
341 IndexInfo info;
342 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::IncreaseIndex(nullptr, name, info, SchemaType::JSON, 1));
343 EXPECT_EQ(-E_NOT_PERMIT, SQLiteUtils::IncreaseIndex(g_db, name, info, SchemaType::JSON, 1));
344 EXPECT_EQ(-E_NOT_PERMIT, SQLiteUtils::ChangeIndex(g_db, name, info, SchemaType::JSON, 1));
345 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::ChangeIndex(nullptr, name, info, SchemaType::JSON, 1));
346
347 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::RegisterJsonFunctions(nullptr));
348 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::CloneIndexes(nullptr, strSchema, strSchema));
349 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::GetRelationalSchema(nullptr, strSchema));
350 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::GetLogTableVersion(nullptr, strSchema));
351 EXPECT_EQ(-E_INVALID_DB, SQLiteUtils::RegisterFlatBufferFunction(nullptr, strSchema));
352 EXPECT_EQ(-E_INTERNAL_ERROR, SQLiteUtils::RegisterFlatBufferFunction(g_db, strSchema));
353 EXPECT_EQ(-E_INVALID_ARGS, SQLiteUtils::ExpandedSql(nullptr, strSchema));
354 SQLiteUtils::ExecuteCheckPoint(nullptr);
355
356 bool isEmpty;
357 EXPECT_EQ(-E_INVALID_ARGS, SQLiteUtils::CheckTableEmpty(nullptr, strSchema, isEmpty));
358 EXPECT_EQ(-E_INVALID_ARGS, SQLiteUtils::SetPersistWalMode(nullptr));
359 EXPECT_EQ(-1, SQLiteUtils::GetLastRowId(nullptr));
360 std::string tableName;
361 EXPECT_EQ(-1, SQLiteUtils::CheckTableExists(nullptr, tableName, isEmpty));
362 }
363
364 /**
365 * @tc.name: AbnormalBranchErrAfterClose
366 * @tc.desc: Test abnormal branch error after close db
367 * @tc.type: FUNC
368 * @tc.require:
369 * @tc.author: lijun
370 */
371 HWTEST_F(DistributedDBSqliteUtilsTest, AbnormalBranchErrAfterClose, TestSize.Level1)
372 {
373 int version;
374 std::string mode;
375 std::string strSchema;
376 std::string tableName;
377 bool isEmpty;
378
379 sqlite3_close_v2(g_db);
380 // After close db
381 EXPECT_EQ(-SQLITE_MISUSE, SQLiteUtils::GetVersion(g_db, version));
382 EXPECT_EQ(-SQLITE_MISUSE, SQLiteUtils::GetJournalMode(g_db, mode));
383 EXPECT_EQ(-SQLITE_MISUSE, SQLiteUtils::SaveSchema(g_db, strSchema));
384 EXPECT_EQ(-SQLITE_MISUSE, SQLiteUtils::GetSchema(g_db, strSchema));
385 EXPECT_EQ(-SQLITE_MISUSE, SQLiteUtils::GetRelationalSchema(g_db, strSchema));
386 EXPECT_EQ(-SQLITE_MISUSE, SQLiteUtils::GetLogTableVersion(g_db, strSchema));
387 EXPECT_EQ(-SQLITE_MISUSE, SQLiteUtils::CheckTableExists(g_db, tableName, isEmpty));
388 }
389