• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 <unistd.h>
17 
18 #include <memory>
19 #include <string>
20 #include <thread>
21 
22 #include "common.h"
23 #include "block_data.h"
24 #include "rdb_errno.h"
25 #include "rdb_helper.h"
26 #include "rdb_open_callback.h"
27 #include "rdb_sql_log.h"
28 #include "rdb_store.h"
29 #include "rdb_store_manager.h"
30 #include "rdb_types.h"
31 #include "executor_pool.h"
32 #include "shared_block.h"
33 #include "sqlite_utils.h"
34 #include "values_bucket.h"
35 
36 using namespace testing::ext;
37 using namespace OHOS::NativeRdb;
38 using namespace OHOS::DistributedRdb;
39 
40 static constexpr int32_t MAX_THREAD = 8;
41 static constexpr int32_t MID_THREAD = 4;
42 static constexpr int32_t SLEEP_TIME = 500;
43 static constexpr int32_t MAX_SLEEP_TIME = 2000;
44 static constexpr int32_t JOURNAL_MAX_SIZE = 4096;
45 static constexpr int32_t JOURNAL_MIN_SIZE = 1024;
46 static constexpr double DEFAULT_SALARY = 100.5;
47 static constexpr int32_t AGE_NUM = 18;
48 
49 class RdbStoreStoreMultiTest : public testing::Test {
50 public:
51     static void SetUpTestCase(void);
52     static void TearDownTestCase(void);
53     void SetUp();
54     void TearDown();
55 
56     static std::shared_ptr<RdbStore> CreateRDB(const std::string &path,
57         bool encrypt = false, const std::string &bundleName = "");
58     static std::shared_ptr<RdbStore> CreateRDBSleep(const std::string &path,
59         bool encrypt = false, const std::string &bundleName = "");
60     static void InsertData(std::shared_ptr<RdbStore> rdbStore);
61     static void QueryData(std::shared_ptr<RdbStore> rdbStore);
62 };
63 
64 
SetUpTestCase(void)65 void RdbStoreStoreMultiTest::SetUpTestCase(void)
66 {
67 }
68 
TearDownTestCase(void)69 void RdbStoreStoreMultiTest::TearDownTestCase(void)
70 {
71 }
72 
SetUp()73 void RdbStoreStoreMultiTest::SetUp()
74 {
75 }
76 
TearDown()77 void RdbStoreStoreMultiTest::TearDown()
78 {
79 }
80 
81 class RDBCallback : public RdbOpenCallback {
82 public:
83     int OnCreate(RdbStore &store) override;
84     int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
85 };
86 
OnCreate(RdbStore & store)87 int RDBCallback::OnCreate(RdbStore &store)
88 {
89     return E_OK;
90 }
91 
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)92 int RDBCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
93 {
94     return E_OK;
95 }
96 
97 class CallbackSleep : public RdbOpenCallback {
98 public:
99     int OnCreate(RdbStore &store) override;
100     int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
101 };
102 
OnCreate(RdbStore & store)103 int CallbackSleep::OnCreate(RdbStore &store)
104 {
105     std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
106     return E_OK;
107 }
108 
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)109 int CallbackSleep::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
110 {
111     std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
112     return E_OK;
113 }
114 
CreateRDB(const std::string & path,bool encrypt,const std::string & bundleName)115 std::shared_ptr<RdbStore> RdbStoreStoreMultiTest::CreateRDB(const std::string &path,
116     bool encrypt, const std::string &bundleName)
117 {
118     int version = 1;
119     RdbStoreConfig config(path);
120     config.SetEncryptStatus(encrypt);
121     config.SetBundleName(bundleName);
122     RDBCallback helper;
123     int errCode = E_OK;
124     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, version, helper, errCode);
125     EXPECT_NE(store, nullptr);
126     return store;
127 }
128 
CreateRDBSleep(const std::string & path,bool encrypt,const std::string & bundleName)129 std::shared_ptr<RdbStore> RdbStoreStoreMultiTest::CreateRDBSleep(const std::string &path,
130     bool encrypt, const std::string &bundleName)
131 {
132     int version = 1;
133     RdbStoreConfig config(path);
134     config.SetEncryptStatus(encrypt);
135     config.SetBundleName(bundleName);
136     CallbackSleep helper;
137     int errCode = E_OK;
138     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, version, helper, errCode);
139     EXPECT_NE(store, nullptr);
140     return store;
141 }
142 
InsertData(std::shared_ptr<RdbStore> rdbStore)143 void RdbStoreStoreMultiTest::InsertData(std::shared_ptr<RdbStore> rdbStore)
144 {
145     const std::string createTable =
146     std::string("CREATE TABLE IF NOT EXISTS test ") + std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, "
147                                                                   "name TEXT NOT NULL, age INTEGER, salary "
148                                                                   "REAL, blobType BLOB)");
149     rdbStore->Execute(createTable);
150     int64_t id;
151     ValuesBucket values;
152 
153     values.PutInt("id", 1);
154     values.PutString("name", std::string("zhangsan"));
155     values.PutInt("age", AGE_NUM);
156     values.PutDouble("salary", DEFAULT_SALARY);
157     values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
158     int ret = rdbStore->Insert(id, "test", values);
159     EXPECT_EQ(ret, E_OK);
160     EXPECT_EQ(1, id);
161 }
162 
QueryData(std::shared_ptr<RdbStore> rdbStore)163 void RdbStoreStoreMultiTest::QueryData(std::shared_ptr<RdbStore> rdbStore)
164 {
165     std::shared_ptr<ResultSet> resultSet = rdbStore->QuerySql("select * from test");
166     int ret = resultSet->GoToNextRow();
167     EXPECT_EQ(ret, E_OK);
168     int columnIndex;
169     std::string strVal;
170 
171     ret = resultSet->GetColumnIndex("name", columnIndex);
172     EXPECT_EQ(ret, E_OK);
173     ret = resultSet->GetString(columnIndex, strVal);
174     EXPECT_EQ(ret, E_OK);
175     EXPECT_EQ("zhangsan", strVal);
176 }
177 
178 std::string g_dbPaths[MAX_THREAD] = { "/data/test/store1.db", "/data/test/store2.db",
179     "/data/test/store3.db", "/data/test/store4.db", "/data/test/store5.db",
180     "/data/test/store6.db", "/data/test/store7.db", "/data/test/store8.db" };
181 
182 std::string g_dbBundlenames[MAX_THREAD] = { "com.ohos.test1", "com.ohos.test2",
183     "com.ohos.test3", "com.ohos.test4", "com.ohos.test5",
184     "com.ohos.test6", "com.ohos.test7", "com.ohos.test8" };
185 
186 /**
187  * @tc.name: GetRdbStoreTest_001
188  * @tc.desc: test Multithreading calls GetRdbStore with same store
189  * @tc.type: FUNC
190  * @tc.require:
191  * @tc.author:
192  */
193 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_001, TestSize.Level1)
194 {
195     std::string path = "/data/test/store.db";
196     std::shared_ptr<RdbStore> stores[MAX_THREAD];
197     std::thread threads[MAX_THREAD];
198     for (int i = 0; i < MAX_THREAD; ++i) {
__anon2ff4e1870102() 199         threads[i] = std::thread([i, &stores, &path]() {
200             stores[i] = RdbStoreStoreMultiTest::CreateRDB(path);
201         });
202     }
203     for (auto& t : threads) {
204         if (t.joinable()) {
205             t.join();
206         }
207     }
208     EXPECT_EQ(stores[0], stores[1]);
209     EXPECT_EQ(stores[1], stores[2]);
210     EXPECT_EQ(stores[2], stores[3]);
211     EXPECT_EQ(stores[3], stores[4]);
212     EXPECT_EQ(stores[4], stores[5]);
213     EXPECT_EQ(stores[5], stores[6]);
214     EXPECT_EQ(stores[6], stores[7]);
215     RdbHelper::DeleteRdbStore(path);
216 }
217 
218 /**
219  * @tc.name: GetRdbStoreTest_002
220  * @tc.desc: test Multithreading calls GetRdbStore with same encrypt store
221  * @tc.type: FUNC
222  * @tc.require:
223  * @tc.author:
224  */
225 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_002, TestSize.Level1)
226 {
227     std::string path = "/data/test/encryptStore.db";
228     std::string bundleName = "com.ohos.test";
229     std::shared_ptr<RdbStore> stores[MAX_THREAD];
230     std::thread threads[MAX_THREAD];
231     for (int i = 0; i < MAX_THREAD; ++i) {
__anon2ff4e1870202() 232         threads[i] = std::thread([i, &stores, &path, &bundleName]() {
233             stores[i] = RdbStoreStoreMultiTest::CreateRDB(path, true, bundleName);
234         });
235     }
236     for (auto& t : threads) {
237         if (t.joinable()) {
238             t.join();
239         }
240     }
241 
242     EXPECT_EQ(stores[0], stores[1]);
243     EXPECT_EQ(stores[1], stores[2]);
244     EXPECT_EQ(stores[2], stores[3]);
245     EXPECT_EQ(stores[3], stores[4]);
246     EXPECT_EQ(stores[4], stores[5]);
247     EXPECT_EQ(stores[5], stores[6]);
248     EXPECT_EQ(stores[6], stores[7]);
249     RdbHelper::DeleteRdbStore(path);
250 }
251 
252 /**
253  * @tc.name: GetRdbStoreTest_003
254  * @tc.desc: test Multithreading calls GetRdbStore with diff store
255  * @tc.type: FUNC
256  * @tc.require:
257  * @tc.author:
258  */
259 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_003, TestSize.Level1)
260 {
261     std::shared_ptr<RdbStore> stores[MAX_THREAD];
262     std::thread threads[MAX_THREAD];
263     for (int i = 0; i < MID_THREAD; ++i) {
__anon2ff4e1870302() 264         threads[i] = std::thread([i, &stores]() {
265             stores[i] = RdbStoreStoreMultiTest::CreateRDB(g_dbPaths[i]);
266         });
267     }
268     for (int i = MID_THREAD; i < MAX_THREAD; ++i) {
__anon2ff4e1870402() 269         threads[i] = std::thread([i, &stores]() {
270             stores[i] = RdbStoreStoreMultiTest::CreateRDBSleep(g_dbPaths[i]);
271         });
272     }
273     for (int i = 0; i < MAX_THREAD; ++i) {
274         if (threads[i].joinable()) {
275             threads[i].join();
276         }
277         EXPECT_NE(stores[i], nullptr);
278     }
279     std::this_thread::sleep_for(std::chrono::milliseconds(MAX_SLEEP_TIME));
280     for (int i = 0; i < MAX_THREAD; ++i) {
281         RdbHelper::DeleteRdbStore(g_dbPaths[i]);
282     }
283 }
284 
285 /**
286  * @tc.name: GetRdbStoreTest_004
287  * @tc.desc: test Multithreading calls GetRdbStore with diff encrypt store
288  * @tc.type: FUNC
289  * @tc.require:
290  * @tc.author:
291  */
292 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_004, TestSize.Level1)
293 {
294     std::string bundleName = "com.ohos.test";
295     std::shared_ptr<RdbStore> stores[MAX_THREAD];
296     std::thread threads[MAX_THREAD];
297     for (int i = 0; i < MID_THREAD; ++i) {
__anon2ff4e1870502() 298         threads[i] = std::thread([i, &stores, &bundleName]() {
299             stores[i] = RdbStoreStoreMultiTest::CreateRDB(g_dbPaths[i], true, bundleName);
300         });
301     }
302     for (int i = MID_THREAD; i < MAX_THREAD; ++i) {
__anon2ff4e1870602() 303         threads[i] = std::thread([i, &stores, &bundleName]() {
304             stores[i] = RdbStoreStoreMultiTest::CreateRDBSleep(g_dbPaths[i], true, bundleName);
305         });
306     }
307     for (int i = 0; i < MAX_THREAD; ++i) {
308         if (threads[i].joinable()) {
309             threads[i].join();
310         }
311         EXPECT_NE(stores[i], nullptr);
312     }
313     std::this_thread::sleep_for(std::chrono::milliseconds(MAX_SLEEP_TIME));
314     for (int i = 0; i < MAX_THREAD; ++i) {
315         RdbHelper::DeleteRdbStore(g_dbPaths[i]);
316     }
317 }
318 
319 /**
320  * @tc.name: GetRdbStoreTest_005
321  * @tc.desc: test Multithreading calls GetRdbStore with diff encrypt store and store
322  * @tc.type: FUNC
323  * @tc.require:
324  * @tc.author:
325  */
326 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_005, TestSize.Level1)
327 {
328     std::string bundleName = "com.ohos.test";
329     std::shared_ptr<RdbStore> stores[MAX_THREAD];
330     std::thread threads[MAX_THREAD];
331     for (int i = 0; i < MID_THREAD; ++i) {
__anon2ff4e1870702() 332         threads[i] = std::thread([i, &stores, &bundleName]() {
333             stores[i] = RdbStoreStoreMultiTest::CreateRDB(g_dbPaths[i]);
334         });
335     }
336     for (int i = MID_THREAD; i < MAX_THREAD; ++i) {
__anon2ff4e1870802() 337         threads[i] = std::thread([i, &stores, &bundleName]() {
338             stores[i] = RdbStoreStoreMultiTest::CreateRDBSleep(g_dbPaths[i], true, bundleName);
339         });
340     }
341     for (int i = 0; i < MAX_THREAD; ++i) {
342         if (threads[i].joinable()) {
343             threads[i].join();
344         }
345         EXPECT_NE(stores[i], nullptr);
346     }
347     std::this_thread::sleep_for(std::chrono::milliseconds(MAX_SLEEP_TIME));
348     for (int i = 0; i < MAX_THREAD; ++i) {
349         RdbHelper::DeleteRdbStore(g_dbPaths[i]);
350     }
351 }
352 
353 /**
354  * @tc.name: GetRdbStoreTest_006
355  * @tc.desc: test Multithreading calls GetRdbStore with diff encrypt store with diff bundlename
356  * @tc.type: FUNC
357  * @tc.require:
358  * @tc.author:
359  */
360 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_006, TestSize.Level1)
361 {
362     std::shared_ptr<RdbStore> stores[MAX_THREAD];
363     std::thread threads[MAX_THREAD];
364     for (int i = 0; i < MAX_THREAD; ++i) {
__anon2ff4e1870902() 365         threads[i] = std::thread([i, &stores]() {
366             stores[i] = RdbStoreStoreMultiTest::CreateRDB(g_dbPaths[i], true, g_dbBundlenames[i]);
367         });
368     }
369     for (int i = 0; i < MAX_THREAD; ++i) {
370         if (threads[i].joinable()) {
371             threads[i].join();
372         }
373         EXPECT_NE(stores[i], nullptr);
374     }
375     std::this_thread::sleep_for(std::chrono::milliseconds(MAX_SLEEP_TIME));
376     for (int i = 0; i < MAX_THREAD; ++i) {
377         RdbHelper::DeleteRdbStore(g_dbPaths[i]);
378     }
379 }
380 
381 /**
382  * @tc.name: GetRdbStoreTest_007
383  * @tc.desc: test Multithreading calls GetRdbStore with diff config
384  * @tc.type: FUNC
385  * @tc.require:
386  * @tc.author:
387  */
388 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_007, TestSize.Level1)
389 {
390     std::string path = "/data/test/encrypt07store.db";
391     int version = 1;
392     RdbStoreConfig configA(path);
393     configA.SetEncryptStatus(true);
394     configA.SetBundleName("com.ohos.test");
395     RDBCallback helper;
396     int errCode = E_OK;
397     std::shared_ptr<RdbStore> storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
398     EXPECT_NE(storeA, nullptr);
399     RdbStoreStoreMultiTest::InsertData(storeA);
400     storeA = nullptr;
401 
402     RdbStoreConfig configB(path);
403     configB.SetEncryptStatus(false);
404     configB.SetBundleName("com.ohos.test");
405     std::shared_ptr<RdbStore> storeB = RdbHelper::GetRdbStore(configB, version, helper, errCode);
406     EXPECT_NE(storeB, nullptr);
407     RdbStoreStoreMultiTest::QueryData(storeB);
408 
409     RdbHelper::DeleteRdbStore(path);
410 }
411 
412 /**
413  * @tc.name: GetRdbStoreTest_008
414  * @tc.desc: test Multithreading calls GetRdbStore with diff config
415  * @tc.type: FUNC
416  * @tc.require:
417  * @tc.author:
418  */
419 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_008, TestSize.Level1)
420 {
421     std::string path = "/data/test/store.db";
422     int version = 1;
423     RdbStoreConfig configA(path);
424     configA.SetJournalSize(JOURNAL_MAX_SIZE);
425     configA.SetBundleName("com.ohos.test");
426     RDBCallback helper;
427     int errCode = E_OK;
428     std::shared_ptr<RdbStore> storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
429     EXPECT_NE(storeA, nullptr);
430 
431     RdbStoreConfig configB(path);
432     configB.SetBundleName("com.ohos.test");
433     configB.SetJournalSize(JOURNAL_MIN_SIZE);
434     std::shared_ptr<RdbStore> storeB = RdbHelper::GetRdbStore(configB, version, helper, errCode);
435     EXPECT_NE(storeB, nullptr);
436     EXPECT_NE(storeA, storeB);
437 
438     std::shared_ptr<RdbStore> storeC = RdbHelper::GetRdbStore(configB, version, helper, errCode);
439     EXPECT_EQ(storeB, storeC);
440     RdbHelper::DeleteRdbStore(path);
441 }
442 
443 /**
444  * @tc.name: GetRdbStoreTest_009
445  * @tc.desc: test Multithreading calls GetRdbStore with diff config and allowRebuild
446  * @tc.type: FUNC
447  * @tc.require:
448  * @tc.author:
449  */
450 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_009, TestSize.Level1)
451 {
452     std::string path = "/data/test/encrypt09store.db";
453     int version = 1;
454     RdbStoreConfig configA(path);
455     configA.SetEncryptStatus(false);
456     configA.SetAllowRebuild(true);
457     configA.SetBundleName("com.ohos.test");
458     RDBCallback helper;
459     int errCode = E_OK;
460     std::shared_ptr<RdbStore> storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
461     ASSERT_NE(storeA, nullptr);
462     RdbStoreStoreMultiTest::InsertData(storeA);
463     storeA = nullptr;
464 
465     RdbStoreConfig configB(path);
466     configB.SetEncryptStatus(true);
467     configB.SetAllowRebuild(true);
468     configB.SetBundleName("com.ohos.test");
469     std::shared_ptr<RdbStore> storeB = RdbHelper::GetRdbStore(configB, version, helper, errCode);
470     ASSERT_NE(storeB, nullptr);
471     auto rebuilt = RebuiltType::NONE;
472     storeB->GetRebuilt(rebuilt);
473     EXPECT_EQ(rebuilt, RebuiltType::NONE);
474     RdbStoreStoreMultiTest::QueryData(storeB);
475 
476     RdbHelper::DeleteRdbStore(path);
477 }
478 
479 /**
480  * @tc.name: GetRdbStoreTest_010
481  * @tc.desc: 1. Create encrypted and non-encrypted databases
482  *           2. Insert a piece of data into a non-encrypted database
483  *           3. Delete encrypted database
484  *           4. Rename the non-encrypted database as an encrypted database
485  *           5. Open with non-encrypted parameters to query data
486  * @tc.type: FUNC
487  * @tc.require:
488  * @tc.author:
489  */
490 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_010, TestSize.Level1)
491 {
492     std::string path1 = "/data/test/encrypt10store.db";
493     std::string path1Wal = "/data/test/encrypt10store.db-wal";
494     std::string path1Shm = "/data/test/encrypt10store.db-shm";
495     std::string path2 = "/data/test/10store.db";
496     std::string path2Wal = "/data/test/10store.db-wal";
497     std::string path2Shm = "/data/test/10store.db-shm";
498     int version = 1;
499     RdbStoreConfig configA(path1);
500     configA.SetEncryptStatus(true);
501     configA.SetAllowRebuild(true);
502     configA.SetBundleName("com.ohos.test");
503     RDBCallback helper;
504     int errCode = E_OK;
505     std::shared_ptr<RdbStore> storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
506     ASSERT_NE(storeA, nullptr);
507     storeA = nullptr;
508 
509     RdbStoreConfig configB(path2);
510     configB.SetEncryptStatus(false);
511     configB.SetAllowRebuild(true);
512     configB.SetBundleName("com.ohos.test");
513     std::shared_ptr<RdbStore> storeB = RdbHelper::GetRdbStore(configB, version, helper, errCode);
514     ASSERT_NE(storeB, nullptr);
515     RdbStoreStoreMultiTest::InsertData(storeB);
516     storeB = nullptr;
517     // Delete the encrypted database path1, rename the database path2 to path1.
518     SqliteUtils::DeleteFile(path1);
519     SqliteUtils::DeleteFile(path1Wal);
520     SqliteUtils::DeleteFile(path1Shm);
521     SqliteUtils::RenameFile(path2, path1);
522     SqliteUtils::RenameFile(path2Wal, path1Wal);
523     SqliteUtils::RenameFile(path2Shm, path1Shm);
524     // The current database of path1 is actually a non-encrypted database,
525     // and the data content is the original data content of path2.
526     configA.SetEncryptStatus(false);
527     storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
528     ASSERT_NE(storeA, nullptr);
529     RdbStoreStoreMultiTest::QueryData(storeA);
530     storeA = nullptr;
531 
532     RdbHelper::DeleteRdbStore(path1);
533 }
534 
535 /**
536  * @tc.name: GetRdbStoreTest_011
537  * @tc.desc: 1. Create encrypted and non-encrypted databases
538  *           2. Insert a piece of data into a non-encrypted database
539  *           3. Delete encrypted database
540  *           4. Rename the non-encrypted database as an encrypted database
541  *           5. Open with encrypted parameters to query data
542  * @tc.type: FUNC
543  * @tc.require:
544  * @tc.author:
545  */
546 HWTEST_F(RdbStoreStoreMultiTest, GetRdbStoreTest_011, TestSize.Level1)
547 {
548     std::string path1 = "/data/test/encrypt11store.db";
549     std::string path1Wal = "/data/test/encrypt11store.db-wal";
550     std::string path1Shm = "/data/test/encrypt11store.db-shm";
551     std::string path2 = "/data/test/11store.db";
552     std::string path2Wal = "/data/test/11store.db-wal";
553     std::string path2Shm = "/data/test/11store.db-shm";
554     int version = 1;
555     RdbStoreConfig configA(path1);
556     configA.SetEncryptStatus(true);
557     configA.SetAllowRebuild(true);
558     configA.SetBundleName("com.ohos.test");
559     RDBCallback helper;
560     int errCode = E_OK;
561     std::shared_ptr<RdbStore> storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
562     ASSERT_NE(storeA, nullptr);
563     storeA = nullptr;
564 
565     RdbStoreConfig configB(path2);
566     configB.SetEncryptStatus(false);
567     configB.SetAllowRebuild(true);
568     configB.SetBundleName("com.ohos.test");
569     std::shared_ptr<RdbStore> storeB = RdbHelper::GetRdbStore(configB, version, helper, errCode);
570     ASSERT_NE(storeB, nullptr);
571     RdbStoreStoreMultiTest::InsertData(storeB);
572     storeB = nullptr;
573     // Delete the encrypted database path1, rename the database path2 to path1, and open path1.
574     SqliteUtils::DeleteFile(path1);
575     SqliteUtils::DeleteFile(path1Wal);
576     SqliteUtils::DeleteFile(path1Shm);
577     SqliteUtils::RenameFile(path2, path1);
578     SqliteUtils::RenameFile(path2Wal, path1Wal);
579     SqliteUtils::RenameFile(path2Shm, path1Shm);
580     // The current database of path1 is actually a non-encrypted database, and it cannot be opened
581     // using encryption parameters. The reconstruction was successful, but there is no data in the table.
582     storeA = RdbHelper::GetRdbStore(configA, version, helper, errCode);
583     ASSERT_NE(storeA, nullptr);
584     RebuiltType rebuiltType;
585     storeA->GetRebuilt(rebuiltType);
586     EXPECT_EQ(rebuiltType, RebuiltType::REBUILT);
587     std::shared_ptr<ResultSet> resultSet = storeA->QuerySql("select * from test");
588     int ret = resultSet->GoToNextRow();
589     EXPECT_EQ(ret, E_SQLITE_ERROR);
590     storeA = nullptr;
591 
592     RdbHelper::DeleteRdbStore(path1);
593 }