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 
16 #include "rdb_store_impl.h"
17 
18 #include <gtest/gtest.h>
19 
20 #include <map>
21 #include <string>
22 
23 #include "common.h"
24 #include "rdb_errno.h"
25 #include "rdb_helper.h"
26 #include "rdb_open_callback.h"
27 #include "relational_store_delegate.h"
28 #include "relational_store_manager.h"
29 #include "sqlite_connection.h"
30 
31 using namespace testing::ext;
32 using namespace OHOS::NativeRdb;
33 
34 class RdbStoreImplTest : public testing::Test {
35 public:
36     static void SetUpTestCase(void);
37     static void TearDownTestCase(void);
38     void SetUp();
39     void TearDown();
40 
41     static const std::string DATABASE_NAME;
42 
43 protected:
44     std::shared_ptr<RdbStore> store_;
45 };
46 
47 const std::string RdbStoreImplTest::DATABASE_NAME = RDB_TEST_PATH + "stepResultSet_impl_test.db";
48 
49 class RdbStoreImplTestOpenCallback : public RdbOpenCallback {
50 public:
51     int OnCreate(RdbStore &store) override;
52     int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
53 };
54 
OnCreate(RdbStore & store)55 int RdbStoreImplTestOpenCallback::OnCreate(RdbStore &store)
56 {
57     return E_OK;
58 }
59 
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)60 int RdbStoreImplTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
61 {
62     return E_OK;
63 }
64 
SetUpTestCase(void)65 void RdbStoreImplTest::SetUpTestCase(void)
66 {
67 }
68 
TearDownTestCase(void)69 void RdbStoreImplTest::TearDownTestCase(void)
70 {
71 }
72 
SetUp(void)73 void RdbStoreImplTest::SetUp(void)
74 {
75     store_ = nullptr;
76     int errCode = RdbHelper::DeleteRdbStore(DATABASE_NAME);
77     EXPECT_EQ(E_OK, errCode);
78     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
79     RdbStoreImplTestOpenCallback helper;
80     store_ = RdbHelper::GetRdbStore(config, 1, helper, errCode);
81     EXPECT_NE(store_, nullptr);
82     EXPECT_EQ(errCode, E_OK);
83 }
84 
TearDown(void)85 void RdbStoreImplTest::TearDown(void)
86 {
87     store_ = nullptr;
88     RdbHelper::ClearCache();
89     int errCode = RdbHelper::DeleteRdbStore(DATABASE_NAME);
90     EXPECT_EQ(E_OK, errCode);
91 }
92 
93 /* *
94  * @tc.name: GetModifyTimeByRowIdTest_001
95  * @tc.desc: Normal testCase for GetModifyTime, get timestamp by id
96  * @tc.type: FUNC
97  */
98 HWTEST_F(RdbStoreImplTest, GetModifyTimeByRowIdTest_001, TestSize.Level2)
99 {
100     store_->ExecuteSql("CREATE TABLE naturalbase_rdb_aux_rdbstoreimpltest_integer_log "
101                        "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, data_key INTEGER, "
102                        "data3 FLOAT, data4 BLOB, data5 BOOLEAN);");
103     int64_t rowId;
104     ValuesBucket valuesBucket;
105     valuesBucket.PutInt("data_key", ValueObject(1));
106     valuesBucket.PutInt("timestamp", ValueObject(1000000000));
107     int errorCode = store_->Insert(rowId, "naturalbase_rdb_aux_rdbstoreimpltest_integer_log", valuesBucket);
108     EXPECT_EQ(E_OK, errorCode);
109     EXPECT_EQ(1, rowId);
110 
111     std::vector<RdbStore::PRIKey> PKey = { 1 };
112     std::map<RdbStore::PRIKey, RdbStore::Date> result =
113         store_->GetModifyTime("rdbstoreimpltest_integer", "ROWID", PKey);
114     int size = result.size();
115     EXPECT_EQ(1, size);
116     EXPECT_EQ(100000, int64_t(result[1]));
117 
118     store_->ExecuteSql("DROP TABLE IF EXISTS naturalbase_rdb_aux_rdbstoreimpltest_integer_log");
119 }
120 
121 /* *
122  * @tc.name: GetModifyTimeByRowIdTest_002
123  * @tc.desc: Abnormal testCase for GetModifyTime, get timestamp by id,
124  *           resultSet is empty or table name is not exist
125  * @tc.type: FUNC
126  */
127 HWTEST_F(RdbStoreImplTest, GetModifyTimeByRowIdTest_002, TestSize.Level2)
128 {
129     store_->ExecuteSql("CREATE TABLE naturalbase_rdb_aux_rdbstoreimpltest_integer_log "
130                        "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, data_key INTEGER, "
131                        "data3 FLOAT, data4 BLOB, data5 BOOLEAN);");
132     int64_t rowId;
133     ValuesBucket valuesBucket;
134     valuesBucket.PutInt("data_key", ValueObject(2));
135     int errorCode = store_->Insert(rowId, "naturalbase_rdb_aux_rdbstoreimpltest_integer_log", valuesBucket);
136     EXPECT_EQ(E_OK, errorCode);
137     EXPECT_EQ(1, rowId);
138 
139     // resultSet is empty
140     std::vector<RdbStore::PRIKey> PKey = { 1 };
141     std::map<RdbStore::PRIKey, RdbStore::Date> result =
142         store_->GetModifyTime("rdbstoreimpltest_integer", "ROWID", PKey);
143     int size = result.size();
144     EXPECT_EQ(0, size);
145 
146     // table name is  not exist , resultSet is null
147     result = store_->GetModifyTime("test", "ROWID", PKey);
148     size = result.size();
149     EXPECT_EQ(0, size);
150 
151     store_->ExecuteSql("DROP TABLE IF EXISTS naturalbase_rdb_aux_rdbstoreimpltest_integer_log");
152 }
153 
154 /* *
155  * @tc.name: GetModifyTimeByRowIdTest_003
156  * @tc.desc: Abnormal testCase for GetModifyTime, get timestamp by id,
157  *           resultSet is empty or table name is not exist
158  * @tc.type: FUNC
159  */
160 HWTEST_F(RdbStoreImplTest, GetModifyTimeByRowIdTest_003, TestSize.Level2)
161 {
162     store_->ExecuteSql("CREATE TABLE naturalbase_rdb_aux_rdbstoreimpltest_integer_log "
163                        "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, data_key INTEGER, "
164                        "data3 FLOAT, data4 BLOB, data5 BOOLEAN);");
165     int64_t rowId;
166     ValuesBucket valuesBucket;
167     valuesBucket.PutInt("data_key", ValueObject(1));
168     int errorCode = store_->Insert(rowId, "naturalbase_rdb_aux_rdbstoreimpltest_integer_log", valuesBucket);
169     EXPECT_EQ(E_OK, errorCode);
170     EXPECT_EQ(1, rowId);
171 
172     std::vector<RdbStore::PRIKey> PKey = { 1 };
173     RdbStore::ModifyTime resultMapTmp = store_->GetModifyTime("rdbstoreimpltest_integer", "ROWID", PKey);
174     std::map<RdbStore::PRIKey, RdbStore::Date> resultMap = std::map<RdbStore::PRIKey, RdbStore::Date>(resultMapTmp);
175     EXPECT_EQ(1, resultMap.size());
176 
177     RdbStore::ModifyTime resultPtrTmp = store_->GetModifyTime("rdbstoreimpltest_integer", "ROWID", PKey);
178     std::shared_ptr<ResultSet> resultPtr = std::shared_ptr<ResultSet>(resultPtrTmp);
179     int count = 0;
180     resultPtr->GetRowCount(count);
181     EXPECT_EQ(1, count);
182 
183     RdbStore::ModifyTime result = store_->GetModifyTime("rdbstoreimpltest_integer", "ROWID", PKey);
184     RdbStore::PRIKey key = result.GetOriginKey(std::vector<uint8_t>{});
185     RdbStore::PRIKey monostate = std::monostate();
186     EXPECT_EQ(monostate, key);
187     EXPECT_EQ(8, result.GetMaxOriginKeySize());
188 
189     store_->ExecuteSql("DROP TABLE IF EXISTS naturalbase_rdb_aux_rdbstoreimpltest_integer_log");
190 }
191 
192 /* *
193  * @tc.name: GetModifyTime_001
194  * @tc.desc: Abnormal testCase for GetModifyTime, tablename columnName, keys is empty,
195  *           and resultSet is null or empty
196  * @tc.type: FUNC
197  */
198 HWTEST_F(RdbStoreImplTest, GetModifyTime_001, TestSize.Level2)
199 {
200     store_->ExecuteSql("CREATE TABLE naturalbase_rdb_aux_rdbstoreimpltest_integer_log "
201                        "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, data_key INTEGER, "
202                        "data3 FLOAT, data4 BLOB, data5 BOOLEAN);");
203 
204     // table name is ""
205     std::vector<RdbStore::PRIKey> PKey = { 1 };
206     std::map<RdbStore::PRIKey, RdbStore::Date> result = store_->GetModifyTime("", "data_key", PKey);
207     int size = result.size();
208     EXPECT_EQ(0, size);
209 
210     // table name is not exist , query resultSet is null
211     result = store_->GetModifyTime("test", "data_key", PKey);
212     size = result.size();
213     EXPECT_EQ(0, size);
214 
215     // columnName is ""
216     result = store_->GetModifyTime("test", "", PKey);
217     size = result.size();
218     EXPECT_EQ(0, size);
219 
220     // keys is empty
221     std::vector<RdbStore::PRIKey> emptyPRIKey;
222     result = store_->GetModifyTime("test", "data_key", emptyPRIKey);
223     size = result.size();
224     EXPECT_EQ(0, size);
225 
226     store_->ExecuteSql("DROP TABLE IF EXISTS naturalbase_rdb_aux_rdbstoreimpltest_integer_log");
227 }
228 
229 /* *
230  * @tc.name: GetModifyTime_002
231  * @tc.desc: Abnormal testCase for GetModifyTime, get timestamp by data3 ,if query resultSet is empty
232  * @tc.type: FUNC
233  */
234 HWTEST_F(RdbStoreImplTest, GetModifyTime_002, TestSize.Level2)
235 {
236     store_->ExecuteSql("CREATE TABLE naturalbase_rdb_aux_rdbstoreimpltest_integer_log "
237                        "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, hash_key INTEGER, "
238                        "data3 FLOAT, data4 BLOB, data5 BOOLEAN);");
239 
240     std::vector<RdbStore::PRIKey> PKey = { 1 };
241     std::map<RdbStore::PRIKey, RdbStore::Date> result =
242         store_->GetModifyTime("rdbstoreimpltest_integer", "data3", PKey);
243     EXPECT_EQ(0, result.size());
244 
245     store_->ExecuteSql("DROP TABLE IF EXISTS naturalbase_rdb_aux_rdbstoreimpltest_integer_log");
246 }
247 
248 /* *
249  * @tc.name: Rdb_BatchInsertTest_001
250  * @tc.desc: Abnormal testCase for BatchInsert, if initialBatchValues is empty
251  * @tc.type: FUNC
252  */
253 HWTEST_F(RdbStoreImplTest, Rdb_BatchInsertTest_001, TestSize.Level2)
254 {
255     std::vector<ValuesBucket> valuesBuckets;
256     int64_t insertNum = 1;
257     int ret = store_->BatchInsert(insertNum, "test", valuesBuckets);
258     EXPECT_EQ(0, insertNum);
259     EXPECT_EQ(E_OK, ret);
260 }
261 
262 /* *
263  * @tc.name: Rdb_BatchInsertTest_002
264  * @tc.desc: Abnormal testCase for BatchInsert, if column is not exist.
265  * @tc.type: FUNC
266  */
267 HWTEST_F(RdbStoreImplTest, Rdb_BatchInsertTest_002, TestSize.Level2)
268 {
269     store_->ExecuteSql("CREATE TABLE batchInsertTest "
270                        "(id INTEGER PRIMARY KEY AUTOINCREMENT, data INTEGER, data1 INTEGER, "
271                        "data2 INTEGER);");
272     ValuesBucket valuesBucket;
273     valuesBucket.PutInt("data", ValueObject(0));
274     valuesBucket.PutInt("data1", ValueObject(1));
275     valuesBucket.PutInt("data2", ValueObject(2));
276     valuesBucket.PutInt("NonexistentColumn", ValueObject(3));
277     std::vector<ValuesBucket> valuesBuckets = { valuesBucket };
278     int64_t insertNum = 1;
279     int ret = store_->BatchInsert(insertNum, "batchInsertTest", valuesBuckets);
280     EXPECT_EQ(-1, insertNum);
281     EXPECT_EQ(E_OK, ret);
282 }
283 
284 /* *
285  * @tc.name: Rdb_QueryTest_001
286  * @tc.desc: Abnormal testCase for Query, if table name is empty
287  * @tc.type: FUNC
288  */
289 HWTEST_F(RdbStoreImplTest, Rdb_QueryTest_001, TestSize.Level2)
290 {
291     int errCode = E_OK;
292     store_->Query(errCode, true, "", {}, "", std::vector<ValueObject>{}, "", "", "", 1, 0);
293     EXPECT_NE(E_OK, errCode);
294 }
295 
296 /* *
297  * @tc.name: Rdb_QueryTest_002
298  * @tc.desc: Normal testCase for Query, get * form test
299  * @tc.type: FUNC
300  */
301 HWTEST_F(RdbStoreImplTest, Rdb_QueryTest_002, TestSize.Level2)
302 {
303     store_->ExecuteSql("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, "
304                        "data2 INTEGER, data3 FLOAT, data4 BLOB, data5 BOOLEAN);");
305     int errCode = E_OK;
306     store_->Query(errCode, true, "test", {}, "", std::vector<ValueObject>{}, "", "", "", 1, 0);
307     EXPECT_EQ(E_OK, errCode);
308 
309     store_->ExecuteSql("DROP TABLE IF EXISTS test");
310 }
311 
312 /* *
313  * @tc.name: Rdb_RemoteQueryTest_001
314  * @tc.desc: Abnormal testCase for RemoteQuery
315  * @tc.type: FUNC
316  */
317 HWTEST_F(RdbStoreImplTest, Rdb_RemoteQueryTest_001, TestSize.Level2)
318 {
319     int errCode = E_OK;
320     AbsRdbPredicates predicates("test");
321     predicates.EqualTo("id", 1);
322 
323     // GetRdbService failed if rdbstoreconfig bundlename_ empty
324     auto ret = store_->RemoteQuery("", predicates, {}, errCode);
325     EXPECT_EQ(E_INVALID_ARGS, errCode);
326     EXPECT_EQ(nullptr, ret);
327     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
328 
329     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
330     config.SetName("RdbStore_impl_test.db");
331     config.SetBundleName("com.example.distributed.rdb");
332     RdbStoreImplTestOpenCallback helper;
333     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
334     EXPECT_EQ(E_OK, errCode);
335 
336     // GetRdbService succeeded if configuration file has already been configured
337     ret = store->RemoteQuery("", predicates, {}, errCode);
338     EXPECT_NE(E_OK, errCode);
339     EXPECT_EQ(nullptr, ret);
340 
341     store = nullptr;
342     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
343 }
344 
345 /* *
346  * @tc.name: Rdb_RollbackTest_001
347  * @tc.desc: Abnormal testCase for Rollback
348  * @tc.type: FUNC
349  */
350 HWTEST_F(RdbStoreImplTest, Rdb_RollbackTest_001, TestSize.Level2)
351 {
352     int ret = store_->RollBack();
353     EXPECT_EQ(OHOS::NativeRdb::E_NO_TRANSACTION_IN_SESSION, ret);
354 }
355 
356 /* *
357  * @tc.name: Rdb_CommitTest_001
358  * @tc.desc: Abnormal testCase for Commit,if not use BeginTransaction
359  * @tc.type: FUNC
360  */
361 HWTEST_F(RdbStoreImplTest, Rdb_CommitTest_001, TestSize.Level2)
362 {
363     int ret = store_->Commit();
364     EXPECT_EQ(E_OK, ret);
365 }
366 
367 /* *
368  * @tc.name: Rdb_BackupTest_001
369  * @tc.desc: Abnormal testCase for Backup
370  * @tc.type: FUNC
371  */
372 HWTEST_F(RdbStoreImplTest, Rdb_BackupTest_001, TestSize.Level2)
373 {
374     int errCode = E_OK;
375     std::string databasePath = RDB_TEST_PATH + "test.db";
376     std::vector<uint8_t> destEncryptKey;
377     // isEncrypt_ is false, and destEncryptKey is emtpy
378     errCode = store_->Backup(databasePath, destEncryptKey);
379     EXPECT_EQ(E_OK, errCode);
380     RdbHelper::DeleteRdbStore(databasePath);
381 
382     // isEncrypt_ is false, and destEncryptKey is not emtpy
383     destEncryptKey.push_back(1);
384     errCode = store_->Backup(databasePath, destEncryptKey);
385     EXPECT_EQ(E_OK, errCode);
386     store_ = nullptr;
387     RdbHelper::DeleteRdbStore(DATABASE_NAME);
388     RdbHelper::DeleteRdbStore(databasePath);
389 
390     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
391     config.SetEncryptStatus(true);
392     RdbStoreImplTestOpenCallback helper;
393     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
394     EXPECT_EQ(E_OK, errCode);
395 
396     // isEncrypt_ is true, and destEncryptKey is not emtpy
397     errCode = store->Backup(databasePath, destEncryptKey);
398     EXPECT_EQ(E_OK, errCode);
399     RdbHelper::DeleteRdbStore(databasePath);
400 
401     // isEncrypt_ is true, and destEncryptKey is not emtpy
402     destEncryptKey.pop_back();
403     errCode = store->Backup(databasePath, destEncryptKey);
404     EXPECT_EQ(E_OK, errCode);
405     store = nullptr;
406     RdbHelper::DeleteRdbStore(databasePath);
407     RdbHelper::DeleteRdbStore(DATABASE_NAME);
408 }
409 
410 /* *
411  * @tc.name: Rdb_SqlitConnectionTest_001
412  * @tc.desc: Abnormal testCase for SetPageSize,
413  *           return ok if open db again and set same page size
414  * @tc.type: FUNC
415  */
416 HWTEST_F(RdbStoreImplTest, Rdb_SqlitConnectionTest_001, TestSize.Level2)
417 {
418     const std::string DATABASE_NAME = RDB_TEST_PATH + "SqlitConnectionOpenTest.db";
419     RdbStoreConfig config(DATABASE_NAME);
420     config.SetReadOnly(false);
421     config.SetPageSize(1024);
422     auto [errCode, connection] = Connection::Create(config, true);
423     EXPECT_NE(nullptr, connection);
424     auto [err, statement] = connection->CreateStatement("PRAGMA page_size", connection);
425     auto [error, object] = statement->ExecuteForValue();
426     EXPECT_EQ(E_OK, error);
427     EXPECT_EQ(1024, static_cast<int64_t>(object));
428 
429     std::tie(errCode, connection) = Connection::Create(config, true);
430     EXPECT_NE(nullptr, connection);
431 }
432 
433 /* *
434  * @tc.name: Rdb_ConnectionPoolTest_001
435  * @tc.desc: Abnormal testCase for ConfigLocale
436  * @tc.type: FUNC
437  */
438 HWTEST_F(RdbStoreImplTest, Rdb_ConnectionPoolTest_001, TestSize.Level2)
439 {
440     const std::string DATABASE_NAME = RDB_TEST_PATH + "ConnectionOpenTest.db";
441     int errCode = E_OK;
442     RdbStoreConfig config(DATABASE_NAME);
443     config.SetReadConSize(1);
444     config.SetStorageMode(StorageMode::MODE_DISK);
445 
446     RdbStoreImplTestOpenCallback helper;
447     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
448     EXPECT_EQ(E_OK, errCode);
449 
450     auto connectionPool = ConnectionPool::Create(config, errCode);
451     EXPECT_NE(nullptr, connectionPool);
452     EXPECT_EQ(E_OK, errCode);
453 
454     // connecting database
455     auto connection = connectionPool->AcquireConnection(true);
456     EXPECT_NE(nullptr, connection);
457     errCode = connectionPool->ConfigLocale("AbnormalTest");
458     EXPECT_EQ(OHOS::NativeRdb::E_DATABASE_BUSY, errCode);
459 
460     store = nullptr;
461     RdbHelper::DeleteRdbStore(DATABASE_NAME);
462 }
463 
464 /* *
465  * @tc.name: Rdb_ConnectionPoolTest_002
466  * @tc.desc: Abnormal testCase for AcquireConnection/AcquireTransaction
467  * @tc.type: FUNC
468  */
469 HWTEST_F(RdbStoreImplTest, Rdb_ConnectionPoolTest_002, TestSize.Level2)
470 {
471     const std::string DATABASE_NAME = RDB_TEST_PATH + "ConnectionTest.db";
472     int errCode = E_OK;
473     RdbStoreConfig config(DATABASE_NAME);
474     config.SetReadConSize(1);
475     config.SetStorageMode(StorageMode::MODE_DISK);
476     auto connectionPool = ConnectionPool::Create(config, errCode);
477     EXPECT_NE(nullptr, connectionPool);
478     EXPECT_EQ(E_OK, errCode);
479 
480     // repeat AcquireReader without release
481     auto connection = connectionPool->AcquireConnection(true);
482     EXPECT_NE(nullptr, connection);
483     connection = connectionPool->AcquireConnection(true);
484     EXPECT_NE(nullptr, connection);
485     connection = connectionPool->AcquireConnection(true);
486     EXPECT_NE(nullptr, connection);
487 
488     // repeat AcquireWriter without release
489     connection = connectionPool->AcquireConnection(false);
490     EXPECT_NE(nullptr, connection);
491     connection = connectionPool->AcquireConnection(false);
492     EXPECT_EQ(nullptr, connection);
493     connection = connectionPool->AcquireConnection(false);
494     EXPECT_NE(nullptr, connection);
495 
496     // repeat AcquireTransaction without release
497     errCode = connectionPool->AcquireTransaction();
498     EXPECT_EQ(E_OK, errCode);
499     errCode = connectionPool->AcquireTransaction();
500     EXPECT_NE(E_OK, errCode);
501     connectionPool->ReleaseTransaction();
502 }
503 
504 /* *
505  * @tc.name: Rdb_ConnectionPoolTest_003
506  * @tc.desc: Abnormal testCase for ChangeDbFileForRestore
507  * @tc.type: FUNC
508  */
509 HWTEST_F(RdbStoreImplTest, Rdb_ConnectionPoolTest_0023, TestSize.Level2)
510 {
511     const std::string DATABASE_NAME = RDB_TEST_PATH + "ConnectionTest.db";
512     int errCode = E_OK;
513     RdbStoreConfig config(DATABASE_NAME);
514     config.SetReadConSize(1);
515     config.SetStorageMode(StorageMode::MODE_DISK);
516     auto connectionPool = ConnectionPool::Create(config, errCode);
517     EXPECT_NE(nullptr, connectionPool);
518     EXPECT_EQ(E_OK, errCode);
519 
520     const std::string newPath = DATABASE_NAME;
521     const std::string backupPath = DATABASE_NAME;
522     const std::vector<uint8_t> newKey;
523 
524     // newPath == currentPath, writeConnectionUsed == true
525     auto connection = connectionPool->AcquireConnection(false);
526     SlaveStatus curStatus;
527     errCode = connectionPool->ChangeDbFileForRestore(newPath, backupPath, newKey, curStatus);
528     EXPECT_EQ(E_ERROR, errCode);
529     connection = nullptr;
530     // newPath == currentPath
531     errCode = connectionPool->ChangeDbFileForRestore(newPath, backupPath, newKey, curStatus);
532     EXPECT_NE(E_OK, errCode);
533     // newPath != currentPath
534     const std::string newPath2 = RDB_TEST_PATH + "tmp.db";
535     errCode = connectionPool->ChangeDbFileForRestore(newPath2, backupPath, newKey, curStatus);
536     EXPECT_EQ(E_ERROR, errCode);
537 }
538 
539 HWTEST_F(RdbStoreImplTest, NotifyDataChangeTest_001, TestSize.Level2)
540 {
541     const std::string DATABASE_NAME = RDB_TEST_PATH + "SqlitConnectionOpenTest.db";
542     RdbStoreConfig config(DATABASE_NAME);
543     config.SetReadOnly(false);
544     config.SetPageSize(1024);
545     auto [errCode, connection] = SqliteConnection::Create(config, true);
546     EXPECT_NE(nullptr, connection);
547     RdbStoreImplTestOpenCallback helper;
548     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
549     EXPECT_NE(nullptr, store);
550 }
551 
552 HWTEST_F(RdbStoreImplTest, NotifyDataChangeTest_002, TestSize.Level2)
553 {
554     int errCode = E_OK;
555     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
556     config.SetReadOnly(false);
557     config.SetPageSize(1024);
558     config.SetBundleName("callback.test2");
559     config.SetSearchable(true);
560     config.SetStorageMode(StorageMode::MODE_DISK);
561     // register callback
562     RdbStoreImplTestOpenCallback helper;
563     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
564     EXPECT_NE(nullptr, store);
565     store->ExecuteSql("DROP TABLE IF EXISTS test_callback_t2;");
566     store->ExecuteSql("CREATE TABLE if not exists test_callback_t2 "
567                       "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, data_key INTEGER, "
568                       "data3 FLOAT, data4 BLOB, data5 BOOLEAN);");
569     // set TrackerTable
570     DistributedDB::TrackerSchema tracker;
571     tracker.tableName = "test_callback_t2";
572     tracker.extendColName = "";
573     tracker.trackerColNames = { "id", "timestamp" };
574     using Delegate = DistributedDB::RelationalStoreDelegate;
575     DistributedDB::RelationalStoreManager rStoreManager("test_app", "test_user_id", 0);
576     Delegate::Option option;
577     Delegate *g_delegate = nullptr;
578     EXPECT_EQ(RdbStoreImplTest::DATABASE_NAME, "/data/test/stepResultSet_impl_test.db");
579     int status = rStoreManager.OpenStore(RdbStoreImplTest::DATABASE_NAME, "test_callback_t2", option, g_delegate);
580     EXPECT_EQ(E_OK, status);
581     auto delegatePtr = std::shared_ptr<Delegate>(
__anon1a94843f0102(Delegate *delegate) 582         g_delegate, [&rStoreManager](Delegate *delegate) { rStoreManager.CloseStore(delegate); });
583     int setStatus = delegatePtr->SetTrackerTable(tracker);
584     EXPECT_EQ(E_OK, setStatus);
585 
586     int64_t rowId;
587     ValuesBucket valuesBucket;
588     valuesBucket.PutInt("data_key", ValueObject(1));
589     valuesBucket.PutInt("timestamp", ValueObject(1000000000));
590     int errorCode = store->Insert(rowId, "test_callback_t2", valuesBucket);
591     EXPECT_EQ(E_OK, errorCode);
592     EXPECT_EQ(1, rowId);
593     store->ExecuteSql("DROP TABLE IF EXISTS test_callback_t2;");
594 }
595 
596 HWTEST_F(RdbStoreImplTest, NotifyDataChangeTest_003, TestSize.Level2)
597 {
598     int errCode = E_OK;
599     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
600     config.SetReadOnly(false);
601     config.SetPageSize(1024);
602     config.SetBundleName("callback.test3");
603     config.SetSearchable(true);
604     config.SetStorageMode(StorageMode::MODE_DISK);
605 
606     RdbStoreImplTestOpenCallback helper;
607     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
608 
609     store->ExecuteSql("DROP TABLE IF EXISTS test_callback_t3;");
610 
611     store->ExecuteSql("CREATE TABLE if not exists test_callback_t3 "
612                       "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, data_key INTEGER, "
613                       "data3 FLOAT, data4 BLOB, data5 BOOLEAN);");
614     // set TrackerTable
615     DistributedDB::TrackerSchema tracker;
616     tracker.tableName = "test_callback_t3";
617     tracker.extendColName = "";
618     tracker.trackerColNames = { "id", "timestamp" };
619     using Delegate = DistributedDB::RelationalStoreDelegate;
620     DistributedDB::RelationalStoreManager rStoreManager("test_app", "test_user_id", 0);
621     Delegate::Option option;
622     Delegate *g_delegate = nullptr;
623     EXPECT_EQ(RdbStoreImplTest::DATABASE_NAME, "/data/test/stepResultSet_impl_test.db");
624     int status = rStoreManager.OpenStore(RdbStoreImplTest::DATABASE_NAME, "test_callback_t3", option, g_delegate);
625     EXPECT_EQ(E_OK, status);
626     auto delegatePtr = std::shared_ptr<Delegate>(
__anon1a94843f0202(Delegate *delegate) 627         g_delegate, [&rStoreManager](Delegate *delegate) { rStoreManager.CloseStore(delegate); });
628     int setStatus = delegatePtr->SetTrackerTable(tracker);
629     EXPECT_EQ(E_OK, setStatus);
630 
631     int64_t rowId;
632     ValuesBucket valuesBucket;
633     valuesBucket.PutInt("data_key", ValueObject(1));
634     valuesBucket.PutInt("timestamp", ValueObject(1000000000));
635     int errorCode = store->Insert(rowId, "test_callback_t3", valuesBucket);
636     EXPECT_EQ(E_OK, errorCode);
637     EXPECT_EQ(1, rowId);
638     errorCode = store->ExecuteSql("UPDATE test_callback_t3 SET timestamp = 100 WHERE id = 1;");
639     EXPECT_EQ(E_OK, errorCode);
640 
641     store->ExecuteSql("DROP TABLE IF EXISTS test_callback_t3;");
642 }
643 
644 /* *
645  * @tc.name: Rdb_QuerySharingResourceTest_001
646  * @tc.desc: QuerySharingResource testCase
647  * @tc.type: FUNC
648  */
649 HWTEST_F(RdbStoreImplTest, Rdb_QuerySharingResourceTest_001, TestSize.Level2)
650 {
651     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
652     int errCode = E_OK;
653     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
654     config.SetName("RdbStore_impl_test.db");
655     config.SetBundleName("com.example.distributed.rdb");
656 
657     RdbStoreImplTestOpenCallback helper;
658     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
659     EXPECT_NE(store, nullptr);
660     EXPECT_EQ(errCode, E_OK);
661     AbsRdbPredicates predicates("test");
662     predicates.EqualTo("id", 1);
663 
664     auto ret = store->QuerySharingResource(predicates, {});
665     EXPECT_NE(E_OK, ret.first);
666     EXPECT_EQ(nullptr, ret.second);
667     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
668 }
669 
670 /* *
671  * @tc.name: Rdb_QuerySharingResourceTest_002
672  * @tc.desc: QuerySharingResource testCase
673  * @tc.type: FUNC
674  */
675 HWTEST_F(RdbStoreImplTest, Rdb_QuerySharingResourceTest_002, TestSize.Level2)
676 {
677     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
678     int errCode = E_OK;
679     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
680     config.SetName("RdbStore_impl_test.db");
681     config.SetBundleName("com.example.distributed.rdb");
682 
683     RdbStoreImplTestOpenCallback helper;
684     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
685     EXPECT_NE(store, nullptr);
686     EXPECT_EQ(errCode, E_OK);
687     store->ExecuteSql("CREATE TABLE test_resource "
688                       "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, data_key INTEGER, "
689                       "data3 FLOAT, data4 BLOB, data5 BOOLEAN);");
690     int64_t rowId;
691     ValuesBucket valuesBucket;
692     valuesBucket.PutInt("data_key", ValueObject(1));
693     valuesBucket.PutInt("timestamp", ValueObject(1000000000));
694     int errorCode = store->Insert(rowId, "test_resource", valuesBucket);
695     EXPECT_EQ(E_OK, errorCode);
696     EXPECT_EQ(1, rowId);
697     AbsRdbPredicates predicates("test_resource");
698     predicates.EqualTo("data_key", 1);
699 
700     auto [status, resultSet] = store->QuerySharingResource(predicates, { "id", "data_key" });
701     EXPECT_NE(E_OK, status);
702     ASSERT_EQ(nullptr, resultSet);
703 
704     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
705 }
706 
707 /* *
708  * @tc.name: CleanDirtyDataTest_001
709  * @tc.desc: Abnormal testCase for CleanDirtyData
710  * @tc.type: FUNC
711  */
712 HWTEST_F(RdbStoreImplTest, Abnormal_CleanDirtyDataTest_001, TestSize.Level2)
713 {
714     store_->ExecuteSql("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, "
715                        "data2 INTEGER, data3 FLOAT, data4 BLOB, data5 BOOLEAN);");
716     int errCode = E_OK;
717 
718     // tabel is empty
719     std::string table = "";
720     uint64_t cursor = UINT64_MAX;
721     errCode = RdbStoreImplTest::store_->CleanDirtyData(table, cursor);
722     EXPECT_EQ(E_INVALID_ARGS, errCode);
723 
724     table = "test";
725     errCode = RdbStoreImplTest::store_->CleanDirtyData(table, cursor);
726     EXPECT_EQ(E_ERROR, errCode);
727     store_->ExecuteSql("DROP TABLE IF EXISTS test");
728 }
729 
730 /* *
731  * @tc.name: ClearCacheTest_001
732  * @tc.desc: Normal testCase for ClearCache
733  * @tc.type: FUNC
734  */
735 HWTEST_F(RdbStoreImplTest, Normal_ClearCacheTest_001, TestSize.Level2)
736 {
737     store_->ExecuteSql("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, "
738                        "data2 INTEGER, data3 FLOAT, data4 BLOB, data5 BOOLEAN);");
739     int errCode = E_OK;
740     int64_t id;
741     ValuesBucket valuesBucket;
742     valuesBucket.PutString("data1", std::string("zhangsan"));
743     valuesBucket.PutInt("data2", 10);
744     errCode = store_->Insert(id, "test", valuesBucket);
745     EXPECT_EQ(errCode, E_OK);
746     EXPECT_EQ(1, id);
747 
748     int rowCount;
749     std::shared_ptr<ResultSet> resultSet = store_->QueryByStep("SELECT * FROM test");
750     EXPECT_NE(resultSet, nullptr);
751     resultSet->GetRowCount(rowCount);
752     EXPECT_EQ(rowCount, 1);
753     int64_t currentMemory = sqlite3_memory_used();
754     EXPECT_EQ(E_OK, resultSet->Close());
755     EXPECT_LT(sqlite3_memory_used(), currentMemory);
756 }
757 
758 /* *
759  * @tc.name: LockCloudContainerTest
760  * @tc.desc: lock cloudContainer testCase
761  * @tc.type: FUNC
762  */
763 HWTEST_F(RdbStoreImplTest, LockCloudContainerTest, TestSize.Level2)
764 {
765     int errCode = E_OK;
766     // GetRdbService failed if rdbstoreconfig bundlename_ empty
767     auto ret = store_->LockCloudContainer();
768     EXPECT_EQ(E_INVALID_ARGS, ret.first);
769     EXPECT_EQ(0, ret.second);
770     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
771 
772     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
773     config.SetName("RdbStore_impl_test.db");
774     config.SetBundleName("com.example.distributed.rdb");
775     RdbStoreImplTestOpenCallback helper;
776     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
777     EXPECT_EQ(E_OK, errCode);
778     // GetRdbService succeeded if configuration file has already been configured
779     ret = store->LockCloudContainer();
780     EXPECT_NE(E_OK, ret.first);
781     store = nullptr;
782     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
783 }
784 
785 /* *
786  * @tc.name: UnlockCloudContainerTest
787  * @tc.desc: unlock cloudContainer testCase
788  * @tc.type: FUNC
789  */
790 HWTEST_F(RdbStoreImplTest, UnlockCloudContainerTest, TestSize.Level2)
791 {
792     int errCode = E_OK;
793     // GetRdbService failed if rdbstoreconfig bundlename_ empty
794     auto result = store_->UnlockCloudContainer();
795     EXPECT_EQ(E_INVALID_ARGS, result);
796     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
797 
798     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
799     config.SetName("RdbStore_impl_test.db");
800     config.SetBundleName("com.example.distributed.rdb");
801     RdbStoreImplTestOpenCallback helper;
802     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
803     EXPECT_EQ(E_OK, errCode);
804     // GetRdbService succeeded if configuration file has already been configured
805     result = store->UnlockCloudContainer();
806     EXPECT_NE(E_OK, result);
807     store = nullptr;
808     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
809 }
810 
811 /* *
812  * @tc.name: LockCloudContainerTest001
813  * @tc.desc: lock cloudContainer testCase
814  * @tc.type: FUNC
815  */
816 HWTEST_F(RdbStoreImplTest, LockCloudContainerTest001, TestSize.Level2)
817 {
818     int errCode = E_OK;
819     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
820     config.SetName("RdbStore_impl_test.db");
821     config.SetBundleName("com.example.distributed.rdb");
822     RdbStoreImplTestOpenCallback helper;
823     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
824     ASSERT_NE(store, nullptr);
825     EXPECT_EQ(E_OK, errCode);
826     // GetRdbService succeeded if configuration file has already been configured
827     auto ret = store->RdbStore::LockCloudContainer();
828     EXPECT_EQ(E_OK, ret.first);
829     EXPECT_EQ(0, ret.second);
830     store = nullptr;
831     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
832 }
833 
834 /* *
835  * @tc.name: UnlockCloudContainerTest001
836  * @tc.desc: unlock cloudContainer testCase
837  * @tc.type: FUNC
838  */
839 HWTEST_F(RdbStoreImplTest, UnlockCloudContainerTest001, TestSize.Level2)
840 {
841     int errCode = E_OK;
842     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
843     config.SetName("RdbStore_impl_test.db");
844     config.SetBundleName("com.example.distributed.rdb");
845     RdbStoreImplTestOpenCallback helper;
846     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
847     ASSERT_NE(store, nullptr);
848     EXPECT_EQ(E_OK, errCode);
849     // GetRdbService succeeded if configuration file has already been configured
850     auto result = store->RdbStore::UnlockCloudContainer();
851     EXPECT_EQ(E_OK, result);
852     store = nullptr;
853     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
854 }
855 
856 /* *
857  * @tc.name: SetSearchableTest
858  * @tc.desc: SetSearchable testCase
859  * @tc.type: FUNC
860  */
861 HWTEST_F(RdbStoreImplTest, SetSearchableTest, TestSize.Level2)
862 {
863     int errCode = E_OK;
864     RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME);
865     config.SetBundleName("");
866     RdbStoreImplTestOpenCallback helper;
867     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
868     EXPECT_EQ(E_OK, errCode);
869 
870     int result = store->SetSearchable(true);
871     EXPECT_EQ(E_INVALID_ARGS, result);
872     RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME);
873 
874     config.SetBundleName("com.example.distributed.rdb");
875     EXPECT_EQ(E_OK, errCode);
876     store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
877     EXPECT_EQ(E_OK, errCode);
878     result = store->SetSearchable(true);
879     EXPECT_EQ(E_OK, result);
880 }
881 
882 /* *
883  * @tc.name: CreateTransaction_001
884  * @tc.desc: create the DEFERRED, IMMEDIATE, EXCLUSIVE transaction.
885  * @tc.type: FUNC
886  */
887 HWTEST_F(RdbStoreImplTest, CreateTransaction_001, TestSize.Level1)
888 {
889     auto [errCode, trans] = store_->CreateTransaction(Transaction::DEFERRED);
890     ASSERT_EQ(errCode, E_OK);
891     ASSERT_NE(trans, nullptr);
892     trans = nullptr;
893     std::tie(errCode, trans) = store_->CreateTransaction(Transaction::IMMEDIATE);
894     ASSERT_EQ(errCode, E_OK);
895     ASSERT_NE(trans, nullptr);
896     trans = nullptr;
897     std::tie(errCode, trans) = store_->CreateTransaction(Transaction::EXCLUSIVE);
898     ASSERT_EQ(errCode, E_OK);
899     ASSERT_NE(trans, nullptr);
900 }
901 
902 /* *
903  * @tc.name: CreateTransaction_002
904  * @tc.desc: create the invalid type transaction.
905  * @tc.type: FUNC
906  */
907 HWTEST_F(RdbStoreImplTest, CreateTransaction_002, TestSize.Level1)
908 {
909     auto [errCode, trans] = store_->CreateTransaction(-1);
910     ASSERT_EQ(errCode, E_INVALID_ARGS);
911     ASSERT_EQ(trans, nullptr);
912     std::tie(errCode, trans) = store_->CreateTransaction(Transaction::TRANS_BUTT);
913     ASSERT_EQ(errCode, E_INVALID_ARGS);
914     ASSERT_EQ(trans, nullptr);
915     std::tie(errCode, trans) = store_->CreateTransaction(100);
916     ASSERT_EQ(errCode, E_INVALID_ARGS);
917     ASSERT_EQ(trans, nullptr);
918 }
919 
920 /* *
921  * @tc.name: CreateTransaction_003
922  * @tc.desc: create the over the max trans.
923  * @tc.type: FUNC
924  */
925 HWTEST_F(RdbStoreImplTest, CreateTransaction_003, TestSize.Level1)
926 {
927     constexpr size_t MAX_TRANS = 4;
928     std::vector<std::shared_ptr<Transaction>> entries;
929     int32_t errCode = E_OK;
930     std::shared_ptr<Transaction> trans = nullptr;
931     for (int i = 0; i < 100; ++i) {
932         std::tie(errCode, trans) = store_->CreateTransaction(Transaction::DEFERRED);
933         if (trans == nullptr) {
934             break;
935         }
936         entries.push_back(std::move(trans));
937     }
938     ASSERT_EQ(errCode, E_DATABASE_BUSY);
939     ASSERT_EQ(entries.size(), MAX_TRANS);
940 }
941 
942 /* *
943  * @tc.name: CreateTransaction_004
944  * @tc.desc: create the auto release trans.
945  * @tc.type: FUNC
946  */
947 HWTEST_F(RdbStoreImplTest, CreateTransaction_004, TestSize.Level1)
948 {
949     int i = 0;
950     for (i = 0; i < 20; ++i) {
951         auto [errCode, trans] = store_->CreateTransaction(Transaction::EXCLUSIVE);
952         ASSERT_EQ(errCode, E_OK);
953         ASSERT_NE(trans, nullptr);
954     }
955     ASSERT_EQ(i, 20);
956 }
957