• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #include <gtest/gtest.h>
16 #include <ctime>
17 #include <cmath>
18 #include <random>
19 #include <chrono>
20 #include <fstream>
21 #include <string>
22 
23 #include "distributeddb_data_generator.h"
24 #include "distributed_test_tools.h"
25 #include "distributeddb_nb_test_tools.h"
26 #include "kv_store_delegate.h"
27 #include "kv_store_delegate_manager.h"
28 
29 using namespace std;
30 using namespace chrono;
31 using namespace testing;
32 #if defined TESTCASES_USING_GTEST_EXT
33 using namespace testing::ext;
34 #endif
35 using namespace DistributedDB;
36 using namespace DistributedDBDataGenerator;
37 
38 namespace DistributeddbKvRealdel {
39 static std::condition_variable g_kvBackupVar;
40 class DistributeddbKvRealdelTest : public testing::Test {
41 public:
42     static void SetUpTestCase(void);
43     static void TearDownTestCase(void);
44     void SetUp();
45     void TearDown();
46 private:
47 };
48 
49 KvStoreDelegate *g_kvBackupDelegate = nullptr; // the delegate used in this suit.
50 KvStoreDelegateManager *g_manager = nullptr;
SetUpTestCase(void)51 void DistributeddbKvRealdelTest::SetUpTestCase(void)
52 {
53 }
54 
TearDownTestCase(void)55 void DistributeddbKvRealdelTest::TearDownTestCase(void)
56 {
57 }
58 
SetUp(void)59 void DistributeddbKvRealdelTest::SetUp(void)
60 {
61     UnitTest *test = UnitTest::GetInstance();
62     ASSERT_NE(test, nullptr);
63     const TestInfo *testinfo = test->current_test_info();
64     ASSERT_NE(testinfo, nullptr);
65     string testCaseName = string(testinfo->name());
66     MST_LOG("[SetUp] test case %s is start to run", testCaseName.c_str());
67 
68     KvOption option = g_kvOption;
69     g_kvBackupDelegate = DistributedTestTools::GetDelegateSuccess(g_manager, g_kvdbParameter1, option);
70     ASSERT_TRUE(g_manager != nullptr && g_kvBackupDelegate != nullptr);
71 }
72 
TearDown(void)73 void DistributeddbKvRealdelTest::TearDown(void)
74 {
75     MST_LOG("TearDown after case.");
76     EXPECT_TRUE(g_manager->CloseKvStore(g_kvBackupDelegate) == OK);
77     g_kvBackupDelegate = nullptr;
78     DBStatus status = g_manager->DeleteKvStore(STORE_ID_1);
79     EXPECT_TRUE(status == DistributedDB::DBStatus::OK) << "fail to delete exist kvdb";
80     delete g_manager;
81     g_manager = nullptr;
82 }
83 
84 /*
85  * @tc.name: KvDeleteAll 001
86  * @tc.desc: test that delete interface will real delete data.
87  * @tc.type: FUNC
88  * @tc.require: SR000D4878
89  * @tc.author: fengxiaoyun
90  */
91 #ifdef KV_REALDEL
92 HWTEST_F(DistributeddbKvRealdelTest, KvDeleteAll001, TestSize.Level1)
93 {
94     /**
95      * @tc.steps: step1. put (k1, v1), (k2, v2) to db, and update (k1, v1) to (k1, v2).
96      * @tc.expected: step1. put successfully.
97      */
98     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_1, VALUE_1), OK);
99     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_2, VALUE_2), OK);
100     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_1, VALUE_2), OK);
101     /**
102      * @tc.steps: step2. use sqlite to open the db and check the data of k1.
103      * @tc.expected: step2. there is only one data of k1 in db.
104      */
105     std::string identifier = g_kvdbParameter1.userId + "-" + g_kvdbParameter1.appId + "-" + g_kvdbParameter1.storeId;
106     std::string hashIdentifierRes = TransferStringToHashHexString(identifier);
107     const std::string kvDbName = DIRECTOR + hashIdentifierRes + KVMULTIDB;
108     std::vector<DistributedDB::Key> keyS1, keyS2;
109     keyS1.push_back(KEY_1);
110     int count = 0;
__anona94a1fac0102()111     EXPECT_TRUE(DistributedTestTools::RepeatCheckAsyncResult([&kvDbName, &count, &keyS1]()->bool {
112         DistributedTestTools::GetRecordCntByKey(kvDbName.c_str(), QUERY_SQL, keyS1, g_kvOption, count);
113         return count == ONE_RECORD;
114     }, 5, 500)); // query 5 times every 500 ms.
115     /**
116      * @tc.steps: step3. delete k1 and then check data of k1 and k2;
117      * @tc.expected: step3. can't find k1, but can find the value of k2 is v2.
118      */
119     EXPECT_EQ(g_kvBackupDelegate->Delete(KEY_1), OK);
120     Value realValue;
121     realValue = DistributedTestTools::Get(*g_kvBackupDelegate, KEY_1);
122     EXPECT_TRUE(realValue.size() == 0);
123     realValue = DistributedTestTools::Get(*g_kvBackupDelegate, KEY_2);
124     EXPECT_TRUE(realValue == VALUE_2);
125     /**
126      * @tc.steps: step4. wait for some seconds and check the data of k1;
127      * @tc.expected: step4. can't find k1.
128      */
__anona94a1fac0202()129     EXPECT_TRUE(DistributedTestTools::RepeatCheckAsyncResult([&kvDbName, &count, &keyS1]()->bool {
130         DistributedTestTools::GetRecordCntByKey(kvDbName.c_str(), QUERY_SQL, keyS1, g_kvOption, count);
131         return count == 0;
132     }, 5, 500)); // query 5 times every 500 ms.
133 }
134 
135 /*
136  * @tc.name: KvDeleteAll 002
137  * @tc.desc: test that deleteBatch interface will real delete data.
138  * @tc.type: FUNC
139  * @tc.require: SR000D4878
140  * @tc.author: fengxiaoyun
141  */
142 HWTEST_F(DistributeddbKvRealdelTest, KvDeleteAll002, TestSize.Level1)
143 {
144     /**
145      * @tc.steps: step1. put (k1, v1), (k2, v2), (k3, v3) to db and use deletebatch interface to delete k1, k2.
146      * @tc.expected: step1. put and delete successfully.
147      */
148     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_1, VALUE_1), OK);
149     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_2, VALUE_2), OK);
150     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_3, VALUE_3), OK);
151     std::vector<DistributedDB::Key> keyS;
152     keyS.push_back(KEY_1);
153     keyS.push_back(KEY_2);
154     EXPECT_EQ(g_kvBackupDelegate->DeleteBatch(keyS), OK);
155     /**
156      * @tc.steps: step2. open the db and check the data of k1, k2, k3.
157      * @tc.expected: step2. there is only k3 in db and can't get k1, k2.
158      */
159     Value realValue;
160     realValue = DistributedTestTools::Get(*g_kvBackupDelegate, KEY_1);
161     EXPECT_TRUE(realValue.size() == 0);
162     realValue = DistributedTestTools::Get(*g_kvBackupDelegate, KEY_2);
163     EXPECT_TRUE(realValue.size() == 0);
164     realValue = DistributedTestTools::Get(*g_kvBackupDelegate, KEY_3);
165     EXPECT_TRUE(realValue == VALUE_3);
166     /**
167      * @tc.steps: step3. wait for some seconds and check the data of k1, k2 by sqlite;
168      * @tc.expected: step3. can't find k1, k2.
169      */
170     std::string identifier = g_kvdbParameter1.userId + "-" + g_kvdbParameter1.appId + "-" + g_kvdbParameter1.storeId;
171     std::string hashIdentifierRes = TransferStringToHashHexString(identifier);
172     const std::string kvDbName = DIRECTOR + hashIdentifierRes + KVMULTIDB;
173     int count = 0;
__anona94a1fac0302()174     EXPECT_TRUE(DistributedTestTools::RepeatCheckAsyncResult([&kvDbName, &count, &keyS]()->bool {
175         DistributedTestTools::GetRecordCntByKey(kvDbName.c_str(), MULTI_KEY_QUERY_SQL, keyS, g_kvOption, count);
176         return count == 0;
177     }, 5, 500)); // query 5 times every 500 ms.
178 }
179 
180 /*
181  * @tc.name: KvDeleteAll 003
182  * @tc.desc: test that clear interface will real delete data.
183  * @tc.type: FUNC
184  * @tc.require: SR000D4878
185  * @tc.author: fengxiaoyun
186  */
187 HWTEST_F(DistributeddbKvRealdelTest, KvDeleteAll003, TestSize.Level1)
188 {
189     /**
190      * @tc.steps: step1. put (k1, v1), (k2, v2) to db and update (k1, v1) to (k1, v2).
191      * @tc.expected: step1. put and update successfully.
192      */
193     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_1, VALUE_1), OK);
194     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_2, VALUE_2), OK);
195     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_1, VALUE_2), OK);
196     /**
197      * @tc.steps: step2. clear the db, and check the data of k1, k2.
198      * @tc.expected: step2. clear and can't find k1, k2.
199      */
200     EXPECT_EQ(g_kvBackupDelegate->Clear(), OK);
201     Value realValue;
202     realValue = DistributedTestTools::Get(*g_kvBackupDelegate, KEY_1);
203     EXPECT_TRUE(realValue.size() == 0);
204     realValue = DistributedTestTools::Get(*g_kvBackupDelegate, KEY_2);
205     EXPECT_TRUE(realValue.size() == 0);
206 
207     /**
208      * @tc.steps: step3. wait for 5 seconds and check the data of k1, k2;
209      * @tc.expected: step3. can't find k1, k2.
210      */
211     std::string identifier = g_kvdbParameter1.userId + "-" + g_kvdbParameter1.appId + "-" + g_kvdbParameter1.storeId;
212     std::string hashIdentifierRes = TransferStringToHashHexString(identifier);
213     const std::string kvDbName = DIRECTOR + hashIdentifierRes + KVMULTIDB;
214     std::vector<DistributedDB::Key> keyS;
215     keyS.push_back(KEY_1);
216     keyS.push_back(KEY_2);
217     int count = 0;
__anona94a1fac0402()218     EXPECT_TRUE(DistributedTestTools::RepeatCheckAsyncResult([&kvDbName, &count, &keyS]()->bool {
219         DistributedTestTools::GetRecordCntByKey(kvDbName.c_str(), MULTI_KEY_QUERY_SQL, keyS, g_kvOption, count);
220         return count == 0;
221     }, 5, 500)); // query 5 times every 500 ms.
222 
223     EncrypteAttribute attribute = {g_kvOption.isEncryptedDb, g_kvOption.passwd};
__anona94a1fac0502()224     EXPECT_TRUE(DistributedTestTools::RepeatCheckAsyncResult([&kvDbName, &attribute, &count]()->bool {
225         DistributedTestTools::QuerySpecifiedData(kvDbName, SYNC_MULTI_VER_QUERY_SQL, attribute, count);
226         return count == ONE_RECORD;
227     }, 5, 500)); // query 5 times every 500 ms.
228 }
229 
230 /*
231  * @tc.name: KvDeleteAll 004
232  * @tc.desc: test that it can get record when snapshot is register, and can't get records after unregister snapshor.
233  * @tc.type: FUNC
234  * @tc.require: SR000D4878
235  * @tc.author: fengxiaoyun
236  */
237 HWTEST_F(DistributeddbKvRealdelTest, KvDeleteAll004, TestSize.Level2)
238 {
239     /**
240      * @tc.steps: step1. put (k1, v1), update (k1, v1) to (k1, v2).
241      * @tc.expected: step1. put and update successfully.
242      */
243     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_1, VALUE_1), OK);
244     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_1, VALUE_2), OK);
245     KvStoreObserverImpl observer;
246     KvStoreSnapshotDelegate *snapShot = DistributedTestTools::RegisterSnapObserver(g_kvBackupDelegate, &observer);
247     EXPECT_NE(snapShot, nullptr);
248     /**
249      * @tc.steps: step2. delete k1 and then check data of k1;
250      * @tc.expected: step2. there is only one records in the db.
251      */
252     EXPECT_EQ(g_kvBackupDelegate->Delete(KEY_1), OK);
253     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND));
254     std::string identifier = g_kvdbParameter1.userId + "-" + g_kvdbParameter1.appId + "-" + g_kvdbParameter1.storeId;
255     std::string hashIdentifierRes = TransferStringToHashHexString(identifier);
256     const std::string kvDbName = DIRECTOR + hashIdentifierRes + KVMULTIDB;
257 
258     std::vector<DistributedDB::Key> keyS;
259     keyS.push_back(KEY_1);
260     int count = 0;
261     DistributedTestTools::GetRecordCntByKey(kvDbName.c_str(), QUERY_SQL, keyS, g_kvOption, count);
262     EXPECT_EQ(count, ONE_RECORD);
263 
264     /**
265      * @tc.steps: step3. after release the snap shot query the records;
266      * @tc.expected: step3. can't find the k1 in db.
267      */
268     EXPECT_EQ(g_kvBackupDelegate->ReleaseKvStoreSnapshot(snapShot), OK);
269     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND));
270     DistributedTestTools::GetRecordCntByKey(kvDbName.c_str(), QUERY_SQL, keyS, g_kvOption, count);
271     EXPECT_TRUE(count == 0);
272 }
273 
274 /*
275  * @tc.name: DeleteAll 006
276  * @tc.desc: value slices will be real deleted if reference count is 0 caused by clear.
277  * @tc.type: FUNC
278  * @tc.require: SR000D4878
279  * @tc.author: fengxiaoyun
280  */
281 HWTEST_F(DistributeddbKvRealdelTest, KvDeleteAll006, TestSize.Level2)
282 {
283     KvStoreDelegate *delegate2 = nullptr;
284     KvStoreDelegateManager *manager2 = nullptr;
285     delegate2 = DistributedTestTools::GetDelegateSuccess(manager2, g_kvdbParameter2, g_kvOption);
286     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr);
287     /**
288      * @tc.steps: step1. put (k1,v1) and (k2,v2), each value of them are 4M.
289      * @tc.expected: step1. call successfully.
290      */
291     EntrySize entrySize = { KEY_SIX_BYTE, FOUR_M_LONG_STRING };
292     std::vector<DistributedDB::Entry> entries;
293     GenerateAppointPrefixAndSizeRecords(entries, entrySize, RECORDS_SMALL_CNT, { 'K' }, { 'v' });
294     for (auto entry : entries) {
295         EXPECT_EQ(delegate2->Put(entry.key, entry.value), OK);
296     }
297     /**
298      * @tc.steps: step2. clear and verify the records of ValueSlice by sqlite interface.
299      * @tc.expected: step1. count is 0.
300      */
301     EXPECT_EQ(delegate2->Clear(), OK);
302     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND));
303     std::string identifier = g_kvdbParameter2.userId + "-" + g_kvdbParameter2.appId +
304         "-" + g_kvdbParameter2.storeId;
305     std::string hashIdentifierRes = TransferStringToHashHexString(identifier);
306     const std::string dbName = DIRECTOR + hashIdentifierRes + MULTIDB;
307     int count = 0;
308     EncrypteAttribute attribute = {g_kvOption.isEncryptedDb, g_kvOption.passwd};
309     EXPECT_TRUE(DistributedTestTools::QuerySpecifiedData(dbName, SYNC_VALUE_SLICE_QUERY_SQL, attribute, count));
310     EXPECT_EQ(count, 0); // there are no ValueSlices in db.
311 
312     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
313     delegate2 = nullptr;
314     EXPECT_EQ(manager2->DeleteKvStore(STORE_ID_2), OK);
315     delete manager2;
316     manager2 = nullptr;
317 }
318 
319 /*
320  * @tc.name: DeleteAll 007
321  * @tc.desc: value slices will be real deleted if reference count is 0 caused by clear.
322  * @tc.type: FUNC
323  * @tc.require: SR000D4878
324  * @tc.author: fengxiaoyun
325  */
326 HWTEST_F(DistributeddbKvRealdelTest, KvDeleteAll007, TestSize.Level2)
327 {
328     KvStoreDelegate *delegate2 = nullptr;
329     KvStoreDelegateManager *manager2 = nullptr;
330     delegate2 = DistributedTestTools::GetDelegateSuccess(manager2, g_kvdbParameter2, g_kvOption);
331     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr);
332     /**
333      * @tc.steps: step1. put (k1,v1) and (k2,v1), each value of them are 4M.
334      * @tc.expected: step1. call successfully.
335      */
336     EntrySize entrySize = { KEY_SIX_BYTE, FOUR_M_LONG_STRING };
337     std::vector<DistributedDB::Entry> entries;
338     GenerateAppointPrefixAndSizeRecords(entries, entrySize, RECORDS_SMALL_CNT, { 'K' }, { 'v' });
339     entries[INDEX_FIRST].value = entries[INDEX_ZEROTH].value;
340     for (auto entry : entries) {
341         EXPECT_EQ(delegate2->Put(entry.key, entry.value), OK);
342     }
343     /**
344      * @tc.steps: step2. delete k1 and verify the records of ValueSlice by sqlite interface.
345      * @tc.expected: step1. count is not equal to 0.
346      */
347     std::string identifier = g_kvdbParameter2.userId + "-" + g_kvdbParameter2.appId +
348         "-" + g_kvdbParameter2.storeId;
349     std::string hashIdentifierRes = TransferStringToHashHexString(identifier);
350     const std::string dbName = DIRECTOR + hashIdentifierRes + MULTIDB;
351     EXPECT_EQ(delegate2->Delete(entries[INDEX_ZEROTH].key), OK);
352     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND));
353     int count = 0;
354     EncrypteAttribute attribute = {g_kvOption.isEncryptedDb, g_kvOption.passwd};
355     EXPECT_TRUE(DistributedTestTools::QuerySpecifiedData(dbName, SYNC_VALUE_SLICE_QUERY_SQL, attribute, count));
356     EXPECT_EQ(count, 0); // there are some ValueSlices in db.
357     /**
358      * @tc.steps: step3. delete k2 and verify the records of ValueSlice by sqlite interface.
359      * @tc.expected: step1. count is 0.
360      */
361     EXPECT_EQ(delegate2->Delete(entries[INDEX_FIRST].key), OK);
362     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND));
363     count = 0;
364     EXPECT_TRUE(DistributedTestTools::QuerySpecifiedData(dbName, SYNC_VALUE_SLICE_QUERY_SQL, attribute, count));
365     EXPECT_EQ(count, 0); // there are no ValueSlices in db.
366 
367     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
368     delegate2 = nullptr;
369     EXPECT_EQ(manager2->DeleteKvStore(STORE_ID_2), OK);
370     delete manager2;
371     manager2 = nullptr;
372 }
373 #endif
374 }