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