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 = 5 * 1024 * 1024; // 5M 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 
__anona04736ca0202(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 
__anona04736ca0302(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 
__anona04736ca0402(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 
__anona04736ca0502(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 
__anona04736ca0602(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 
__anona04736ca0702(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 
__anona04736ca0802(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 
__anona04736ca0902(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 
__anona04736ca0a02(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 
__anona04736ca0b02(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 
__anona04736ca0c02(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 
__anona04736ca0d02(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 }