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