• 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 
17 #include "distributeddb_nb_test_tools.h"
18 #include "process_communicator_test_stub.h"
19 
20 using namespace testing;
21 #if defined TESTCASES_USING_GTEST_EXT
22 using namespace testing::ext;
23 #endif
24 using namespace std;
25 using namespace DistributedDB;
26 using namespace DistributedDBDataGenerator;
27 
28 namespace DistributedbNbDbDamage {
29 KvStoreDelegateManager *g_manager = nullptr;
30 
31 class DistributedbNbDbDamageTest : public testing::Test {
32 public:
33     static void SetUpTestCase(void);
34     static void TearDownTestCase(void);
35     void SetUp();
36     void TearDown();
37 };
38 
SetUpTestCase(void)39 void DistributedbNbDbDamageTest::SetUpTestCase(void)
40 {
41 }
42 
TearDownTestCase(void)43 void DistributedbNbDbDamageTest::TearDownTestCase(void)
44 {
45 }
46 
SetUp(void)47 void DistributedbNbDbDamageTest::SetUp(void)
48 {
49     RemoveDir(DistributedDBConstant::NB_DIRECTOR);
50     UnitTest *test = UnitTest::GetInstance();
51     ASSERT_NE(test, nullptr);
52     const TestInfo *testinfo = test->current_test_info();
53     ASSERT_NE(testinfo, nullptr);
54     string testCaseName = string(testinfo->name());
55     MST_LOG("[SetUp] test case %s is start to run", testCaseName.c_str());
56 }
57 
TearDown(void)58 void DistributedbNbDbDamageTest::TearDown(void)
59 {
60 }
61 
62 /*
63  * @tc.name: DbDamageRecover 001
64  * @tc.desc: Verify that set isNeedIntegrityCheck and isNeedRmCorruptedDb when open db, if open failed the callback will
65  *  be triggered  when has register corruption callback.
66  * @tc.type: FUNC
67  * @tc.require: SR000D4878
68  * @tc.author: fengxiaoyun
69  */
70 #ifdef NB_DBDAMAGE
71 HWTEST_F(DistributedbNbDbDamageTest, DbDamageRecover001, TestSize.Level1)
72 {
73     Option option = g_option;
74     KvStoreNbDelegate *delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, option);
75     ASSERT_NE(g_manager, nullptr);
76     ASSERT_NE(delegate, nullptr);
77     EXPECT_EQ(g_manager->CloseKvStore(delegate), OK);
78     delegate = nullptr;
79 
80     /**
81      * @tc.steps: step1. device A call SetKvStoreCorruptionHandler and make db file corrupted.
82      * @tc.expected: step1. operate successfully.
83      */
84     KvStoreNbCorruptInfo corruptInfo;
85     bool isCalled = false;
86     auto notifier = bind(&KvStoreNbCorruptInfo::CorruptCallBack, &corruptInfo,
87         placeholders::_1, placeholders::_2, placeholders::_3, std::ref(isCalled));
88     g_manager->SetKvStoreCorruptionHandler(notifier);
89     std::string dbFliePath = DistributedDBNbTestTools::GetKvNbStoreDirectory(g_dbParameter1);
90     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
91 
92     /**
93      * @tc.steps: step2. set isNeedIntegrityCheck = true, isNeedRmCorruptedDb = false when open db and check the
94      *  corruption callback is whether triggered or not.
95      * @tc.expected: step2. open db failed and the callback is triggered.
96      */
97     option.isNeedIntegrityCheck = true;
98     option.isNeedRmCorruptedDb = false;
99     DBStatus status;
100     KvStoreDelegateManager *manager = nullptr;
101     EXPECT_EQ(DistributedDBNbTestTools::GetNbDelegateStatus(manager, status, g_dbParameter1, option), nullptr);
102     EXPECT_EQ(status, INVALID_PASSWD_OR_CORRUPTED_DB);
103     EXPECT_TRUE(isCalled);
104 
105     /**
106      * @tc.steps: step3. set isNeedIntegrityCheck = true, isNeedRmCorruptedDb = true when open db and check the
107      *  corruption callback is whether triggered or not.
108      * @tc.expected: step3. open db success and the callback isn't triggered.
109      */
110     option.isNeedRmCorruptedDb = true;
111     isCalled = false;
112     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, option);
113     ASSERT_TRUE(g_manager != nullptr && delegate != nullptr);
114     EXPECT_FALSE(isCalled);
115     g_manager->SetKvStoreCorruptionHandler(nullptr);
116     EXPECT_TRUE(EndCaseDeleteDB(g_manager, delegate, STORE_ID_1, option.isMemoryDb));
117 }
118 
119 /*
120  * @tc.name: DbDamageRecover 002
121  * @tc.desc: Verify that set isNeedIntegrityCheck and isNeedRmCorruptedDb when open db, if open successfully, the data
122  * insert before db damaged is lost and the db can CRUD normally.
123  * @tc.type: FUNC
124  * @tc.require: SR000D4878
125  * @tc.author: fengxiaoyun
126  */
127 HWTEST_F(DistributedbNbDbDamageTest, DbDamageRecover002, TestSize.Level1)
128 {
129     Option option = g_option;
130     /**
131      * @tc.steps: step1. device A put (k1,v1), close db and call SetKvStoreCorruptionHandler and make db file corrupted.
132      * @tc.expected: step1. operate successfully.
133      */
134     KvStoreNbDelegate *delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, option);
135     ASSERT_NE(g_manager, nullptr);
136     ASSERT_NE(delegate, nullptr);
137     EXPECT_EQ(DistributedDBNbTestTools::Put(*delegate, KEY_1, VALUE_1), OK);
138     EXPECT_EQ(g_manager->CloseKvStore(delegate), OK);
139     delegate = nullptr;
140     KvStoreNbCorruptInfo corruptInfo;
141     bool isCalled = false;
142     auto notifier = bind(&KvStoreNbCorruptInfo::CorruptCallBack, &corruptInfo,
143         placeholders::_1, placeholders::_2, placeholders::_3, std::ref(isCalled));
144     g_manager->SetKvStoreCorruptionHandler(notifier);
145     std::string dbFliePath = DistributedDBNbTestTools::GetKvNbStoreDirectory(g_dbParameter1);
146     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
147 
148     /**
149      * @tc.steps: step2. set isNeedIntegrityCheck = false, isNeedRmCorruptedDb = true when open db and check the
150      *  corruption callback is whether triggered or not.
151      * @tc.expected: step2. open db success and the callback isn't triggered.
152      */
153     option.isNeedIntegrityCheck = false;
154     option.isNeedRmCorruptedDb = true;
155     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, option);
156     ASSERT_TRUE(g_manager != nullptr && delegate != nullptr);
157     EXPECT_FALSE(isCalled);
158 
159     /**
160      * @tc.steps: step4. Get(k1), put(k1,v1)(k2,v2), delete(k1), put(k2,v3), Get(k1)(k2).
161      * @tc.expected: step4. Get(k1)=null, put and delete successfully, Get(k1)=v1, Get(k2)=v3.
162      */
163     EXPECT_TRUE(DistributedDBNbTestTools::CheckNbRecord(delegate, KEY_1, VALUE_EMPTY));
164     EXPECT_EQ(DistributedDBNbTestTools::Put(*delegate, KEY_1, VALUE_1), OK);
165     EXPECT_EQ(DistributedDBNbTestTools::Put(*delegate, KEY_2, VALUE_2), OK);
166     EXPECT_EQ(DistributedDBNbTestTools::Delete(*delegate, KEY_2), OK);
167     EXPECT_EQ(DistributedDBNbTestTools::Put(*delegate, KEY_1, VALUE_2), OK);
168     EXPECT_TRUE(DistributedDBNbTestTools::CheckNbRecord(delegate, KEY_1, VALUE_2));
169     EXPECT_TRUE(DistributedDBNbTestTools::CheckNbRecord(delegate, KEY_2, VALUE_EMPTY));
170     g_manager->SetKvStoreCorruptionHandler(nullptr);
171     EXPECT_TRUE(EndCaseDeleteDB(g_manager, delegate, STORE_ID_1, option.isMemoryDb));
172 }
173 #endif
174 /*
175  * @tc.name: DbDamageRecover 003
176  * @tc.desc: Verify that the db is damaged after db is opened, open db again won't trigger damage recover even set
177  *  isNeedIntegrityCheck and isNeedRmCorruptedDb.
178  * @tc.type: FUNC
179  * @tc.require: SR000D4878
180  * @tc.author: fengxiaoyun
181  */
182 HWTEST_F(DistributedbNbDbDamageTest, DbDamageRecover003, TestSize.Level1)
183 {
184     Option option = g_option;
185     /**
186      * @tc.steps: step1. device A open delegate1 and don't close, call SetKvStoreCorruptionHandler and make db file
187      *  corrupted.
188      * @tc.expected: step1. operate successfully.
189      */
190     KvStoreDelegateManager *manager1 = nullptr;
191     KvStoreNbDelegate *delegate1 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager1, g_dbParameter1, option);
192     ASSERT_NE(manager1, nullptr);
193     ASSERT_NE(delegate1, nullptr);
194 
195     KvStoreNbCorruptInfo corruptInfo;
196     bool isCalled = false;
197     auto notifier = bind(&KvStoreNbCorruptInfo::CorruptCallBack, &corruptInfo,
198         placeholders::_1, placeholders::_2, placeholders::_3, std::ref(isCalled));
199     g_manager->SetKvStoreCorruptionHandler(notifier);
200     std::string dbFliePath = DistributedDBNbTestTools::GetKvNbStoreDirectory(g_dbParameter1);
201     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
202     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath + "-wal"));
203 
204     /**
205      * @tc.steps: step2. set isNeedIntegrityCheck = true, isNeedRmCorruptedDb = false when open db and check the
206      *  corruption callback is whether triggered or not.
207      * @tc.expected: step2. open db successfully and the callback isn't triggered.
208      */
209     option.isNeedIntegrityCheck = true;
210     option.isNeedRmCorruptedDb = false;
211     KvStoreDelegateManager *manager2 = nullptr;
212     KvStoreNbDelegate *delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter1, option);
213     ASSERT_NE(manager2, nullptr);
214     ASSERT_NE(delegate2, nullptr);
215     EXPECT_FALSE(isCalled);
216 
217     /**
218      * @tc.steps: step3. close delegate1 and do step 2 again.
219      * @tc.expected: step3. open db success and the callback isn't triggered.
220      */
221     EXPECT_TRUE(DistributedTestTools::CloseAndRelease(manager1, delegate1));
222     delegate1 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager1, g_dbParameter1, option);
223     ASSERT_NE(manager1, nullptr);
224     ASSERT_NE(delegate1, nullptr);
225     EXPECT_FALSE(isCalled);
226 
227     /**
228      * @tc.steps: step4. device A put(k1,v1) and check the corruption callback.
229      * @tc.expected: step4. put failed and return INVALID_PASSWD_OR_CORRUPTED_DB, the callback is triggered.
230      */
231     EXPECT_EQ(DistributedDBNbTestTools::Put(*delegate1, KEY_1, VALUE_1), INVALID_PASSWD_OR_CORRUPTED_DB);
232     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND)); // wait for callback complete for 1 second.
233     EXPECT_TRUE(isCalled);
234 
235     /**
236      * @tc.steps: step5. close delegate1,delegate2, then open db with isNeedIntegrityCheck = true,
237      *  isNeedRmCorruptedDb = false, and check the corruption callback.
238      * @tc.expected: step5. open failed and return INVALID_PASSWD_OR_CORRUPTED_DB, the callback is triggered.
239      */
240     EXPECT_TRUE(DistributedTestTools::CloseAndRelease(manager1, delegate1));
241     EXPECT_TRUE(DistributedTestTools::CloseAndRelease(manager2, delegate2));
242     DBStatus status;
243     isCalled = false;
244     EXPECT_EQ(DistributedDBNbTestTools::GetNbDelegateStatus(manager1, status, g_dbParameter1, option), nullptr);
245     EXPECT_EQ(status, INVALID_PASSWD_OR_CORRUPTED_DB);
246     EXPECT_TRUE(isCalled);
247     KvStoreDelegateManager Manager(APP_ID_1, USER_ID_1);
248     Manager.SetKvStoreCorruptionHandler(nullptr);
249     RemoveDir(DistributedDBConstant::NB_DIRECTOR);
250 }
251 } // end of namespace DistributedbNbDbDamageTest