diff --git a/services/BUILD.gn b/services/BUILD.gn index b269f07e4f45536470b414dab3bda87b140f5777..4d0e391f73294d40f695222e583b4243c464f9a5 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -177,7 +177,8 @@ ohos_shared_library("file_access_service") { "${user_file_service_path}/interfaces/inner_api/cloud_disk_kit_inner/include", "${user_file_service_path}/interfaces/inner_api/file_access/include", "${user_file_service_path}/services/native/file_access_service/include", - "${user_file_service_path}/services/native/notify_event/include" + "${user_file_service_path}/services/native/notify_event/include", + "${user_file_service_path}/services/rdb_adapter/include" ] shlib_type = "sa" sources = [ @@ -187,7 +188,8 @@ ohos_shared_library("file_access_service") { "native/file_access_service/src/file_access_ext_connection.cpp", "native/file_access_service/src/file_access_service.cpp", "native/file_access_service/src/file_access_service_client.cpp", - "native/notify_event/src/notify_work_service.cpp" + "native/notify_event/src/notify_work_service.cpp", + "rdb_adapter/src/ufs_rdb_adapter.cpp" ] configs = [ ":ability_config" ] version_script = "libfile_access_service.map" diff --git a/services/rdb_adapter/include/ufs_rdb_adapter.h b/services/rdb_adapter/include/ufs_rdb_adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..80b15d0802899fa56eaecd91e8c825cdcfdbe581 --- /dev/null +++ b/services/rdb_adapter/include/ufs_rdb_adapter.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_UFS_RDB_ADAPTER_H +#define OHOS_UFS_RDB_ADAPTER_H + +#include +#include +#include +#include +#include "rdb_helper.h" +#include "rdb_store.h" +#include "result_set.h" +#include +#include "rdb_open_callback.h" + +namespace OHOS { +namespace FileAccessFwk { + +using namespace OHOS::NativeRdb; + +class IRdbAdapter { +public: + virtual ~IRdbAdapter() = default; + + virtual bool Init() = 0; + virtual bool UnInit() = 0; + virtual bool Put(int64_t& outRowId, const std::string& table, const NativeRdb::ValuesBucket& Values) = 0; + virtual bool Delete(int32_t& deleteRows, const std::string& table, const std::string& whereClause, + const std::vector& bindArgs) = 0; + virtual bool Update(int32_t& changedRows, const std::string& table, const NativeRdb::ValuesBucket& values, + const std::string& whereClause, const std::vector& bindArgs) = 0; + virtual bool CreateTable() = 0; + virtual std::shared_ptr Get(const std::string& sql, + const std::vector& args) = 0; + virtual bool GetRDBPtr() = 0; +}; + +class RdbAdapter : public IRdbAdapter { +public: + RdbAdapter() = default; + ~RdbAdapter() override = default; + + bool Init() override; + bool UnInit() override; + bool Put(int64_t& outRowId, const std::string& table, const NativeRdb::ValuesBucket& Values) override; + bool Delete(int32_t& deleteRows, const std::string& table, const std::string& whereClause, + const std::vector& bindArgs = {}) override; + bool Update(int32_t& changedRows, const std::string& table, const NativeRdb::ValuesBucket& values, + const std::string& whereClause, const std::vector& bindArgs = {}) override; + bool CreateTable() override; + std::shared_ptr Get(const std::string& sql, + const std::vector& args = {}) override; + bool GetRDBPtr() override; + +private: + std::shared_ptr store_ = nullptr; + std::mutex rdbAdapterMtx_; +}; + +class OpenCallback : public NativeRdb::RdbOpenCallback { +public: + int32_t OnCreate(RdbStore& store) override; + int32_t OnUpgrade(RdbStore& store, int oldVersion, int newVersion) override; + bool CreateTable(RdbStore& store); + bool CreateUniqueIndex(RdbStore& store); +private: + std::mutex rdbStoreMtx_; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // OHOS_UFS_RDB_ADAPTER_H diff --git a/services/rdb_adapter/src/ufs_rdb_adapter.cpp b/services/rdb_adapter/src/ufs_rdb_adapter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..deed1781fb5f352e99030f82ad95f950ae0231d1 --- /dev/null +++ b/services/rdb_adapter/src/ufs_rdb_adapter.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2023-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "ufs_rdb_adapter.h" +#include "rdb_errno.h" +#include "hilog_wrapper.h" + +namespace OHOS { +namespace FileAccessFwk { +using namespace std::chrono_literals; + + +namespace { + const std::set TABLES = { + "synchronous_root_table", + }; + const std::string TAG = "UfsRdbAdapter"; + const std::string CREATE_SYNCHRONOUS_ROOT_TABLE_SQL = "CREATE TABLE IF NOT EXISTS synchronous_root_table \ + ( \ + path TEXT PRIMARY KEY, \ + state INTEGER, \ + displayName TEXT, \ + displayNameResId INTEGER, \ + bundleName TEXT, \ + userId INTEGER, \ + appIndex INTEGER, \ + lastModifyTime TEXT \ + );"; + constexpr const char* SYNCHRONOUS_ROOT_DATA_RDB_PATH = "/data/service/el1/public/database/ufs_db/"; + constexpr const char* SYNCHRONOUS_ROOT_DATABASE_NAME = "ufs_synchronous_root_db.db"; + const int32_t RDB_INIT_MAX_TIMES = 30; + const int32_t RDB_INIT_INTERVAL_TIME = 100000; + std::vector emp{}; +} + +bool RdbAdapter::Init() +{ + int32_t retryTimes = RDB_INIT_MAX_TIMES; + uint32_t attemptedTimes = 0; + while (retryTimes > 0) { + attemptedTimes++; + if (GetRDBPtr()) { + uint32_t totalTimeMs = (attemptedTimes - 1) * RDB_INIT_INTERVAL_TIME / 1000; + HILOG_INFO("rder init success, attempted times: %u, total time: %dms", + attemptedTimes, totalTimeMs); + return true; + } + usleep(RDB_INIT_INTERVAL_TIME); + retryTimes--; + } + uint32_t totalTimeMs = attemptedTimes * RDB_INIT_INTERVAL_TIME / 1000; + HILOG_ERROR("rdbit failed, attempted times: %u, total time: %dms", + attemptedTimes, totalTimeMs); + return false; +} + +bool RdbAdapter::UnInit() +{ + HILOG_INFO("rdbAdapter unInit"); + { + std::lock_guard lock(rdbAdapterMtx_); + store_ = nullptr; + } + return true; +} + +bool RdbAdapter::Put(int64_t& outRowId, const std::string& table, const ValuesBucket& values) +{ + if (TABLES.find(table) == TABLES.end()) { + HILOG_ERROR("table does not exist"); + return false; + } + { + std::lock_guard lock(rdbAdapterMtx_); + if (store_ == nullptr) { + HILOG_ERROR("RDBStore_ is null"); + return false; + } + int32_t ret = store_->Insert(outRowId, table, values); + if (ret == E_SQLITE_CORRUPT) { + HILOG_ERROR("database corrupt ret:%{public}d", ret); + int32_t restoreRet = store_->Restore("", emp); + if (restoreRet != E_OK) { + HILOG_ERROR("Restore failed restoreRet:%{public}d", restoreRet); + return false; + } + ret = store_->Insert(outRowId, table, values); + } + if (ret != E_OK) { + HILOG_ERROR("rdbAdapter put failed ret:%{public}d", ret); + return false; + } + } + return true; +} + +bool RdbAdapter::Delete(int32_t& deleteRows, const std::string& table, const std::string& whereClause, + const std::vector& bindArgs) +{ + if (TABLES.find(table) == TABLES.end()) { + HILOG_ERROR("table does not exist"); + return false; + } + { + std::lock_guard lock(rdbAdapterMtx_); + if (store_ == nullptr) { + HILOG_ERROR("RDBStore_ is null"); + return false; + } + int32_t ret = store_->Delete(deleteRows, table, whereClause, bindArgs); + if (ret == E_SQLITE_CORRUPT) { + HILOG_ERROR("database corrupt ret:%{public}d", ret); + int32_t restoreRet = store_->Restore("", emp); + if (restoreRet != E_OK) { + HILOG_ERROR("Restore failed restoreRet:%{public}d", restoreRet); + return false; + } + ret = store_->Delete(deleteRows, table, whereClause, bindArgs); + } + if (ret != E_OK) { + HILOG_ERROR("rdbAdapter delete failed ret:%{public}d", ret); + return false; + } + } + return true; +} + +bool RdbAdapter::Update(int32_t& changedRows, const std::string& table, const ValuesBucket& values, + const std::string& whereClause, const std::vector& bindArgs) +{ + if (TABLES.find(table) == TABLES.end()) { + HILOG_ERROR("table does not exist"); + return false; + } + { + if (store_ == nullptr) { + HILOG_ERROR("RDBStore_ is null"); + return false; + } + int32_t ret = store_->Update(changedRows, table, values, whereClause, bindArgs); + if (ret == E_SQLITE_CORRUPT) { + HILOG_ERROR("database corrupt ret:%{public}d", ret); + int32_t restoreRet = store_->Restore("", emp); + if (restoreRet != E_OK) { + HILOG_ERROR("Restore failed restoreRet:%{public}d", restoreRet); + return false; + } + ret = store_->Update(changedRows, table, values, whereClause, bindArgs); + } + if (ret != E_OK) { + HILOG_ERROR("rdbAdapter update failed ret:%{public}d", ret); + return false; + } + } + return true; +} + +std::shared_ptr RdbAdapter::Get(const std::string& sql, const std::vector& args) +{ + std::shared_ptr resultSet = nullptr; + { + if (store_ == nullptr) { + HILOG_ERROR("RDBStore_ is null"); + return nullptr; + } + resultSet = store_->QueryByStep(sql, args); + if (resultSet == nullptr) { + HILOG_ERROR("resultSet is null"); + return nullptr; + } + int32_t rowCount = -1; + int32_t ret = resultSet->GetRowCount(rowCount); + if (ret == E_SQLITE_CORRUPT) { + HILOG_ERROR("database corrupt ret:%{public}d", ret); + resultSet->Close(); + ret = store_->Restore("", emp); + if (ret != E_OK) { + HILOG_ERROR("Restore failed ret:%{public}d", ret); + return nullptr; + } + resultSet = store_->QueryByStep(sql, args); + } + } + return resultSet; +} + +bool RdbAdapter::GetRDBPtr() +{ + int32_t version = 1; + OpenCallback helper; + RdbStoreConfig config(std::string(SYNCHRONOUS_ROOT_DATA_RDB_PATH) + std::string(SYNCHRONOUS_ROOT_DATABASE_NAME)); + int32_t errCode = E_OK; + { + std::lock_guard lock(rdbAdapterMtx_); + if (store_ != nullptr) { + store_ = nullptr; + } + store_ = RdbHelper::GetRdbStore(config, version, helper, errCode); + if (errCode != E_OK) { + HILOG_ERROR("getRDBPtr failed errCode:%{public}d", errCode); + return false; + } + if (store_ == nullptr) { + HILOG_ERROR("RDBStore_ is null"); + return false; + } + NativeRdb::RebuiltType rebuiltType = NativeRdb::RebuiltType::NONE; + errCode = store_->GetRebuilt(rebuiltType); + if (errCode != E_OK) { + HILOG_ERROR("GetRebuilt failed errCode:%{public}d", errCode); + return false; + } + if (rebuiltType == NativeRdb::RebuiltType::REBUILT) { + HILOG_ERROR("database corrupt"); + int32_t restoreRet = store_->Restore("", emp); + if (restoreRet != E_OK) { + HILOG_ERROR("Restore failed restoreRet:%{public}d", restoreRet); + return false; + } + } + } + return true; +} + +bool RdbAdapter::CreateTable() +{ + std::lock_guard lock(rdbAdapterMtx_); + std::string sql = CREATE_SYNCHRONOUS_ROOT_TABLE_SQL; + if (store_ == nullptr) { + HILOG_ERROR("RDBStore_ is null"); + return false; + } + if (store_->ExecuteSql(sql) != E_OK) { + HILOG_ERROR("rdbAdapter create table failed"); + return false; + } + return true; +} + +int32_t OpenCallback::OnCreate(RdbStore& store) +{ + HILOG_INFO("rdbStore create"); + if (!CreateTable(store)) { + HILOG_ERROR("CreateTable failed"); + return -1; + } + HILOG_INFO("rdbStore create"); + return NativeRdb::E_OK; +} + +int32_t OpenCallback::OnUpgrade(RdbStore& store, int oldVersion, int newVersion) +{ + HILOG_INFO("rdbStore upgrade, oldVersion : %{public}d, newVersion : %{public}d", oldVersion, newVersion); + return NativeRdb::E_OK; +} + +bool OpenCallback::CreateTable(RdbStore& store) +{ + std::lock_guard lock(rdbStoreMtx_); + if (store.ExecuteSql(CREATE_SYNCHRONOUS_ROOT_TABLE_SQL) != NativeRdb::E_OK) { + HILOG_ERROR("synchronous_root_table create failed"); + return false; + } + return true; +} + +} // namespace FileAccessFwk +} // namespace OHOS diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 64ddccaffac9ce24be4639e7ca40dc51a34e3812..9752f45c5027f4019aca7326c88de5f49040389e 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -346,6 +346,61 @@ ohos_unittest("js_file_access_ext_ability_test") { use_exceptions = true } +ohos_unittest("ufs_rdb_adapter_test") { + branch_protector_ret = "pac_ret" + sanitize = { + integer_overflow = true + cfi = true + cfi_cross_dso = true + debug = false + } + module_out_path = "user_file_service/user_file_service" + + sources = [ + "ufs_rdb_adapter_test.cpp", + "${user_file_service_path}/services/rdb_adapter/src/ufs_rdb_adapter.cpp", + ] + + include_dirs = [ + "//foundation/filemanagement/user_file_service/interfaces/inner_api/file_access/include", + "//foundation/filemanagement/user_file_service/services/native/file_access_service/include", + "//foundation/filemanagement/user_file_service/services/rdb_adapter/include", + "//foundation/filemanagement/user_file_service/test/unittest/mock", + ] + + configs = [ "//build/config/compiler:exceptions" ] + + deps = [ + "${user_file_service_path}/services:file_access_service", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:app_context", + "ability_runtime:extensionkit_native", + "ability_runtime:napi_common", + "ability_runtime:runtime", + "access_token:libaccesstoken_sdk", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "file_api:filemgmt_libn", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "hitrace:hitrace_meter", + "init:libbegetutil", + "ipc:ipc_core", + "ipc:ipc_napi", + "napi:ace_napi", + "os_account:os_account_innerkits", + "relational_store:native_rdb", + ] + + defines = [ "private=public" ] + part_name = "user_file_service" +} + ohos_unittest("urie_test") { module_out_path = "user_file_service/user_file_service" sources = [ @@ -539,6 +594,7 @@ group("user_file_service_unit_test") { ":file_access_ext_stub_impl_test", ":js_file_access_ext_ability_test", ":notify_work_service_test", + ":ufs_rdb_adapter_test", ":urie_test", ] } \ No newline at end of file diff --git a/test/unittest/mock/rdb_store_mock.h b/test/unittest/mock/rdb_store_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..263da62e0d10fb818dd725fda196afe29c7d5a3b --- /dev/null +++ b/test/unittest/mock/rdb_store_mock.h @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef UFS_MOCK_RDB_H +#define UFS_MOCK_RDB_H +#include "gmock/gmock.h" +#include "rdb_store.h" +#include "rdb_helper.h" +namespace OHOS::FileAccessFwk { +namespace MOC { +static std::shared_ptr g_mockRdbStore = nullptr; +} +void MockGetRdbStore(std::shared_ptr mockRdbStore) +{ + MOC::g_mockRdbStore = mockRdbStore; +} +void MockSetRdbStore() +{ + MOC::g_mockRdbStore = nullptr; +} +} + +namespace OHOS::NativeRdb { +using namespace OHOS::FileAccessFwk; +inline std::shared_ptr RdbHelper::GetRdbStore( + const RdbStoreConfig& config, int version, RdbOpenCallback& openCallback, int& errCode) +{ + return MOC::g_mockRdbStore; +} +class MockResultSet : public AbsSharedResultSet { +public: + MOCK_METHOD(int, GoToFirstRow, (), (override)); + MOCK_METHOD(int, GoToNextRow, (), (override)); + MOCK_METHOD(int, GetString, (int columnIndex, std::string& value), (override)); + MOCK_METHOD(int, GetInt, (int columnIndex, int& value), (override)); + MOCK_METHOD(int, Close, (), (override)); + MOCK_METHOD(int, GetColumnCount, (int& count), (override)); + MOCK_METHOD(int, GetRowCount, (int &count), (override)); +}; +class MockRdbStore : public RdbStore { +public: + MockRdbStore() = default; + MOCK_METHOD(int, ExecuteSql, (const std::string& sql, const std::vector& bindArgs), (override)); + MOCK_METHOD(int, InsertWithConflictResolution, + (int64_t & outRowId, const std::string& table, const ValuesBucket& values, + ConflictResolution conflictResolution), + (override)); + + MOCK_METHOD(int, Delete, + (int& deletedRows, const std::string& table, const std::string& whereClause, + const std::vector& bindArgs), + (override)); + + MOCK_METHOD(std::shared_ptr, Query, + (const AbsRdbPredicates& predicates, const std::vector& columns), (override)); + MOCK_METHOD(int, BeginTransaction, (), (override)); + MOCK_METHOD(int, RollBack, (), (override)); + MOCK_METHOD(int, Commit, (), (override)); + MOCK_METHOD(int, Insert, (int64_t& outRowId, const std::string& table, + const ValuesBucket& initialValues), (override)); + MOCK_METHOD2(Restore, int(const std::string&, const std::vector&)); + MOCK_METHOD(int, Update, + (int& changedRows, const std::string& table, const ValuesBucket& values, + const std::string& whereClause, const std::vector& bindArgs), + (override)); + MOCK_METHOD(std::shared_ptr, QueryByStep, + (const std::string& sql, const std::vector& bindArgs, bool preCount), + (override)); + ~MockRdbStore() override = default; + + int BatchInsert( + int64_t& outInsertNum, const std::string& table, const std::vector& initialBatchValues) override + { + return NativeRdb::E_ERROR; + }; + int Replace(int64_t& outRowId, const std::string& table, const ValuesBucket& initialValues) override + { + return NativeRdb::E_ERROR; + }; + + int Update(int& changedRows, const std::string& table, const ValuesBucket& values, const std::string& whereClaus, + const std::vector& whereArgs) override + { + return NativeRdb::E_ERROR; + }; + int UpdateWithConflictResolution(int& changedRows, const std::string& table, const ValuesBucket& values, + const std::string& whereClause, const std::vector& whereArgs, + ConflictResolution conflictResolution) override + { + return NativeRdb::E_ERROR; + }; + int UpdateWithConflictResolution(int& changedRows, const std::string& table, const ValuesBucket& values, + const std::string& whereClause, const std::vector& bindArgs, + ConflictResolution conflictResolution) override + { + return NativeRdb::E_ERROR; + }; + + std::shared_ptr Query(int& errCode, bool distinct, const std::string& table, + const std::vector& columns, const std::string& whereClause, + const std::vector& bindArgs, const std::string& groupBy, const std::string& indexName, + const std::string& orderBy, const int& limit, const int& offset) override + { + return nullptr; + }; + std::shared_ptr QuerySql( + const std::string& sql, const std::vector& selectionArgs) override + { + return nullptr; + }; + std::shared_ptr QuerySql( + const std::string& sql, const std::vector& selectionArgs) override + { + return nullptr; + }; + std::shared_ptr QueryByStep( + const std::string& sql, const std::vector& selectionArgs) override + { + return nullptr; + }; + + int ExecuteAndGetLong(int64_t& outValue, const std::string& sql, const std::vector& bindArgs) override + { + return NativeRdb::E_ERROR; + }; + int ExecuteAndGetString( + std::string& outValue, const std::string& sql, const std::vector& bindArgs) override + { + return NativeRdb::E_ERROR; + }; + int ExecuteForLastInsertedRowId( + int64_t& outValue, const std::string& sql, const std::vector& bindArgs) override + { + return NativeRdb::E_ERROR; + }; + int ExecuteForChangedRowCount( + int64_t& outValue, const std::string& sql, const std::vector& bindArgs) override + { + return NativeRdb::E_ERROR; + }; + int Backup(const std::string& databasePath, const std::vector& destEncryptKey) override + { + return NativeRdb::E_ERROR; + }; + int Attach( + const std::string& alias, const std::string& pathName, const std::vector destEncryptKey) override + { + return NativeRdb::E_ERROR; + }; + + int Count(int64_t& outValue, const AbsRdbPredicates& predicates) override + { + return NativeRdb::E_ERROR; + }; + + std::shared_ptr QueryByStep( + const AbsRdbPredicates& predicates, const std::vector& columns, bool preCount) override + { + return nullptr; + }; + std::shared_ptr RemoteQuery(const std::string& device, const AbsRdbPredicates& predicates, + const std::vector& columns, int& errCode) override + { + return nullptr; + }; + int Update(int& changedRows, const ValuesBucket& values, const AbsRdbPredicates& predicates) override + { + return NativeRdb::E_ERROR; + }; + + virtual int GetStatus() + { + return NativeRdb::E_ERROR; + }; + virtual void SetStatus(int status) {}; + int GetVersion(int& version) override + { + return NativeRdb::E_ERROR; + }; + int SetVersion(int version) override + { + return NativeRdb::E_ERROR; + }; + + bool IsInTransaction() override + { + return false; + }; + std::string GetPath() override + { + return ""; + } + bool IsHoldingConnection() override + { + return false; + }; + bool IsOpen() const override + { + return false; + }; + bool IsReadOnly() const override + { + return false; + }; + bool IsMemoryRdb() const override + { + return false; + }; + virtual int ChangeDbFileForRestore( + const std::string newPath, const std::string backupPath, const std::vector& newKey) + { + return NativeRdb::E_ERROR; + }; + + int SetDistributedTables(const std::vector& tables, int type, + const DistributedRdb::DistributedConfig& distributedConfig) override + { + return E_ERROR; + }; + + std::string ObtainDistributedTableName(const std::string& device, const std::string& table, int& errCode) override + { + return ""; + } + + int Sync(const SyncOption& option, const AbsRdbPredicates& predicate, const AsyncBrief& async) override + { + return E_ERROR; + }; + + int Sync(const SyncOption& option, const AbsRdbPredicates& predicate, const AsyncDetail& async) override + { + return E_ERROR; + }; + + int Sync(const SyncOption& option, const std::vector& tables, const AsyncDetail& async) override + { + return E_ERROR; + }; + + int Subscribe(const SubscribeOption& option, std::shared_ptr observer) override + { + return E_ERROR; + }; + + int UnSubscribe(const SubscribeOption& option, std::shared_ptr observer) override + { + return E_ERROR; + }; + + int RegisterAutoSyncCallback(std::shared_ptr syncObserver) override + { + return E_ERROR; + }; + + int UnregisterAutoSyncCallback(std::shared_ptr syncObserver) override + { + return E_ERROR; + }; + + int Notify(const std::string& event) override + { + return E_ERROR; + } + + virtual bool DropDeviceData(const std::vector& devices, const DropOption& option) + { + return false; + }; + + ModifyTime GetModifyTime( + const std::string& table, const std::string& columnName, std::vector& keys) override + { + return {}; + }; + + int CleanDirtyData(const std::string& table, uint64_t cursor) override + { + return E_ERROR; + }; + + int GetRebuilt(RebuiltType& rebuilt) override + { + return E_OK; + } +}; + +} +#endif // UFS_MOCK_RDB_H diff --git a/test/unittest/ufs_rdb_adapter_test.cpp b/test/unittest/ufs_rdb_adapter_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4ad76aff4bfcaaeaec73ff937c69464974d38f22 --- /dev/null +++ b/test/unittest/ufs_rdb_adapter_test.cpp @@ -0,0 +1,804 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include "ufs_rdb_adapter.h" +#include "rdb_store_mock.h" + + +namespace OHOS { +namespace FileAccessFwk { +using namespace testing; +using namespace testing::ext; +using namespace OHOS::NativeRdb; + +namespace { + const std::string TAG = "rdbAdapterTest"; + const std::string SUCCESS_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS synchronous_root_table \ + ( \ + path TEXT PRIMARY KEY, \ + state INTEGER, \ + displayName TEXT, \ + displayNameResId INTEGER, \ + bundleName TEXT, \ + userId INTEGER, \ + appIndex INTEGER, \ + lastModifyTime TEXT \ + );"; + const std::string UN_SUCCESS_CREATE_TABLE_SQL = "NOT EXISTS \ + ( \ + path TEXT PRIMARY KEY, \ + state INTEGER, \ + displayName TEXT, \ + displayNameResId INTEGER, \ + bundleName TEXT, \ + userId INTEGER, \ + appIndex INTEGER, \ + lastModifyTime TEXT \ + );"; + const std::string PATH = "path"; + const std::string STATE = "state"; + const std::string DISPLAY_NAME = "displayName"; + const std::string DISPLAY_NAME_RES_ID = "displayNameResId"; + const std::string BUNDLENAME = "bundleName"; + const std::string USERID = "userId"; + const std::string INDEX = "appIndex"; + const std::string LAST_MODIFY_TIME = "lastModifyTime"; +} + +class RdbAdapterTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + static std::shared_ptr store; + static std::shared_ptr mockStore; // 添加一个静态成员来保存 Mock 对象 + static std::mutex rdbAdapterTestMtx; +}; + +std::shared_ptr RdbAdapterTest::store = nullptr; +std::shared_ptr RdbAdapterTest::mockStore = nullptr; +std::mutex RdbAdapterTest::rdbAdapterTestMtx; + +void RdbAdapterTest::SetUpTestCase(void) +{ + std::lock_guard lock(rdbAdapterTestMtx); + store = std::make_shared(); + mockStore = std::make_shared(); + MockGetRdbStore(mockStore); + store->store_ = mockStore; +} + +void RdbAdapterTest::TearDownTestCase(void) +{ + MockSetRdbStore(); + store = nullptr; + mockStore = nullptr; +} + +void RdbAdapterTest::SetUp() +{ + std::lock_guard lock(rdbAdapterTestMtx); + if (store->store_ == nullptr) { + store->store_ = mockStore; + } +} + +void RdbAdapterTest::TearDown() +{ + std::lock_guard lock(rdbAdapterTestMtx); + store->UnInit(); +} + +/** + * @tc.name: + * @tc.desc: UnInit success + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, UnInit001, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + auto errCode = store->UnInit(); + EXPECT_EQ(errCode, true); +} + +/** + * @tc.name: + * @tc.desc: CreateTable success + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, CreateTable001, TestSize.Level1) +{ + EXPECT_CALL(*mockStore, ExecuteSql(_, _)) + .WillOnce( + Return(0) + ); + std::lock_guard lock(rdbAdapterTestMtx); + auto errCode = store->CreateTable(); + EXPECT_EQ(errCode, true); +} + +/** + * @tc.name: + * @tc.desc: CreateTable failed + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, CreateTable002, TestSize.Level1) +{ + EXPECT_CALL(*mockStore, ExecuteSql(_, _)) + .WillOnce( + Return(-1) + ); + std::lock_guard lock(rdbAdapterTestMtx); + auto errCode = store->CreateTable(); + EXPECT_EQ(errCode, false); +} + +/** + * @tc.name: + * @tc.desc: CreateTable failed + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, CreateTable003, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + store->UnInit(); + auto errCode = store->CreateTable(); + EXPECT_EQ(errCode, false); +} + +/** + * @tc.name: + * @tc.desc: Put Success + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Put001, TestSize.Level1) +{ + EXPECT_CALL(*mockStore, Insert(_, _, _)) + .WillOnce( + Return(OHOS::NativeRdb::E_OK) + ); + std::lock_guard lock(rdbAdapterTestMtx); + int64_t outRowId = 0; + std::string table = "synchronous_root_table"; + ValuesBucket values; + values.PutString(BUNDLENAME, "bundleName"); + values.PutString(PATH, "path_"); + values.PutInt(STATE, 0); + values.PutInt(DISPLAY_NAME_RES_ID, 123); + values.PutInt(USERID, 100); + values.PutInt(INDEX, 001); + values.PutString("lastModifyTime", "currentTime"); + + int32_t putErrCode = store->Put(outRowId, table, values); + EXPECT_EQ(putErrCode, true); +} + +/** + * @tc.name: + * @tc.desc: Put table does not exist failed + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Put002, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + int64_t outRowId = 0; + std::string table = "trust_xxxdevice_table"; + ValuesBucket values; + values.PutString(BUNDLENAME, "bundleName"); + values.PutString(PATH, "path_"); + values.PutInt(STATE, 0); + values.PutInt(DISPLAY_NAME_RES_ID, 123); + values.PutInt(USERID, 100); + values.PutInt(INDEX, 001); + values.PutString("lastModifyTime", "currentTime"); + int32_t putErrCode = store->Put(outRowId, table, values); + EXPECT_EQ(putErrCode, false); +} + +/** + * @tc.name: + * @tc.desc: Put failed + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Put003, TestSize.Level1) +{ + EXPECT_CALL(*mockStore, Insert(_, _, _)) + .WillOnce( + Return(OHOS::NativeRdb::E_SQLITE_CORRUPT) + ); + EXPECT_CALL(*mockStore, Restore(_, _)) + .WillOnce( + Return(OHOS::NativeRdb::E_SQLITE_CORRUPT) + ); + std::lock_guard lock(rdbAdapterTestMtx); + int64_t outRowId1 = 0; + std::string table = "synchronous_root_table"; + ValuesBucket values; + values.PutString(BUNDLENAME, "bundleName"); + values.PutString(PATH, "path_"); + values.PutInt(STATE, 0); + values.PutInt(DISPLAY_NAME_RES_ID, 123); + values.PutInt(USERID, 100); + values.PutInt(INDEX, 001); + values.PutString("lastModifyTime", "currentTime"); + int32_t putErrCode1 = store->Put(outRowId1, table, values); + EXPECT_EQ(putErrCode1, false); +} + +/** + * @tc.name: + * @tc.desc: Put failed + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Put004, TestSize.Level1) +{ + EXPECT_CALL(*mockStore, Insert(_, _, _)) + .WillOnce( + Return(OHOS::NativeRdb::E_SQLITE_CORRUPT) + ).WillOnce( + Return(OHOS::NativeRdb::E_OK) + );; + EXPECT_CALL(*mockStore, Restore(_, _)) + .WillOnce( + Return(OHOS::NativeRdb::E_OK) + ); + + std::lock_guard lock(rdbAdapterTestMtx); + int64_t outRowId1 = 0; + std::string table = "synchronous_root_table"; + ValuesBucket values; + values.PutString(BUNDLENAME, "bundleName"); + values.PutString(PATH, "path_"); + values.PutInt(STATE, 0); + values.PutInt(DISPLAY_NAME_RES_ID, 123); + values.PutInt(USERID, 100); + values.PutInt(INDEX, 001); + values.PutString("lastModifyTime", "currentTime"); + int32_t putErrCode1 = store->Put(outRowId1, table, values); + EXPECT_EQ(putErrCode1, true); +} + +/** + * @tc.name: Put005 + * @tc.desc: Put failed, RDBStore_ is null. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Put005, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + int64_t outRowId = 0; + std::string table = "synchronous_root_table"; + ValuesBucket values; + values.PutString(BUNDLENAME, "bundleName"); + values.PutString(PATH, "path_"); + values.PutInt(STATE, 0); + values.PutInt(DISPLAY_NAME_RES_ID, 123); + values.PutInt(USERID, 100); + values.PutInt(INDEX, 001); + values.PutString("lastModifyTime", "currentTime"); + store->UnInit(); + int32_t putErrCode = store->Put(outRowId, table, values); + EXPECT_EQ(putErrCode, false); + store->Init(); +} + +/** + * @tc.name: + * @tc.desc: Delete success + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Delete001, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + std::string table = "synchronous_root_table"; + int32_t deleteRows = 0; + std::string whereClause = "deviceId = ?"; + ValueObject valueObject(std::string("111aaa")); + const std::vector& bindArgs = {valueObject}; + + EXPECT_CALL(*mockStore, Delete( + ::testing::Ref(deleteRows), + ::testing::Eq(table), + ::testing::Eq(whereClause), + ::testing::Eq(bindArgs) + )) + .WillOnce(Return(OHOS::NativeRdb::E_OK)); + + int32_t deleteErrCode = store->Delete(deleteRows, table, whereClause, bindArgs); + EXPECT_EQ(deleteErrCode, true); +} + +/** + * @tc.name: + * @tc.desc: Delete table does not exist failed + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Delete002, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + int32_t deleteRows = 0; + std::string deleteTable = "trust_xxxdevice_table"; + std::string whereClause = "deviceId = ?"; + ValueObject valueObject(std::string("111aaa")); + const std::vector& bindArgs = {valueObject}; + + int32_t deleteErrCode = store->Delete(deleteRows, deleteTable, whereClause, bindArgs); + EXPECT_EQ(deleteErrCode, false); +} + +/** + * @tc.name: + * @tc.desc: Delete failed, RDBStore_ is null. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Delete003, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + std::string table = "synchronous_root_table"; + int32_t deleteRows = 0; + std::string deleteTable = "synchronous_root_table"; + std::string whereClause = "xxxdeviceId = ?"; + ValueObject valueObject(std::string("111aaa")); + const std::vector& bindArgs = {valueObject}; + store->UnInit(); + int32_t deleteErrCode = store->Delete(deleteRows, deleteTable, whereClause, bindArgs); + EXPECT_EQ(deleteErrCode, false); +} + +/** + * @tc.name: Delete004 + * @tc.desc: Delete failed, Restore failed. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Delete004, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + std::string table = "synchronous_root_table"; + int32_t deleteRows = 0; + std::string whereClause = "deviceId = ?"; + ValueObject valueObject(std::string("111aaa")); + const std::vector& bindArgs = {valueObject}; + + EXPECT_CALL(*mockStore, Delete( + ::testing::Ref(deleteRows), + ::testing::Eq(table), + ::testing::Eq(whereClause), + ::testing::Eq(bindArgs) + )) + .WillOnce(Return(OHOS::NativeRdb::E_SQLITE_CORRUPT)); + + EXPECT_CALL(*mockStore, Restore(_, _)) + .WillOnce( + Return(OHOS::NativeRdb::E_SQLITE_CORRUPT) + ); + + int32_t deleteErrCode = store->Delete(deleteRows, table, whereClause, bindArgs); + EXPECT_EQ(deleteErrCode, false); +} + +/** + * @tc.name: Delete005 + * @tc.desc: Delete failed, Restore success. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Delete005, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + std::string table = "synchronous_root_table"; + int32_t deleteRows = 0; + std::string whereClause = "deviceId = ?"; + ValueObject valueObject(std::string("111aaa")); + const std::vector& bindArgs = {valueObject}; + + EXPECT_CALL(*mockStore, Delete( + ::testing::Ref(deleteRows), + ::testing::Eq(table), + ::testing::Eq(whereClause), + ::testing::Eq(bindArgs) + )) + .WillOnce(Return(OHOS::NativeRdb::E_SQLITE_CORRUPT)).WillOnce(Return(OHOS::NativeRdb::E_OK)); + + EXPECT_CALL(*mockStore, Restore(_, _)) + .WillOnce( + Return(OHOS::NativeRdb::E_OK) + ); + + int32_t deleteErrCode = store->Delete(deleteRows, table, whereClause, bindArgs); + EXPECT_EQ(deleteErrCode, true); +} + +/** + * @tc.name: + * @tc.desc: Update success + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Update001, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + std::string table = "synchronous_root_table"; + ValuesBucket newValues; + newValues.Clear(); + newValues.PutString("deviceId", std::string("111aaa")); + newValues.PutInt("deviceIdType", 3); + newValues.PutString("deviceIdHash", std::string("222bbb")); + newValues.PutInt("status", 2); + + int32_t changedRows = 0; + std::string whereClause = "deviceId = ?"; + ValueObject valueObject(std::string("111aaa")); + const std::vector& bindArgs = {valueObject}; + + EXPECT_CALL(*mockStore, Update( + ::testing::Ref(changedRows), + ::testing::Eq(table), + _, + ::testing::Eq(whereClause), + ::testing::Eq(bindArgs) + )) + .WillOnce(DoAll( + SetArgReferee<0>(1), + Return(OHOS::NativeRdb::E_OK) + )); + + auto updateErrCode = store->Update(changedRows, table, newValues, whereClause, bindArgs); + EXPECT_EQ(updateErrCode, true); +} + +/** + * @tc.name: + * @tc.desc: Update table does not exist failed + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Update002, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + std::string table = "synchXXXXus_root_table"; + ValuesBucket newValues; + newValues.Clear(); + newValues.PutString("deviceId", std::string("111aaa")); + newValues.PutInt("deviceIdType", 3); + newValues.PutString("deviceIdHash", std::string("222bbb")); + newValues.PutInt("status", 2); + + int32_t changedRows = 0; + std::string whereClause = "deviceId = ?"; + ValueObject valueObject(std::string("111aaa")); + const std::vector& bindArgs = {valueObject}; + + auto updateErrCode = store->Update(changedRows, table, newValues, whereClause, bindArgs); + EXPECT_EQ(updateErrCode, false); +} + +/** + * @tc.name: + * @tc.desc: Update failed + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Update003, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + std::string table = "synchronous_root_table"; + ValuesBucket newValues; + newValues.Clear(); + newValues.PutString("deviceId", std::string("111aaa")); + newValues.PutInt("deviceIdType", 3); + newValues.PutString("deviceIdHash", std::string("222bbb")); + newValues.PutInt("status", 2); + + int32_t changedRows = 0; + std::string whereClause = "deviceId = ?"; + ValueObject valueObject(std::string("111aaa")); + const std::vector& bindArgs = {valueObject}; + + EXPECT_CALL(*mockStore, Update( + ::testing::Ref(changedRows), + ::testing::Eq(table), + _, + ::testing::Eq(whereClause), + ::testing::Eq(bindArgs) + )) + .WillOnce(DoAll( + SetArgReferee<0>(1), + Return(OHOS::NativeRdb::E_SQLITE_CORRUPT) + )); + + EXPECT_CALL(*mockStore, Restore(_, _)) + .WillOnce( + Return(OHOS::NativeRdb::E_SQLITE_CORRUPT) + ); + auto updateErrCode = store->Update(changedRows, table, newValues, whereClause, bindArgs); + EXPECT_EQ(updateErrCode, false); +} + +/** + * @tc.name: + * @tc.desc: Update failed,retore success + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Update004, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + std::string table = "synchronous_root_table"; + ValuesBucket newValues; + newValues.Clear(); + newValues.PutString("deviceId", std::string("111aaa")); + newValues.PutInt("deviceIdType", 3); + newValues.PutString("deviceIdHash", std::string("222bbb")); + newValues.PutInt("status", 2); + + int32_t changedRows = 0; + std::string whereClause = "deviceId = ?"; + ValueObject valueObject(std::string("111aaa")); + const std::vector& bindArgs = {valueObject}; + + EXPECT_CALL(*mockStore, Update( + ::testing::Ref(changedRows), + ::testing::Eq(table), + _, + ::testing::Eq(whereClause), + ::testing::Eq(bindArgs) + )) + .WillOnce(DoAll( + SetArgReferee<0>(1), + Return(OHOS::NativeRdb::E_SQLITE_CORRUPT) + )).WillOnce(DoAll( + SetArgReferee<0>(1), + Return(OHOS::NativeRdb::E_OK) + )); + + EXPECT_CALL(*mockStore, Restore(_, _)) + .WillOnce( + Return(OHOS::NativeRdb::E_OK) + ); + + auto updateErrCode = store->Update(changedRows, table, newValues, whereClause, bindArgs); + EXPECT_EQ(updateErrCode, true); +} + +/** + * @tc.name: Update005 + * @tc.desc: Update failed, RDBStore_ is null. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Update005, TestSize.Level1) +{ + std::lock_guard lock(rdbAdapterTestMtx); + std::string table = "synchronous_root_table"; + ValuesBucket newValues; + newValues.Clear(); + newValues.PutString("deviceId", std::string("111aaa")); + newValues.PutInt("deviceIdType", 3); + newValues.PutString("deviceIdHash", std::string("222bbb")); + newValues.PutInt("status", 2); + + int32_t changedRows = 0; + std::string whereClause = "deviceId = ?"; + ValueObject valueObject(std::string("111aaa")); + const std::vector& bindArgs = {valueObject}; + + store->UnInit(); + int32_t updateErrCode = store->Update(changedRows, table, newValues, whereClause, bindArgs); + EXPECT_EQ(updateErrCode, false); +} + +/** + * @tc.name: + * @tc.desc: Get success + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Get001, TestSize.Level1) +{ + std::string sql = "SELECT * FROM users WHERE id = ?"; + std::vector bindArgs = { ValueObject(1) }; + + std::shared_ptr mockResultSet = std::make_shared(); + + EXPECT_CALL(*mockStore, QueryByStep( + ::testing::Eq(sql), + ::testing::Eq(bindArgs), + _)).WillOnce(Return(mockResultSet)); + + EXPECT_CALL(*mockResultSet, GetRowCount(_)) + .WillOnce(Return(OHOS::NativeRdb::E_OK)); + + std::lock_guard lock(rdbAdapterTestMtx); + std::shared_ptr resultSet = store->Get(sql, bindArgs); + EXPECT_NE(resultSet, nullptr); +} + +/** + * @tc.name: Get002 + * @tc.desc: Get failed, RDBStore_ is null. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Get002, TestSize.Level1) +{ + std::string sql = "SELECT * FROM users WHERE id = ?"; + std::vector bindArgs = { ValueObject(1) }; + + std::shared_ptr mockResultSet = std::make_shared(); + std::lock_guard lock(rdbAdapterTestMtx); + store->UnInit(); + std::shared_ptr resultSet = store->Get(sql, bindArgs); + EXPECT_EQ(resultSet, nullptr); +} + +/** + * @tc.name: Get003 + * @tc.desc: Get failed. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Get003, TestSize.Level1) +{ + std::string sql = "SELECT * FROM users WHERE id = ?"; + std::vector bindArgs = { ValueObject(1) }; + + std::shared_ptr mockResultSet = std::make_shared(); + + EXPECT_CALL(*mockStore, QueryByStep( + ::testing::Eq(sql), + ::testing::Eq(bindArgs), + _)).WillOnce(Return(mockResultSet)); + + EXPECT_CALL(*mockResultSet, GetRowCount(_)) + .WillOnce(Return(OHOS::NativeRdb::E_OK)); + + std::lock_guard lock(rdbAdapterTestMtx); + std::shared_ptr resultSet = store->Get(sql, bindArgs); + EXPECT_EQ(resultSet, mockResultSet); +} + +/** + * @tc.name: Get004 + * @tc.desc: Get failed. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Get004, TestSize.Level1) +{ + std::string sql = "SELECT * FROM users WHERE id = ?"; + std::vector bindArgs = { ValueObject(1) }; + + std::shared_ptr mockResultSet = std::make_shared(); + std::shared_ptr mockSecondResultSet = std::make_shared(); + + EXPECT_CALL(*mockStore, QueryByStep( + ::testing::Eq(sql), + ::testing::Eq(bindArgs), + _)).WillOnce(Return(mockResultSet)); + + EXPECT_CALL(*mockResultSet, GetRowCount(_)) + .WillOnce(Return(OHOS::NativeRdb::E_SQLITE_CORRUPT)); + EXPECT_CALL(*mockStore, Restore(_, _)) + .WillOnce( + Return(OHOS::NativeRdb::E_SQLITE_CORRUPT) + ); + + std::lock_guard lock(rdbAdapterTestMtx); + std::shared_ptr resultSet = store->Get(sql, bindArgs); + EXPECT_NE(resultSet, mockResultSet); +} + +/** + * @tc.name: Get005 + * @tc.desc: Get failed. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, Get005, TestSize.Level1) +{ + std::string sql = "SELECT * FROM users WHERE id = ?"; + std::vector bindArgs = { ValueObject(1) }; + + std::shared_ptr mockResultSet = std::make_shared(); + std::shared_ptr mockSecondResultSet = std::make_shared(); + + EXPECT_CALL(*mockStore, QueryByStep( + ::testing::Eq(sql), + ::testing::Eq(bindArgs), + _)).WillOnce(Return(mockResultSet)).WillOnce(Return(mockSecondResultSet)); + + EXPECT_CALL(*mockResultSet, GetRowCount(_)) + .WillOnce(Return(OHOS::NativeRdb::E_SQLITE_CORRUPT)); + EXPECT_CALL(*mockStore, Restore(_, _)) + .WillOnce( + Return(OHOS::NativeRdb::E_OK) + ); + + std::lock_guard lock(rdbAdapterTestMtx); + std::shared_ptr resultSet = store->Get(sql, bindArgs); + EXPECT_NE(resultSet, mockResultSet); + EXPECT_EQ(resultSet, mockSecondResultSet); +} + +/** + * @tc.name: OnCreate001 + * @tc.desc: OnCreate failed. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, OnCreate001, TestSize.Level1) +{ + OpenCallback helper; + EXPECT_CALL(*mockStore, ExecuteSql(_, _)) + .WillOnce( + Return(NativeRdb::E_SQLITE_CORRUPT) + ); + auto ret = helper.OnCreate(*(store->store_)); + EXPECT_EQ(ret, -1); +} + +/** + * @tc.name: OnCreate002 + * @tc.desc: OnCreate success. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, OnCreate002, TestSize.Level1) +{ + OpenCallback helper; + EXPECT_CALL(*mockStore, ExecuteSql(_, _)) + .WillOnce( + Return(NativeRdb::E_OK) + ); + auto ret = helper.OnCreate(*(store->store_)); + EXPECT_EQ(ret, NativeRdb::E_OK); +} + +/** + * @tc.name: OnUpgrade001 + * @tc.desc: OnCreate success. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbAdapterTest, OnUpgrade001, TestSize.Level1) +{ + OpenCallback helper; + int oldVersion = 1; + int newVersion = 2; + auto ret = helper.OnUpgrade(*(store->store_), oldVersion, newVersion); + EXPECT_EQ(ret, NativeRdb::E_OK); +} +} // namespace FileAccessFwk +} // namespace OHOS