• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_data_generate_unit_test.h"
19 #include "kvdb_manager.h"
20 #include "native_sqlite.h"
21 #include "sqlite_local_kvdb.h"
22 #include "sqlite_local_kvdb_connection.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     SQLiteLocalKvDBConnection *g_connection = nullptr;
32     SQLiteLocalKvDB *g_invalidDb = nullptr;
33     SQLiteLocalKvDBConnection *g_invalidConnection = nullptr;
34 
CreateConnInInvalidDb()35     void CreateConnInInvalidDb()
36     {
37         ASSERT_EQ(g_invalidDb, nullptr);
38         g_invalidConnection = new (std::nothrow) SQLiteLocalKvDBConnection(g_invalidDb);
39         ASSERT_NE(g_invalidConnection, nullptr);
40     }
41 
CloseConnInInvalidDb()42     void CloseConnInInvalidDb()
43     {
44         if (g_invalidConnection != nullptr) {
45             delete g_invalidConnection;
46             g_invalidConnection = nullptr;
47         }
48     }
49 
CreateConnInNewDb()50     void CreateConnInNewDb()
51     {
52         g_invalidDb = new (std::nothrow) SQLiteLocalKvDB();
53         ASSERT_NE(g_invalidDb, nullptr);
54         int errCode;
55         g_invalidConnection = static_cast<SQLiteLocalKvDBConnection *>(g_invalidDb->GetDBConnection(errCode));
56         ASSERT_NE(g_invalidConnection, nullptr);
57         RefObject::DecObjRef(g_invalidDb);
58     }
59 
CloseConnInNewDb()60     void CloseConnInNewDb()
61     {
62         if (g_invalidConnection != nullptr) {
63             EXPECT_EQ(g_invalidConnection->Close(), E_OK);
64             g_invalidConnection = nullptr;
65             g_invalidDb = nullptr;
66         }
67         if (g_invalidDb != nullptr) {
68             delete g_invalidDb;
69             g_invalidDb = nullptr;
70         }
71     }
72 
TestFunc(const KvDBCommitNotifyData & data)73     void TestFunc(const KvDBCommitNotifyData &data)
74     {
75     }
76 }
77 
78 class DistributedDBStorageDataConnectionTest : public testing::Test {
79 public:
80     static void SetUpTestCase(void);
81     static void TearDownTestCase(void);
82     void SetUp();
83     void TearDown();
84 };
85 
SetUpTestCase(void)86 void DistributedDBStorageDataConnectionTest::SetUpTestCase(void)
87 {
88     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
89 }
90 
TearDownTestCase(void)91 void DistributedDBStorageDataConnectionTest::TearDownTestCase(void)
92 {
93     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
94         LOGE("rm test db files error!");
95     }
96 }
97 
SetUp(void)98 void DistributedDBStorageDataConnectionTest::SetUp(void)
99 {
100     DistributedDBToolsUnitTest::PrintTestCaseInfo();
101     KvDBProperties properties;
102     properties.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
103     properties.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::LOCAL_TYPE);
104     properties.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
105     properties.SetStringProp(KvDBProperties::STORE_ID, "test");
106     properties.SetStringProp(KvDBProperties::IDENTIFIER_DIR, "test");
107 
108     int errCode = E_OK;
109     g_connection = static_cast<SQLiteLocalKvDBConnection *>(KvDBManager::GetDatabaseConnection(properties, errCode));
110     EXPECT_EQ(errCode, E_OK);
111     ASSERT_NE(g_connection, nullptr);
112 }
113 
TearDown(void)114 void DistributedDBStorageDataConnectionTest::TearDown(void)
115 {
116     if (g_connection != nullptr) {
117         g_connection->Close();
118         g_connection = nullptr;
119     }
120     CloseConnInInvalidDb();
121     CloseConnInNewDb();
122     return;
123 }
124 
125 /**
126   * @tc.name: ConnectionTest001
127   * @tc.desc: Get value from abnormal connection
128   * @tc.type: FUNC
129   * @tc.require:
130   * @tc.author: bty
131   */
132 HWTEST_F(DistributedDBStorageDataConnectionTest, ConnectionTest001, TestSize.Level1)
133 {
134     /**
135      * @tc.steps: step1. Create a connection when the db is null
136      * @tc.expected: step1. Expect not null
137      */
138     CreateConnInInvalidDb();
139 
140     /**
141      * @tc.steps: step2 Get value
142      * @tc.expected: step2. Expect -E_INVALID_DB
143      */
144     IOption option;
145     Value value;
146     EXPECT_EQ(g_invalidConnection->Get(option, KEY_3, value), -E_INVALID_DB);
147     CloseConnInInvalidDb();
148 
149     /**
150      * @tc.steps: step3. Use db to create a new connection, but db is not open
151      * @tc.expected: step3. Expect not null
152      */
153     CreateConnInNewDb();
154 
155     /**
156      * @tc.steps: step4. Get value
157      * @tc.expected: step4. Expect -E_INVALID_DB
158      */
159     EXPECT_EQ(g_invalidConnection->Get(option, KEY_3, value), -E_INVALID_DB);
160     CloseConnInNewDb();
161 }
162 
163 /**
164   * @tc.name: ConnectionTest002
165   * @tc.desc: Delete and clear from abnormal connection
166   * @tc.type: FUNC
167   * @tc.require:
168   * @tc.author: bty
169   */
170 HWTEST_F(DistributedDBStorageDataConnectionTest, ConnectionTest002, TestSize.Level1)
171 {
172     /**
173      * @tc.steps: step1. Use db to create a new connection, but db is not open
174      * @tc.expected: step1. Expect not null
175      */
176     CreateConnInNewDb();
177 
178     /**
179      * @tc.steps: step2. Clear and delete
180      * @tc.expected: step2. Expect -E_INVALID_DB
181      */
182     IOption option;
183     Value value;
184     EXPECT_EQ(g_invalidConnection->Delete(option, KEY_3), -E_INVALID_DB);
185     EXPECT_EQ(g_invalidConnection->Clear(option), -E_INVALID_DB);
186     CloseConnInNewDb();
187 }
188 
189 /**
190   * @tc.name: ConnectionTest003
191   * @tc.desc: Get entries from abnormal connection
192   * @tc.type: FUNC
193   * @tc.require:
194   * @tc.author: bty
195   */
196 HWTEST_F(DistributedDBStorageDataConnectionTest, ConnectionTest003, TestSize.Level1)
197 {
198     /**
199      * @tc.steps: step1. Create a connection when the db is null
200      * @tc.expected: step1. Expect not null
201      */
202     CreateConnInInvalidDb();
203 
204     /**
205      * @tc.steps: step2. Get entries
206      * @tc.expected: step2. Expect -E_INVALID_DB
207      */
208     IOption option;
209     std::vector<Entry> entry;
210     Key key(DBConstant::MAX_KEY_SIZE + 1, 'w');
211     EXPECT_EQ(g_invalidConnection->GetEntries(option, key, entry), -E_INVALID_DB);
212     CloseConnInInvalidDb();
213 
214     /**
215      * @tc.steps: step3. Key is over size
216      * @tc.expected: step3. Expect -E_INVALID_ARGS
217      */
218     CreateConnInNewDb();
219     EXPECT_EQ(g_invalidConnection->GetEntries(option, key, entry), -E_INVALID_ARGS);
220 
221     /**
222      * @tc.steps: step4. Key is normal, but the db not open
223      * @tc.expected: step4. Expect -E_INVALID_DB
224      */
225     EXPECT_EQ(g_invalidConnection->GetEntries(option, KEY_3, entry), -E_INVALID_DB);
226     CloseConnInNewDb();
227 }
228 
229 /**
230   * @tc.name: ConnectionTest004
231   * @tc.desc: Put batch from abnormal connection
232   * @tc.type: FUNC
233   * @tc.require:
234   * @tc.author: bty
235   */
236 HWTEST_F(DistributedDBStorageDataConnectionTest, ConnectionTest004, TestSize.Level1)
237 {
238     /**
239      * @tc.steps: step1. Create a connection when the db is null
240      * @tc.expected: step1. Expect not null
241      */
242     CreateConnInInvalidDb();
243 
244     /**
245      * @tc.steps: step2. Put empty entries
246      * @tc.expected: step2. Expect -E_INVALID_ARGS
247      */
248     IOption option;
249     std::vector<Entry> entry;
250     EXPECT_EQ(g_invalidConnection->PutBatch(option, entry), -E_INVALID_ARGS);
251 
252     /**
253      * @tc.steps: step3. Entries is normal, but the db is null
254      * @tc.expected: step3. Expect -E_INVALID_ARGS
255      */
256     Value value;
257     Entry ent = {KEY_3, value};
258     entry.push_back(ent);
259     EXPECT_EQ(g_invalidConnection->PutBatch(option, entry), -E_INVALID_ARGS);
260     CloseConnInInvalidDb();
261 
262     /**
263      * @tc.steps: step4. The db is not open
264      * @tc.expected: step4. Expect -E_INVALID_DB
265      */
266     CreateConnInNewDb();
267     EXPECT_EQ(g_invalidConnection->PutBatch(option, entry), -E_INVALID_DB);
268     CloseConnInNewDb();
269 }
270 
271 /**
272   * @tc.name: ConnectionTest005
273   * @tc.desc: Delete batch from abnormal connection
274   * @tc.type: FUNC
275   * @tc.require:
276   * @tc.author: bty
277   */
278 HWTEST_F(DistributedDBStorageDataConnectionTest, ConnectionTest005, TestSize.Level1)
279 {
280     /**
281      * @tc.steps: step1. Create a connection when the db is null
282      * @tc.expected: step1. Expect not null
283      */
284     CreateConnInInvalidDb();
285 
286     /**
287      * @tc.steps: step2. delete, but the keys is empty
288      * @tc.expected: step2. Expect -E_INVALID_ARGS
289      */
290     IOption option;
291     std::vector<Key> keys;
292     EXPECT_EQ(g_invalidConnection->DeleteBatch(option, keys), -E_INVALID_ARGS);
293 
294     /**
295      * @tc.steps: step3. The key is over size
296      * @tc.expected: step3. Expect -E_INVALID_ARGS
297      */
298     Key key(DBConstant::MAX_KEY_SIZE + 1, 'w');
299     keys.push_back(key);
300     EXPECT_EQ(g_invalidConnection->DeleteBatch(option, keys), -E_INVALID_ARGS);
301 
302     /**
303      * @tc.steps: step4. key is normal , but the db is null
304      * @tc.expected: step4. Expect -E_INVALID_DB
305      */
306     keys.clear();
307     keys.push_back(KEY_3);
308     EXPECT_EQ(g_invalidConnection->DeleteBatch(option, keys), -E_INVALID_DB);
309     CloseConnInInvalidDb();
310 }
311 
312 /**
313   * @tc.name: ConnectionTest006
314   * @tc.desc: Get snapshot from abnormal connection
315   * @tc.type: FUNC
316   * @tc.require:
317   * @tc.author: bty
318   */
319 HWTEST_F(DistributedDBStorageDataConnectionTest, ConnectionTest006, TestSize.Level1)
320 {
321     /**
322      * @tc.steps: step1. Create a connection when the db is null
323      * @tc.expected: step1. Expect not null
324      */
325     CreateConnInInvalidDb();
326 
327     /**
328      * @tc.steps: step2. the db is null
329      * @tc.expected: step2. Expect -E_INVALID_DB
330      */
331     IKvDBSnapshot *snapshot = nullptr;
332     EXPECT_EQ(g_invalidConnection->GetSnapshot(snapshot), -E_INVALID_DB);
333     CloseConnInInvalidDb();
334 
335     /**
336      * @tc.steps: step3. GetSnapshot after changing db operate perm to DISABLE_PERM
337      * @tc.expected: step3. Expect -E_STALE
338      */
339     SQLiteLocalKvDB *localKvdb = new (std::nothrow) SQLiteLocalKvDB();
340     ASSERT_NE(localKvdb, nullptr);
341     EXPECT_EQ(localKvdb->TryToDisableConnection(OperatePerm::DISABLE_PERM), E_OK);
342     int errCode;
343     SQLiteLocalKvDBConnection *connection =
344         static_cast<SQLiteLocalKvDBConnection *>(localKvdb->NewConnection(errCode));
345     ASSERT_NE(connection, nullptr);
346     EXPECT_EQ(connection->GetSnapshot(snapshot), -E_STALE);
347     EXPECT_EQ(connection->Close(), E_OK);
348     connection = nullptr;
349     localKvdb = nullptr;
350 
351     /**
352      * @tc.steps: step4. Get snapshot from normal db, then preClose
353      * @tc.expected: step4. Expect -E_BUSY
354      */
355     EXPECT_EQ(g_connection->GetSnapshot(snapshot), E_OK);
356     EXPECT_EQ(g_connection->PreClose(), -E_BUSY);
357     g_connection->ReleaseSnapshot(snapshot);
358 }
359 
360 /**
361   * @tc.name: ConnectionTest007
362   * @tc.desc: Test transaction from abnormal connection
363   * @tc.type: FUNC
364   * @tc.require:
365   * @tc.author: bty
366   */
367 HWTEST_F(DistributedDBStorageDataConnectionTest, ConnectionTest007, TestSize.Level1)
368 {
369     /**
370      * @tc.steps: step1. Start transaction when the db is null
371      * @tc.expected: step1. Expect -E_INVALID_DB
372      */
373     CreateConnInInvalidDb();
374     EXPECT_EQ(g_invalidConnection->StartTransaction(), -E_INVALID_DB);
375     CloseConnInInvalidDb();
376 
377     /**
378      * @tc.steps: step2. Start transaction and rollback
379      * @tc.expected: step2. Expect true after StartTransaction, false after rollback
380      */
381     g_connection->StartTransaction();
382     EXPECT_EQ(g_connection->IsTransactionStarted(), true);
383     g_connection->RollBack();
384     EXPECT_EQ(g_connection->IsTransactionStarted(), false);
385 }
386 
387 /**
388   * @tc.name: ConnectionTest008
389   * @tc.desc: Export,import and rekey from abnormal connection
390   * @tc.type: FUNC
391   * @tc.require:
392   * @tc.author: bty
393   */
394 HWTEST_F(DistributedDBStorageDataConnectionTest, ConnectionTest008, TestSize.Level1)
395 {
396     /**
397      * @tc.steps: step1. the db is null
398      * @tc.expected: step1. Expect -E_INVALID_DB
399      */
400     CreateConnInInvalidDb();
401     CipherPassword passwd;
402     string filePath = g_testDir + "/ExportTest.db";
403     EXPECT_EQ(g_invalidConnection->Rekey(passwd), -E_INVALID_DB);
404     EXPECT_EQ(g_invalidConnection->Export(filePath, passwd), -E_INVALID_DB);
405     EXPECT_EQ(g_invalidConnection->Import(filePath, passwd), -E_INVALID_DB);
406     CloseConnInInvalidDb();
407 
408     /**
409      * @tc.steps: step2. Make OperatePerm not equal to NORMAL_PERM
410      * @tc.expected: step2. Expect -E_BUSY
411      */
412     SQLiteLocalKvDB *localKvdb = new (std::nothrow) SQLiteLocalKvDB();
413     ASSERT_NE(localKvdb, nullptr);
414     EXPECT_EQ(localKvdb->TryToDisableConnection(OperatePerm::DISABLE_PERM), E_OK);
415     int errCode;
416     SQLiteLocalKvDBConnection *connection =
417         static_cast<SQLiteLocalKvDBConnection *>(localKvdb->NewConnection(errCode));
418     ASSERT_NE(connection, nullptr);
419     EXPECT_EQ(connection->Import(filePath, passwd), -E_BUSY);
420     EXPECT_EQ(connection->Close(), E_OK);
421     connection = nullptr;
422     localKvdb = nullptr;
423 
424     /**
425      * @tc.steps: step3. Test in transaction
426      * @tc.expected: step3. Expect -E_BUSY
427      */
428     g_connection->StartTransaction();
429     EXPECT_EQ(g_connection->Rekey(passwd), -E_BUSY);
430     EXPECT_EQ(g_connection->Import(filePath, passwd), -E_BUSY);
431     g_connection->RollBack();
432 
433     /**
434      * @tc.steps: step4. Test after Registering observer
435      * @tc.expected: step4. Expect -E_BUSY
436      */
437     int result;
438     Key key;
439     key.push_back('a');
440     KvDBObserverHandle* handle = g_connection->RegisterObserver(
441         static_cast<unsigned int>(SQLITE_GENERAL_NS_LOCAL_PUT_EVENT), key, TestFunc, result);
442     EXPECT_EQ(result, E_OK);
443     EXPECT_NE(handle, nullptr);
444     EXPECT_EQ(g_connection->Rekey(passwd), -E_BUSY);
445     EXPECT_EQ(g_connection->Import(filePath, passwd), -E_BUSY);
446     g_connection->UnRegisterObserver(handle);
447 }